<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p><br>
</p>
<div class="moz-cite-prefix">On 2023-10-19 16:05, Felix Kuehling
wrote:<br>
</div>
<blockquote type="cite" cite="mid:0f8c20d2-65bb-4b03-901d-804c80f9300e@amd.com">
<br>
On 2023-10-18 18:26, Alex Sierra wrote:
<br>
<blockquote type="cite">Split SVM ranges that have been mapped
into 2MB page table entries,
<br>
require to be remap in case the split has happened in a
non-aligned
<br>
VA.
<br>
[WHY]:
<br>
This condition causes the 2MB page table entries be split into
4KB
<br>
PTEs.
<br>
<br>
Signed-off-by: Alex Sierra <a class="moz-txt-link-rfc2396E" href="mailto:alex.sierra@amd.com"><alex.sierra@amd.com></a>
<br>
---
<br>
drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 45
+++++++++++++++++++++-------
<br>
1 file changed, 34 insertions(+), 11 deletions(-)
<br>
<br>
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
<br>
index 7b81233bc9ae..1dd9a1cf2358 100644
<br>
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
<br>
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
<br>
@@ -1104,26 +1104,34 @@ svm_range_split(struct svm_range
*prange, uint64_t start, uint64_t last,
<br>
}
<br>
static int
<br>
-svm_range_split_tail(struct svm_range *prange,
<br>
- uint64_t new_last, struct list_head *insert_list)
<br>
+svm_range_split_tail(struct svm_range *prange, uint64_t
new_last,
<br>
+ struct list_head *insert_list, struct list_head
*remap_list)
<br>
{
<br>
struct svm_range *tail;
<br>
int r = svm_range_split(prange, prange->start,
new_last, &tail);
<br>
- if (!r)
<br>
+ if (!r) {
<br>
list_add(&tail->list, insert_list);
<br>
+ if (!IS_ALIGNED(tail->last + 1 - tail->start,
<br>
+ 1UL << tail->granularity))
<br>
</blockquote>
<br>
I'm not sure about this condition. I thought this condition should
be about the point where the range is split, not the size of it.
So my understanding is that this should be
<br>
<br>
if (!IS_ALIGNED(new_last+1, 1UL <<
prange->granularity))
<br>
</blockquote>
<p>I think prange->granularity is not always 9, 512 pages, we
should check the original prange size is larger than 512.<br>
</p>
<p> if (!IS_ALIGNED(new_last + 1, 512) &&
tail->last - prange->start >= 512)<br>
</p>
<blockquote type="cite" cite="mid:0f8c20d2-65bb-4b03-901d-804c80f9300e@amd.com">
<br>
<br>
<blockquote type="cite">+
list_add(&tail->update_list, remap_list);
<br>
+ }
<br>
return r;
<br>
}
<br>
static int
<br>
-svm_range_split_head(struct svm_range *prange,
<br>
- uint64_t new_start, struct list_head *insert_list)
<br>
+svm_range_split_head(struct svm_range *prange, uint64_t
new_start,
<br>
+ struct list_head *insert_list, struct list_head
*remap_list)
<br>
{
<br>
struct svm_range *head;
<br>
int r = svm_range_split(prange, new_start,
prange->last, &head);
<br>
- if (!r)
<br>
+ if (!r) {
<br>
list_add(&head->list, insert_list);
<br>
+ if (!IS_ALIGNED(head->last + 1 - head->start,
<br>
+ 1UL << head->granularity))
<br>
</blockquote>
<br>
Similar as above.
<br>
<br>
if (!IS_ALIGNED(new_start, 1UL <<
prange->granularity))
<br>
</blockquote>
<p> if (!IS_ALIGNED(new_start, 512) &&
prange->last - head->start >= 512)</p>
<blockquote type="cite" cite="mid:0f8c20d2-65bb-4b03-901d-804c80f9300e@amd.com">
<br>
Regards,
<br>
Felix
<br>
<br>
<br>
<blockquote type="cite">+
list_add(&head->update_list, remap_list);
<br>
+ }
<br>
return r;
<br>
}
<br>
@@ -2113,7 +2121,7 @@ static int
<br>
svm_range_add(struct kfd_process *p, uint64_t start, uint64_t
size,
<br>
uint32_t nattr, struct kfd_ioctl_svm_attribute
*attrs,
<br>
struct list_head *update_list, struct list_head
*insert_list,
<br>
- struct list_head *remove_list)
<br>
+ struct list_head *remove_list, struct list_head
*remap_list)
<br>
{
<br>
unsigned long last = start + size - 1UL;
<br>
struct svm_range_list *svms = &p->svms;
<br>
@@ -2129,6 +2137,7 @@ svm_range_add(struct kfd_process *p,
uint64_t start, uint64_t size,
<br>
INIT_LIST_HEAD(insert_list);
<br>
INIT_LIST_HEAD(remove_list);
<br>
INIT_LIST_HEAD(&new_list);
<br>
+ INIT_LIST_HEAD(remap_list);
<br>
node = interval_tree_iter_first(&svms->objects,
start, last);
<br>
while (node) {
<br>
@@ -2153,6 +2162,7 @@ svm_range_add(struct kfd_process *p,
uint64_t start, uint64_t size,
<br>
struct svm_range *old = prange;
<br>
prange = svm_range_clone(old);
<br>
+
<br>
</blockquote>
</blockquote>
<p>unnecessary change.</p>
<p>Regards,</p>
<p>Philip<br>
</p>
<blockquote type="cite" cite="mid:0f8c20d2-65bb-4b03-901d-804c80f9300e@amd.com">
<blockquote type="cite"> if (!prange) {
<br>
r = -ENOMEM;
<br>
goto out;
<br>
@@ -2161,18 +2171,17 @@ svm_range_add(struct kfd_process *p,
uint64_t start, uint64_t size,
<br>
list_add(&old->update_list, remove_list);
<br>
list_add(&prange->list, insert_list);
<br>
list_add(&prange->update_list,
update_list);
<br>
-
<br>
if (node->start < start) {
<br>
pr_debug("change old range start\n");
<br>
r = svm_range_split_head(prange, start,
<br>
- insert_list);
<br>
+ insert_list, remap_list);
<br>
if (r)
<br>
goto out;
<br>
}
<br>
if (node->last > last) {
<br>
pr_debug("change old range last\n");
<br>
r = svm_range_split_tail(prange, last,
<br>
- insert_list);
<br>
+ insert_list, remap_list);
<br>
if (r)
<br>
goto out;
<br>
}
<br>
@@ -3565,6 +3574,7 @@ svm_range_set_attr(struct kfd_process *p,
struct mm_struct *mm,
<br>
struct list_head update_list;
<br>
struct list_head insert_list;
<br>
struct list_head remove_list;
<br>
+ struct list_head remap_list;
<br>
struct svm_range_list *svms;
<br>
struct svm_range *prange;
<br>
struct svm_range *next;
<br>
@@ -3596,7 +3606,7 @@ svm_range_set_attr(struct kfd_process *p,
struct mm_struct *mm,
<br>
/* Add new range and split existing ranges as needed */
<br>
r = svm_range_add(p, start, size, nattr, attrs,
&update_list,
<br>
- &insert_list, &remove_list);
<br>
+ &insert_list, &remove_list,
&remap_list);
<br>
if (r) {
<br>
mutex_unlock(&svms->lock);
<br>
mmap_write_unlock(mm);
<br>
@@ -3661,6 +3671,19 @@ svm_range_set_attr(struct kfd_process *p,
struct mm_struct *mm,
<br>
ret = r;
<br>
}
<br>
+ list_for_each_entry(prange, &remap_list, update_list)
{
<br>
+ pr_debug("Remapping prange 0x%p [0x%lx 0x%lx]\n",
<br>
+ prange, prange->start, prange->last);
<br>
+ mutex_lock(&prange->migrate_mutex);
<br>
+ r = svm_range_validate_and_map(mm, prange,
MAX_GPU_INSTANCE,
<br>
+ true, true,
prange->mapped_to_gpu);
<br>
+ if (r)
<br>
+ pr_debug("failed %d on remap svm range\n", r);
<br>
+ mutex_unlock(&prange->migrate_mutex);
<br>
+ if (r)
<br>
+ ret = r;
<br>
+ }
<br>
+
<br>
dynamic_svm_range_dump(svms);
<br>
mutex_unlock(&svms->lock);
<br>
</blockquote>
</blockquote>
</body>
</html>