From: Xiaogang Chen <[email protected]>

When use HPAGE_PMD_SIZE based device private pages during migration core HMM
treats device private memory in HPAGE_PMD_SIZE compound folio if possible.
Current kfd driver uses prange->granularity that can be changed by user. Need
have migration size in CPU and GPU page fault handler in HPAGE_PMD_SIZE based.

For AMD GPU that exposes private device memory choose HPAGE_PMD_SIZE as
minimums migration size in CPU and GPU page fault handler. For x86 it is
same as default prange->granularity.

Signed-off-by: Xiaogang Chen <[email protected]>
---
 drivers/gpu/drm/amd/amdkfd/kfd_migrate.c |  6 ++++--
 drivers/gpu/drm/amd/amdkfd/kfd_svm.c     | 13 +++++++++++--
 drivers/gpu/drm/amd/amdkfd/kfd_svm.h     | 12 ++++++++++++
 3 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
index 49a231e60dfa..f1399dd90d2f 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
@@ -1020,8 +1020,10 @@ static vm_fault_t svm_migrate_to_ram(struct vm_fault 
*vmf)
        if (!prange->actual_loc)
                goto out_unlock_prange;
 
-       /* Align migration range start and size to granularity size */
-       size = 1UL << prange->granularity;
+       /* Align migration range start and size to max of
+        * THP with HPAGE_PMD_ORDER and granularity size
+        */
+       size = 1UL << max(prange->granularity, HPAGE_PMD_ORDER);
        start = max(ALIGN_DOWN(addr, size), prange->start);
        last = min(ALIGN(addr + 1, size) - 1, prange->last);
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
index 280c38932217..c66f83abedd0 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -3062,6 +3062,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, 
unsigned int pasid,
        struct kfd_node *node;
        int32_t best_loc;
        int32_t gpuid, gpuidx = MAX_GPU_INSTANCE;
+       bool is_private_device = false;
        bool write_locked = false;
        struct vm_area_struct *vma;
        bool migration = false;
@@ -3078,6 +3079,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, 
unsigned int pasid,
                return 0;
        }
        svms = &p->svms;
+       is_private_device = svm_is_private_zone(adev);
 
        pr_debug("restoring svms 0x%p fault address 0x%llx\n", svms, addr);
 
@@ -3215,8 +3217,15 @@ svm_range_restore_pages(struct amdgpu_device *adev, 
unsigned int pasid,
        kfd_smi_event_page_fault_start(node, p->lead_thread, addr,
                                       write_fault, timestamp);
 
-       /* Align migration range start and size to granularity size */
-       size = 1UL << prange->granularity;
+       if (is_private_device)
+               /* Align migration range start and size to max of
+                * THP and granularity size
+                */
+               size = 1UL << max(prange->granularity, HPAGE_PMD_ORDER);
+       else
+               /* Align migration range start and size to granularity size */
+               size = 1UL << prange->granularity;
+
        start = max_t(unsigned long, ALIGN_DOWN(addr, size), prange->start);
        last = min_t(unsigned long, ALIGN(addr + 1, size) - 1, prange->last);
        if (prange->actual_loc != 0 || best_loc != 0) {
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h 
b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
index c7d7adae4476..0c9bb9cfd0b5 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
@@ -214,6 +214,13 @@ void svm_range_bo_unref_async(struct svm_range_bo *svm_bo);
 void svm_range_set_max_pages(struct amdgpu_device *adev);
 int svm_range_switch_xnack_reserve_mem(struct kfd_process *p, bool 
xnack_enabled);
 
+/* check adev has device private zone memory */
+static inline bool svm_is_private_zone(struct amdgpu_device *adev)
+{
+       struct amdgpu_kfd_dev *kfddev = &adev->kfd;
+       return (kfddev->pgmap.type == MEMORY_DEVICE_PRIVATE);
+}
+
 #else
 
 struct kfd_process;
@@ -276,6 +283,11 @@ static inline void svm_range_set_max_pages(struct 
amdgpu_device *adev)
 {
 }
 
+static inline bool svm_is_private_zone(struct amdgpu_device *adev)
+{
+       return false;
+}
+
 #define KFD_IS_SVM_API_SUPPORTED(dev) false
 
 #endif /* IS_ENABLED(CONFIG_HSA_AMD_SVM) */
-- 
2.34.1

Reply via email to