[PATCH 1/3] Increase robustness against DRM page flip ioctl failures v2
Alex Deucher
alexdeucher at gmail.com
Fri Mar 27 08:08:26 PDT 2015
On Thu, Mar 26, 2015 at 4:30 AM, Michel Dänzer <michel at daenzer.net> wrote:
> From: Michel Dänzer <michel.daenzer at amd.com>
>
> Centralize cleanup, only clean up things that have been allocated for
> the failed ioctl call.
>
> Fixes double-free after a flip ioctl failure.
>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89681
>
> v2: Only call drmModeRmFB for flipdata->old_fb_id on receipt of last DRM
> page flip event. Fixes Black screen on making glxgears fullscreen with
> DRI3 enabled.
>
> Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
For the series:
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
> ---
> src/drmmode_display.c | 46 +++++++++++++++++++++++++---------------------
> 1 file changed, 25 insertions(+), 21 deletions(-)
>
> diff --git a/src/drmmode_display.c b/src/drmmode_display.c
> index f719f0c..35bbd9e 100644
> --- a/src/drmmode_display.c
> +++ b/src/drmmode_display.c
> @@ -1836,9 +1836,6 @@ drmmode_flip_free(drmmode_flipevtcarrier_ptr flipcarrier)
> if (--flipdata->flip_count > 0)
> return;
>
> - /* Release framebuffer */
> - drmModeRmFB(flipdata->drmmode->fd, flipdata->old_fb_id);
> -
> free(flipdata);
> }
>
> @@ -1867,10 +1864,16 @@ drmmode_flip_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec, void *even
> flipdata->fe_usec = usec;
> }
>
> - /* Deliver cached msc, ust from reference crtc to flip event handler */
> - if (flipdata->event_data && flipdata->flip_count == 1)
> - flipcarrier->handler(scrn, flipdata->fe_frame, flipdata->fe_usec,
> - flipdata->event_data);
> + if (flipdata->flip_count == 1) {
> + /* Deliver cached msc, ust from reference crtc to flip event handler */
> + if (flipdata->event_data)
> + flipcarrier->handler(scrn, flipdata->fe_frame,
> + flipdata->fe_usec,
> + flipdata->event_data);
> +
> + /* Release framebuffer */
> + drmModeRmFB(flipdata->drmmode->fd, flipdata->old_fb_id);
> + }
>
> drmmode_flip_free(flipcarrier);
> }
> @@ -2276,10 +2279,10 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
> unsigned int pitch;
> int i, old_fb_id;
> uint32_t tiling_flags = 0;
> - int height, emitted = 0;
> + int height;
> drmmode_flipdata_ptr flipdata;
> drmmode_flipevtcarrier_ptr flipcarrier = NULL;
> - struct radeon_drm_queue_entry *drm_queue = 0;
> + struct radeon_drm_queue_entry *drm_queue = NULL;
>
> if (info->allowColorTiling) {
> if (info->ChipFamily >= CHIP_FAMILY_R600)
> @@ -2322,6 +2325,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
>
> flipdata->event_data = data;
> flipdata->drmmode = drmmode;
> + flipdata->old_fb_id = old_fb_id;
>
> for (i = 0; i < config->num_crtc; i++) {
> if (!config->crtc[i]->enabled)
> @@ -2334,8 +2338,6 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
> if (!flipcarrier) {
> xf86DrvMsg(scrn->scrnIndex, X_WARNING,
> "flip queue: carrier alloc failed.\n");
> - if (emitted == 0)
> - free(flipdata);
> goto error_undo;
> }
>
> @@ -2362,25 +2364,27 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
> drm_queue)) {
> xf86DrvMsg(scrn->scrnIndex, X_WARNING,
> "flip queue failed: %s\n", strerror(errno));
> - free(flipcarrier);
> - if (emitted == 0)
> - free(flipdata);
> goto error_undo;
> }
> - emitted++;
> + flipcarrier = NULL;
> + drm_queue = NULL;
> }
>
> - flipdata->old_fb_id = old_fb_id;
> - return TRUE;
> + if (flipdata->flip_count > 0)
> + return TRUE;
>
> error_undo:
> + if (!flipdata || flipdata->flip_count <= 1) {
> + drmModeRmFB(drmmode->fd, drmmode->fb_id);
> + drmmode->fb_id = old_fb_id;
> + }
> +
> if (drm_queue)
> radeon_drm_abort_entry(drm_queue);
> - else
> + else if (flipcarrier)
> drmmode_flip_abort(scrn, flipcarrier);
> -
> - drmModeRmFB(drmmode->fd, drmmode->fb_id);
> - drmmode->fb_id = old_fb_id;
> + else
> + free(flipdata);
>
> error_out:
> xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Page flip failed: %s\n",
> --
> 2.1.4
>
> _______________________________________________
> xorg-driver-ati mailing list
> xorg-driver-ati at lists.x.org
> http://lists.x.org/mailman/listinfo/xorg-driver-ati
More information about the xorg-driver-ati
mailing list