]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
amdkfd: destroy kfd secondary contexts through fd close
authorZhu Lingshan <lingshan.zhu@amd.com>
Mon, 28 Oct 2024 07:55:01 +0000 (15:55 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 8 Dec 2025 18:56:41 +0000 (13:56 -0500)
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.zhu@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_chardev.c
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
drivers/gpu/drm/amd/amdkfd/kfd_process.c

index 22925df6a791bec0600ae5e6ac242710850dfe3f..1eb826d9208e3d1d6f85f96241a4f3a948ee4b65 100644 (file)
@@ -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->context_id != KFD_CONTEXT_ID_PRIMARY)
+               kfd_process_notifier_release_internal(process);
+
+       kfd_unref_process(process);
 
        return 0;
 }
index 9abcc00b65a3f2ed669d73de3d0e8cee16a4547a..48dc6e737d0da4ad18d602359911abedae5904db 100644 (file)
@@ -1095,6 +1095,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,
index 6cc787b0f27e1818f9fe64859180a56eb053d192..622a0dc9d3c7bd993a0f67fcc7e82ee2c6b2e47c 100644 (file)
@@ -1231,10 +1231,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);
 
@@ -1276,7 +1296,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->context_id == KFD_CONTEXT_ID_PRIMARY)
+               mmu_notifier_put(&p->mmu_notifier);
 }
 
 static void kfd_process_notifier_release(struct mmu_notifier *mn,
@@ -1292,22 +1313,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);
 }