summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/i915_vma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_vma.c')
-rw-r--r--drivers/gpu/drm/i915/i915_vma.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 8243818b1c6c..b3ec954105c9 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -237,6 +237,7 @@ vma_create(struct drm_i915_gem_object *obj,
INIT_LIST_HEAD(&vma->vm_bind_link);
INIT_LIST_HEAD(&vma->non_priv_vm_bind_link);
+ INIT_LIST_HEAD(&vma->vm_rebind_link);
return vma;
err_unlock:
@@ -1622,7 +1623,8 @@ void i915_vma_close(struct i915_vma *vma)
if (atomic_dec_and_lock_irqsave(&vma->open_count,
&gt->closed_lock,
flags)) {
- __vma_close(vma, gt);
+ if (!i915_vma_is_persistent(vma))
+ __vma_close(vma, gt);
spin_unlock_irqrestore(&gt->closed_lock, flags);
}
}
@@ -1647,6 +1649,13 @@ static void force_unbind(struct i915_vma *vma)
if (!drm_mm_node_allocated(&vma->node))
return;
+ /*
+ * Mark persistent vma as purged to avoid it waiting
+ * for VM to be released.
+ */
+ if (i915_vma_is_persistent(vma))
+ i915_vma_set_purged(vma);
+
atomic_and(~I915_VMA_PIN_MASK, &vma->flags);
WARN_ON(__i915_vma_unbind(vma));
GEM_BUG_ON(drm_mm_node_allocated(&vma->node));
@@ -1666,9 +1675,12 @@ static void release_references(struct i915_vma *vma, struct intel_gt *gt,
spin_unlock(&obj->vma.lock);
- i915_gem_vm_bind_lock(vma->vm);
- i915_gem_vm_bind_remove(vma, true);
- i915_gem_vm_bind_unlock(vma->vm);
+ if (i915_vma_is_persistent(vma) &&
+ !i915_vma_is_freed(vma)) {
+ i915_gem_vm_bind_lock(vma->vm);
+ i915_gem_vm_bind_remove(vma, true);
+ i915_gem_vm_bind_unlock(vma->vm);
+ }
spin_lock_irq(&gt->closed_lock);
__i915_vma_remove_closed(vma);
@@ -1843,6 +1855,8 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
int err;
assert_object_held(obj);
+ if (i915_vma_is_persistent(vma))
+ return -EINVAL;
GEM_BUG_ON(!vma->pages);
@@ -2003,6 +2017,16 @@ int __i915_vma_unbind(struct i915_vma *vma)
__i915_vma_evict(vma, false);
drm_mm_remove_node(&vma->node); /* pairs with i915_vma_release() */
+
+ if (i915_vma_is_persistent(vma)) {
+ spin_lock(&vma->vm->vm_rebind_lock);
+ if (list_empty(&vma->vm_rebind_link) &&
+ !i915_vma_is_purged(vma))
+ list_add_tail(&vma->vm_rebind_link,
+ &vma->vm->vm_rebind_list);
+ spin_unlock(&vma->vm->vm_rebind_lock);
+ }
+
return 0;
}