mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 03:44:45 +01:00
drm/amdgpu: clean up amdgpu hmm range functions
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>
This commit is contained in:
parent
e095b55155
commit
b1dd0db1c6
8 changed files with 56 additions and 74 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue