diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 76 |
1 files changed, 75 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 019932a7ea3a..e5ece1fae149 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | |||
@@ -155,6 +155,75 @@ void amdgpu_ring_undo(struct amdgpu_ring *ring) | |||
155 | } | 155 | } |
156 | 156 | ||
157 | /** | 157 | /** |
158 | * amdgpu_ring_priority_put - restore a ring's priority | ||
159 | * | ||
160 | * @ring: amdgpu_ring structure holding the information | ||
161 | * @priority: target priority | ||
162 | * | ||
163 | * Release a request for executing at @priority | ||
164 | */ | ||
165 | void amdgpu_ring_priority_put(struct amdgpu_ring *ring, | ||
166 | enum amd_sched_priority priority) | ||
167 | { | ||
168 | int i; | ||
169 | |||
170 | if (!ring->funcs->set_priority) | ||
171 | return; | ||
172 | |||
173 | if (atomic_dec_return(&ring->num_jobs[priority]) > 0) | ||
174 | return; | ||
175 | |||
176 | /* no need to restore if the job is already at the lowest priority */ | ||
177 | if (priority == AMD_SCHED_PRIORITY_NORMAL) | ||
178 | return; | ||
179 | |||
180 | mutex_lock(&ring->priority_mutex); | ||
181 | /* something higher prio is executing, no need to decay */ | ||
182 | if (ring->priority > priority) | ||
183 | goto out_unlock; | ||
184 | |||
185 | /* decay priority to the next level with a job available */ | ||
186 | for (i = priority; i >= AMD_SCHED_PRIORITY_MIN; i--) { | ||
187 | if (i == AMD_SCHED_PRIORITY_NORMAL | ||
188 | || atomic_read(&ring->num_jobs[i])) { | ||
189 | ring->priority = i; | ||
190 | ring->funcs->set_priority(ring, i); | ||
191 | break; | ||
192 | } | ||
193 | } | ||
194 | |||
195 | out_unlock: | ||
196 | mutex_unlock(&ring->priority_mutex); | ||
197 | } | ||
198 | |||
199 | /** | ||
200 | * amdgpu_ring_priority_get - change the ring's priority | ||
201 | * | ||
202 | * @ring: amdgpu_ring structure holding the information | ||
203 | * @priority: target priority | ||
204 | * | ||
205 | * Request a ring's priority to be raised to @priority (refcounted). | ||
206 | */ | ||
207 | void amdgpu_ring_priority_get(struct amdgpu_ring *ring, | ||
208 | enum amd_sched_priority priority) | ||
209 | { | ||
210 | if (!ring->funcs->set_priority) | ||
211 | return; | ||
212 | |||
213 | atomic_inc(&ring->num_jobs[priority]); | ||
214 | |||
215 | mutex_lock(&ring->priority_mutex); | ||
216 | if (priority <= ring->priority) | ||
217 | goto out_unlock; | ||
218 | |||
219 | ring->priority = priority; | ||
220 | ring->funcs->set_priority(ring, priority); | ||
221 | |||
222 | out_unlock: | ||
223 | mutex_unlock(&ring->priority_mutex); | ||
224 | } | ||
225 | |||
226 | /** | ||
158 | * amdgpu_ring_init - init driver ring struct. | 227 | * amdgpu_ring_init - init driver ring struct. |
159 | * | 228 | * |
160 | * @adev: amdgpu_device pointer | 229 | * @adev: amdgpu_device pointer |
@@ -169,7 +238,7 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, | |||
169 | unsigned max_dw, struct amdgpu_irq_src *irq_src, | 238 | unsigned max_dw, struct amdgpu_irq_src *irq_src, |
170 | unsigned irq_type) | 239 | unsigned irq_type) |
171 | { | 240 | { |
172 | int r; | 241 | int r, i; |
173 | int sched_hw_submission = amdgpu_sched_hw_submission; | 242 | int sched_hw_submission = amdgpu_sched_hw_submission; |
174 | 243 | ||
175 | /* Set the hw submission limit higher for KIQ because | 244 | /* Set the hw submission limit higher for KIQ because |
@@ -247,9 +316,14 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, | |||
247 | } | 316 | } |
248 | 317 | ||
249 | ring->max_dw = max_dw; | 318 | ring->max_dw = max_dw; |
319 | ring->priority = AMD_SCHED_PRIORITY_NORMAL; | ||
320 | mutex_init(&ring->priority_mutex); | ||
250 | INIT_LIST_HEAD(&ring->lru_list); | 321 | INIT_LIST_HEAD(&ring->lru_list); |
251 | amdgpu_ring_lru_touch(adev, ring); | 322 | amdgpu_ring_lru_touch(adev, ring); |
252 | 323 | ||
324 | for (i = 0; i < AMD_SCHED_PRIORITY_MAX; ++i) | ||
325 | atomic_set(&ring->num_jobs[i], 0); | ||
326 | |||
253 | if (amdgpu_debugfs_ring_init(adev, ring)) { | 327 | if (amdgpu_debugfs_ring_init(adev, ring)) { |
254 | DRM_ERROR("Failed to register debugfs file for rings !\n"); | 328 | DRM_ERROR("Failed to register debugfs file for rings !\n"); |
255 | } | 329 | } |