]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amdgpu: clean up amdgpu hmm range functions
authorSunil Khatri <sunil.khatri@amd.com>
Tue, 30 Sep 2025 08:15:11 +0000 (13:45 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 13 Oct 2025 18:14:28 +0000 (14:14 -0400)
Clean up the amdgpu hmm range functions for clearer
definition of each.

a. Split amdgpu_ttm_tt_get_user_pages_done into two:
   1. amdgpu_hmm_range_valid: To check if the user pages
      are valid and update seq num
   2. amdgpu_hmm_range_free: Clean up the hmm range
      and pfn memory.

b. amdgpu_ttm_tt_get_user_pages_done and
   amdgpu_ttm_tt_discard_user_pages are similar function so remove
   discard and directly use amdgpu_hmm_range_free to clean up the
   hmm range and pfn memory.

Suggested-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Sunil Khatri <sunil.khatri@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.h
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
drivers/gpu/drm/amd/amdkfd/kfd_svm.c

index 70c83e10b9c4f3013e154b4e338cee3f86e01c0b..d0b1468a2ae180c8c960b47b643a555ed34060c4 100644 (file)
@@ -1089,7 +1089,7 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr,
                return 0;
        }
 
-       range = kzalloc(sizeof(*range), GFP_KERNEL);
+       range = amdgpu_hmm_range_alloc();
        if (unlikely(!range)) {
                ret = -ENOMEM;
                goto unregister_out;
@@ -1097,7 +1097,7 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr,
 
        ret = amdgpu_ttm_tt_get_user_pages(bo, range);
        if (ret) {
-               kfree(range);
+               amdgpu_hmm_range_free(range);
                if (ret == -EAGAIN)
                        pr_debug("Failed to get user pages, try again\n");
                else
@@ -1120,7 +1120,7 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr,
        amdgpu_bo_unreserve(bo);
 
 release_out:
-       amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range);
+       amdgpu_hmm_range_free(range);
 unregister_out:
        if (ret)
                amdgpu_hmm_unregister(bo);
@@ -1923,7 +1923,7 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
        if (amdgpu_ttm_tt_get_usermm(mem->bo->tbo.ttm)) {
                amdgpu_hmm_unregister(mem->bo);
                mutex_lock(&process_info->notifier_lock);
-               amdgpu_ttm_tt_discard_user_pages(mem->bo->tbo.ttm, mem->range);
+               amdgpu_hmm_range_free(mem->range);
                mutex_unlock(&process_info->notifier_lock);
        }
 
@@ -2549,7 +2549,7 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info,
 
                bo = mem->bo;
 
-               amdgpu_ttm_tt_discard_user_pages(bo->tbo.ttm, mem->range);
+               amdgpu_hmm_range_free(mem->range);
                mem->range = NULL;
 
                /* BO reservations and getting user pages (hmm_range_fault)
@@ -2573,13 +2573,13 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info,
                        }
                }
 
-               mem->range = kzalloc(sizeof(*mem->range), GFP_KERNEL);
+               mem->range = amdgpu_hmm_range_alloc();
                if (unlikely(!mem->range))
                        return -ENOMEM;
                /* Get updated user pages */
                ret = amdgpu_ttm_tt_get_user_pages(bo, mem->range);
                if (ret) {
-                       kfree(mem->range);
+                       amdgpu_hmm_range_free(mem->range);
                        mem->range = NULL;
                        pr_debug("Failed %d to get user pages\n", ret);
 
@@ -2753,8 +2753,8 @@ static int confirm_valid_user_pages_locked(struct amdkfd_process_info *process_i
                        continue;
 
                /* Only check mem with hmm range associated */
-               valid = amdgpu_ttm_tt_get_user_pages_done(
-                                       mem->bo->tbo.ttm, mem->range);
+               valid = amdgpu_hmm_range_valid(mem->range);
+               amdgpu_hmm_range_free(mem->range);
 
                mem->range = NULL;
                if (!valid) {
index 59951d07570307e4f88176fec3126a836eb18025..c319d216421e82ac4564c85d5330b52a79eefb5c 100644 (file)
@@ -41,6 +41,7 @@
 #include "amdgpu_gmc.h"
 #include "amdgpu_gem.h"
 #include "amdgpu_ras.h"
+#include "amdgpu_hmm.h"
 
 static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p,
                                 struct amdgpu_device *adev,
@@ -891,7 +892,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
                bool userpage_invalidated = false;
                struct amdgpu_bo *bo = e->bo;
 
-               e->range = kzalloc(sizeof(*e->range), GFP_KERNEL);
+               e->range = amdgpu_hmm_range_alloc();
                if (unlikely(!e->range))
                        return -ENOMEM;
 
@@ -994,9 +995,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
 
 out_free_user_pages:
        amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
-               struct amdgpu_bo *bo = e->bo;
-
-               amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, e->range);
+               amdgpu_hmm_range_free(e->range);
                e->range = NULL;
        }
        mutex_unlock(&p->bo_list->bo_list_mutex);
@@ -1327,8 +1326,8 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
         */
        r = 0;
        amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
-               r |= !amdgpu_ttm_tt_get_user_pages_done(e->bo->tbo.ttm,
-                                                       e->range);
+               r |= !amdgpu_hmm_range_valid(e->range);
+               amdgpu_hmm_range_free(e->range);
                e->range = NULL;
        }
        if (r) {
index b0c2a1434f032e4ebb8ca121839fd316f007efbc..4bc506f4924ab421253c927a1bfa42fe980ad40f 100644 (file)
@@ -572,12 +572,12 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
                goto release_object;
 
        if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) {
-               range = kzalloc(sizeof(*range), GFP_KERNEL);
+               range = amdgpu_hmm_range_alloc();
                if (unlikely(!range))
                        return -ENOMEM;
                r = amdgpu_ttm_tt_get_user_pages(bo, range);
                if (r) {
-                       kfree(range);
+                       amdgpu_hmm_range_free(range);
                        goto release_object;
                }
                r = amdgpu_bo_reserve(bo, true);
@@ -601,8 +601,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
 
 user_pages_done:
        if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE)
-               amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range);
-
+               amdgpu_hmm_range_free(range);
 release_object:
        drm_gem_object_put(gobj);
 
