Commit | Line | Data |
---|---|---|
a72ce6f8 JZ |
1 | /* |
2 | * Copyright 2015 Advanced Micro Devices, Inc. | |
3 | * | |
4 | * Permission is hereby granted, free of charge, to any person obtaining a | |
5 | * copy of this software and associated documentation files (the "Software"), | |
6 | * to deal in the Software without restriction, including without limitation | |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
8 | * and/or sell copies of the Software, and to permit persons to whom the | |
9 | * Software is furnished to do so, subject to the following conditions: | |
10 | * | |
11 | * The above copyright notice and this permission notice shall be included in | |
12 | * all copies or substantial portions of the Software. | |
13 | * | |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
20 | * OTHER DEALINGS IN THE SOFTWARE. | |
21 | * | |
22 | */ | |
23 | ||
24 | #ifndef _GPU_SCHEDULER_H_ | |
25 | #define _GPU_SCHEDULER_H_ | |
26 | ||
27 | #include <linux/kfifo.h> | |
4cef9267 | 28 | #include <linux/fence.h> |
a72ce6f8 | 29 | |
a72ce6f8 | 30 | struct amd_gpu_scheduler; |
432a4ff8 | 31 | struct amd_sched_rq; |
a72ce6f8 JZ |
32 | |
33 | /** | |
34 | * A scheduler entity is a wrapper around a job queue or a group | |
35 | * of other entities. Entities take turns emitting jobs from their | |
36 | * job queues to corresponding hardware ring based on scheduling | |
37 | * policy. | |
38 | */ | |
39 | struct amd_sched_entity { | |
40 | struct list_head list; | |
0f75aee7 CK |
41 | struct amd_sched_rq *rq; |
42 | struct amd_gpu_scheduler *sched; | |
43 | ||
91404fb2 | 44 | spinlock_t queue_lock; |
0f75aee7 CK |
45 | struct kfifo job_queue; |
46 | ||
47 | atomic_t fence_seq; | |
f556cb0c | 48 | uint64_t fence_context; |
0f75aee7 | 49 | |
e61235db CK |
50 | struct fence *dependency; |
51 | struct fence_cb cb; | |
a72ce6f8 JZ |
52 | }; |
53 | ||
54 | /** | |
55 | * Run queue is a set of entities scheduling command submissions for | |
56 | * one specific ring. It implements the scheduling policy that selects | |
57 | * the next entity to emit commands from. | |
58 | */ | |
432a4ff8 | 59 | struct amd_sched_rq { |
2b184d8d | 60 | spinlock_t lock; |
432a4ff8 CK |
61 | struct list_head entities; |
62 | struct amd_sched_entity *current_entity; | |
a72ce6f8 JZ |
63 | }; |
64 | ||
f556cb0c CZ |
65 | struct amd_sched_fence { |
66 | struct fence base; | |
258f3f99 | 67 | struct fence_cb cb; |
9b398fa5 | 68 | struct amd_gpu_scheduler *sched; |
f556cb0c | 69 | spinlock_t lock; |
84f76ea6 | 70 | void *owner; |
2440ff2c JZ |
71 | struct delayed_work dwork; |
72 | struct list_head list; | |
f556cb0c CZ |
73 | }; |
74 | ||
4cef9267 | 75 | struct amd_sched_job { |
4cef9267 | 76 | struct amd_gpu_scheduler *sched; |
953e8fd4 | 77 | struct amd_sched_entity *s_entity; |
f556cb0c | 78 | struct amd_sched_fence *s_fence; |
84f76ea6 | 79 | void *owner; |
4cef9267 CZ |
80 | }; |
81 | ||
f556cb0c CZ |
82 | extern const struct fence_ops amd_sched_fence_ops; |
83 | static inline struct amd_sched_fence *to_amd_sched_fence(struct fence *f) | |
84 | { | |
85 | struct amd_sched_fence *__f = container_of(f, struct amd_sched_fence, base); | |
86 | ||
87 | if (__f->base.ops == &amd_sched_fence_ops) | |
88 | return __f; | |
89 | ||
90 | return NULL; | |
91 | } | |
92 | ||
a72ce6f8 JZ |
93 | /** |
94 | * Define the backend operations called by the scheduler, | |
95 | * these functions should be implemented in driver side | |
96 | */ | |
97 | struct amd_sched_backend_ops { | |
4c7eb91c JZ |
98 | struct fence *(*dependency)(struct amd_sched_job *sched_job); |
99 | struct fence *(*run_job)(struct amd_sched_job *sched_job); | |
a72ce6f8 JZ |
100 | }; |
101 | ||
102 | /** | |
103 | * One scheduler is implemented for each hardware ring | |
104 | */ | |
105 | struct amd_gpu_scheduler { | |
4f839a24 CK |
106 | struct amd_sched_backend_ops *ops; |
107 | uint32_t hw_submission_limit; | |
2440ff2c | 108 | long timeout; |
4f839a24 | 109 | const char *name; |
432a4ff8 CK |
110 | struct amd_sched_rq sched_rq; |
111 | struct amd_sched_rq kernel_rq; | |
c2b6bd7e CK |
112 | wait_queue_head_t wake_up_worker; |
113 | wait_queue_head_t job_scheduled; | |
4f839a24 | 114 | atomic_t hw_rq_count; |
2440ff2c JZ |
115 | struct list_head fence_list; |
116 | spinlock_t fence_list_lock; | |
4f839a24 | 117 | struct task_struct *thread; |
a72ce6f8 JZ |
118 | }; |
119 | ||
4f839a24 CK |
120 | int amd_sched_init(struct amd_gpu_scheduler *sched, |
121 | struct amd_sched_backend_ops *ops, | |
2440ff2c | 122 | uint32_t hw_submission, long timeout, const char *name); |
4f839a24 | 123 | void amd_sched_fini(struct amd_gpu_scheduler *sched); |
a72ce6f8 | 124 | |
91404fb2 CK |
125 | int amd_sched_entity_init(struct amd_gpu_scheduler *sched, |
126 | struct amd_sched_entity *entity, | |
432a4ff8 | 127 | struct amd_sched_rq *rq, |
91404fb2 | 128 | uint32_t jobs); |
062c7fb3 CK |
129 | void amd_sched_entity_fini(struct amd_gpu_scheduler *sched, |
130 | struct amd_sched_entity *entity); | |
6c859274 | 131 | int amd_sched_entity_push_job(struct amd_sched_job *sched_job); |
a72ce6f8 | 132 | |
f556cb0c | 133 | struct amd_sched_fence *amd_sched_fence_create( |
84f76ea6 | 134 | struct amd_sched_entity *s_entity, void *owner); |
f556cb0c CZ |
135 | void amd_sched_fence_signal(struct amd_sched_fence *fence); |
136 | ||
137 | ||
a72ce6f8 | 138 | #endif |