aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c76
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 */
165void 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
195out_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 */
207void 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
222out_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 }