Giant svm range split to smaller ranges, align the range start address to max svm range pages to improve MMU TLB usage. Signed-off-by: Philip Yang <Philip.Yang@xxxxxxx> --- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 52 +++++++++++++++++++--------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index cf9565ddddf8..044bb99f88ea 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -1885,6 +1885,37 @@ __init void svm_range_set_max_pages(struct amdgpu_device *adev) max_svm_range_pages = ALIGN(max_svm_range_pages, 1ULL << 9); } +static int +__svm_range_add(struct svm_range_list *svms, uint64_t start, uint64_t last, + struct list_head *insert_list, struct list_head *update_list) +{ + struct svm_range *prange; + uint64_t l; + + pr_debug("max_svm_range_pages 0x%llx adding [0x%llx 0x%llx]\n", + max_svm_range_pages, start, last); + + while (last >= start) { + if (last - start + 1 > max_svm_range_pages) { + if (start % max_svm_range_pages) + l = ALIGN(start, max_svm_range_pages) - 1; + else + l = start + max_svm_range_pages - 1; + } else { + l = last; + } + + prange = svm_range_new(svms, start, l); + if (!prange) + return -ENOMEM; + list_add(&prange->list, insert_list); + list_add(&prange->update_list, update_list); + + start = l + 1; + } + return 0; +} + /** * svm_range_add - add svm range and handle overlap * @p: the range add to this process svms @@ -1987,14 +2018,10 @@ svm_range_add(struct kfd_process *p, uint64_t start, uint64_t size, /* insert a new node if needed */ if (node->start > start) { - prange = svm_range_new(svms, start, node->start - 1); - if (!prange) { - r = -ENOMEM; + r = __svm_range_add(svms, start, node->start - 1, + insert_list, update_list); + if (r) goto out; - } - - list_add(&prange->list, insert_list); - list_add(&prange->update_list, update_list); } node = next; @@ -2002,15 +2029,8 @@ svm_range_add(struct kfd_process *p, uint64_t start, uint64_t size, } /* add a final range at the end if needed */ - if (start <= last) { - prange = svm_range_new(svms, start, last); - if (!prange) { - r = -ENOMEM; - goto out; - } - list_add(&prange->list, insert_list); - list_add(&prange->update_list, update_list); - } + if (start <= last) + r = __svm_range_add(svms, start, last, insert_list, update_list); out: if (r) -- 2.35.1