[PATCH 2/3] drm/gma500: Fix mem leak of cursor objects on Poulsbo

Patrik Jakobsson patrik.r.jakobsson at gmail.com
Mon May 20 03:47:01 PDT 2013


All dumb allocated buffers are now automatically pinned so no extra
pinning is needed. Also properly unreference gem objects so they can be
freed up properly. This only affects Poulsbo chips.

Signed-off-by: Patrik Jakobsson <patrik.r.jakobsson at gmail.com>
---
 drivers/gpu/drm/gma500/psb_intel_display.c | 49 ++++++++----------------------
 1 file changed, 12 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c
index a768c98..efc4cd6 100644
--- a/drivers/gpu/drm/gma500/psb_intel_display.c
+++ b/drivers/gpu/drm/gma500/psb_intel_display.c
@@ -838,7 +838,7 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
 	struct gtt_range *cursor_gt = psb_intel_crtc->cursor_gt;
 	struct drm_gem_object *obj;
 	void *tmp_dst, *tmp_src;
-	int ret, i, cursor_pages;
+	int ret = 0, i, cursor_pages;
 
 	/* if we want to turn of the cursor ignore width and height */
 	if (!handle) {
@@ -851,15 +851,7 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
 			gma_power_end(dev);
 		}
 
-		/* Unpin the old GEM object */
-		if (psb_intel_crtc->cursor_obj) {
-			gt = container_of(psb_intel_crtc->cursor_obj,
-							struct gtt_range, gem);
-			psb_gtt_unpin(gt);
-			drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-			psb_intel_crtc->cursor_obj = NULL;
-		}
-
+		psb_intel_crtc->cursor_obj = NULL;
 		return 0;
 	}
 
@@ -875,22 +867,19 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
 
 	if (obj->size < width * height * 4) {
 		dev_dbg(dev->dev, "buffer is to small\n");
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto unref_cursor;
 	}
 
 	gt = container_of(obj, struct gtt_range, gem);
 
-	/* Pin the memory into the GTT */
-	ret = psb_gtt_pin(gt);
-	if (ret) {
-		dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
-		return ret;
-	}
+	WARN_ON(gt->in_gart < 1);
 
 	if (dev_priv->ops->cursor_needs_phys) {
 		if (cursor_gt == NULL) {
 			dev_err(dev->dev, "No hardware cursor mem available");
-			return -ENOMEM;
+			ret = -ENOMEM;
+			goto unref_cursor;
 		}
 
 		/* Prevent overflow */
@@ -925,15 +914,11 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
 		gma_power_end(dev);
 	}
 
-	/* unpin the old bo */
-	if (psb_intel_crtc->cursor_obj) {
-		gt = container_of(psb_intel_crtc->cursor_obj,
-							struct gtt_range, gem);
-		psb_gtt_unpin(gt);
-		drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-		psb_intel_crtc->cursor_obj = obj;
-	}
-	return 0;
+	psb_intel_crtc->cursor_obj = obj;
+
+unref_cursor:
+	drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
+	return ret;
 }
 
 static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
@@ -1127,16 +1112,6 @@ struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev,
 static void psb_intel_crtc_destroy(struct drm_crtc *crtc)
 {
 	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	struct gtt_range *gt;
-
-	/* Unpin the old GEM object */
-	if (psb_intel_crtc->cursor_obj) {
-		gt = container_of(psb_intel_crtc->cursor_obj,
-						struct gtt_range, gem);
-		psb_gtt_unpin(gt);
-		drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
-		psb_intel_crtc->cursor_obj = NULL;
-	}
 
 	if (psb_intel_crtc->cursor_gt != NULL)
 		psb_gtt_free_range(crtc->dev, psb_intel_crtc->cursor_gt);
-- 
1.8.1.2



More information about the dri-devel mailing list