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 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 Suggested-by: Christian König <[email protected]> Suggested-by: Huang Rui <[email protected]> Signed-off-by: Honglei Huang <[email protected]> --- drivers/gpu/drm/amd/amdgpu/Kconfig | 10 ++++++++++ drivers/gpu/drm/amd/amdgpu/Makefile | 4 ++++ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 +++- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 23 +++++++++++++++++++++-- 4 files changed, 38 insertions(+), 3 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 7b08814a24da4..96fd2b195c295 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -326,6 +326,10 @@ 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 + 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 9c5e93cd3ee64..2a03d5cd78e85 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" @@ -3121,7 +3122,8 @@ 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_UALINK_HANDLE, amdgpu_gem_ualink_handle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW) + DRM_IOCTL_DEF_DRV(AMDGPU_UALINK_HANDLE, amdgpu_gem_ualink_handle_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 4fb22195607a5..77f1794eb5011 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -44,6 +44,7 @@ #include "amdgpu_xgmi.h" #include "amdgpu_dma_buf.h" #include "amdgpu_res_cursor.h" +#include "amdgpu_svm.h" #include "kfd_svm.h" /** @@ -2672,6 +2673,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; @@ -2816,6 +2818,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; @@ -2888,6 +2894,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); @@ -3127,6 +3136,7 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid, { struct amdgpu_vm_update_params params; bool is_compute_context = false; + bool use_amdgpu_svm = false; uint64_t *dst, flags[AMDGPU_VM_MAX_LEVEL]; struct amdgpu_vm *vm; struct drm_exec exec; @@ -3146,6 +3156,7 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid, } is_compute_context = vm->is_compute_context; + use_amdgpu_svm = !!vm->svm; if (is_compute_context) { /* Release the root PD lock since svm_range_restore_pages @@ -3155,8 +3166,16 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid, */ drm_exec_fini(&exec); - 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) return true; /* Re-acquire the VM lock, could be that the VM was freed in between. */ -- 2.53.0
