Life cycle of a KFD secondary context(kfd_process) is tied
to the opened file. Therefore this commit destroy a kfd
secondary context when close the fd it belonging to.

This commit extracts the code removing the kfd_process
from the kfd_process_table to a separate function and
call it in kfd_process_notifier_release_internal unconditionally.

Signed-off-by: Zhu Lingshan <lingshan....@amd.com>
Reviewed-by: Felix Kuehling <felix.kuehl...@amd.com>
---
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c |  9 ++++--
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h    |  1 +
 drivers/gpu/drm/amd/amdkfd/kfd_process.c | 41 +++++++++++++-----------
 3 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index 828a9ceef1e7..e8c6273de99b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -164,8 +164,13 @@ static int kfd_release(struct inode *inode, struct file 
*filep)
 {
        struct kfd_process *process = filep->private_data;
 
-       if (process)
-               kfd_unref_process(process);
+       if (!process)
+               return 0;
+
+       if (!process->primary)
+               kfd_process_notifier_release_internal(process);
+
+       kfd_unref_process(process);
 
        return 0;
 }
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h 
b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index 0818705820c6..d1436f1f527d 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -1085,6 +1085,7 @@ bool kfd_process_xnack_mode(struct kfd_process *p, bool 
supported);
 
 int kfd_reserved_mem_mmap(struct kfd_node *dev, struct kfd_process *process,
                          struct vm_area_struct *vma);
+void kfd_process_notifier_release_internal(struct kfd_process *p);
 
 /* KFD process API for creating and translating handles */
 int kfd_process_device_create_obj_handle(struct kfd_process_device *pdd,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index bce7e35a15c9..5d59a4d994d5 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -1233,10 +1233,30 @@ static void kfd_process_free_notifier(struct 
mmu_notifier *mn)
        kfd_unref_process(container_of(mn, struct kfd_process, mmu_notifier));
 }
 
-static void kfd_process_notifier_release_internal(struct kfd_process *p)
+static void kfd_process_table_remove(struct kfd_process *p)
+{
+       mutex_lock(&kfd_processes_mutex);
+       /*
+        * Do early return if table is empty.
+        *
+        * This could potentially happen if this function is called concurrently
+        * by mmu_notifier and by kfd_cleanup_pocesses.
+        *
+        */
+       if (hash_empty(kfd_processes_table)) {
+               mutex_unlock(&kfd_processes_mutex);
+               return;
+       }
+       hash_del_rcu(&p->kfd_processes);
+       mutex_unlock(&kfd_processes_mutex);
+       synchronize_srcu(&kfd_processes_srcu);
+}
+
+void kfd_process_notifier_release_internal(struct kfd_process *p)
 {
        int i;
 
+       kfd_process_table_remove(p);
        cancel_delayed_work_sync(&p->eviction_work);
        cancel_delayed_work_sync(&p->restore_work);
 
@@ -1270,7 +1290,8 @@ static void kfd_process_notifier_release_internal(struct 
kfd_process *p)
                srcu_read_unlock(&kfd_processes_srcu, idx);
        }
 
-       mmu_notifier_put(&p->mmu_notifier);
+       if (p->primary)
+               mmu_notifier_put(&p->mmu_notifier);
 }
 
 static void kfd_process_notifier_release(struct mmu_notifier *mn,
@@ -1286,22 +1307,6 @@ static void kfd_process_notifier_release(struct 
mmu_notifier *mn,
        if (WARN_ON(p->mm != mm))
                return;
 
-       mutex_lock(&kfd_processes_mutex);
-       /*
-        * Do early return if table is empty.
-        *
-        * This could potentially happen if this function is called concurrently
-        * by mmu_notifier and by kfd_cleanup_pocesses.
-        *
-        */
-       if (hash_empty(kfd_processes_table)) {
-               mutex_unlock(&kfd_processes_mutex);
-               return;
-       }
-       hash_del_rcu(&p->kfd_processes);
-       mutex_unlock(&kfd_processes_mutex);
-       synchronize_srcu(&kfd_processes_srcu);
-
        kfd_process_notifier_release_internal(p);
 }
 
-- 
2.47.1

Reply via email to