From 86f43722d3443e54a426bc705b833a132030dc5b Mon Sep 17 00:00:00 2001 From: Sean Keely Date: Wed, 15 Jul 2015 02:43:42 -0500 Subject: [PATCH 2109/4131] drm/amdkfd: Fix scheduler race in kfd_wait_on_events sleep loop This reapplies a fix that was accidentally reverted when cleaning up code for upstreaming. Added a comment to explain the race condition and how it is fixed. Change-Id: Ic030a0f5be1d4147ce0c36b57e5526f748c3b25a Signed-off-by: Sean Keely Signed-off-by: Felix Kuehling --- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index 09e3fe65..b130b64 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -870,6 +870,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)) @@ -884,7 +895,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); -- 2.7.4