[Intel-gfx] [PATCH] [drm/i915] Retry execbuffer pinning after clearing the GTT

Keith Packard keithp at keithp.com
Fri Nov 21 10:00:15 CET 2008


If we fail to pin all of the buffers in an execbuffer request, go through
and clear the GTT and try again to see if its just a matter of fragmentation

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 drivers/gpu/drm/i915/i915_gem.c |   51 ++++++++++++++++++++++++++++++++-------
 1 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 7fd1b26..3e54e94 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1089,6 +1089,19 @@ i915_gem_evict_something(struct drm_device *dev)
 }
 
 static int
+i915_gem_evict_everything(struct drm_device *dev)
+{
+	int ret;
+
+	for (;;) {
+		ret = i915_gem_evict_something(dev);
+		if (ret != -ENOMEM)
+			break;
+	}
+	return ret;
+}
+
+static int
 i915_gem_object_get_page_list(struct drm_gem_object *obj)
 {
 	struct drm_i915_gem_object *obj_priv = obj->driver_private;
@@ -1896,6 +1909,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
 	int ret, i, pinned = 0;
 	uint64_t exec_offset;
 	uint32_t seqno, flush_domains;
+	int pin_tries;
 
 #if WATCH_EXEC
 	DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
@@ -1957,17 +1971,36 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
 	}
 
 	/* Pin and relocate */
-	for (i = 0; i < args->buffer_count; i++) {
-		object_list[i]->pending_read_domains = 0;
-		object_list[i]->pending_write_domain = 0;
-		ret = i915_gem_object_pin_and_relocate(object_list[i],
-						       file_priv,
-						       &exec_list[i]);
-		if (ret) {
-			DRM_ERROR("object bind and relocate failed %d\n", ret);
+	for (pin_tries = 0; ; pin_tries++) {
+		ret = 0;
+		for (i = 0; i < args->buffer_count; i++) {
+			object_list[i]->pending_read_domains = 0;
+			object_list[i]->pending_write_domain = 0;
+			ret = i915_gem_object_pin_and_relocate(object_list[i],
+							       file_priv,
+							       &exec_list[i]);
+			if (ret)
+				break;
+			pinned = i + 1;
+		}
+		/* success */
+		if (ret == 0)
+			break;
+
+		/* error other than GTT full, or we've already tried again */
+		if (ret != -ENOMEM || pin_tries >= 1) {
+			DRM_ERROR("Failed to pin buffers %d\n", ret);
 			goto err;
 		}
-		pinned = i + 1;
+
+		/* unpin all of our buffers */
+		for (i = 0; i < pinned; i++)
+			i915_gem_object_unpin(object_list[i]);
+
+		/* evict everyone we can from the aperture */
+		ret = i915_gem_evict_everything(dev);
+		if (ret)
+			goto err;
 	}
 
 	/* Set the pending read domains for the batch buffer to COMMAND */
-- 
1.5.6.5




More information about the Intel-gfx mailing list