init_waitqueue_head(&xe->ufence_wq);
- err = drmm_mutex_init(&xe->drm, &xe->usm.lock);
- if (err)
- goto err;
+ init_rwsem(&xe->usm.lock);
xa_init_flags(&xe->usm.asid_to_vm, XA_FLAGS_ALLOC);
/** @usm.next_asid: next ASID, used to cyclical alloc asids */
u32 next_asid;
/** @usm.lock: protects UM state */
- struct mutex lock;
+ struct rw_semaphore lock;
} usm;
/** @pinned: pinned BO state */
return -EFAULT;
/* ASID to VM */
- mutex_lock(&xe->usm.lock);
+ down_read(&xe->usm.lock);
vm = xa_load(&xe->usm.asid_to_vm, pf->asid);
if (vm && xe_vm_in_fault_mode(vm))
xe_vm_get(vm);
else
vm = NULL;
- mutex_unlock(&xe->usm.lock);
+ up_read(&xe->usm.lock);
if (!vm)
return -EINVAL;
return -EINVAL;
/* ASID to VM */
- mutex_lock(&xe->usm.lock);
+ down_read(&xe->usm.lock);
vm = xa_load(&xe->usm.asid_to_vm, acc->asid);
if (vm)
xe_vm_get(vm);
- mutex_unlock(&xe->usm.lock);
+ up_read(&xe->usm.lock);
if (!vm || !xe_vm_in_fault_mode(vm))
return -EINVAL;
up_write(&vm->lock);
- mutex_lock(&xe->usm.lock);
+ down_write(&xe->usm.lock);
if (vm->usm.asid) {
void *lookup;
lookup = xa_erase(&xe->usm.asid_to_vm, vm->usm.asid);
xe_assert(xe, lookup == vm);
}
- mutex_unlock(&xe->usm.lock);
+ up_write(&xe->usm.lock);
for_each_tile(tile, xe, id)
xe_range_fence_tree_fini(&vm->rftree[id]);
goto err_close_and_put;
if (xe->info.has_asid) {
- mutex_lock(&xe->usm.lock);
+ down_write(&xe->usm.lock);
err = xa_alloc_cyclic(&xe->usm.asid_to_vm, &asid, vm,
XA_LIMIT(1, XE_MAX_ASID - 1),
&xe->usm.next_asid, GFP_KERNEL);
- mutex_unlock(&xe->usm.lock);
+ up_write(&xe->usm.lock);
if (err < 0)
goto err_free_id;