]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amdkfd: Fix scheduler race in kfd_wait_on_events sleep loop
authorSean Keely <sean.keely@amd.com>
Fri, 27 Oct 2017 23:35:21 +0000 (19:35 -0400)
committerOded Gabbay <oded.gabbay@gmail.com>
Fri, 27 Oct 2017 23:35:21 +0000 (19:35 -0400)
Signed-off-by: Sean Keely <sean.keely@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Acked-by: Oded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
drivers/gpu/drm/amd/amdkfd/kfd_events.c

index f3d88c833135df3b5f09f4d85c464342b3dacb21..1efd6a8c2a40accc1f20efaeb99e823136e72384 100644 (file)
@@ -806,6 +806,17 @@ int kfd_wait_on_events(struct kfd_process *p,
                        break;
                }
 
+               /* Set task state to interruptible sleep before
+                * checking wake-up conditions. A concurrent wake-up
+                * will put the task back into runnable state. In that
+                * case schedule_timeout will not put the task to
+                * sleep and we'll get a chance to re-check the
+                * updated conditions almost immediately. Otherwise,
+                * this race condition would lead to a soft hang or a
+                * very long sleep.
+                */
+               set_current_state(TASK_INTERRUPTIBLE);
+
                if (test_event_condition(all, num_events, event_waiters)) {
                        if (copy_signaled_event_data(num_events,
                                        event_waiters, events))
@@ -820,7 +831,7 @@ int kfd_wait_on_events(struct kfd_process *p,
                        break;
                }
 
-               timeout = schedule_timeout_interruptible(timeout);
+               timeout = schedule_timeout(timeout);
        }
        __set_current_state(TASK_RUNNING);