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

Reply via email to