diff options
Diffstat (limited to 'drivers/gpu/drm/amd/scheduler')
-rw-r--r-- | drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/scheduler/sched_fence.c | 10 |
4 files changed, 47 insertions, 17 deletions
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h b/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h index 144f50acc971..c89dc777768f 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h +++ b/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h | |||
@@ -16,6 +16,8 @@ TRACE_EVENT(amd_sched_job, | |||
16 | TP_ARGS(sched_job), | 16 | TP_ARGS(sched_job), |
17 | TP_STRUCT__entry( | 17 | TP_STRUCT__entry( |
18 | __field(struct amd_sched_entity *, entity) | 18 | __field(struct amd_sched_entity *, entity) |
19 | __field(struct amd_sched_job *, sched_job) | ||
20 | __field(struct fence *, fence) | ||
19 | __field(const char *, name) | 21 | __field(const char *, name) |
20 | __field(u32, job_count) | 22 | __field(u32, job_count) |
21 | __field(int, hw_job_count) | 23 | __field(int, hw_job_count) |
@@ -23,16 +25,32 @@ TRACE_EVENT(amd_sched_job, | |||
23 | 25 | ||
24 | TP_fast_assign( | 26 | TP_fast_assign( |
25 | __entry->entity = sched_job->s_entity; | 27 | __entry->entity = sched_job->s_entity; |
28 | __entry->sched_job = sched_job; | ||
29 | __entry->fence = &sched_job->s_fence->base; | ||
26 | __entry->name = sched_job->sched->name; | 30 | __entry->name = sched_job->sched->name; |
27 | __entry->job_count = kfifo_len( | 31 | __entry->job_count = kfifo_len( |
28 | &sched_job->s_entity->job_queue) / sizeof(sched_job); | 32 | &sched_job->s_entity->job_queue) / sizeof(sched_job); |
29 | __entry->hw_job_count = atomic_read( | 33 | __entry->hw_job_count = atomic_read( |
30 | &sched_job->sched->hw_rq_count); | 34 | &sched_job->sched->hw_rq_count); |
31 | ), | 35 | ), |
32 | TP_printk("entity=%p, ring=%s, job count:%u, hw job count:%d", | 36 | TP_printk("entity=%p, sched job=%p, fence=%p, ring=%s, job count:%u, hw job count:%d", |
33 | __entry->entity, __entry->name, __entry->job_count, | 37 | __entry->entity, __entry->sched_job, __entry->fence, __entry->name, |
34 | __entry->hw_job_count) | 38 | __entry->job_count, __entry->hw_job_count) |
35 | ); | 39 | ); |
40 | |||
41 | TRACE_EVENT(amd_sched_process_job, | ||
42 | TP_PROTO(struct amd_sched_fence *fence), | ||
43 | TP_ARGS(fence), | ||
44 | TP_STRUCT__entry( | ||
45 | __field(struct fence *, fence) | ||
46 | ), | ||
47 | |||
48 | TP_fast_assign( | ||
49 | __entry->fence = &fence->base; | ||
50 | ), | ||
51 | TP_printk("fence=%p signaled", __entry->fence) | ||
52 | ); | ||
53 | |||
36 | #endif | 54 | #endif |
37 | 55 | ||
38 | /* This part must be outside protection */ | 56 | /* This part must be outside protection */ |
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index 89619a5a4289..ea30d6ad4c13 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | |||
@@ -34,6 +34,9 @@ static struct amd_sched_job * | |||
34 | amd_sched_entity_pop_job(struct amd_sched_entity *entity); | 34 | amd_sched_entity_pop_job(struct amd_sched_entity *entity); |
35 | static void amd_sched_wakeup(struct amd_gpu_scheduler *sched); | 35 | static void amd_sched_wakeup(struct amd_gpu_scheduler *sched); |
36 | 36 | ||
37 | struct kmem_cache *sched_fence_slab; | ||
38 | atomic_t sched_fence_slab_ref = ATOMIC_INIT(0); | ||
39 | |||
37 | /* Initialize a given run queue struct */ | 40 | /* Initialize a given run queue struct */ |
38 | static void amd_sched_rq_init(struct amd_sched_rq *rq) | 41 | static void amd_sched_rq_init(struct amd_sched_rq *rq) |
39 | { | 42 | { |
@@ -273,22 +276,13 @@ static bool amd_sched_entity_in(struct amd_sched_job *sched_job) | |||
273 | * | 276 | * |
274 | * Returns 0 for success, negative error code otherwise. | 277 | * Returns 0 for success, negative error code otherwise. |
275 | */ | 278 | */ |
276 | int amd_sched_entity_push_job(struct amd_sched_job *sched_job) | 279 | void amd_sched_entity_push_job(struct amd_sched_job *sched_job) |
277 | { | 280 | { |
278 | struct amd_sched_entity *entity = sched_job->s_entity; | 281 | struct amd_sched_entity *entity = sched_job->s_entity; |
279 | struct amd_sched_fence *fence = amd_sched_fence_create( | ||
280 | entity, sched_job->owner); | ||
281 | |||
282 | if (!fence) | ||
283 | return -ENOMEM; | ||
284 | |||
285 | fence_get(&fence->base); | ||
286 | sched_job->s_fence = fence; | ||
287 | 282 | ||
288 | wait_event(entity->sched->job_scheduled, | 283 | wait_event(entity->sched->job_scheduled, |
289 | amd_sched_entity_in(sched_job)); | 284 | amd_sched_entity_in(sched_job)); |
290 | trace_amd_sched_job(sched_job); | 285 | trace_amd_sched_job(sched_job); |
291 | return 0; | ||
292 | } | 286 | } |
293 | 287 | ||
294 | /** | 288 | /** |
@@ -343,6 +337,7 @@ static void amd_sched_process_job(struct fence *f, struct fence_cb *cb) | |||
343 | list_del_init(&s_fence->list); | 337 | list_del_init(&s_fence->list); |
344 | spin_unlock_irqrestore(&sched->fence_list_lock, flags); | 338 | spin_unlock_irqrestore(&sched->fence_list_lock, flags); |
345 | } | 339 | } |
340 | trace_amd_sched_process_job(s_fence); | ||
346 | fence_put(&s_fence->base); | 341 | fence_put(&s_fence->base); |
347 | wake_up_interruptible(&sched->wake_up_worker); | 342 | wake_up_interruptible(&sched->wake_up_worker); |
348 | } | 343 | } |
@@ -450,6 +445,13 @@ int amd_sched_init(struct amd_gpu_scheduler *sched, | |||
450 | init_waitqueue_head(&sched->wake_up_worker); | 445 | init_waitqueue_head(&sched->wake_up_worker); |
451 | init_waitqueue_head(&sched->job_scheduled); | 446 | init_waitqueue_head(&sched->job_scheduled); |
452 | atomic_set(&sched->hw_rq_count, 0); | 447 | atomic_set(&sched->hw_rq_count, 0); |
448 | if (atomic_inc_return(&sched_fence_slab_ref) == 1) { | ||
449 | sched_fence_slab = kmem_cache_create( | ||
450 | "amd_sched_fence", sizeof(struct amd_sched_fence), 0, | ||
451 | SLAB_HWCACHE_ALIGN, NULL); | ||
452 | if (!sched_fence_slab) | ||
453 | return -ENOMEM; | ||
454 | } | ||
453 | 455 | ||
454 | /* Each scheduler will run on a seperate kernel thread */ | 456 | /* Each scheduler will run on a seperate kernel thread */ |
455 | sched->thread = kthread_run(amd_sched_main, sched, sched->name); | 457 | sched->thread = kthread_run(amd_sched_main, sched, sched->name); |
@@ -470,4 +472,6 @@ void amd_sched_fini(struct amd_gpu_scheduler *sched) | |||
470 | { | 472 | { |
471 | if (sched->thread) | 473 | if (sched->thread) |
472 | kthread_stop(sched->thread); | 474 | kthread_stop(sched->thread); |
475 | if (atomic_dec_and_test(&sched_fence_slab_ref)) | ||
476 | kmem_cache_destroy(sched_fence_slab); | ||
473 | } | 477 | } |
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h index 929e9aced041..939692b14f4b 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | |||
@@ -30,6 +30,9 @@ | |||
30 | struct amd_gpu_scheduler; | 30 | struct amd_gpu_scheduler; |
31 | struct amd_sched_rq; | 31 | struct amd_sched_rq; |
32 | 32 | ||
33 | extern struct kmem_cache *sched_fence_slab; | ||
34 | extern atomic_t sched_fence_slab_ref; | ||
35 | |||
33 | /** | 36 | /** |
34 | * A scheduler entity is a wrapper around a job queue or a group | 37 | * A scheduler entity is a wrapper around a job queue or a group |
35 | * of other entities. Entities take turns emitting jobs from their | 38 | * of other entities. Entities take turns emitting jobs from their |
@@ -76,7 +79,6 @@ struct amd_sched_job { | |||
76 | struct amd_gpu_scheduler *sched; | 79 | struct amd_gpu_scheduler *sched; |
77 | struct amd_sched_entity *s_entity; | 80 | struct amd_sched_entity *s_entity; |
78 | struct amd_sched_fence *s_fence; | 81 | struct amd_sched_fence *s_fence; |
79 | void *owner; | ||
80 | }; | 82 | }; |
81 | 83 | ||
82 | extern const struct fence_ops amd_sched_fence_ops; | 84 | extern const struct fence_ops amd_sched_fence_ops; |
@@ -128,7 +130,7 @@ int amd_sched_entity_init(struct amd_gpu_scheduler *sched, | |||
128 | uint32_t jobs); | 130 | uint32_t jobs); |
129 | void amd_sched_entity_fini(struct amd_gpu_scheduler *sched, | 131 | void amd_sched_entity_fini(struct amd_gpu_scheduler *sched, |
130 | struct amd_sched_entity *entity); | 132 | struct amd_sched_entity *entity); |
131 | int amd_sched_entity_push_job(struct amd_sched_job *sched_job); | 133 | void amd_sched_entity_push_job(struct amd_sched_job *sched_job); |
132 | 134 | ||
133 | struct amd_sched_fence *amd_sched_fence_create( | 135 | struct amd_sched_fence *amd_sched_fence_create( |
134 | struct amd_sched_entity *s_entity, void *owner); | 136 | struct amd_sched_entity *s_entity, void *owner); |
diff --git a/drivers/gpu/drm/amd/scheduler/sched_fence.c b/drivers/gpu/drm/amd/scheduler/sched_fence.c index d802638094f4..8d2130b9ff05 100644 --- a/drivers/gpu/drm/amd/scheduler/sched_fence.c +++ b/drivers/gpu/drm/amd/scheduler/sched_fence.c | |||
@@ -32,7 +32,7 @@ struct amd_sched_fence *amd_sched_fence_create(struct amd_sched_entity *s_entity | |||
32 | struct amd_sched_fence *fence = NULL; | 32 | struct amd_sched_fence *fence = NULL; |
33 | unsigned seq; | 33 | unsigned seq; |
34 | 34 | ||
35 | fence = kzalloc(sizeof(struct amd_sched_fence), GFP_KERNEL); | 35 | fence = kmem_cache_zalloc(sched_fence_slab, GFP_KERNEL); |
36 | if (fence == NULL) | 36 | if (fence == NULL) |
37 | return NULL; | 37 | return NULL; |
38 | fence->owner = owner; | 38 | fence->owner = owner; |
@@ -71,11 +71,17 @@ static bool amd_sched_fence_enable_signaling(struct fence *f) | |||
71 | return true; | 71 | return true; |
72 | } | 72 | } |
73 | 73 | ||
74 | static void amd_sched_fence_release(struct fence *f) | ||
75 | { | ||
76 | struct amd_sched_fence *fence = to_amd_sched_fence(f); | ||
77 | kmem_cache_free(sched_fence_slab, fence); | ||
78 | } | ||
79 | |||
74 | const struct fence_ops amd_sched_fence_ops = { | 80 | const struct fence_ops amd_sched_fence_ops = { |
75 | .get_driver_name = amd_sched_fence_get_driver_name, | 81 | .get_driver_name = amd_sched_fence_get_driver_name, |
76 | .get_timeline_name = amd_sched_fence_get_timeline_name, | 82 | .get_timeline_name = amd_sched_fence_get_timeline_name, |
77 | .enable_signaling = amd_sched_fence_enable_signaling, | 83 | .enable_signaling = amd_sched_fence_enable_signaling, |
78 | .signaled = NULL, | 84 | .signaled = NULL, |
79 | .wait = fence_default_wait, | 85 | .wait = fence_default_wait, |
80 | .release = NULL, | 86 | .release = amd_sched_fence_release, |
81 | }; | 87 | }; |