diff options
author | Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> | 2022-07-01 15:50:55 -0700 |
---|---|---|
committer | Andi Shyti <andi.shyti@linux.intel.com> | 2022-07-27 14:02:21 +0000 |
commit | fb01c2a39a73f5c9305fe768ad6b383307cc9704 (patch) | |
tree | 34f464176239756a6523b5db6b7f1d30b99face6 | |
parent | 50b7191a3c46b2dbf994fd5094fa0985e60581d7 (diff) |
drm/i915/vm_bind: Fix vm->vm_bind_mutex and vm->mutex nestingvm-bind
VM_BIND functionality maintain that vm->vm_bind_mutex will never be taken
while holding vm->mutex.
However, while closing 'vm', vma is destroyed while holding vm->mutex.
But vma releasing needs to take vm->vm_bind_mutex in order to delete vma
from the vm_bind_list. To avoid this, destroy the vma 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..4f707d0eb3ef 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_move_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 */ |