diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_vma.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_vma.c | 32 |
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, >->closed_lock, flags)) { - __vma_close(vma, gt); + if (!i915_vma_is_persistent(vma)) + __vma_close(vma, gt); spin_unlock_irqrestore(>->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(>->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; } |