linux/drivers/gpu/drm/exynos
Daniel Vetter a8e11d1c43 drm/gem: fix up flink name create race
This is the 2nd attempt, I've always been a bit dissatisified with the
tricky nature of the first one:

http://lists.freedesktop.org/archives/dri-devel/2012-July/025451.html

The issue is that the flink ioctl can race with calling gem_close on
the last gem handle. In that case we'll end up with a zero handle
count, but an flink name (and it's corresponding reference). Which
results in a neat space leak.

In my first attempt I've solved this by rechecking the handle count.
But fundamentally the issue is that ->handle_count isn't your usual
refcount - it can be resurrected from 0 among other things.

For those special beasts atomic_t often suggest way more ordering that
it actually guarantees. To prevent being tricked by those hairy
semantics take the easy way out and simply protect the handle with the
existing dev->object_name_lock.

With that change implemented it's dead easy to fix the flink vs. gem
close reace: When we try to create the name we simply have to check
whether there's still officially a gem handle around and if not refuse
to create the flink name. Since the handle count decrement and flink
name destruction is now also protected by that lock the reace is gone
and we can't ever leak the flink reference again.

Outside of the drm core only the exynos driver looks at the handle
count, and tbh I have no idea why (it's just for debug dmesg output
luckily).

I've considered inlining the drm_gem_object_handle_free, but I plan to
add more name-like things (like the exported dma_buf) to this scheme,
so it's clearer to leave the handle freeing in its own function.

This is exercised by the new gem_flink_race i-g-t testcase, which on
my snb leaks gem objects at a rate of roughly 1k objects/s.

v2: Fix up the error path handling in handle_create and make it more
robust by simply calling object_handle_unreference.

v3: Fix up the handle_unreference logic bug - atomic_dec_and_test
retursn 1 for 0. Oops.

v4: Squash in inlining of drm_gem_object_handle_reference as suggested
by Dave Airlie and add a note that we now have a testcase.

Cc: Dave Airlie <airlied@gmail.com>
Cc: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Dave Airlie <airlied@redhat.com>
2013-08-21 12:53:45 +10:00
..
exynos_ddc.c drm/exynos: add new compatible strings for hdmi subsystem 2013-06-28 21:13:57 +09:00
exynos_drm_buf.c drm/exynos: remove duplicated error routine and unnecessary assign 2013-07-04 15:55:37 +09:00
exynos_drm_buf.h drm/exynos: change file license to GPL 2013-01-04 15:54:32 +09:00
exynos_drm_connector.c drm/exynos: Remove tracking log functions 2013-06-28 21:13:55 +09:00
exynos_drm_connector.h drm/exynos: change file license to GPL 2013-01-04 15:54:32 +09:00
exynos_drm_core.c drm/exynos: Remove tracking log functions 2013-06-28 21:13:55 +09:00
exynos_drm_crtc.c drm/exynos: Remove tracking log functions 2013-06-28 21:13:55 +09:00
exynos_drm_crtc.h drm/exynos: move finish page flip to a common place 2013-01-07 13:58:37 +09:00
exynos_drm_dmabuf.c drm/exynos: explicit store base gem object in dma_buf->priv 2013-08-19 10:45:38 +10:00
exynos_drm_dmabuf.h drm/exynos: change file license to GPL 2013-01-04 15:54:32 +09:00
exynos_drm_drv.c drm: const'ify ioctls table (v2) 2013-08-07 10:10:02 +10:00
exynos_drm_drv.h drm/exynos: hdmi: use drm_display_mode to check the supported modes 2013-06-28 21:12:52 +09:00
exynos_drm_encoder.c drm/exynos: Remove tracking log functions 2013-06-28 21:13:55 +09:00
exynos_drm_encoder.h drm/exynos: change file license to GPL 2013-01-04 15:54:32 +09:00
exynos_drm_fb.c drm/exynos: Remove tracking log functions 2013-06-28 21:13:55 +09:00
exynos_drm_fb.h drm/exynos: change file license to GPL 2013-01-04 15:54:32 +09:00
exynos_drm_fbdev.c drm/exynos: Remove tracking log functions 2013-06-28 21:13:55 +09:00
exynos_drm_fbdev.h drm/exynos: change file license to GPL 2013-01-04 15:54:32 +09:00
exynos_drm_fimc.c drm/exynos: Clean up logs for DRM_ERROR / DRM_DEBUG_KMS 2013-06-28 21:13:56 +09:00
exynos_drm_fimc.h drm/exynos: change file license to GPL 2013-01-04 15:54:32 +09:00
exynos_drm_fimd.c drm/exynos: Remove tracking log functions 2013-06-28 21:13:55 +09:00
exynos_drm_g2d.c drm/exynos: remove duplicated error routine and unnecessary assign 2013-07-04 15:55:37 +09:00
exynos_drm_g2d.h
exynos_drm_gem.c drm/gem: fix up flink name create race 2013-08-21 12:53:45 +10:00
exynos_drm_gem.h drm/gem: create drm_gem_dumb_destroy 2013-08-07 09:59:24 +10:00
exynos_drm_gsc.c drm/exynos: Clean up logs for DRM_ERROR / DRM_DEBUG_KMS 2013-06-28 21:13:56 +09:00
exynos_drm_gsc.h drm/exynos: change file license to GPL 2013-01-04 15:54:32 +09:00
exynos_drm_hdmi.c drm/exynos: Remove tracking log functions 2013-06-28 21:13:55 +09:00
exynos_drm_hdmi.h drm/exynos: hdmi: use drm_display_mode to check the supported modes 2013-06-28 21:12:52 +09:00
exynos_drm_iommu.c drm/exynos: change file license to GPL 2013-01-04 15:54:32 +09:00
exynos_drm_iommu.h drm/exynos: fix iommu address allocation order 2013-02-21 15:00:26 +09:00
exynos_drm_ipp.c drm/exynos: exynos_drm_ipp: Remove redundant break statement 2013-06-28 21:13:56 +09:00
exynos_drm_ipp.h drm/exynos: change member variable name. 2013-01-04 15:54:33 +09:00
exynos_drm_plane.c drm/exynos: Remove tracking log functions 2013-06-28 21:13:55 +09:00
exynos_drm_plane.h
exynos_drm_rotator.c drm/exynos: Clean up logs for DRM_ERROR / DRM_DEBUG_KMS 2013-06-28 21:13:56 +09:00
exynos_drm_rotator.h drm/exynos: change file license to GPL 2013-01-04 15:54:32 +09:00
exynos_drm_vidi.c drm/exynos: remove dead code in vidi_power_on 2013-07-04 15:55:36 +09:00
exynos_drm_vidi.h drm/exynos: change file license to GPL 2013-01-04 15:54:32 +09:00
exynos_hdmi.c drm/exynos: add new compatible strings for hdmi subsystem 2013-06-28 21:13:57 +09:00
exynos_hdmi.h drm/exynos: change file license to GPL 2013-01-04 15:54:32 +09:00
exynos_hdmiphy.c drm/exynos: add new compatible strings for hdmi subsystem 2013-06-28 21:13:57 +09:00
exynos_mixer.c drm/exynos: initialize the buf_num in vp_video_buffer 2013-07-04 15:55:36 +09:00
Kconfig drm/exynos: Select VIDEOMODE_HELPERS for FIMD 2013-04-29 14:35:32 +09:00
Makefile drm/exynos: add gsc ipp driver 2012-12-15 02:40:00 +09:00
regs-fimc.h drm/exynos: add device tree support for fimc ipp driver 2013-04-29 14:35:32 +09:00
regs-gsc.h drm/exynos: add gsc ipp driver 2012-12-15 02:40:00 +09:00
regs-hdmi.h drm/exynos: add support for hdmiphy power control for exynos5 2012-12-14 15:40:49 +09:00
regs-mixer.h drm/exynos: add support for exynos5420 mixer 2013-06-28 21:13:57 +09:00
regs-rotator.h drm/exynos: add rotator ipp driver 2012-12-15 02:39:41 +09:00
regs-vp.h