index 53d405a92a14ba73139729413014ce859bac1baa..b582fd217bd0c9c4d4030c8fe7b20a3ec6245689 100644 (file)
@@ -226,14 +226,25 @@ out_free_range:
        return r;
 }
 
-bool amdgpu_hmm_range_get_pages_done(struct hmm_range *hmm_range)
+bool amdgpu_hmm_range_valid(struct hmm_range *hmm_range)
 {
-       bool r;
+       if (!hmm_range)
+               return false;
+
+       return !mmu_interval_read_retry(hmm_range->notifier,
+                                       hmm_range->notifier_seq);
+}
+
+struct hmm_range *amdgpu_hmm_range_alloc(void)
+{
+       return kzalloc(sizeof(struct hmm_range), GFP_KERNEL);
+}
+
+void amdgpu_hmm_range_free(struct hmm_range *hmm_range)
+{
+       if (!hmm_range)
+               return;
 
-       r = mmu_interval_read_retry(hmm_range->notifier,
-                                   hmm_range->notifier_seq);
        kvfree(hmm_range->hmm_pfns);
        kfree(hmm_range);
-
-       return r;
 }
index c54e3c64251a442fa03310c135826018da82bda1..e85f912b89382d4f534833afd338c61eb3d52d64 100644 (file)
@@ -35,9 +35,11 @@ int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier,
                               uint64_t start, uint64_t npages, bool readonly,
                               void *owner,
                               struct hmm_range *hmm_range);
-bool amdgpu_hmm_range_get_pages_done(struct hmm_range *hmm_range);
 
 #if defined(CONFIG_HMM_MIRROR)
+bool amdgpu_hmm_range_valid(struct hmm_range *hmm_range);
+struct hmm_range *amdgpu_hmm_range_alloc(void);
+void amdgpu_hmm_range_free(struct hmm_range *hmm_range);
 int amdgpu_hmm_register(struct amdgpu_bo *bo, unsigned long addr);
 void amdgpu_hmm_unregister(struct amdgpu_bo *bo);
 #else
@@ -47,7 +49,20 @@ static inline int amdgpu_hmm_register(struct amdgpu_bo *bo, unsigned long addr)
                      "add CONFIG_ZONE_DEVICE=y in config file to fix this\n");
        return -ENODEV;
 }
+
 static inline void amdgpu_hmm_unregister(struct amdgpu_bo *bo) {}
