aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorFelix Kuehling <Felix.Kuehling@amd.com>2021-12-07 21:04:06 -0500
committerAlex Deucher <alexander.deucher@amd.com>2021-12-13 16:32:35 -0500
commit4853cbcd94bdd654e94aa40ae718efcf5b6ae57a (patch)
tree0c1aeb0676a69eaab207303ef144d250d782f1e8 /drivers
parentf864df76ff1021b21776a7df029c0da884794c28 (diff)
drm/amdkfd: Don't split unchanged SVM ranges
If an existing SVM range overlaps an svm_range_set_attr call, we would normally split it in order to update only the overlapping part. However, if the attributes of the existing range would not be changed splitting it is unnecessary. Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com> Reviewed-by: Philip Yang <Philip.Yang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_svm.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
index 07342630740e..c178d56361d6 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -1855,18 +1855,24 @@ svm_range_add(struct kfd_process *p, uint64_t start, uint64_t size,
node = interval_tree_iter_first(&svms->objects, start, last);
while (node) {
struct interval_tree_node *next;
- struct svm_range *old;
unsigned long next_start;
pr_debug("found overlap node [0x%lx 0x%lx]\n", node->start,
node->last);
- old = container_of(node, struct svm_range, it_node);
+ prange = container_of(node, struct svm_range, it_node);
next = interval_tree_iter_next(node, start, last);
next_start = min(node->last, last) + 1;
- if (node->start < start || node->last > last) {
- /* node intersects the updated range, clone+split it */
+ if (svm_range_is_same_attrs(p, prange, nattr, attrs)) {
+ /* nothing to do */
+ } else if (node->start < start || node->last > last) {
+ /* node intersects the update range and its attributes
+ * will change. Clone and split it, apply updates only
+ * to the overlapping part
+ */
+ struct svm_range *old = prange;
+
prange = svm_range_clone(old);
if (!prange) {
r = -ENOMEM;
@@ -1875,6 +1881,7 @@ svm_range_add(struct kfd_process *p, uint64_t start, uint64_t size,
list_add(&old->remove_list, remove_list);
list_add(&prange->insert_list, insert_list);
+ list_add(&prange->update_list, update_list);
if (node->start < start) {
pr_debug("change old range start\n");
@@ -1894,16 +1901,12 @@ svm_range_add(struct kfd_process *p, uint64_t start, uint64_t size,
/* The node is contained within start..last,
* just update it
*/
- prange = old;
- }
-
- if (!svm_range_is_same_attrs(p, prange, nattr, attrs))
list_add(&prange->update_list, update_list);
+ }
/* insert a new node if needed */
if (node->start > start) {
- prange = svm_range_new(prange->svms, start,
- node->start - 1);
+ prange = svm_range_new(svms, start, node->start - 1);
if (!prange) {
r = -ENOMEM;
goto out;