diff options
author | Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> | 2020-08-24 21:35:41 -0700 |
---|---|---|
committer | Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> | 2022-06-18 17:26:54 +0000 |
commit | e43cd7a96521417e74784f12e54a1cd2dec6c90a (patch) | |
tree | b0b835c0bfc976d76d0cfd8750f680b955581b60 | |
parent | 40270e35c3aea4d2ec7f0903a0110cb0519832bd (diff) |
drm/i915/vm_bind: Fix vm->vm_bind_mutex and vm->mutex nestingvm_bind_upstream_7
VM_BIND functionality maintain that vm->vm_bind_mutex will never be taken
while holding vm->mutex.
However, while closing 'vm', vma is released (__i915_vma_put()) while
holding vm->mutex. But vma release function i915_vma_release() needs to
take vm->vm_bind_mutex in order to delete vma from the vm_bind_list.
To avoid this, release vma (__i915_vma_put()) outside vm->mutex while
closing the 'vm'.
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
-rw-r--r-- | drivers/gpu/drm/i915/gt/intel_gtt.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c index 4ab3bda644ff..e9e268a04f62 100644 --- a/drivers/gpu/drm/i915/gt/intel_gtt.c +++ b/drivers/gpu/drm/i915/gt/intel_gtt.c @@ -109,7 +109,8 @@ int map_pt_dma_locked(struct i915_address_space *vm, struct drm_i915_gem_object return 0; } -static void clear_vm_list(struct list_head *list) +static void clear_vm_list(struct list_head *list, + struct list_head *destroy_list) { struct i915_vma *vma, *vn; @@ -138,8 +139,7 @@ static void clear_vm_list(struct list_head *list) i915_vm_resv_get(vma->vm); vma->vm_ddestroy = true; } else { - i915_vma_destroy_locked(vma); - i915_gem_object_put(obj); + list_add_tail(&vma->vm_link, destroy_list); } } @@ -147,16 +147,29 @@ static void clear_vm_list(struct list_head *list) static void __i915_vm_close(struct i915_address_space *vm) { + struct i915_vma *vma, *vn; + struct list_head list; + + INIT_LIST_HEAD(&list); + mutex_lock(&vm->mutex); - clear_vm_list(&vm->bound_list); - clear_vm_list(&vm->unbound_list); + clear_vm_list(&vm->bound_list, &list); + clear_vm_list(&vm->unbound_list, &list); /* Check for must-fix unanticipated side-effects */ GEM_BUG_ON(!list_empty(&vm->bound_list)); GEM_BUG_ON(!list_empty(&vm->unbound_list)); mutex_unlock(&vm->mutex); + + /* Destroy vmas outside vm->mutex */ + list_for_each_entry_safe(vma, vn, &list, vm_link) { + struct drm_i915_gem_object *obj = vma->obj; + + i915_vma_destroy(vma); + i915_gem_object_put(obj); + } } /* lock the vm into the current ww, if we lock one, we lock all */ |