From: Sean Keely Date: Fri, 27 Oct 2017 23:35:21 +0000 (-0400) Subject: drm/amdkfd: Fix scheduler race in kfd_wait_on_events sleep loop X-Git-Tag: v4.15-rc1~90^2~12^2~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d9aeec4cbb58599008e6dd4cc23f5bfbdbd0f4ff;p=thirdparty%2Flinux.git drm/amdkfd: Fix scheduler race in kfd_wait_on_events sleep loop Signed-off-by: Sean Keely Signed-off-by: Felix Kuehling Acked-by: Oded Gabbay Signed-off-by: Oded Gabbay --- diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index f3d88c833135d..1efd6a8c2a40a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -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);