aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2109-drm-amdkfd-Fix-scheduler-race-in-kfd_wait_on_events-.patch
blob: f01fb019ec58132d18a34fd6be3d3fadc1307bf6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
From 86f43722d3443e54a426bc705b833a132030dc5b Mon Sep 17 00:00:00 2001
From: Sean Keely <sean.keely@amd.com>
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 <sean.keely@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
---
 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