drm/amdkfd: Add SVM range mapped_to_gpu flag
authorPhilip Yang <Philip.Yang@amd.com>
Tue, 19 Apr 2022 01:32:14 +0000 (21:32 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 26 Apr 2022 15:42:44 +0000 (11:42 -0400)
To avoid unnecessary unmap SVM range from GPUs if range is not mapped on
GPUs when migrating the range. This flag will also be used to flush TLB
when updating the existing mapping on GPUs.

It is protected by prange->migrate_mutex and mmap read lock in MMU
notifier callback.

Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdkfd/kfd_svm.c
drivers/gpu/drm/amd/amdkfd/kfd_svm.h

index aed2f6f3ce5e3cb7edebdd4768a7e4a95c96e246..fff17e747a71914c2e46ff4113be20bdb70238df 100644 (file)
@@ -950,6 +950,7 @@ svm_range_split_adjust(struct svm_range *new, struct svm_range *old,
        new->prefetch_loc = old->prefetch_loc;
        new->actual_loc = old->actual_loc;
        new->granularity = old->granularity;
+       new->mapped_to_gpu = old->mapped_to_gpu;
        bitmap_copy(new->bitmap_access, old->bitmap_access, MAX_GPU_INSTANCE);
        bitmap_copy(new->bitmap_aip, old->bitmap_aip, MAX_GPU_INSTANCE);
 
@@ -1203,6 +1204,17 @@ svm_range_unmap_from_gpus(struct svm_range *prange, unsigned long start,
        uint32_t gpuidx;
        int r = 0;
 
+       if (!prange->mapped_to_gpu) {
+               pr_debug("prange 0x%p [0x%lx 0x%lx] not mapped to GPU\n",
+                        prange, prange->start, prange->last);
+               return 0;
+       }
+
+       if (prange->start == start && prange->last == last) {
+               pr_debug("unmap svms 0x%p prange 0x%p\n", prange->svms, prange);
+               prange->mapped_to_gpu = false;
+       }
+
        bitmap_or(bitmap, prange->bitmap_access, prange->bitmap_aip,
                  MAX_GPU_INSTANCE);
        p = container_of(prange->svms, struct kfd_process, svms);
@@ -1587,8 +1599,10 @@ unlock_out:
                addr = next;
        }
 
-       if (addr == end)
+       if (addr == end) {
                prange->validated_once = true;
+               prange->mapped_to_gpu = true;
+       }
 
 unreserve_out:
        svm_range_unreserve_bos(&ctx);
@@ -1819,6 +1833,7 @@ static struct svm_range *svm_range_clone(struct svm_range *old)
        new->prefetch_loc = old->prefetch_loc;
        new->actual_loc = old->actual_loc;
        new->granularity = old->granularity;
+       new->mapped_to_gpu = old->mapped_to_gpu;
        bitmap_copy(new->bitmap_access, old->bitmap_access, MAX_GPU_INSTANCE);
        bitmap_copy(new->bitmap_aip, old->bitmap_aip, MAX_GPU_INSTANCE);
 
index 66c77f00ac3e4e8c554768b5df8b685e9e405d62..2d54147b4ddaac835c8fae3ffd324de6fa3145a1 100644 (file)
@@ -133,6 +133,7 @@ struct svm_range {
        DECLARE_BITMAP(bitmap_access, MAX_GPU_INSTANCE);
        DECLARE_BITMAP(bitmap_aip, MAX_GPU_INSTANCE);
        bool                            validated_once;
+       bool                            mapped_to_gpu;
 };
 
 static inline void svm_range_lock(struct svm_range *prange)