From: Honglei Huang <[email protected]> Wire up the SVM subsystem:
Kconfig: - CONFIG_DRM_AMDGPU_SVM option, depends on DEVICE_PRIVATE, selects DRM_GPUSVM, HMM_MIRROR, MMU_NOTIFIER, default n Makefile: - Build amdgpu_svm.o, amdgpu_svm_attr.o, amdgpu_svm_fault.o, amdgpu_svm_range.o when CONFIG_DRM_AMDGPU_SVM=y - KBUILD_EXTRA_SYMBOLS for drm Module.symvers - clean-svm phony target for development convenience amdgpu_drv.c: - Register DRM_IOCTL_DEF_DRV in ioctl table amdgpu_vm.c: - Initialize vm->svm = NULL in amdgpu_vm_init - Call amdgpu_svm_init in amdgpu_vm_make_compute - Call amdgpu_svm_close + amdgpu_svm_fini in amdgpu_vm_fini - Route GPU page faults through amdgpu_svm_handle_fault when SVM context exists, without falling back to svm_range_restore_pages Signed-off-by: Honglei Huang <[email protected]> --- drivers/gpu/drm/amd/amdgpu/Kconfig | 10 ++++++++++ drivers/gpu/drm/amd/amdgpu/Makefile | 9 +++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 23 +++++++++++++++++++++-- 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig b/drivers/gpu/drm/amd/amdgpu/Kconfig index 12e4a41bf1f04..68f519b3479db 100644 --- a/drivers/gpu/drm/amd/amdgpu/Kconfig +++ b/drivers/gpu/drm/amd/amdgpu/Kconfig @@ -81,6 +81,16 @@ config DRM_AMDGPU_USERPTR This option selects CONFIG_HMM and CONFIG_HMM_MIRROR if it isn't already selected to enabled full userptr support. +config DRM_AMDGPU_SVM + bool "Enable AMDGPU SVM support (experimental)" + depends on DRM_AMDGPU + depends on DEVICE_PRIVATE + select DRM_GPUSVM + select HMM_MIRROR + select MMU_NOTIFIER + help + Experimental SVM support based on DRM GPUSVM. + config DRM_AMD_ISP bool "Enable AMD Image Signal Processor IP support" depends on DRM_AMDGPU && ACPI diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index ba80542ead9d9..884cdc5c1e4af 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -322,6 +322,15 @@ amdgpu-$(CONFIG_VGA_SWITCHEROO) += amdgpu_atpx_handler.o amdgpu-$(CONFIG_ACPI) += amdgpu_acpi.o amdgpu-$(CONFIG_HMM_MIRROR) += amdgpu_hmm.o +# svm support +amdgpu-$(CONFIG_DRM_AMDGPU_SVM) += amdgpu_svm.o amdgpu_svm_attr.o \ + amdgpu_svm_fault.o amdgpu_svm_range.o + +.PHONY: clean-svm +clean-svm: + rm -f $(obj)/amdgpu_svm.o $(obj)/amdgpu_svm_attr.o $(obj)/amdgpu_svm_fault.o $(obj)/amdgpu_svm_range.o \ + $(obj)/.amdgpu_svm.o.cmd $(obj)/.amdgpu_svm_attr.o.cmd $(obj)/.amdgpu_svm_fault.o.cmd $(obj)/.amdgpu_svm_range.o.cmd + include $(FULL_AMD_PATH)/pm/Makefile amdgpu-y += $(AMD_POWERPLAY_FILES) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 503bb64c1e55f..46a074caba53a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -51,6 +51,7 @@ #include "amdgpu_ras.h" #include "amdgpu_reset.h" #include "amdgpu_sched.h" +#include "amdgpu_svm.h" #include "amdgpu_xgmi.h" #include "amdgpu_userq.h" #include "amdgpu_userq_fence.h" @@ -3077,6 +3078,7 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(AMDGPU_USERQ_WAIT, amdgpu_userq_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_GEM_LIST_HANDLES, amdgpu_gem_list_handles_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_PROC_OPTIONS, amdgpu_proc_options_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_GEM_SVM, amdgpu_gem_svm_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), }; static const struct drm_driver amdgpu_kms_driver = { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 2f3470208829e..9274b0359a164 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -43,6 +43,7 @@ #include "amdgpu_xgmi.h" #include "amdgpu_dma_buf.h" #include "amdgpu_res_cursor.h" +#include "amdgpu_svm.h" #include "kfd_svm.h" /** @@ -2573,6 +2574,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int r, i; vm->va = RB_ROOT_CACHED; + vm->svm = NULL; for (i = 0; i < AMDGPU_MAX_VMHUBS; i++) vm->reserved_vmid[i] = NULL; @@ -2731,6 +2733,10 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm) vm->is_compute_context = true; vm->need_tlb_fence = true; + r = amdgpu_svm_init(adev, vm); + if (r) + goto unreserve_bo; + unreserve_bo: amdgpu_bo_unreserve(vm->root.bo); return r; @@ -2763,6 +2769,9 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) unsigned long flags; int i; + amdgpu_svm_close(vm); + amdgpu_svm_fini(vm); + amdgpu_amdkfd_gpuvm_destroy_cb(adev, vm); root = amdgpu_bo_ref(vm->root.bo); @@ -2985,6 +2994,7 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid, uint64_t ts, bool write_fault) { bool is_compute_context = false; + bool use_amdgpu_svm = false; struct amdgpu_bo *root; uint64_t value, flags; struct amdgpu_vm *vm; @@ -2995,14 +3005,23 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid, return false; is_compute_context = vm->is_compute_context; + use_amdgpu_svm = !!vm->svm; if (is_compute_context) { /* Unreserve root since svm_range_restore_pages might try to reserve it. */ /* TODO: rework svm_range_restore_pages so that this isn't necessary. */ amdgpu_bo_unreserve(root); - if (!svm_range_restore_pages(adev, pasid, vmid, - node_id, addr >> PAGE_SHIFT, ts, write_fault)) { + if (use_amdgpu_svm) + r = amdgpu_svm_handle_fault(adev, pasid, + addr >> PAGE_SHIFT, ts, + write_fault); + else + r = svm_range_restore_pages(adev, pasid, vmid, node_id, + addr >> PAGE_SHIFT, ts, + write_fault); + + if (!r) { amdgpu_bo_unref(&root); return true; } -- 2.53.0
