aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0485-drm-amdgpu-fix-entity-wakeup-race-condition.patch
blob: 414ca97eee13982bb56910f056feb4905f77b6d6 (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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
From aef4852eed2841892796fb1e9abd7f8468384e62 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
Date: Thu, 20 Aug 2015 14:47:46 +0200
Subject: [PATCH 0485/1050] drm/amdgpu: fix entity wakeup race condition
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

That actually didn't worked at all.

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
---
 drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 43 +++++++++++++--------------
 drivers/gpu/drm/amd/scheduler/gpu_scheduler.h |  1 -
 2 files changed, 21 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
index 2dd9c8a..0133697 100644
--- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
+++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
@@ -108,7 +108,6 @@ static bool amd_sched_ready(struct amd_gpu_scheduler *sched)
 static struct amd_sched_entity *
 amd_sched_select_context(struct amd_gpu_scheduler *sched)
 {
-	struct amd_sched_entity *wake_entity = NULL;
 	struct amd_sched_entity *tmp;
 
 	if (!amd_sched_ready(sched))
@@ -119,11 +118,6 @@ amd_sched_select_context(struct amd_gpu_scheduler *sched)
 	if (tmp == NULL)
 		tmp = amd_sched_rq_select_entity(&sched->sched_rq);
 
-	if (sched->current_entity && (sched->current_entity != tmp))
-		wake_entity = sched->current_entity;
-	sched->current_entity = tmp;
-	if (wake_entity && wake_entity->need_wakeup)
-		wake_up(&wake_entity->wait_queue);
 	return tmp;
 }
 
@@ -184,16 +178,17 @@ static bool is_context_entity_initialized(struct amd_gpu_scheduler *sched,
 		entity->belongto_rq != NULL;
 }
 
-static bool is_context_entity_idle(struct amd_gpu_scheduler *sched,
-				   struct amd_sched_entity *entity)
+/**
+ * Check if entity is idle
+ *
+ * @entity	The pointer to a valid scheduler entity
+ *
+ * Return true if entity don't has any unscheduled jobs.
+ */
+static bool amd_sched_entity_is_idle(struct amd_sched_entity *entity)
 {
-	/**
-	 * Idle means no pending IBs, and the entity is not
-	 * currently being used.
-	*/
-	barrier();
-	if ((sched->current_entity != entity) &&
-	    kfifo_is_empty(&entity->job_queue))
+	rmb();
+	if (kfifo_is_empty(&entity->job_queue))
 		return true;
 
 	return false;
@@ -210,8 +205,8 @@ static bool is_context_entity_idle(struct amd_gpu_scheduler *sched,
 int amd_sched_entity_fini(struct amd_gpu_scheduler *sched,
 			    struct amd_sched_entity *entity)
 {
-	int r = 0;
 	struct amd_sched_rq *rq = entity->belongto_rq;
+	long r;
 
 	if (!is_context_entity_initialized(sched, entity))
 		return 0;
@@ -220,13 +215,11 @@ int amd_sched_entity_fini(struct amd_gpu_scheduler *sched,
 	 * The client will not queue more IBs during this fini, consume existing
 	 * queued IBs
 	*/
-	r = wait_event_timeout(
-		entity->wait_queue,
-		is_context_entity_idle(sched, entity),
-		msecs_to_jiffies(AMD_GPU_WAIT_IDLE_TIMEOUT_IN_MS)
-		) ?  0 : -1;
+	r = wait_event_timeout(entity->wait_queue,
+		amd_sched_entity_is_idle(entity),
+		msecs_to_jiffies(AMD_GPU_WAIT_IDLE_TIMEOUT_IN_MS));
 
-	if (r)
+	if (r <= 0)
 		DRM_INFO("Entity %p is in waiting state during fini\n",
 			 entity);
 
@@ -325,6 +318,12 @@ static int amd_sched_main(void *param)
 			fence_put(fence);
 		}
 		mutex_unlock(&sched->sched_lock);
+
+		if (c_entity->need_wakeup) {
+			c_entity->need_wakeup = false;
+			wake_up(&c_entity->wait_queue);
+		}
+
 	}
 	return 0;
 }
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
index bbfcc37..d4116bb 100644
--- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
+++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
@@ -117,7 +117,6 @@ struct amd_gpu_scheduler {
 	uint32_t			granularity; /* in ms unit */
 	uint32_t			preemption;
 	wait_queue_head_t		wait_queue;
-	struct amd_sched_entity	*current_entity;
 	struct mutex			sched_lock;
 	uint32_t                        hw_submission_limit;
 };
-- 
1.9.1