+
+static inline bool amdgpu_hmm_range_valid(struct hmm_range *hmm_range)
+{
+       return false;
+}
+
+static inline struct hmm_range *amdgpu_hmm_range_alloc(void)
+{
+       return NULL;
+}
+
+static inline void amdgpu_hmm_range_free(struct hmm_range *hmm_range) {}
 #endif
 
 #endif
index 890123bf8ee872958b5650f1d5416b9cc1585956..2fb8cd79583e874513d1af893013bc5f5fa28b5f 100644 (file)
@@ -754,38 +754,6 @@ out_unlock:
        return r;
 }
 
-/* amdgpu_ttm_tt_discard_user_pages - Discard range and pfn array allocations
- */
-void amdgpu_ttm_tt_discard_user_pages(struct ttm_tt *ttm,
-                                     struct hmm_range *range)
-{
-       struct amdgpu_ttm_tt *gtt = (void *)ttm;
-
-       if (gtt && gtt->userptr && range)
-               amdgpu_hmm_range_get_pages_done(range);
-}
-
-/*
- * amdgpu_ttm_tt_get_user_pages_done - stop HMM track the CPU page table change
- * Check if the pages backing this ttm range have been invalidated
- *
- * Returns: true if pages are still valid
- */
-bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm,
-                                      struct hmm_range *range)
-{
-       struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);
-
-       if (!gtt || !gtt->userptr || !range)
-               return false;
-
-       DRM_DEBUG_DRIVER("user_pages_done 0x%llx pages 0x%x\n",
-               gtt->userptr, ttm->num_pages);
-
-       WARN_ONCE(!range->hmm_pfns, "No user pages to check\n");
-
-       return !amdgpu_hmm_range_get_pages_done(range);
-}
 #endif
 
 /*
index 64109912ae9e9d5e75ab363ae42813168c1771bd..bbd6e524de9ec81f2a08ac650f29451a6586e270 100644 (file)
@@ -193,25 +193,12 @@ uint64_t amdgpu_ttm_domain_start(struct amdgpu_device *adev, uint32_t type);
 #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
 int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo,
                                 struct hmm_range *range);
-void amdgpu_ttm_tt_discard_user_pages(struct ttm_tt *ttm,
-                                     struct hmm_range *range);
-bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm,
-                                      struct hmm_range *range);
 #else
 static inline int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo,
                                               struct hmm_range *range)
 {
        return -EPERM;
 }
-static inline void amdgpu_ttm_tt_discard_user_pages(struct ttm_tt *ttm,
-                                                   struct hmm_range *range)
-{
-}
-static inline bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm,
-                                                    struct hmm_range *range)
-{
-       return false;
-}
 #endif
 
 void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct hmm_range *range);
index 8c3787b00f364791e41715410b7dd20a61f9844a..91609dd5730f9a972a3d61be41d48f506ded0c06 100644 (file)
@@ -1737,13 +1737,13 @@ static int svm_range_validate_and_map(struct mm_struct *mm,
                        }
 
                        WRITE_ONCE(p->svms.faulting_task, current);
-                       hmm_range = kzalloc(sizeof(*hmm_range), GFP_KERNEL);
+                       hmm_range = amdgpu_hmm_range_alloc();
                        r = amdgpu_hmm_range_get_pages(&prange->notifier, addr, npages,
                                                       readonly, owner,
                                                       hmm_range);
                        WRITE_ONCE(p->svms.faulting_task, NULL);
                        if (r) {
-                               kfree(hmm_range);
+                               amdgpu_hmm_range_free(hmm_range);
                                pr_debug("failed %d to get svm range pages\n", r);
                        }
                } else {
@@ -1764,10 +1764,13 @@ static int svm_range_validate_and_map(struct mm_struct *mm,
                 * Overrride return value to TRY AGAIN only if prior returns
                 * were successful
                 */
-               if (hmm_range && amdgpu_hmm_range_get_pages_done(hmm_range) && !r) {
+               if (hmm_range && !amdgpu_hmm_range_valid(hmm_range) && !r) {
                        pr_debug("hmm update the range, need validate again\n");
                        r = -EAGAIN;
                }
+               /* Free the hmm range */
+               amdgpu_hmm_range_free(hmm_range);
+
 
                if (!r && !list_empty(&prange->child_list)) {
                        pr_debug("range split by unmap in parallel, validate again\n");