On Wed, 2025-01-29 at 11:51 -0800, Matthew Brost wrote: > Add SVM init / close / fini to faulting VMs. Minimual implementation > acting as a placeholder for follow on patches. > > v2: > - Add close function > v3: > - Better commit message (Thomas) > - Kernel doc (Thomas) > - Update chunk array to be unsigned long (Thomas) > - Use new drm_gpusvm.h header location (Thomas) > - Newlines between functions in xe_svm.h (Thomas) > - Call drm_gpusvm_driver_set_lock in init (Thomas) > > Signed-off-by: Matthew Brost <matthew.brost@xxxxxxxxx> Reviewed-by: Thomas Hellström <thomas.hellstrom@xxxxxxxxxxxxxxx> > --- > drivers/gpu/drm/xe/Makefile | 1 + > drivers/gpu/drm/xe/xe_svm.c | 73 > ++++++++++++++++++++++++++++++++ > drivers/gpu/drm/xe/xe_svm.h | 17 ++++++++ > drivers/gpu/drm/xe/xe_vm.c | 12 ++++++ > drivers/gpu/drm/xe/xe_vm_types.h | 7 +++ > 5 files changed, 110 insertions(+) > create mode 100644 drivers/gpu/drm/xe/xe_svm.c > create mode 100644 drivers/gpu/drm/xe/xe_svm.h > > diff --git a/drivers/gpu/drm/xe/Makefile > b/drivers/gpu/drm/xe/Makefile > index 328aff36831b..a078a8895ec5 100644 > --- a/drivers/gpu/drm/xe/Makefile > +++ b/drivers/gpu/drm/xe/Makefile > @@ -97,6 +97,7 @@ xe-y += xe_bb.o \ > xe_sched_job.o \ > xe_step.o \ > xe_survivability_mode.o \ > + xe_svm.o \ > xe_sync.o \ > xe_tile.o \ > xe_tile_sysfs.o \ > diff --git a/drivers/gpu/drm/xe/xe_svm.c > b/drivers/gpu/drm/xe/xe_svm.c > new file mode 100644 > index 000000000000..79da859f02b1 > --- /dev/null > +++ b/drivers/gpu/drm/xe/xe_svm.c > @@ -0,0 +1,73 @@ > +// SPDX-License-Identifier: MIT > +/* > + * Copyright © 2024 Intel Corporation > + */ > + > +#include "xe_svm.h" > +#include "xe_vm.h" > +#include "xe_vm_types.h" > + > +static void xe_svm_invalidate(struct drm_gpusvm *gpusvm, > + struct drm_gpusvm_notifier *notifier, > + const struct mmu_notifier_range > *mmu_range) > +{ > + /* TODO: Implement */ > +} > + > +static const struct drm_gpusvm_ops gpusvm_ops = { > + .invalidate = xe_svm_invalidate, > +}; > + > +static const unsigned long fault_chunk_sizes[] = { > + SZ_2M, > + SZ_64K, > + SZ_4K, > +}; > + > +/** > + * xe_svm_init() - SVM initialize > + * @vm: The VM. > + * > + * Initialize SVM state which is embedded within the VM. > + * > + * Return: 0 on success, negative error code on error. > + */ > +int xe_svm_init(struct xe_vm *vm) > +{ > + int err; > + > + err = drm_gpusvm_init(&vm->svm.gpusvm, "Xe SVM", &vm->xe- > >drm, > + current->mm, NULL, 0, vm->size, > + SZ_512M, &gpusvm_ops, > fault_chunk_sizes, > + ARRAY_SIZE(fault_chunk_sizes)); > + if (err) > + return err; > + > + drm_gpusvm_driver_set_lock(&vm->svm.gpusvm, &vm->lock); > + > + return 0; > +} > + > +/** > + * xe_svm_close() - SVM close > + * @vm: The VM. > + * > + * Close SVM state (i.e., stop and flush all SVM actions). > + */ > +void xe_svm_close(struct xe_vm *vm) > +{ > + xe_assert(vm->xe, xe_vm_is_closed(vm)); > +} > + > +/** > + * xe_svm_fini() - SVM finalize > + * @vm: The VM. > + * > + * Finalize SVM state which is embedded within the VM. > + */ > +void xe_svm_fini(struct xe_vm *vm) > +{ > + xe_assert(vm->xe, xe_vm_is_closed(vm)); > + > + drm_gpusvm_fini(&vm->svm.gpusvm); > +} > diff --git a/drivers/gpu/drm/xe/xe_svm.h > b/drivers/gpu/drm/xe/xe_svm.h > new file mode 100644 > index 000000000000..49cfd938aa17 > --- /dev/null > +++ b/drivers/gpu/drm/xe/xe_svm.h > @@ -0,0 +1,17 @@ > +/* SPDX-License-Identifier: MIT */ > +/* > + * Copyright © 2024 Intel Corporation > + */ > + > +#ifndef _XE_SVM_H_ > +#define _XE_SVM_H_ > + > +struct xe_vm; > + > +int xe_svm_init(struct xe_vm *vm); > + > +void xe_svm_fini(struct xe_vm *vm); > + > +void xe_svm_close(struct xe_vm *vm); > + > +#endif > diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c > index dff10dfa9c69..bc34e6738c8c 100644 > --- a/drivers/gpu/drm/xe/xe_vm.c > +++ b/drivers/gpu/drm/xe/xe_vm.c > @@ -34,6 +34,7 @@ > #include "xe_preempt_fence.h" > #include "xe_pt.h" > #include "xe_res_cursor.h" > +#include "xe_svm.h" > #include "xe_sync.h" > #include "xe_trace_bo.h" > #include "xe_wa.h" > @@ -1504,6 +1505,12 @@ struct xe_vm *xe_vm_create(struct xe_device > *xe, u32 flags) > } > } > > + if (flags & XE_VM_FLAG_FAULT_MODE) { > + err = xe_svm_init(vm); > + if (err) > + goto err_close; > + } > + > if (number_tiles > 1) > vm->composite_fence_ctx = > dma_fence_context_alloc(1); > > @@ -1549,6 +1556,8 @@ void xe_vm_close_and_put(struct xe_vm *vm) > xe_vm_close(vm); > if (xe_vm_in_preempt_fence_mode(vm)) > flush_work(&vm->preempt.rebind_work); > + if (xe_vm_in_fault_mode(vm)) > + xe_svm_close(vm); > > down_write(&vm->lock); > for_each_tile(tile, xe, id) { > @@ -1617,6 +1626,9 @@ void xe_vm_close_and_put(struct xe_vm *vm) > xe_vma_destroy_unlocked(vma); > } > > + if (xe_vm_in_fault_mode(vm)) > + xe_svm_fini(vm); > + > up_write(&vm->lock); > > down_write(&xe->usm.lock); > diff --git a/drivers/gpu/drm/xe/xe_vm_types.h > b/drivers/gpu/drm/xe/xe_vm_types.h > index f6855e4fb9e6..aa075d5e7a3f 100644 > --- a/drivers/gpu/drm/xe/xe_vm_types.h > +++ b/drivers/gpu/drm/xe/xe_vm_types.h > @@ -6,6 +6,7 @@ > #ifndef _XE_VM_TYPES_H_ > #define _XE_VM_TYPES_H_ > > +#include <drm/drm_gpusvm.h> > #include <drm/drm_gpuvm.h> > > #include <linux/dma-resv.h> > @@ -140,6 +141,12 @@ struct xe_vm { > /** @gpuvm: base GPUVM used to track VMAs */ > struct drm_gpuvm gpuvm; > > + /** @svm: Shared virtual memory state */ > + struct { > + /** @svm.gpusvm: base GPUSVM used to track fault > allocations */ > + struct drm_gpusvm gpusvm; > + } svm; > + > struct xe_device *xe; > > /* exec queue used for (un)binding vma's */