<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-02 15:27, Felix Kuehling
wrote:<br>
</div>
<blockquote type="cite" cite="mid:3c56e437-b901-4d93-a3bb-1b788d1aba18@amd.com">
<div class="moz-cite-prefix">On 2023-09-29 10:11, Philip Yang
wrote:<br>
</div>
<blockquote type="cite" cite="mid:20230929141115.10016-2-Philip.Yang@amd.com">
<pre class="moz-quote-pre" wrap="">Align unmap range start and last address to granularity boundary.
Skip unmap if range is already unmapped from GPUs.</pre>
</blockquote>
<p>This only handles unmap due to MMU notifiers with XNACK on.
What about svm_range_unmap_from_cpu?<br>
</p>
</blockquote>
unmap_from_cpu is going to remove the range, we cannot align range
based on granularity, still split the prange and unmap from GPU the
exact range .<br>
<blockquote type="cite" cite="mid:3c56e437-b901-4d93-a3bb-1b788d1aba18@amd.com">
<p> </p>
<p>Regards,<br>
Felix</p>
<p><br>
</p>
<blockquote type="cite" cite="mid:20230929141115.10016-2-Philip.Yang@amd.com">
<pre class="moz-quote-pre" wrap="">This also solve the rocgdb CWSR migration related issue.
Signed-off-by: Philip Yang <a class="moz-txt-link-rfc2396E" href="mailto:Philip.Yang@amd.com" moz-do-not-send="true"><Philip.Yang@amd.com></a>
---
drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 35 ++++++++++++++++++++++++----
1 file changed, 31 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
index 626e0dd4ec79..ac65bf25c685 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -2004,6 +2004,26 @@ static void svm_range_restore_work(struct work_struct *work)
mmput(mm);
}
+static unsigned long
+svm_range_align_start(struct svm_range *prange, unsigned long start)
+{
+ unsigned long start_align;
+
+ start_align = ALIGN_DOWN(start, 1UL << prange->granularity);
+ start_align = max_t(unsigned long, start_align, prange->start);
+ return start_align;
+}
+
+static unsigned long
+svm_range_align_last(struct svm_range *prange, unsigned long last)
+{
+ unsigned long last_align;
+
+ last_align = ALIGN(last, 1UL << prange->granularity) - 1;</pre>
</blockquote>
<p>I think this should be</p>
<pre> last_align = ALIGN(last + 1, 1UL << prange->granularity) - 1;
</pre>
<p>Otherwise you're off by one granule when (last & (1UL
<< prange->granularity)) == 0.<br>
</p>
<p><br>
</p>
<blockquote type="cite" cite="mid:20230929141115.10016-2-Philip.Yang@amd.com">
<pre class="moz-quote-pre" wrap="">+ last_align = min_t(unsigned long, last_align, prange->last);
+ return last_align;
+}
+
/**
* svm_range_evict - evict svm range
* @prange: svm range structure
@@ -2078,6 +2098,12 @@ svm_range_evict(struct svm_range *prange, struct mm_struct *mm,
unsigned long s, l;
uint32_t trigger;
+ if (!svm_range_partial_mapped(prange, start, last)) {
+ pr_debug("svms 0x%p [0x%lx 0x%lx] unmapped already\n",
+ prange->svms, start, last);
+ return 0;
+ }
+
if (event == MMU_NOTIFY_MIGRATE)
trigger = KFD_SVM_UNMAP_TRIGGER_MMU_NOTIFY_MIGRATE;
else
@@ -2085,16 +2111,17 @@ svm_range_evict(struct svm_range *prange, struct mm_struct *mm,
pr_debug("invalidate unmap svms 0x%p [0x%lx 0x%lx] from GPUs\n",
prange->svms, start, last);
+
list_for_each_entry(pchild, &prange->child_list, child_list) {
mutex_lock_nested(&pchild->lock, 1);
- s = max(start, pchild->start);
- l = min(last, pchild->last);
+ s = svm_range_align_start(pchild, start);
+ l = svm_range_align_last(pchild, last);
if (l >= s)
svm_range_unmap_from_gpus(pchild, s, l, trigger);
mutex_unlock(&pchild->lock);
}
- s = max(start, prange->start);
- l = min(last, prange->last);
+ s = svm_range_align_start(prange, start);
+ l = svm_range_align_last(prange, last);
if (l >= s)
svm_range_unmap_from_gpus(prange, s, l, trigger);
}
</pre>
</blockquote>
</blockquote>
</body>
</html>