aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h4
-rw-r--r--drivers/gpu/drm/amd/scheduler/gpu_scheduler.c68
-rw-r--r--drivers/gpu/drm/amd/scheduler/gpu_scheduler.h4
3 files changed, 29 insertions, 47 deletions
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h b/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h
index 283a0dc25e84..705380eb693c 100644
--- a/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h
+++ b/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h
@@ -29,8 +29,8 @@ TRACE_EVENT(amd_sched_job,
29 __entry->id = sched_job->id; 29 __entry->id = sched_job->id;
30 __entry->fence = &sched_job->s_fence->finished; 30 __entry->fence = &sched_job->s_fence->finished;
31 __entry->name = sched_job->sched->name; 31 __entry->name = sched_job->sched->name;
32 __entry->job_count = kfifo_len( 32 __entry->job_count = spsc_queue_count(
33 &sched_job->s_entity->job_queue) / sizeof(sched_job); 33 &sched_job->s_entity->job_queue);
34 __entry->hw_job_count = atomic_read( 34 __entry->hw_job_count = atomic_read(
35 &sched_job->sched->hw_rq_count); 35 &sched_job->sched->hw_rq_count);
36 ), 36 ),
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
index 1474866d9048..1a2267ce62a8 100644
--- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
+++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
@@ -28,9 +28,14 @@
28#include <drm/drmP.h> 28#include <drm/drmP.h>
29#include "gpu_scheduler.h" 29#include "gpu_scheduler.h"
30 30
31#include "spsc_queue.h"
32
31#define CREATE_TRACE_POINTS 33#define CREATE_TRACE_POINTS
32#include "gpu_sched_trace.h" 34#include "gpu_sched_trace.h"
33 35
36#define to_amd_sched_job(sched_job) \
37 container_of((sched_job), struct amd_sched_job, queue_node)
38
34static bool amd_sched_entity_is_ready(struct amd_sched_entity *entity); 39static bool amd_sched_entity_is_ready(struct amd_sched_entity *entity);
35static void amd_sched_wakeup(struct amd_gpu_scheduler *sched); 40static void amd_sched_wakeup(struct amd_gpu_scheduler *sched);
36static void amd_sched_process_job(struct dma_fence *f, struct dma_fence_cb *cb); 41static void amd_sched_process_job(struct dma_fence *f, struct dma_fence_cb *cb);
@@ -123,8 +128,6 @@ int amd_sched_entity_init(struct amd_gpu_scheduler *sched,
123 struct amd_sched_rq *rq, 128 struct amd_sched_rq *rq,
124 uint32_t jobs, atomic_t *guilty) 129 uint32_t jobs, atomic_t *guilty)
125{ 130{
126 int r;
127
128 if (!(sched && entity && rq)) 131 if (!(sched && entity && rq))
129 return -EINVAL; 132 return -EINVAL;
130 133
@@ -136,9 +139,7 @@ int amd_sched_entity_init(struct amd_gpu_scheduler *sched,
136 139
137 spin_lock_init(&entity->rq_lock); 140 spin_lock_init(&entity->rq_lock);
138 spin_lock_init(&entity->queue_lock); 141 spin_lock_init(&entity->queue_lock);
139 r = kfifo_alloc(&entity->job_queue, jobs * sizeof(void *), GFP_KERNEL); 142 spsc_queue_init(&entity->job_queue);
140 if (r)
141 return r;
142 143
143 atomic_set(&entity->fence_seq, 0); 144 atomic_set(&entity->fence_seq, 0);
144 entity->fence_context = dma_fence_context_alloc(2); 145 entity->fence_context = dma_fence_context_alloc(2);
@@ -171,7 +172,7 @@ static bool amd_sched_entity_is_initialized(struct amd_gpu_scheduler *sched,
171static bool amd_sched_entity_is_idle(struct amd_sched_entity *entity) 172static bool amd_sched_entity_is_idle(struct amd_sched_entity *entity)
172{ 173{
173 rmb(); 174 rmb();
174 if (kfifo_is_empty(&entity->job_queue)) 175 if (spsc_queue_peek(&entity->job_queue) == NULL)
175 return true; 176 return true;
176 177
177 return false; 178 return false;
@@ -186,7 +187,7 @@ static bool amd_sched_entity_is_idle(struct amd_sched_entity *entity)
186 */ 187 */
187static bool amd_sched_entity_is_ready(struct amd_sched_entity *entity) 188static bool amd_sched_entity_is_ready(struct amd_sched_entity *entity)
188{ 189{
189 if (kfifo_is_empty(&entity->job_queue)) 190 if (spsc_queue_peek(&entity->job_queue) == NULL)
190 return false; 191 return false;
191 192
192 if (READ_ONCE(entity->dependency)) 193 if (READ_ONCE(entity->dependency))
@@ -228,7 +229,7 @@ void amd_sched_entity_fini(struct amd_gpu_scheduler *sched,
228 */ 229 */
229 kthread_park(sched->thread); 230 kthread_park(sched->thread);
230 kthread_unpark(sched->thread); 231 kthread_unpark(sched->thread);
231 while (kfifo_out(&entity->job_queue, &job, sizeof(job))) { 232 while ((job = to_amd_sched_job(spsc_queue_pop(&entity->job_queue)))) {
232 struct amd_sched_fence *s_fence = job->s_fence; 233 struct amd_sched_fence *s_fence = job->s_fence;
233 amd_sched_fence_scheduled(s_fence); 234 amd_sched_fence_scheduled(s_fence);
234 dma_fence_set_error(&s_fence->finished, -ESRCH); 235 dma_fence_set_error(&s_fence->finished, -ESRCH);
@@ -236,9 +237,7 @@ void amd_sched_entity_fini(struct amd_gpu_scheduler *sched,
236 dma_fence_put(&s_fence->finished); 237 dma_fence_put(&s_fence->finished);
237 sched->ops->free_job(job); 238 sched->ops->free_job(job);
238 } 239 }
239
240 } 240 }
241 kfifo_free(&entity->job_queue);
242} 241}
243 242
244static void amd_sched_entity_wakeup(struct dma_fence *f, struct dma_fence_cb *cb) 243static void amd_sched_entity_wakeup(struct dma_fence *f, struct dma_fence_cb *cb)
@@ -333,40 +332,41 @@ static bool amd_sched_entity_add_dependency_cb(struct amd_sched_entity *entity)
333} 332}
334 333
335static struct amd_sched_job * 334static struct amd_sched_job *
336amd_sched_entity_peek_job(struct amd_sched_entity *entity) 335amd_sched_entity_pop_job(struct amd_sched_entity *entity)
337{ 336{
338 struct amd_gpu_scheduler *sched = entity->sched; 337 struct amd_gpu_scheduler *sched = entity->sched;
339 struct amd_sched_job *sched_job; 338 struct amd_sched_job *sched_job = to_amd_sched_job(
339 spsc_queue_peek(&entity->job_queue));
340 340
341 if (!kfifo_out_peek(&entity->job_queue, &sched_job, sizeof(sched_job))) 341 if (!sched_job)
342 return NULL; 342 return NULL;
343 343
344 while ((entity->dependency = sched->ops->dependency(sched_job))) 344 while ((entity->dependency = sched->ops->dependency(sched_job)))
345 if (amd_sched_entity_add_dependency_cb(entity)) 345 if (amd_sched_entity_add_dependency_cb(entity))
346 return NULL; 346 return NULL;
347 347
348 sched_job->s_entity = NULL;
349 spsc_queue_pop(&entity->job_queue);
348 return sched_job; 350 return sched_job;
349} 351}
350 352
351/** 353/**
352 * Helper to submit a job to the job queue 354 * Submit a job to the job queue
353 * 355 *
354 * @sched_job The pointer to job required to submit 356 * @sched_job The pointer to job required to submit
355 * 357 *
356 * Returns true if we could submit the job. 358 * Returns 0 for success, negative error code otherwise.
357 */ 359 */
358static bool amd_sched_entity_in(struct amd_sched_job *sched_job) 360void amd_sched_entity_push_job(struct amd_sched_job *sched_job)
359{ 361{
360 struct amd_gpu_scheduler *sched = sched_job->sched; 362 struct amd_gpu_scheduler *sched = sched_job->sched;
361 struct amd_sched_entity *entity = sched_job->s_entity; 363 struct amd_sched_entity *entity = sched_job->s_entity;
362 bool added, first = false; 364 bool first = false;
363 365
364 spin_lock(&entity->queue_lock); 366 trace_amd_sched_job(sched_job);
365 added = kfifo_in(&entity->job_queue, &sched_job,
366 sizeof(sched_job)) == sizeof(sched_job);
367 367
368 if (added && kfifo_len(&entity->job_queue) == sizeof(sched_job)) 368 spin_lock(&entity->queue_lock);
369 first = true; 369 first = spsc_queue_push(&entity->job_queue, &sched_job->queue_node);
370 370
371 spin_unlock(&entity->queue_lock); 371 spin_unlock(&entity->queue_lock);
372 372
@@ -378,7 +378,6 @@ static bool amd_sched_entity_in(struct amd_sched_job *sched_job)
378 spin_unlock(&entity->rq_lock); 378 spin_unlock(&entity->rq_lock);
379 amd_sched_wakeup(sched); 379 amd_sched_wakeup(sched);
380 } 380 }
381 return added;
382} 381}
383 382
384/* job_finish is called after hw fence signaled 383/* job_finish is called after hw fence signaled
@@ -535,22 +534,6 @@ void amd_sched_job_recovery(struct amd_gpu_scheduler *sched)
535 spin_unlock(&sched->job_list_lock); 534 spin_unlock(&sched->job_list_lock);
536} 535}
537 536
538/**
539 * Submit a job to the job queue
540 *
541 * @sched_job The pointer to job required to submit
542 *
543 * Returns 0 for success, negative error code otherwise.
544 */
545void amd_sched_entity_push_job(struct amd_sched_job *sched_job)
546{
547 struct amd_sched_entity *entity = sched_job->s_entity;
548
549 trace_amd_sched_job(sched_job);
550 wait_event(entity->sched->job_scheduled,
551 amd_sched_entity_in(sched_job));
552}
553
554/* init a sched_job with basic field */ 537/* init a sched_job with basic field */
555int amd_sched_job_init(struct amd_sched_job *job, 538int amd_sched_job_init(struct amd_sched_job *job,
556 struct amd_gpu_scheduler *sched, 539 struct amd_gpu_scheduler *sched,
@@ -641,7 +624,7 @@ static int amd_sched_main(void *param)
641{ 624{
642 struct sched_param sparam = {.sched_priority = 1}; 625 struct sched_param sparam = {.sched_priority = 1};
643 struct amd_gpu_scheduler *sched = (struct amd_gpu_scheduler *)param; 626 struct amd_gpu_scheduler *sched = (struct amd_gpu_scheduler *)param;
644 int r, count; 627 int r;
645 628
646 sched_setscheduler(current, SCHED_FIFO, &sparam); 629 sched_setscheduler(current, SCHED_FIFO, &sparam);
647 630
@@ -659,7 +642,7 @@ static int amd_sched_main(void *param)
659 if (!entity) 642 if (!entity)
660 continue; 643 continue;
661 644
662 sched_job = amd_sched_entity_peek_job(entity); 645 sched_job = amd_sched_entity_pop_job(entity);
663 if (!sched_job) 646 if (!sched_job)
664 continue; 647 continue;
665 648
@@ -686,9 +669,6 @@ static int amd_sched_main(void *param)
686 amd_sched_process_job(NULL, &s_fence->cb); 669 amd_sched_process_job(NULL, &s_fence->cb);
687 } 670 }
688 671
689 count = kfifo_out(&entity->job_queue, &sched_job,
690 sizeof(sched_job));
691 WARN_ON(count != sizeof(sched_job));
692 wake_up(&sched->job_scheduled); 672 wake_up(&sched->job_scheduled);
693 } 673 }
694 return 0; 674 return 0;
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
index be75172587da..f9e3a83cddc6 100644
--- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
+++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
@@ -26,6 +26,7 @@
26 26
27#include <linux/kfifo.h> 27#include <linux/kfifo.h>
28#include <linux/dma-fence.h> 28#include <linux/dma-fence.h>
29#include "spsc_queue.h"
29 30
30struct amd_gpu_scheduler; 31struct amd_gpu_scheduler;
31struct amd_sched_rq; 32struct amd_sched_rq;
@@ -56,7 +57,7 @@ struct amd_sched_entity {
56 struct amd_gpu_scheduler *sched; 57 struct amd_gpu_scheduler *sched;
57 58
58 spinlock_t queue_lock; 59 spinlock_t queue_lock;
59 struct kfifo job_queue; 60 struct spsc_queue job_queue;
60 61
61 atomic_t fence_seq; 62 atomic_t fence_seq;
62 uint64_t fence_context; 63 uint64_t fence_context;
@@ -88,6 +89,7 @@ struct amd_sched_fence {
88}; 89};
89 90
90struct amd_sched_job { 91struct amd_sched_job {
92 struct spsc_node queue_node;
91 struct amd_gpu_scheduler *sched; 93 struct amd_gpu_scheduler *sched;
92 struct amd_sched_entity *s_entity; 94 struct amd_sched_entity *s_entity;
93 struct amd_sched_fence *s_fence; 95 struct amd_sched_fence *s_fence;