From: Alex Sierra Date: Wed, 10 Mar 2021 04:12:15 +0000 (-0600) Subject: drm/amdkfd: Maintain svm_bo reference in page->zone_device_data X-Git-Tag: v5.15~303^2~20^2~234 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7981ec65497a42ab83dfe43192ed7a98c542f001;p=platform%2Fkernel%2Flinux-starfive.git drm/amdkfd: Maintain svm_bo reference in page->zone_device_data Each zone-device page holds a reference to the SVM BO that manages its backing storage. This is necessary to correctly hold on to the BO in case zone_device pages are shared with a child-process. Signed-off-by: Alex Sierra Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c index 3a51384..dab290a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c @@ -218,7 +218,8 @@ svm_migrate_get_vram_page(struct svm_range *prange, unsigned long pfn) struct page *page; page = pfn_to_page(pfn); - page->zone_device_data = prange; + svm_range_bo_ref(prange->svm_bo); + page->zone_device_data = prange->svm_bo; get_page(page); lock_page(page); } @@ -502,7 +503,12 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc, static void svm_migrate_page_free(struct page *page) { - /* Keep this function to avoid warning */ + struct svm_range_bo *svm_bo = page->zone_device_data; + + if (svm_bo) { + pr_debug("svm_bo ref left: %d\n", kref_read(&svm_bo->kref)); + svm_range_bo_unref(svm_bo); + } } static int diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index f9a1a47..9a71d89 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -312,14 +312,6 @@ static bool svm_bo_ref_unless_zero(struct svm_range_bo *svm_bo) return true; } -static struct svm_range_bo *svm_range_bo_ref(struct svm_range_bo *svm_bo) -{ - if (svm_bo) - kref_get(&svm_bo->kref); - - return svm_bo; -} - static void svm_range_bo_release(struct kref *kref) { struct svm_range_bo *svm_bo; @@ -358,7 +350,7 @@ static void svm_range_bo_release(struct kref *kref) kfree(svm_bo); } -static void svm_range_bo_unref(struct svm_range_bo *svm_bo) +void svm_range_bo_unref(struct svm_range_bo *svm_bo) { if (!svm_bo) return; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h index 41115a2..3fc1fd8 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h @@ -150,6 +150,14 @@ static inline void svm_range_unlock(struct svm_range *prange) mutex_unlock(&prange->lock); } +static inline struct svm_range_bo *svm_range_bo_ref(struct svm_range_bo *svm_bo) +{ + if (svm_bo) + kref_get(&svm_bo->kref); + + return svm_bo; +} + int svm_range_list_init(struct kfd_process *p); void svm_range_list_fini(struct kfd_process *p); int svm_ioctl(struct kfd_process *p, enum kfd_ioctl_svm_op op, uint64_t start, @@ -186,6 +194,7 @@ svm_range_get_pdd_by_adev(struct svm_range *prange, struct amdgpu_device *adev); */ #define KFD_IS_SVM_API_SUPPORTED(dev) ((dev)->pgmap.type != 0) +void svm_range_bo_unref(struct svm_range_bo *svm_bo); #else struct kfd_process;