[PATCH 09/11] drm/i915: fix overlay fb object handling

Jesse Barnes jbarnes at virtuousgeek.org
Tue Oct 25 02:47:04 PDT 2011


To avoid the object being destroyed before our disable hook is called,
take a private reference on it.  This will guarantee that we can still
access the object at disable time.

Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_overlay2.c |   27 ++++++++++++++++++++++-----
 1 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_overlay2.c b/drivers/gpu/drm/i915/intel_overlay2.c
index 61b1a2f..8876857 100644
--- a/drivers/gpu/drm/i915/intel_overlay2.c
+++ b/drivers/gpu/drm/i915/intel_overlay2.c
@@ -35,6 +35,18 @@
 #include "i915_drm.h"
 #include "i915_drv.h"
 
+/*
+ * Note on refcounting:
+ * When the user creates an fb for the GEM object to be used for the plane,
+ * a ref is taken on the object.  However, if the application exits before
+ * disabling the plane, the DRM close handling will free all the fbs and
+ * unless we take a ref on the object, it will be destroyed before the
+ * plane disable hook is called, causing obvious trouble with our efforts
+ * to look up and unpin the object.  So we take a ref after we move the
+ * object to the display plane so it won't be destroyed until our disable
+ * hook is called and we drop our private reference.
+ */
+
 static int
 ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 		   struct drm_framebuffer *fb, int crtc_x, int crtc_y,
@@ -106,6 +118,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 	if (ret)
 		goto out_unlock;
 
+	drm_gem_object_reference(&obj->base);
+
 	intel_plane->obj = obj;
 
 	sprctl |= SPRITE_TILED;
@@ -117,9 +131,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 	start = obj->gtt_offset;
 	offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
 
-	DRM_ERROR("enabling sprite, pos %d,%d, size %dx%d\n",
-		  crtc_x, crtc_y, fb->width, fb->height);
-
 	I915_WRITE(SPRSTRIDE(pipe), fb->pitch);
 	I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
 	I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
@@ -215,6 +226,8 @@ snb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 	if (ret)
 		goto out_unlock;
 
+	drm_gem_object_reference(&obj->base);
+
 	intel_plane->obj = obj;
 
 	dvscntr |= DVS_TILED;
@@ -260,13 +273,15 @@ ivb_disable_plane(struct drm_plane *plane)
 
 	if (!intel_plane->obj)
 		goto out_unlock;
-#if 0
+
 	ret = i915_gem_object_finish_gpu(intel_plane->obj);
 	if (ret)
 		goto out_unlock;
 
 	i915_gem_object_unpin(intel_plane->obj);
-#endif
+
+	drm_gem_object_reference(&intel_plane->obj->base);
+
 out_unlock:
 	intel_plane->obj = NULL;
 
@@ -299,6 +314,8 @@ snb_disable_plane(struct drm_plane *plane)
 
 	i915_gem_object_unpin(intel_plane->obj);
 
+	drm_gem_object_reference(&intel_plane->obj->base);
+
 out_unlock:
 	intel_plane->obj = NULL;
 
-- 
1.7.4.1



More information about the dri-devel mailing list