From ede4434f3a1212a45c599b20d9417bdd1f90e07c Mon Sep 17 00:00:00 2001 From: Sean Keely Date: Wed, 15 Jul 2015 02:43:42 -0500 Subject: [PATCH 1346/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 f565530..8debe6e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -869,6 +869,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)) @@ -883,7 +894,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