[PATCH] drm/i915: Unbind vma if asked to pin with conflicting flags

Nirmoy Das nirmoy.das at intel.com
Wed Jan 18 14:02:54 UTC 2023


From: Chris Wilson <chris.p.wilson at linux.intel.com>

Currently, if a vma is unpinned but bound into the drm_mm and we try to
pin it with conflicting alignment or flags, we simply rebind it into the
current location despite the misplacement. Force the unbind (if allowed)
if there is a conflict between the current position of the vma in the
drm_mm and the caller's requirements.

Signed-off-by: Chris Wilson <chris.p.wilson at linux.intel.com>
Signed-off-by: Nirmoy Das <nirmoy.das at intel.com>
---
 drivers/gpu/drm/i915/display/intel_fb_pin.c |  6 -----
 drivers/gpu/drm/i915/i915_gem.c             |  4 ---
 drivers/gpu/drm/i915/i915_vma.c             | 27 +++++++++++++++++++++
 3 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c
index 1aca7552a85d..ddcd479a8ae8 100644
--- a/drivers/gpu/drm/i915/display/intel_fb_pin.c
+++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c
@@ -76,12 +76,6 @@ intel_pin_fb_obj_dpt(struct drm_framebuffer *fb,
 			continue;
 		}
 
-		if (i915_vma_misplaced(vma, 0, alignment, 0)) {
-			ret = i915_vma_unbind(vma);
-			if (ret)
-				continue;
-		}
-
 		ret = i915_vma_pin_ww(vma, &ww, 0, alignment, PIN_GLOBAL);
 		if (ret)
 			continue;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 35950fa91406..5ae29d3891f9 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -973,10 +973,6 @@ i915_gem_object_ggtt_pin_ww(struct drm_i915_gem_object *obj,
 			discard_ggtt_vma(vma);
 			goto new_vma;
 		}
-
-		ret = i915_vma_unbind(vma);
-		if (ret)
-			return ERR_PTR(ret);
 	}
 
 	ret = i915_vma_pin_ww(vma, ww, size, alignment, flags | PIN_GLOBAL);
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 5272e2be990e..15f6b36f9706 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -650,6 +650,25 @@ void i915_vma_unpin_and_release(struct i915_vma **p_vma, unsigned int flags)
 	i915_gem_object_put(obj);
 }
 
+/**
+ * i915_vma_misplaced - check the current placement against requested
+ * @vma - i915_vma to compare
+ * @size - the size of the range required in the GTT for this vma access, or 0
+ * @alignment - the required virtual address alignment or 0 for default
+ * @flags - placement flags, see i915_vma_pin()
+ *
+ * i915_vma_misplaced() checks that if the vma is currently bound,
+ * the current drm_mm_node (offset and size) match the caller's required
+ * placement restraints, as would passed to i915_vma_pin().
+ *
+ * Normally, i915_vma_pin() would unbind any conflicting and /unpinned/ vma,
+ * but sometimes we would prefer to e.g. use a secondary vma if this vma
+ * itself would not satisfy the callers constraints, and thus would like
+ * to check if the placement is valid for itself.
+ *
+ * Returns true if the vma is currently bound and its placement in the GTT
+ * does not match the passed in constraints.
+ */
 bool i915_vma_misplaced(const struct i915_vma *vma,
 			u64 size, u64 alignment, u64 flags)
 {
@@ -1484,6 +1503,14 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 		goto err_unlock;
 	}
 
+	if (unlikely(i915_vma_misplaced(vma, size, alignment, flags))) {
+		err = -EBUSY;
+		if (!(flags & (PIN_NONBLOCK | PIN_NOEVICT)))
+			err = __i915_vma_unbind(vma);
+		if (err)
+			goto err_unlock;
+	}
+
 	bound = atomic_read(&vma->flags);
 	if (unlikely(bound & I915_VMA_ERROR)) {
 		err = -ENOMEM;
-- 
2.39.0



More information about the Intel-gfx-trybot mailing list