Re: [PATCH v2] drm/amdkfd: fix svm_bo release invalid wait context warning

2021-12-10 Thread Felix Kuehling

On 2021-12-09 4:18 p.m., Philip Yang wrote:

Add svm_range_bo_unref_async to schedule work to wait for svm_bo
eviction work done and then free svm_bo. __do_munmap put_page
is atomic context, call svm_range_bo_unref_async to avoid warning
invalid wait context. Other non atomic context call svm_range_bo_unref.

Signed-off-by: Philip Yang 


Reviewed-by: Felix Kuehling 



---
  drivers/gpu/drm/amd/amdkfd/kfd_migrate.c |  2 +-
  drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 31 +---
  drivers/gpu/drm/amd/amdkfd/kfd_svm.h |  3 ++-
  3 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
index 9731151b67d6..d5d2cf2ee788 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
@@ -550,7 +550,7 @@ static void svm_migrate_page_free(struct page *page)
  
  	if (svm_bo) {

pr_debug_ratelimited("ref: %d\n", kref_read(_bo->kref));
-   svm_range_bo_unref(svm_bo);
+   svm_range_bo_unref_async(svm_bo);
}
  }
  
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c

index c178d56361d6..b216842b5fe2 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -332,6 +332,8 @@ static void svm_range_bo_release(struct kref *kref)
struct svm_range_bo *svm_bo;
  
  	svm_bo = container_of(kref, struct svm_range_bo, kref);

+   pr_debug("svm_bo 0x%p\n", svm_bo);
+
spin_lock(_bo->list_lock);
while (!list_empty(_bo->range_list)) {
struct svm_range *prange =
@@ -365,12 +367,33 @@ static void svm_range_bo_release(struct kref *kref)
kfree(svm_bo);
  }
  
-void svm_range_bo_unref(struct svm_range_bo *svm_bo)

+static void svm_range_bo_wq_release(struct work_struct *work)
  {
-   if (!svm_bo)
-   return;
+   struct svm_range_bo *svm_bo;
+
+   svm_bo = container_of(work, struct svm_range_bo, release_work);
+   svm_range_bo_release(_bo->kref);
+}
+
+static void svm_range_bo_release_async(struct kref *kref)
+{
+   struct svm_range_bo *svm_bo;
+
+   svm_bo = container_of(kref, struct svm_range_bo, kref);
+   pr_debug("svm_bo 0x%p\n", svm_bo);
+   INIT_WORK(_bo->release_work, svm_range_bo_wq_release);
+   schedule_work(_bo->release_work);
+}
  
-	kref_put(_bo->kref, svm_range_bo_release);

+void svm_range_bo_unref_async(struct svm_range_bo *svm_bo)
+{
+   kref_put(_bo->kref, svm_range_bo_release_async);
+}
+
+static void svm_range_bo_unref(struct svm_range_bo *svm_bo)
+{
+   if (svm_bo)
+   kref_put(_bo->kref, svm_range_bo_release);
  }
  
  static bool

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h 
b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
index 6dc91c33e80f..2f8a95e86dcb 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
@@ -48,6 +48,7 @@ struct svm_range_bo {
struct work_struct  eviction_work;
struct svm_range_list   *svms;
uint32_tevicting;
+   struct work_struct  release_work;
  };
  
  enum svm_work_list_ops {

@@ -195,7 +196,7 @@ void svm_range_list_lock_and_flush_work(struct 
svm_range_list *svms, struct mm_s
   */
  #define KFD_IS_SVM_API_SUPPORTED(dev) ((dev)->pgmap.type != 0)
  
-void svm_range_bo_unref(struct svm_range_bo *svm_bo);

+void svm_range_bo_unref_async(struct svm_range_bo *svm_bo);
  #else
  
  struct kfd_process;


[PATCH v2] drm/amdkfd: fix svm_bo release invalid wait context warning

2021-12-09 Thread Philip Yang
Add svm_range_bo_unref_async to schedule work to wait for svm_bo
eviction work done and then free svm_bo. __do_munmap put_page
is atomic context, call svm_range_bo_unref_async to avoid warning
invalid wait context. Other non atomic context call svm_range_bo_unref.

Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdkfd/kfd_migrate.c |  2 +-
 drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 31 +---
 drivers/gpu/drm/amd/amdkfd/kfd_svm.h |  3 ++-
 3 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
index 9731151b67d6..d5d2cf2ee788 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
@@ -550,7 +550,7 @@ static void svm_migrate_page_free(struct page *page)
 
if (svm_bo) {
pr_debug_ratelimited("ref: %d\n", kref_read(_bo->kref));
-   svm_range_bo_unref(svm_bo);
+   svm_range_bo_unref_async(svm_bo);
}
 }
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
index c178d56361d6..b216842b5fe2 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -332,6 +332,8 @@ static void svm_range_bo_release(struct kref *kref)
struct svm_range_bo *svm_bo;
 
svm_bo = container_of(kref, struct svm_range_bo, kref);
+   pr_debug("svm_bo 0x%p\n", svm_bo);
+
spin_lock(_bo->list_lock);
while (!list_empty(_bo->range_list)) {
struct svm_range *prange =
@@ -365,12 +367,33 @@ static void svm_range_bo_release(struct kref *kref)
kfree(svm_bo);
 }
 
-void svm_range_bo_unref(struct svm_range_bo *svm_bo)
+static void svm_range_bo_wq_release(struct work_struct *work)
 {
-   if (!svm_bo)
-   return;
+   struct svm_range_bo *svm_bo;
+
+   svm_bo = container_of(work, struct svm_range_bo, release_work);
+   svm_range_bo_release(_bo->kref);
+}
+
+static void svm_range_bo_release_async(struct kref *kref)
+{
+   struct svm_range_bo *svm_bo;
+
+   svm_bo = container_of(kref, struct svm_range_bo, kref);
+   pr_debug("svm_bo 0x%p\n", svm_bo);
+   INIT_WORK(_bo->release_work, svm_range_bo_wq_release);
+   schedule_work(_bo->release_work);
+}
 
-   kref_put(_bo->kref, svm_range_bo_release);
+void svm_range_bo_unref_async(struct svm_range_bo *svm_bo)
+{
+   kref_put(_bo->kref, svm_range_bo_release_async);
+}
+
+static void svm_range_bo_unref(struct svm_range_bo *svm_bo)
+{
+   if (svm_bo)
+   kref_put(_bo->kref, svm_range_bo_release);
 }
 
 static bool
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h 
b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
index 6dc91c33e80f..2f8a95e86dcb 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
@@ -48,6 +48,7 @@ struct svm_range_bo {
struct work_struct  eviction_work;
struct svm_range_list   *svms;
uint32_tevicting;
+   struct work_struct  release_work;
 };
 
 enum svm_work_list_ops {
@@ -195,7 +196,7 @@ void svm_range_list_lock_and_flush_work(struct 
svm_range_list *svms, struct mm_s
  */
 #define KFD_IS_SVM_API_SUPPORTED(dev) ((dev)->pgmap.type != 0)
 
-void svm_range_bo_unref(struct svm_range_bo *svm_bo);
+void svm_range_bo_unref_async(struct svm_range_bo *svm_bo);
 #else
 
 struct kfd_process;
-- 
2.17.1