drm/exynos: fix race in exynos_drm_fb_map
authorMandeep Singh Baines <msb@chromium.org>
Mon, 10 Sep 2012 01:43:33 +0000 (18:43 -0700)
committerMandeep Singh Baines <msb@chromium.org>
Fri, 28 Sep 2012 02:10:51 +0000 (19:10 -0700)
In commit c4898d15, "drm/exynos: grab dma-buf reference just once",
I introduced a race where the gem object could be freed before
the kds callback ran and did the unmap.

You'd see the following in dmesg:

[  114.024936] [drm:exynos_drm_fb_unmap] *ERROR* buffer is null
[  114.024952] [drm:exynos_drm_kds_callback_rm_fb] *ERROR* Couldn't unmap buffer

This caused suspend/resume to randomly fail.

BUG=chrome-os-partner:12170
TEST=Many suspend/resume cycles. Many VT switches.

Change-Id: If806dbf5fdf57b6d910872dfc6b47f04fa9e8271
Signed-off-by: Mandeep Singh Baines <msb@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/34247

drivers/gpu/drm/exynos/exynos_drm_fb.c

index b3ea07e..5893a2c 100644 (file)
@@ -51,6 +51,8 @@ static int exynos_drm_fb_map(struct drm_framebuffer *fb)
                return -ENOMEM;
        }
 
+       drm_gem_object_reference(obj);
+
        ret = dma_map_sg(obj->dev->dev,
                         buf->sgt->sgl,
                         buf->sgt->orig_nents,
@@ -91,6 +93,8 @@ static int exynos_drm_fb_unmap(struct drm_framebuffer *fb)
                     buf->sgt->orig_nents,
                     DMA_BIDIRECTIONAL);
 
+       drm_gem_object_unreference_unlocked(obj);
+
        buf->dma_addr = 0;
 
        return 0;