aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2015-08-25 05:05:36 -0400
committerAlex Deucher <alexander.deucher@amd.com>2015-08-28 15:04:17 -0400
commite61235db62c5e68e56e59bea62b88f9f3d7a3cf5 (patch)
tree9f28992f9423cc754e1ea4f94eba149eca96effc
parent69bd5bf13a8eccb4db5f26de608556416a56d973 (diff)
drm/amdgpu: add scheduler dependency callback v2
This way the scheduler doesn't wait in it's work thread any more. v2: fix race conditions Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Chunming Zhou <david1.zhou@amd.com> Reviewed-by: Jammy Zhou <Jammy.Zhou@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c22
-rw-r--r--drivers/gpu/drm/amd/scheduler/gpu_scheduler.c22
-rw-r--r--drivers/gpu/drm/amd/scheduler/gpu_scheduler.h3
5 files changed, 55 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index aa2dcf578dd6..719506808b4a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -717,6 +717,7 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
717 void *owner); 717 void *owner);
718int amdgpu_sync_rings(struct amdgpu_sync *sync, 718int amdgpu_sync_rings(struct amdgpu_sync *sync,
719 struct amdgpu_ring *ring); 719 struct amdgpu_ring *ring);
720struct fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync);
720int amdgpu_sync_wait(struct amdgpu_sync *sync); 721int amdgpu_sync_wait(struct amdgpu_sync *sync);
721void amdgpu_sync_free(struct amdgpu_device *adev, struct amdgpu_sync *sync, 722void amdgpu_sync_free(struct amdgpu_device *adev, struct amdgpu_sync *sync,
722 struct fence *fence); 723 struct fence *fence);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
index f93fb3541488..de98fbd2971e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
@@ -27,6 +27,12 @@
27#include <drm/drmP.h> 27#include <drm/drmP.h>
28#include "amdgpu.h" 28#include "amdgpu.h"
29 29
30static struct fence *amdgpu_sched_dependency(struct amd_sched_job *job)
31{
32 struct amdgpu_job *sched_job = (struct amdgpu_job *)job;
33 return amdgpu_sync_get_fence(&sched_job->ibs->sync);
34}
35
30static struct fence *amdgpu_sched_run_job(struct amd_sched_job *job) 36static struct fence *amdgpu_sched_run_job(struct amd_sched_job *job)
31{ 37{
32 struct amdgpu_job *sched_job; 38 struct amdgpu_job *sched_job;
@@ -75,6 +81,7 @@ static void amdgpu_sched_process_job(struct amd_sched_job *job)
75} 81}
76 82
77struct amd_sched_backend_ops amdgpu_sched_ops = { 83struct amd_sched_backend_ops amdgpu_sched_ops = {
84 .dependency = amdgpu_sched_dependency,
78 .run_job = amdgpu_sched_run_job, 85 .run_job = amdgpu_sched_run_job,
79 .process_job = amdgpu_sched_process_job 86 .process_job = amdgpu_sched_process_job
80}; 87};
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
index 4fffb2539331..69b7d4540c6e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
@@ -202,6 +202,28 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
202 return r; 202 return r;
203} 203}
204 204
205struct fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync)
206{
207 struct amdgpu_sync_entry *e;
208 struct hlist_node *tmp;
209 struct fence *f;
210 int i;
211
212 hash_for_each_safe(sync->fences, i, tmp, e, node) {
213
214 f = e->fence;
215
216 hash_del(&e->node);
217 kfree(e);
218
219 if (!fence_is_signaled(f))
220 return f;
221
222 fence_put(f);
223 }
224 return NULL;
225}
226
205int amdgpu_sync_wait(struct amdgpu_sync *sync) 227int amdgpu_sync_wait(struct amdgpu_sync *sync)
206{ 228{
207 struct amdgpu_sync_entry *e; 229 struct amdgpu_sync_entry *e;
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
index 205cb887d023..2f5d1f0da8e5 100644
--- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
+++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
@@ -192,14 +192,36 @@ void amd_sched_entity_fini(struct amd_gpu_scheduler *sched,
192 kfifo_free(&entity->job_queue); 192 kfifo_free(&entity->job_queue);
193} 193}
194 194
195static void amd_sched_entity_wakeup(struct fence *f, struct fence_cb *cb)
196{
197 struct amd_sched_entity *entity =
198 container_of(cb, struct amd_sched_entity, cb);
199 entity->dependency = NULL;
200 fence_put(f);
201 amd_sched_wakeup(entity->scheduler);
202}
203
195static struct amd_sched_job * 204static struct amd_sched_job *
196amd_sched_entity_pop_job(struct amd_sched_entity *entity) 205amd_sched_entity_pop_job(struct amd_sched_entity *entity)
197{ 206{
207 struct amd_gpu_scheduler *sched = entity->scheduler;
198 struct amd_sched_job *job; 208 struct amd_sched_job *job;
199 209
210 if (ACCESS_ONCE(entity->dependency))
211 return NULL;
212
200 if (!kfifo_out_peek(&entity->job_queue, &job, sizeof(job))) 213 if (!kfifo_out_peek(&entity->job_queue, &job, sizeof(job)))
201 return NULL; 214 return NULL;
202 215
216 while ((entity->dependency = sched->ops->dependency(job))) {
217
218 if (fence_add_callback(entity->dependency, &entity->cb,
219 amd_sched_entity_wakeup))
220 fence_put(entity->dependency);
221 else
222 return NULL;
223 }
224
203 return job; 225 return job;
204} 226}
205 227
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
index e797796dcad7..2af0e4d4d817 100644
--- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
+++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
@@ -45,6 +45,8 @@ struct amd_sched_entity {
45 spinlock_t queue_lock; 45 spinlock_t queue_lock;
46 struct amd_gpu_scheduler *scheduler; 46 struct amd_gpu_scheduler *scheduler;
47 uint64_t fence_context; 47 uint64_t fence_context;
48 struct fence *dependency;
49 struct fence_cb cb;
48}; 50};
49 51
50/** 52/**
@@ -89,6 +91,7 @@ static inline struct amd_sched_fence *to_amd_sched_fence(struct fence *f)
89 * these functions should be implemented in driver side 91 * these functions should be implemented in driver side
90*/ 92*/
91struct amd_sched_backend_ops { 93struct amd_sched_backend_ops {
94 struct fence *(*dependency)(struct amd_sched_job *job);
92 struct fence *(*run_job)(struct amd_sched_job *job); 95 struct fence *(*run_job)(struct amd_sched_job *job);
93 void (*process_job)(struct amd_sched_job *job); 96 void (*process_job)(struct amd_sched_job *job);
94}; 97};