summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>2020-08-24 21:35:41 -0700
committerNiranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>2022-06-18 17:26:54 +0000
commite43cd7a96521417e74784f12e54a1cd2dec6c90a (patch)
treeb0b835c0bfc976d76d0cfd8750f680b955581b60
parent40270e35c3aea4d2ec7f0903a0110cb0519832bd (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.c23
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 */