]> www.infradead.org Git - users/hch/misc.git/commitdiff
drm/amdkfd: KFD release_work possible circular locking
authorPhilip Yang <Philip.Yang@amd.com>
Tue, 18 Feb 2025 01:08:29 +0000 (20:08 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 27 Feb 2025 21:50:04 +0000 (16:50 -0500)
If waiting for gpu reset done in KFD release_work, thers is WARNING:
possible circular locking dependency detected

  #2  kfd_create_process
        kfd_process_mutex
          flush kfd release work

  #1  kfd release work
        wait for amdgpu reset work

  #0  amdgpu_device_gpu_reset
        kgd2kfd_pre_reset
          kfd_process_mutex

  Possible unsafe locking scenario:

        CPU0                    CPU1
        ----                    ----
   lock((work_completion)(&p->release_work));
                  lock((wq_completion)kfd_process_wq);
                  lock((work_completion)(&p->release_work));
   lock((wq_completion)amdgpu-reset-dev);

To fix this, KFD create process move flush release work outside
kfd_process_mutex.

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_process.c

index 1067afdb456ecd06b12ca084bfe94f781e3c61a7..2715ca53e9daa82e5d632a4fc92c69482911bc48 100644 (file)
@@ -838,6 +838,14 @@ struct kfd_process *kfd_create_process(struct task_struct *thread)
                return ERR_PTR(-EINVAL);
        }
 
+       /* If the process just called exec(3), it is possible that the
+        * cleanup of the kfd_process (following the release of the mm
+        * of the old process image) is still in the cleanup work queue.
+        * Make sure to drain any job before trying to recreate any
+        * resource for this process.
+        */
+       flush_workqueue(kfd_process_wq);
+
        /*
         * take kfd processes mutex before starting of process creation
         * so there won't be a case where two threads of the same process
@@ -858,14 +866,6 @@ struct kfd_process *kfd_create_process(struct task_struct *thread)
        if (process) {
                pr_debug("Process already found\n");
        } else {
-               /* If the process just called exec(3), it is possible that the
-                * cleanup of the kfd_process (following the release of the mm
-                * of the old process image) is still in the cleanup work queue.
-                * Make sure to drain any job before trying to recreate any
-                * resource for this process.
-                */
-               flush_workqueue(kfd_process_wq);
-
                process = create_process(thread);
                if (IS_ERR(process))
                        goto out;