Op 15-06-15 om 08:22 schreef Daniel Vetter: > On Tue, Jun 02, 2015 at 09:00:46AM +0200, Maarten Lankhorst wrote: >> All users of async updates seem to clear clear crtc_state->event >> correctly, so move destroying vblank event to crtc_destroy_state. >> >> This is better than manually free'ing it in the atomic ioctl, since >> this code seems to do it wrong. >> >> While we're at it handle -EDEADLK from atomic_commit correctly, >> because the check might fail otherwise if it takes additional state. > Please don't smash unrelated fixes together into the same patch. > >> Changes since v1: >> - Fix freeing a NULL framebuffer, thanks for catching Daniel Stone. >> >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@xxxxxxxxxxxxxxx> >> Reviewed-by: Daniel Stone <daniels@xxxxxxxxxxxxx> >> --- >> drivers/gpu/drm/drm_atomic.c | 45 +++++++++---------------------------- >> drivers/gpu/drm/drm_atomic_helper.c | 15 +++++++++++++ >> 2 files changed, 26 insertions(+), 34 deletions(-) >> >> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c >> index c7e59b074e62..8add0dd8dc5d 100644 >> --- a/drivers/gpu/drm/drm_atomic.c >> +++ b/drivers/gpu/drm/drm_atomic.c >> @@ -1328,17 +1328,6 @@ out: >> return e; >> } >> >> -static void destroy_vblank_event(struct drm_device *dev, >> - struct drm_file *file_priv, struct drm_pending_vblank_event *e) >> -{ >> - unsigned long flags; >> - >> - spin_lock_irqsave(&dev->event_lock, flags); >> - file_priv->event_space += sizeof e->event; >> - spin_unlock_irqrestore(&dev->event_lock, flags); >> - kfree(e); >> -} >> - >> static int atomic_set_prop(struct drm_atomic_state *state, >> struct drm_mode_object *obj, struct drm_property *prop, >> uint64_t prop_value) >> @@ -1534,13 +1523,18 @@ retry: >> if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) { >> ret = drm_atomic_check_only(state); >> /* _check_only() does not free state, unlike _commit() */ >> - drm_atomic_state_free(state); >> + if (!ret) >> + drm_atomic_state_free(state); >> } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) { >> ret = drm_atomic_async_commit(state); >> } else { >> ret = drm_atomic_commit(state); >> } >> >> +fail: >> + if (ret == -EDEADLK) >> + goto backoff; >> + >> /* if succeeded, fixup legacy plane crtc/fb ptrs before dropping >> * locks (ie. while it is still safe to deref plane->state). We >> * need to do this here because the driver entry points cannot >> @@ -1553,32 +1547,15 @@ retry: >> drm_framebuffer_reference(new_fb); >> plane->fb = new_fb; >> plane->crtc = plane->state->crtc; >> - } else { >> - plane->old_fb = NULL; >> - } >> - if (plane->old_fb) { >> - drm_framebuffer_unreference(plane->old_fb); >> - plane->old_fb = NULL; >> - } >> - } >> - >> - drm_modeset_drop_locks(&ctx); >> - drm_modeset_acquire_fini(&ctx); >> - >> - return ret; >> - >> -fail: >> - if (ret == -EDEADLK) >> - goto backoff; > We have a pre-existing bug here already of leaking plane->old_fb before > dropping locks. I think the EDEADLK case needs to be after the cleanup > loop to clear old_fb. > Ok, I'll send a fix for that first. It's also bugged because old_fb is assigned before the plane lock is taken, resulting in possible memory corruption or leaks. _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel