[Intel-gfx] [PATCH] drm/i915: Double check vma placement upon gaining the vm lock
Tvrtko Ursulin
tvrtko.ursulin at linux.intel.com
Tue Nov 26 17:04:43 UTC 2019
On 26/11/2019 15:26, Chris Wilson wrote:
> 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;
> + }
> +
What about other callers? They will not be expecting this.
> GEM_BUG_ON(!vma->pages);
> err = i915_vma_bind(vma,
> vma->obj ? vma->obj->cache_level : 0,
>
Regards,
Tvrtko
More information about the Intel-gfx
mailing list