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

Reply via email to