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 | |
393a0bd4 CK |
30 | #define AMD_SCHED_FENCE_SCHEDULED_BIT FENCE_FLAG_USER_BITS |
31 | ||
a72ce6f8 | 32 | struct amd_gpu_scheduler; |
432a4ff8 | 33 | struct amd_sched_rq; |
a72ce6f8 | 34 | |
f5617f9d CZ |
35 | extern struct kmem_cache *sched_fence_slab; |
36 | extern atomic_t sched_fence_slab_ref; | |
37 | ||
a72ce6f8 JZ |
38 | /** |
39 | * A scheduler entity is a wrapper around a job queue or a group | |
40 | * of other entities. Entities take turns emitting jobs from their | |
41 | * job queues to corresponding hardware ring based on scheduling | |
42 | * policy. | |
43 | */ | |
44 | struct amd_sched_entity { | |
45 | struct list_head list; | |
0f75aee7 CK |
46 | struct amd_sched_rq *rq; |
47 | struct amd_gpu_scheduler *sched; | |
48 | ||
91404fb2 | 49 | spinlock_t queue_lock; |
0f75aee7 CK |
50 | struct kfifo job_queue; |
51 | ||
52 | atomic_t fence_seq; | |
f556cb0c | 53 | uint64_t fence_context; |
0f75aee7 | 54 | |
e61235db CK |
55 | struct fence *dependency; |
56 | struct fence_cb cb; | |
a72ce6f8 JZ |
57 | }; |
58 | ||
59 | /** | |
60 | * Run queue is a set of entities scheduling command submissions for | |
61 | * one specific ring. It implements the scheduling policy that selects | |
62 | * the next entity to emit commands from. | |
63 | */ | |
432a4ff8 | 64 | struct amd_sched_rq { |
2b184d8d | 65 | spinlock_t lock; |
432a4ff8 CK |
66 | struct list_head entities; |
67 | struct amd_sched_entity *current_entity; | |
a72ce6f8 JZ |
68 | }; |
69 | ||
f556cb0c CZ |
70 | struct amd_sched_fence { |
71 | struct fence base; | |
258f3f99 | 72 | struct fence_cb cb; |
393a0bd4 | 73 | struct list_head scheduled_cb; |
9b398fa5 | 74 | struct amd_gpu_scheduler *sched; |
f556cb0c | 75 | spinlock_t lock; |
84f76ea6 | 76 | void *owner; |
2440ff2c JZ |
77 | struct delayed_work dwork; |
78 | struct list_head list; | |
f556cb0c CZ |
79 | }; |
80 | ||
4cef9267 | 81 | struct amd_sched_job { |
4cef9267 | 82 | struct amd_gpu_scheduler *sched; |
953e8fd4 | 83 | struct amd_sched_entity *s_entity; |
f556cb0c | 84 | struct amd_sched_fence *s_fence; |
4cef9267 CZ |
85 | }; |
86 | ||
f556cb0c CZ |
87 | extern const struct fence_ops amd_sched_fence_ops; |
88 | static inline struct amd_sched_fence *to_amd_sched_fence(struct fence *f) | |
89 | { | |
90 | struct amd_sched_fence *__f = container_of(f, struct amd_sched_fence, base); | |
91 | ||
92 | if (__f->base.ops == &amd_sched_fence_ops) | |
93 | return __f; | |
94 | ||
95 | return NULL; | |
96 | } | |
97 | ||
a72ce6f8 JZ |
98 | /** |
99 | * Define the backend operations called by the scheduler, | |
100 | * these functions should be implemented in driver side | |
101 | */ | |
102 | struct amd_sched_backend_ops { | |
4c7eb91c JZ |
103 | struct fence *(*dependency)(struct amd_sched_job *sched_job); |
104 | struct fence *(*run_job)(struct amd_sched_job *sched_job); | |
a72ce6f8 JZ |
105 | }; |
106 | ||
d033a6de CZ |
107 | enum amd_sched_priority { |
108 | AMD_SCHED_PRIORITY_KERNEL = 0, | |
109 | AMD_SCHED_PRIORITY_NORMAL, | |
110 | AMD_SCHED_MAX_PRIORITY | |
111 | }; | |
112 | ||
a72ce6f8 JZ |
113 | /** |
114 | * One scheduler is implemented for each hardware ring | |
115 | */ | |
116 | struct amd_gpu_scheduler { | |
4f839a24 CK |
117 | struct amd_sched_backend_ops *ops; |
118 | uint32_t hw_submission_limit; | |
2440ff2c | 119 | long timeout; |
4f839a24 | 120 | const char *name; |
d033a6de | 121 | struct amd_sched_rq sched_rq[AMD_SCHED_MAX_PRIORITY]; |
c2b6bd7e CK |
122 | wait_queue_head_t wake_up_worker; |
123 | wait_queue_head_t job_scheduled; | |
4f839a24 | 124 | atomic_t hw_rq_count; |
2440ff2c JZ |
125 | struct list_head fence_list; |
126 | spinlock_t fence_list_lock; | |
4f839a24 | 127 | struct task_struct *thread; |
a72ce6f8 JZ |
128 | }; |
129 | ||
4f839a24 CK |
130 | int amd_sched_init(struct amd_gpu_scheduler *sched, |
131 | struct amd_sched_backend_ops *ops, | |
2440ff2c | 132 | uint32_t hw_submission, long timeout, const char *name); |
4f839a24 | 133 | void amd_sched_fini(struct amd_gpu_scheduler *sched); |
a72ce6f8 | 134 | |
91404fb2 CK |
135 | int amd_sched_entity_init(struct amd_gpu_scheduler *sched, |
136 | struct amd_sched_entity *entity, | |
432a4ff8 | 137 | struct amd_sched_rq *rq, |
91404fb2 | 138 | uint32_t jobs); |
062c7fb3 CK |
139 | void amd_sched_entity_fini(struct amd_gpu_scheduler *sched, |
140 | struct amd_sched_entity *entity); | |
e2840221 | 141 | void amd_sched_entity_push_job(struct amd_sched_job *sched_job); |
a72ce6f8 | 142 | |
f556cb0c | 143 | struct amd_sched_fence *amd_sched_fence_create( |
84f76ea6 | 144 | struct amd_sched_entity *s_entity, void *owner); |
393a0bd4 | 145 | void amd_sched_fence_scheduled(struct amd_sched_fence *fence); |
f556cb0c CZ |
146 | void amd_sched_fence_signal(struct amd_sched_fence *fence); |
147 | ||
a72ce6f8 | 148 | #endif |