diff mbox

[2/2] drm/i915: Skip the sanity checks if the current relocation is valid

Message ID 1252527315-12803-2-git-send-email-chris@chris-wilson.co.uk (mailing list archive)
State Accepted
Headers show

Commit Message

Chris Wilson Sept. 9, 2009, 8:15 p.m. UTC
If the presumed_offset as feed to userspace and returned to the kernel
from a previous execbuffer is still valid, then we do not need to rewrite
the relocation entry and may skip the offset sanity checks.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem.c |   92 ++++++++++++++++++++-------------------
 1 files changed, 47 insertions(+), 45 deletions(-)

Comments

Jesse Barnes Sept. 18, 2009, 10:32 p.m. UTC | #1
On Wed,  9 Sep 2009 21:15:15 +0100
Chris Wilson <chris@chris-wilson.co.uk> wrote:

> If the presumed_offset as feed to userspace and returned to the kernel
> from a previous execbuffer is still valid, then we do not need to
> rewrite the relocation entry and may skip the offset sanity checks.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>  drivers/gpu/drm/i915/i915_gem.c |   92
> ++++++++++++++++++++------------------- 1 files changed, 47
> insertions(+), 45 deletions(-)

Applied these two, sorry for missing them before.
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 7d053c6..be0c5dd 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2984,6 +2984,21 @@  i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
 		}
 		target_obj_priv = target_obj->driver_private;
 
+#if WATCH_RELOC
+		DRM_INFO("%s: obj %p offset %08x target %d "
+			 "read %08x write %08x gtt %08x "
+			 "presumed %08x delta %08x\n",
+			 __func__,
+			 obj,
+			 (int) reloc->offset,
+			 (int) reloc->target_handle,
+			 (int) reloc->read_domains,
+			 (int) reloc->write_domain,
+			 (int) target_obj_priv->gtt_offset,
+			 (int) reloc->presumed_offset,
+			 reloc->delta);
+#endif
+
 		/* The target buffer should have appeared before us in the
 		 * exec_object list, so it should have a GTT space bound by now.
 		 */
@@ -2995,35 +3010,7 @@  i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
 			return -EINVAL;
 		}
 
-		if (reloc->offset > obj->size - 4) {
-			DRM_ERROR("Relocation beyond object bounds: "
-				  "obj %p target %d offset %d size %d.\n",
-				  obj, reloc->target_handle,
-				  (int) reloc->offset, (int) obj->size);
-			drm_gem_object_unreference(target_obj);
-			i915_gem_object_unpin(obj);
-			return -EINVAL;
-		}
-		if (reloc->offset & 3) {
-			DRM_ERROR("Relocation not 4-byte aligned: "
-				  "obj %p target %d offset %d.\n",
-				  obj, reloc->target_handle,
-				  (int) reloc->offset);
-			drm_gem_object_unreference(target_obj);
-			i915_gem_object_unpin(obj);
-			return -EINVAL;
-		}
-
-		if (reloc->delta >= target_obj->size) {
-			DRM_ERROR("Relocation beyond target object bounds: "
-				  "obj %p target %d delta %d size %d.\n",
-				  obj, reloc->target_handle,
-				  (int) reloc->delta, (int) target_obj->size);
-			drm_gem_object_unreference(target_obj);
-			i915_gem_object_unpin(obj);
-			return -EINVAL;
-		}
-
+		/* Validate that the target is in a valid r/w GPU domain */
 		if (reloc->write_domain & I915_GEM_DOMAIN_CPU ||
 		    reloc->read_domains & I915_GEM_DOMAIN_CPU) {
 			DRM_ERROR("reloc with read/write CPU domains: "
@@ -3037,7 +3024,6 @@  i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
 			i915_gem_object_unpin(obj);
 			return -EINVAL;
 		}
-
 		if (reloc->write_domain && target_obj->pending_write_domain &&
 		    reloc->write_domain != target_obj->pending_write_domain) {
 			DRM_ERROR("Write domain conflict: "
@@ -3052,21 +3038,6 @@  i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
 			return -EINVAL;
 		}
 
-#if WATCH_RELOC
-		DRM_INFO("%s: obj %p offset %08x target %d "
-			 "read %08x write %08x gtt %08x "
-			 "presumed %08x delta %08x\n",
-			 __func__,
-			 obj,
-			 (int) reloc->offset,
-			 (int) reloc->target_handle,
-			 (int) reloc->read_domains,
-			 (int) reloc->write_domain,
-			 (int) target_obj_priv->gtt_offset,
-			 (int) reloc->presumed_offset,
-			 reloc->delta);
-#endif
-
 		target_obj->pending_read_domains |= reloc->read_domains;
 		target_obj->pending_write_domain |= reloc->write_domain;
 
@@ -3078,6 +3049,37 @@  i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
 			continue;
 		}
 
+		/* Check that the relocation address is valid... */
+		if (reloc->offset > obj->size - 4) {
+			DRM_ERROR("Relocation beyond object bounds: "
+				  "obj %p target %d offset %d size %d.\n",
+				  obj, reloc->target_handle,
+				  (int) reloc->offset, (int) obj->size);
+			drm_gem_object_unreference(target_obj);
+			i915_gem_object_unpin(obj);
+			return -EINVAL;
+		}
+		if (reloc->offset & 3) {
+			DRM_ERROR("Relocation not 4-byte aligned: "
+				  "obj %p target %d offset %d.\n",
+				  obj, reloc->target_handle,
+				  (int) reloc->offset);
+			drm_gem_object_unreference(target_obj);
+			i915_gem_object_unpin(obj);
+			return -EINVAL;
+		}
+
+		/* and points to somewhere within the target object. */
+		if (reloc->delta >= target_obj->size) {
+			DRM_ERROR("Relocation beyond target object bounds: "
+				  "obj %p target %d delta %d size %d.\n",
+				  obj, reloc->target_handle,
+				  (int) reloc->delta, (int) target_obj->size);
+			drm_gem_object_unreference(target_obj);
+			i915_gem_object_unpin(obj);
+			return -EINVAL;
+		}
+
 		ret = i915_gem_object_set_to_gtt_domain(obj, 1);
 		if (ret != 0) {
 			drm_gem_object_unreference(target_obj);