aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2015-11-11 05:29:10 -0500
committerJani Nikula <jani.nikula@intel.com>2015-11-17 06:02:14 -0500
commitf72c6b33edda439acff81a0da612f2bcd1f46f35 (patch)
tree008194388572c3ff7b594f06214a23b0406efc04
parent0f45c26fc302c02b0576db37d4849baa53a2bb41 (diff)
drm/core: Fix old_fb handling in restore_fbdev_mode_atomic.
Don't touch plane->old_fb/fb without having the right locks held. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Jani Nikula <jani.nikula@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1447237751-9663-5-git-send-email-maarten.lankhorst@ubuntu.com
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c21
1 files changed, 6 insertions, 15 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index e673c13c7391..abd50863506e 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -342,6 +342,7 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper)
342 struct drm_plane *plane; 342 struct drm_plane *plane;
343 struct drm_atomic_state *state; 343 struct drm_atomic_state *state;
344 int i, ret; 344 int i, ret;
345 unsigned plane_mask;
345 346
346 state = drm_atomic_state_alloc(dev); 347 state = drm_atomic_state_alloc(dev);
347 if (!state) 348 if (!state)
@@ -349,11 +350,10 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper)
349 350
350 state->acquire_ctx = dev->mode_config.acquire_ctx; 351 state->acquire_ctx = dev->mode_config.acquire_ctx;
351retry: 352retry:
353 plane_mask = 0;
352 drm_for_each_plane(plane, dev) { 354 drm_for_each_plane(plane, dev) {
353 struct drm_plane_state *plane_state; 355 struct drm_plane_state *plane_state;
354 356
355 plane->old_fb = plane->fb;
356
357 plane_state = drm_atomic_get_plane_state(state, plane); 357 plane_state = drm_atomic_get_plane_state(state, plane);
358 if (IS_ERR(plane_state)) { 358 if (IS_ERR(plane_state)) {
359 ret = PTR_ERR(plane_state); 359 ret = PTR_ERR(plane_state);
@@ -362,6 +362,9 @@ retry:
362 362
363 plane_state->rotation = BIT(DRM_ROTATE_0); 363 plane_state->rotation = BIT(DRM_ROTATE_0);
364 364
365 plane->old_fb = plane->fb;
366 plane_mask |= 1 << drm_plane_index(plane);
367
365 /* disable non-primary: */ 368 /* disable non-primary: */
366 if (plane->type == DRM_PLANE_TYPE_PRIMARY) 369 if (plane->type == DRM_PLANE_TYPE_PRIMARY)
367 continue; 370 continue;
@@ -382,19 +385,7 @@ retry:
382 ret = drm_atomic_commit(state); 385 ret = drm_atomic_commit(state);
383 386
384fail: 387fail:
385 drm_for_each_plane(plane, dev) { 388 drm_atomic_clean_old_fb(dev, plane_mask, ret);
386 if (ret == 0) {
387 struct drm_framebuffer *new_fb = plane->state->fb;
388 if (new_fb)
389 drm_framebuffer_reference(new_fb);
390 plane->fb = new_fb;
391 plane->crtc = plane->state->crtc;
392
393 if (plane->old_fb)
394 drm_framebuffer_unreference(plane->old_fb);
395 }
396 plane->old_fb = NULL;
397 }
398 389
399 if (ret == -EDEADLK) 390 if (ret == -EDEADLK)
400 goto backoff; 391 goto backoff;