[Intel-gfx] [PATCH] drm/i915: Double check vma placement upon gaining the vm lock
Chris Wilson
chris at chris-wilson.co.uk
Tue Nov 26 15:26:16 UTC 2019
The current unbind + retry of i915_gem_object_ggtt_pin() allows for
someone else to sneak and claim the vma under a different placement
before the first GGTT bind is complete. Leading to confusion and
complaints all over.
Ideally we would pull the evict + rebind under the same lock, but for
now, simply try again.
Fixes: 2850748ef876 ("drm/i915: Pull i915_vma_pin under the vm->mutex")
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
---
drivers/gpu/drm/i915/i915_gem.c | 39 +++++++++++++++++++--------------
drivers/gpu/drm/i915/i915_vma.c | 6 +++++
2 files changed, 28 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 61395b03443e..b0878d35ed1d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -938,33 +938,38 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
if (IS_ERR(vma))
return vma;
- if (i915_vma_misplaced(vma, size, alignment, flags)) {
- if (flags & PIN_NONBLOCK) {
- if (i915_vma_is_pinned(vma) || i915_vma_is_active(vma))
- return ERR_PTR(-ENOSPC);
-
- if (flags & PIN_MAPPABLE &&
- vma->fence_size > ggtt->mappable_end / 2)
- return ERR_PTR(-ENOSPC);
+ do {
+ if (i915_vma_misplaced(vma, size, alignment, flags)) {
+ if (flags & PIN_NONBLOCK) {
+ if (i915_vma_is_pinned(vma) ||
+ i915_vma_is_active(vma))
+ return ERR_PTR(-ENOSPC);
+
+ if (flags & PIN_MAPPABLE &&
+ vma->fence_size > ggtt->mappable_end / 2)
+ return ERR_PTR(-ENOSPC);
+ }
+
+ ret = i915_vma_unbind(vma);
+ if (ret)
+ return ERR_PTR(ret);
}
- ret = i915_vma_unbind(vma);
- if (ret)
- return ERR_PTR(ret);
- }
+ ret = i915_vma_pin(vma, size, alignment, flags | PIN_GLOBAL);
+ } while (ret == -EAGAIN); /* retry if we lost our placement */
+ if (ret)
+ return ERR_PTR(ret);
if (vma->fence && !i915_gem_object_is_tiled(obj)) {
mutex_lock(&ggtt->vm.mutex);
ret = i915_vma_revoke_fence(vma);
mutex_unlock(&ggtt->vm.mutex);
- if (ret)
+ if (ret) {
+ i915_vma_unpin(vma);
return ERR_PTR(ret);
+ }
}
- ret = i915_vma_pin(vma, size, alignment, flags | PIN_GLOBAL);
- if (ret)
- return ERR_PTR(ret);
-
return vma;
}
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index e5512f26e20a..f6e661428b02 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -905,6 +905,12 @@ int i915_vma_pin(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
__i915_vma_set_map_and_fenceable(vma);
}
+ /* Somebody else managed to gazump our placement? */
+ if (i915_vma_misplaced(vma, size, alignment, flags)) {
+ err = -EAGAIN;
+ goto err_active;
+ }
+
GEM_BUG_ON(!vma->pages);
err = i915_vma_bind(vma,
vma->obj ? vma->obj->cache_level : 0,
--
2.24.0
More information about the Intel-gfx
mailing list