[PATCH xf86-video-amdgpu] Simplify tracking of PRIME scanout pixmap
Deucher, Alexander
Alexander.Deucher at amd.com
Tue May 23 12:29:11 UTC 2017
> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-bounces at lists.freedesktop.org] On Behalf
> Of Michel Dänzer
> Sent: Friday, May 12, 2017 6:11 AM
> To: amd-gfx at lists.freedesktop.org
> Subject: [PATCH xf86-video-amdgpu] Simplify tracking of PRIME scanout
> pixmap
>
> From: Michel Dänzer <michel.daenzer at amd.com>
>
> Remember the shared pixmap passed to drmmode_set_scanout_pixmap for
> each
> CRTC, and just compare against that.
>
> Fixes leaving stale entries in ScreenRec::pixmap_dirty_list under some
> circumstances, which would usually result in use-after-free and a crash
> down the line.
>
> (Ported from radeon commit 7dc68e26755466f9056f8c72195ab8690660693d)
>
> Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
> ---
> src/amdgpu_kms.c | 7 ++-----
> src/drmmode_display.c | 21 +++++++++++----------
> src/drmmode_display.h | 3 +++
> 3 files changed, 16 insertions(+), 15 deletions(-)
>
> diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
> index 4df81f993..a418cf9d3 100644
> --- a/src/amdgpu_kms.c
> +++ b/src/amdgpu_kms.c
> @@ -562,8 +562,7 @@ amdgpu_prime_dirty_to_crtc(PixmapDirtyUpdatePtr
> dirty)
> xf86CrtcPtr xf86_crtc = xf86_config->crtc[c];
> drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc-
> >driver_private;
>
> - if (drmmode_crtc->scanout[0].pixmap == dirty->slave_dst ||
> - drmmode_crtc->scanout[1].pixmap == dirty-
> >slave_dst)
> + if (drmmode_crtc->prime_scanout_pixmap == dirty->src)
> return xf86_crtc;
> }
>
> @@ -576,13 +575,11 @@ amdgpu_prime_scanout_do_update(xf86CrtcPtr
> crtc, unsigned scanout_id)
> ScrnInfoPtr scrn = crtc->scrn;
> ScreenPtr screen = scrn->pScreen;
> drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
> - PixmapPtr scanoutpix = crtc->randr_crtc->scanout_pixmap;
> PixmapDirtyUpdatePtr dirty;
> Bool ret = FALSE;
>
> xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
> - if (dirty->src == scanoutpix && dirty->slave_dst ==
> - drmmode_crtc->scanout[scanout_id ^ drmmode_crtc-
> >tear_free].pixmap) {
> + if (dirty->src == drmmode_crtc->prime_scanout_pixmap) {
> RegionPtr region;
>
> if (master_has_sync_shared_pixmap(scrn, dirty))
> diff --git a/src/drmmode_display.c b/src/drmmode_display.c
> index 9996d2f70..add8287a0 100644
> --- a/src/drmmode_display.c
> +++ b/src/drmmode_display.c
> @@ -681,9 +681,7 @@ drmmode_crtc_prime_scanout_update(xf86CrtcPtr
> crtc, DisplayModePtr mode,
>
> xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list,
> ent) {
> - if (dirty->src == crtc->randr_crtc->scanout_pixmap
> &&
> - dirty->slave_dst ==
> - drmmode_crtc->scanout[drmmode_crtc-
> >scanout_id].pixmap) {
> + if (dirty->src == drmmode_crtc-
> >prime_scanout_pixmap) {
> dirty->slave_dst =
> drmmode_crtc-
> >scanout[scanout_id].pixmap;
> break;
> @@ -838,7 +836,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc,
> DisplayModePtr mode,
>
> fb_id = drmmode->fb_id;
> #ifdef AMDGPU_PIXMAP_SHARING
> - if (crtc->randr_crtc && crtc->randr_crtc->scanout_pixmap) {
> + if (drmmode_crtc->prime_scanout_pixmap) {
> drmmode_crtc_prime_scanout_update(crtc, mode,
> scanout_id,
> &fb_id, &x, &y);
> } else
> @@ -1242,14 +1240,15 @@ static Bool
> drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
> PixmapDirtyUpdatePtr dirty;
>
> xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
> - if (dirty->slave_dst != drmmode_crtc-
> >scanout[scanout_id].pixmap)
> - continue;
> -
> - PixmapStopDirtyTracking(dirty->src, dirty->slave_dst);
> - drmmode_crtc_scanout_free(drmmode_crtc);
> - break;
> + if (dirty->src == drmmode_crtc->prime_scanout_pixmap) {
> + PixmapStopDirtyTracking(dirty->src, dirty-
> >slave_dst);
> + break;
> + }
> }
>
> + drmmode_crtc_scanout_free(drmmode_crtc);
> + drmmode_crtc->prime_scanout_pixmap = NULL;
> +
> if (!ppix)
> return TRUE;
>
> @@ -1266,6 +1265,8 @@ static Bool
> drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
> return FALSE;
> }
>
> + drmmode_crtc->prime_scanout_pixmap = ppix;
> +
> #ifdef HAS_DIRTYTRACKING_ROTATION
> PixmapStartDirtyTracking(ppix, drmmode_crtc-
> >scanout[scanout_id].pixmap,
> 0, 0, 0, 0, RR_Rotate_0);
> diff --git a/src/drmmode_display.h b/src/drmmode_display.h
> index 2d5698f61..6a57fd23b 100644
> --- a/src/drmmode_display.h
> +++ b/src/drmmode_display.h
> @@ -83,6 +83,9 @@ typedef struct {
> unsigned scanout_id;
> Bool scanout_update_pending;
> Bool tear_free;
> +
> + PixmapPtr prime_scanout_pixmap;
> +
> int dpms_mode;
> /* For when a flip is pending when DPMS off requested */
> int pending_dpms_mode;
> --
> 2.11.0
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
More information about the amd-gfx
mailing list