From: Honglei Huang <[email protected]> Enable SVM compilation and integrate it into the VM subsystem:
Kconfig: - Add CONFIG_DRM_AMDGPU_SVM option (depends on DRM_AMDGPU and DEVICE_PRIVATE, selects DRM_GPUSVM, HMM_MIRROR, MMU_NOTIFIER) Makefile: - Build amdgpu_svm.o, amdgpu_svm_attr.o, amdgpu_svm_range.o when CONFIG_DRM_AMDGPU_SVM is enabled amdgpu_drv.c: - Register DRM_IOCTL_AMDGPU_GEM_SVM in the ioctl table amdgpu_vm.c: - Initialize vm->svm = NULL in amdgpu_vm_init - Call amdgpu_svm_init in amdgpu_vm_make_compute for compute VMs - Call amdgpu_svm_close + amdgpu_svm_fini in amdgpu_vm_fini - Integrate SVM fault handling in amdgpu_vm_handle_fault Signed-off-by: Honglei Huang <[email protected]> --- drivers/gpu/drm/amd/amdgpu/Kconfig | 11 +++++++ drivers/gpu/drm/amd/amdgpu/Makefile | 13 ++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 40 ++++++++++++++++++++++--- 4 files changed, 62 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig b/drivers/gpu/drm/amd/amdgpu/Kconfig index 1acfed2f9..22f679b85 100644 --- a/drivers/gpu/drm/amd/amdgpu/Kconfig +++ b/drivers/gpu/drm/amd/amdgpu/Kconfig @@ -74,6 +74,17 @@ 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 + default y + 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 64e7acff8..6507d9a39 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -43,6 +43,10 @@ ccflags-y := -I$(FULL_AMD_PATH)/include/asic_reg \ subdir-ccflags-y += -Wno-override-init subdir-ccflags-$(CONFIG_DRM_AMDGPU_WERROR) += -Werror +ifneq ($(wildcard $(objtree)/drivers/gpu/drm/Module.symvers),) +KBUILD_EXTRA_SYMBOLS += $(objtree)/drivers/gpu/drm/Module.symvers +endif + amdgpu-y := amdgpu_drv.o # add KMS driver @@ -303,6 +307,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_range.o + +.PHONY: clean-svm +clean-svm: + rm -f $(obj)/amdgpu_svm.o $(obj)/amdgpu_svm_attr.o $(obj)/amdgpu_svm_range.o \ + $(obj)/.amdgpu_svm.o.cmd $(obj)/.amdgpu_svm_attr.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 7333e1929..12b587f9c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -50,6 +50,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" @@ -3068,6 +3069,7 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(AMDGPU_USERQ_SIGNAL, amdgpu_userq_signal_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 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_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 676e24fb8..f64392117 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" /** @@ -2564,6 +2565,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; INIT_LIST_HEAD(&vm->evicted); @@ -2722,6 +2724,10 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm) vm->last_update = dma_fence_get_stub(); vm->is_compute_context = true; + r = amdgpu_svm_init(adev, vm); + if (r) + goto unreserve_bo; + unreserve_bo: amdgpu_bo_unreserve(vm->root.bo); return r; @@ -2754,6 +2760,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); @@ -2939,8 +2948,10 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid, bool write_fault) { bool is_compute_context = false; + bool has_svm = false; struct amdgpu_bo *root; unsigned long irqflags; + uint64_t fault_addr = addr; uint64_t value, flags; struct amdgpu_vm *vm; int r; @@ -2950,6 +2961,7 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid, if (vm) { root = amdgpu_bo_ref(vm->root.bo); is_compute_context = vm->is_compute_context; + has_svm = !!vm->svm; } else { root = NULL; } @@ -2960,12 +2972,30 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid, addr /= AMDGPU_GPU_PAGE_SIZE; - if (is_compute_context && !svm_range_restore_pages(adev, pasid, vmid, - node_id, addr, ts, write_fault)) { - amdgpu_bo_unref(&root); - return true; + pr_debug("vm_handle_fault: pasid=%u addr=0x%llx compute=%d has_svm=%d write=%d\n", + pasid, fault_addr, is_compute_context, has_svm, write_fault); + + if (is_compute_context && has_svm) { + r = amdgpu_svm_handle_fault(adev, pasid, fault_addr, write_fault); + pr_debug("vm_handle_fault: svm_handle_fault returned %d\n", r); + if (!r) { + amdgpu_bo_unref(&root); + return true; + } } + if (is_compute_context && !has_svm) { + r = svm_range_restore_pages(adev, pasid, vmid, + node_id, addr, ts, write_fault); + pr_debug("vm_handle_fault: kfd svm_range_restore_pages returned %d\n", r); + if (!r) { + amdgpu_bo_unref(&root); + return true; + } + } + + pr_debug("vm_handle_fault: SVM paths exhausted, falling through to NORETRY path\n"); + r = amdgpu_bo_reserve(root, true); if (r) goto error_unref; @@ -3020,6 +3050,8 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid, error_unref: amdgpu_bo_unref(&root); + pr_debug("vm_handle_fault: returning false (unhandled) pasid=%u addr=0x%llx\n", + pasid, fault_addr); return false; } -- 2.34.1
