mirror of
https://github.com/torvalds/linux.git
synced 2026-11-13 05:04:29 +01:00
drm/xe: Allow prefetch-only VM bind IOCTLs to use VM read lock
Prefetch-only VM bind IOCTLs do not modify VMAs or use userptr pages. Downgrade vm->lock to read mode once setup is complete. Lays the groundwork for prefetch IOCTLs to use threaded migration. Signed-off-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Francois Dugast <francois.dugast@intel.com> Link: https://patch.msgid.link/20260806185202.3922432-3-matthew.brost@intel.com
This commit is contained in:
parent
941bcc1a4b
commit
53e76bde11
|
|
@ -2451,10 +2451,12 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_vma_ops *vops,
|
|||
.map.gem.offset = bo_offset_or_userptr,
|
||||
};
|
||||
|
||||
vops->flags |= XE_VMA_OPS_FLAG_MODIFIES_GPUVA;
|
||||
ops = drm_gpuvm_sm_map_ops_create(&vm->gpuvm, &map_req);
|
||||
break;
|
||||
}
|
||||
case DRM_XE_VM_BIND_OP_UNMAP:
|
||||
vops->flags |= XE_VMA_OPS_FLAG_MODIFIES_GPUVA;
|
||||
ops = drm_gpuvm_sm_unmap_ops_create(&vm->gpuvm, addr, range);
|
||||
break;
|
||||
case DRM_XE_VM_BIND_OP_PREFETCH:
|
||||
|
|
@ -2463,6 +2465,7 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_vma_ops *vops,
|
|||
case DRM_XE_VM_BIND_OP_UNMAP_ALL:
|
||||
xe_assert(vm->xe, bo);
|
||||
|
||||
vops->flags |= XE_VMA_OPS_FLAG_MODIFIES_GPUVA;
|
||||
err = xe_bo_lock(bo, true);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
|
@ -2524,6 +2527,9 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_vma_ops *vops,
|
|||
u32 i;
|
||||
bool need_put;
|
||||
|
||||
if (xe_vma_is_userptr(vma))
|
||||
vops->flags |= XE_VMA_OPS_FLAG_MODIFIES_GPUVA;
|
||||
|
||||
if (!xe_vma_is_cpu_addr_mirror(vma)) {
|
||||
op->prefetch.region = prefetch_region;
|
||||
continue;
|
||||
|
|
@ -2715,10 +2721,12 @@ static int xe_vma_op_commit(struct xe_vm *vm, struct xe_vma_op *op)
|
|||
{
|
||||
int err = 0;
|
||||
|
||||
xe_vm_assert_write_mode_or_garbage_collector(vm);
|
||||
lockdep_assert_held(&vm->lock);
|
||||
|
||||
switch (op->base.op) {
|
||||
case DRM_GPUVA_OP_MAP:
|
||||
xe_vm_assert_write_mode_or_garbage_collector(vm);
|
||||
|
||||
err |= xe_vm_insert_vma(vm, op->map.vma);
|
||||
if (!err)
|
||||
op->flags |= XE_VMA_OP_COMMITTED;
|
||||
|
|
@ -2728,6 +2736,8 @@ static int xe_vma_op_commit(struct xe_vm *vm, struct xe_vma_op *op)
|
|||
u8 tile_present =
|
||||
gpuva_to_vma(op->base.remap.unmap->va)->tile_present;
|
||||
|
||||
xe_vm_assert_write_mode_or_garbage_collector(vm);
|
||||
|
||||
prep_vma_destroy(vm, gpuva_to_vma(op->base.remap.unmap->va),
|
||||
true);
|
||||
op->flags |= XE_VMA_OP_COMMITTED;
|
||||
|
|
@ -2762,6 +2772,8 @@ static int xe_vma_op_commit(struct xe_vm *vm, struct xe_vma_op *op)
|
|||
break;
|
||||
}
|
||||
case DRM_GPUVA_OP_UNMAP:
|
||||
xe_vm_assert_write_mode_or_garbage_collector(vm);
|
||||
|
||||
prep_vma_destroy(vm, gpuva_to_vma(op->base.unmap.va), true);
|
||||
op->flags |= XE_VMA_OP_COMMITTED;
|
||||
break;
|
||||
|
|
@ -2986,10 +2998,12 @@ static void xe_vma_op_unwind(struct xe_vm *vm, struct xe_vma_op *op,
|
|||
bool post_commit, bool prev_post_commit,
|
||||
bool next_post_commit)
|
||||
{
|
||||
xe_vm_assert_write_mode_or_garbage_collector(vm);
|
||||
lockdep_assert_held(&vm->lock);
|
||||
|
||||
switch (op->base.op) {
|
||||
case DRM_GPUVA_OP_MAP:
|
||||
xe_vm_assert_write_mode_or_garbage_collector(vm);
|
||||
|
||||
if (op->map.vma) {
|
||||
prep_vma_destroy(vm, op->map.vma, post_commit);
|
||||
xe_vma_destroy_unlocked(op->map.vma);
|
||||
|
|
@ -2999,6 +3013,8 @@ static void xe_vma_op_unwind(struct xe_vm *vm, struct xe_vma_op *op,
|
|||
{
|
||||
struct xe_vma *vma = gpuva_to_vma(op->base.unmap.va);
|
||||
|
||||
xe_vm_assert_write_mode_or_garbage_collector(vm);
|
||||
|
||||
if (vma) {
|
||||
xe_svm_notifier_lock(vm);
|
||||
vma->gpuva.flags &= ~XE_VMA_DESTROYED;
|
||||
|
|
@ -3012,6 +3028,8 @@ static void xe_vma_op_unwind(struct xe_vm *vm, struct xe_vma_op *op,
|
|||
{
|
||||
struct xe_vma *vma = gpuva_to_vma(op->base.remap.unmap->va);
|
||||
|
||||
xe_vm_assert_write_mode_or_garbage_collector(vm);
|
||||
|
||||
if (op->remap.prev) {
|
||||
prep_vma_destroy(vm, op->remap.prev, prev_post_commit);
|
||||
xe_vma_destroy_unlocked(op->remap.prev);
|
||||
|
|
@ -3596,7 +3614,7 @@ static struct dma_fence *vm_bind_ioctl_ops_execute(struct xe_vm *vm,
|
|||
struct dma_fence *fence;
|
||||
int err = 0;
|
||||
|
||||
lockdep_assert_held_write(&vm->lock);
|
||||
lockdep_assert_held(&vm->lock);
|
||||
|
||||
xe_validation_guard(&ctx, &vm->xe->val, &exec,
|
||||
((struct xe_val_flags) {
|
||||
|
|
@ -3919,7 +3937,7 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
|||
u32 num_syncs, num_ufence = 0;
|
||||
struct xe_sync_entry *syncs = NULL;
|
||||
struct drm_xe_vm_bind_op *bind_ops = NULL;
|
||||
struct xe_vma_ops vops;
|
||||
struct xe_vma_ops vops = { .flags = 0, };
|
||||
struct dma_fence *fence;
|
||||
int err;
|
||||
int i;
|
||||
|
|
@ -4094,6 +4112,11 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
|||
goto unwind_ops;
|
||||
}
|
||||
|
||||
if (!(vops.flags & XE_VMA_OPS_FLAG_MODIFIES_GPUVA)) {
|
||||
vops.flags |= XE_VMA_OPS_FLAG_DOWNGRADE_LOCK;
|
||||
downgrade_write(&vm->lock);
|
||||
}
|
||||
|
||||
err = xe_vma_ops_alloc(&vops, args->num_binds > 1);
|
||||
if (err)
|
||||
goto unwind_ops;
|
||||
|
|
@ -4130,7 +4153,10 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
|||
free_bos:
|
||||
kvfree(bos);
|
||||
release_vm_lock:
|
||||
up_write(&vm->lock);
|
||||
if (vops.flags & XE_VMA_OPS_FLAG_DOWNGRADE_LOCK)
|
||||
up_read(&vm->lock);
|
||||
else
|
||||
up_write(&vm->lock);
|
||||
put_exec_queue:
|
||||
if (q)
|
||||
xe_exec_queue_put(q);
|
||||
|
|
|
|||
|
|
@ -561,6 +561,8 @@ struct xe_vma_ops {
|
|||
#define XE_VMA_OPS_ARRAY_OF_BINDS BIT(2)
|
||||
#define XE_VMA_OPS_FLAG_SKIP_TLB_WAIT BIT(3)
|
||||
#define XE_VMA_OPS_FLAG_ALLOW_SVM_UNMAP BIT(4)
|
||||
#define XE_VMA_OPS_FLAG_MODIFIES_GPUVA BIT(5)
|
||||
#define XE_VMA_OPS_FLAG_DOWNGRADE_LOCK BIT(6)
|
||||
u32 flags;
|
||||
#ifdef TEST_VM_OPS_ERROR
|
||||
/** @inject_error: inject error to test error handling */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user