[PATCH xf86-video-ati] Simplify tracking of PRIME scanout pixmap

Deucher, Alexander Alexander.Deucher at amd.com
Wed May 10 16:07:55 UTC 2017


> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-bounces at lists.freedesktop.org] On Behalf
> Of Michel Dänzer
> Sent: Wednesday, May 10, 2017 5:11 AM
> To: amd-gfx at lists.freedesktop.org
> Subject: [PATCH xf86-video-ati] 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.
> 
> Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>

Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

> ---
>  src/drmmode_display.c | 21 +++++++++++----------
>  src/drmmode_display.h |  3 +++
>  src/radeon_kms.c      |  7 ++-----
>  3 files changed, 16 insertions(+), 15 deletions(-)
> 
> diff --git a/src/drmmode_display.c b/src/drmmode_display.c
> index ec3072621..e2899cf50 100644
> --- a/src/drmmode_display.c
> +++ b/src/drmmode_display.c
> @@ -732,9 +732,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;
> @@ -887,7 +885,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc,
> DisplayModePtr mode,
>  		drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
> 
>  #ifdef RADEON_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, &x, &y);
>  		} else
> @@ -1278,14 +1276,15 @@ 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;
> 
> @@ -1302,6 +1301,8 @@ 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 14d1cb034..df2c4b7bb 100644
> --- a/src/drmmode_display.h
> +++ b/src/drmmode_display.h
> @@ -92,6 +92,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;
> diff --git a/src/radeon_kms.c b/src/radeon_kms.c
> index 2b410eb3d..c4bdfcfac 100644
> --- a/src/radeon_kms.c
> +++ b/src/radeon_kms.c
> @@ -657,8 +657,7 @@ radeon_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;
>      }
> 
> @@ -671,13 +670,11 @@ radeon_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))
> --
> 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