2 * Copyright 2015 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
26 #include <drm/drm_auth.h>
28 #include "amdgpu_sched.h"
30 #define to_amdgpu_ctx_ring(e) \
31 container_of((e), struct amdgpu_ctx_ring, entity)
33 static int amdgpu_ctx_priority_permit(struct drm_file *filp,
34 enum drm_sched_priority priority)
36 /* NORMAL and below are accessible by everyone */
37 if (priority <= DRM_SCHED_PRIORITY_NORMAL)
40 if (capable(CAP_SYS_NICE))
43 if (drm_is_current_master(filp))
49 static int amdgpu_ctx_init(struct amdgpu_device *adev,
50 enum drm_sched_priority priority,
51 struct drm_file *filp,
52 struct amdgpu_ctx *ctx)
54 struct drm_sched_rq *sdma_rqs[AMDGPU_MAX_RINGS];
55 struct drm_sched_rq *comp_rqs[AMDGPU_MAX_RINGS];
56 unsigned i, j, num_sdma_rqs, num_comp_rqs;
59 if (priority < 0 || priority >= DRM_SCHED_PRIORITY_MAX)
62 r = amdgpu_ctx_priority_permit(filp, priority);
66 memset(ctx, 0, sizeof(*ctx));
68 kref_init(&ctx->refcount);
69 spin_lock_init(&ctx->ring_lock);
70 ctx->fences = kcalloc(amdgpu_sched_jobs * AMDGPU_MAX_RINGS,
71 sizeof(struct dma_fence*), GFP_KERNEL);
75 mutex_init(&ctx->lock);
77 for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
78 ctx->rings[i].sequence = 1;
79 ctx->rings[i].fences = &ctx->fences[amdgpu_sched_jobs * i];
82 ctx->reset_counter = atomic_read(&adev->gpu_reset_counter);
83 ctx->reset_counter_query = ctx->reset_counter;
84 ctx->vram_lost_counter = atomic_read(&adev->vram_lost_counter);
85 ctx->init_priority = priority;
86 ctx->override_priority = DRM_SCHED_PRIORITY_UNSET;
90 for (i = 0; i < adev->num_rings; i++) {
91 struct amdgpu_ring *ring = adev->rings[i];
92 struct drm_sched_rq *rq;
94 rq = &ring->sched.sched_rq[priority];
95 if (ring->funcs->type == AMDGPU_RING_TYPE_SDMA)
96 sdma_rqs[num_sdma_rqs++] = rq;
97 else if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE)
98 comp_rqs[num_comp_rqs++] = rq;
101 /* create context entity for each ring */
102 for (i = 0; i < adev->num_rings; i++) {
103 struct amdgpu_ring *ring = adev->rings[i];
105 if (ring == &adev->gfx.kiq.ring)
108 if (ring->funcs->type == AMDGPU_RING_TYPE_SDMA) {
109 r = drm_sched_entity_init(&ctx->rings[i].entity,
110 sdma_rqs, num_sdma_rqs,
112 } else if (ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE) {
113 r = drm_sched_entity_init(&ctx->rings[i].entity,
114 comp_rqs, num_comp_rqs,
117 struct drm_sched_rq *rq;
119 rq = &ring->sched.sched_rq[priority];
120 r = drm_sched_entity_init(&ctx->rings[i].entity,
121 &rq, 1, &ctx->guilty);
130 for (j = 0; j < i; j++)
131 drm_sched_entity_destroy(&ctx->rings[j].entity);
137 static void amdgpu_ctx_fini(struct kref *ref)
139 struct amdgpu_ctx *ctx = container_of(ref, struct amdgpu_ctx, refcount);
140 struct amdgpu_device *adev = ctx->adev;
146 for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
147 for (j = 0; j < amdgpu_sched_jobs; ++j)
148 dma_fence_put(ctx->rings[i].fences[j]);
152 mutex_destroy(&ctx->lock);
157 int amdgpu_ctx_get_entity(struct amdgpu_ctx *ctx, u32 hw_ip, u32 instance,
158 u32 ring, struct drm_sched_entity **entity)
160 struct amdgpu_device *adev = ctx->adev;
161 unsigned num_rings = 0;
162 struct amdgpu_ring *out_ring;
164 /* Right now all IPs have only one instance - multiple rings. */
166 DRM_DEBUG("invalid ip instance: %d\n", instance);
171 case AMDGPU_HW_IP_GFX:
172 out_ring = &adev->gfx.gfx_ring[ring];
173 num_rings = adev->gfx.num_gfx_rings;
175 case AMDGPU_HW_IP_COMPUTE:
176 out_ring = &adev->gfx.compute_ring[ring];
177 num_rings = adev->gfx.num_compute_rings;
179 case AMDGPU_HW_IP_DMA:
180 out_ring = &adev->sdma.instance[ring].ring;
181 num_rings = adev->sdma.num_instances;
183 case AMDGPU_HW_IP_UVD:
184 out_ring = &adev->uvd.inst[0].ring;
185 num_rings = adev->uvd.num_uvd_inst;
187 case AMDGPU_HW_IP_VCE:
188 out_ring = &adev->vce.ring[ring];
189 num_rings = adev->vce.num_rings;
191 case AMDGPU_HW_IP_UVD_ENC:
192 out_ring = &adev->uvd.inst[0].ring_enc[ring];
193 num_rings = adev->uvd.num_enc_rings;
195 case AMDGPU_HW_IP_VCN_DEC:
196 out_ring = &adev->vcn.ring_dec;
199 case AMDGPU_HW_IP_VCN_ENC:
200 out_ring = &adev->vcn.ring_enc[ring];
201 num_rings = adev->vcn.num_enc_rings;
203 case AMDGPU_HW_IP_VCN_JPEG:
204 out_ring = &adev->vcn.ring_jpeg;
208 DRM_ERROR("unknown HW IP type: %d\n", hw_ip);
212 if (ring > num_rings)
215 *entity = &ctx->rings[out_ring->idx].entity;
219 static int amdgpu_ctx_alloc(struct amdgpu_device *adev,
220 struct amdgpu_fpriv *fpriv,
221 struct drm_file *filp,
222 enum drm_sched_priority priority,
225 struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
226 struct amdgpu_ctx *ctx;
229 ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
233 mutex_lock(&mgr->lock);
234 r = idr_alloc(&mgr->ctx_handles, ctx, 1, 0, GFP_KERNEL);
236 mutex_unlock(&mgr->lock);
242 r = amdgpu_ctx_init(adev, priority, filp, ctx);
244 idr_remove(&mgr->ctx_handles, *id);
248 mutex_unlock(&mgr->lock);
252 static void amdgpu_ctx_do_release(struct kref *ref)
254 struct amdgpu_ctx *ctx;
257 ctx = container_of(ref, struct amdgpu_ctx, refcount);
259 for (i = 0; i < ctx->adev->num_rings; i++) {
261 if (ctx->adev->rings[i] == &ctx->adev->gfx.kiq.ring)
264 drm_sched_entity_destroy(&ctx->rings[i].entity);
267 amdgpu_ctx_fini(ref);
270 static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, uint32_t id)
272 struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
273 struct amdgpu_ctx *ctx;
275 mutex_lock(&mgr->lock);
276 ctx = idr_remove(&mgr->ctx_handles, id);
278 kref_put(&ctx->refcount, amdgpu_ctx_do_release);
279 mutex_unlock(&mgr->lock);
280 return ctx ? 0 : -EINVAL;
283 static int amdgpu_ctx_query(struct amdgpu_device *adev,
284 struct amdgpu_fpriv *fpriv, uint32_t id,
285 union drm_amdgpu_ctx_out *out)
287 struct amdgpu_ctx *ctx;
288 struct amdgpu_ctx_mgr *mgr;
289 unsigned reset_counter;
294 mgr = &fpriv->ctx_mgr;
295 mutex_lock(&mgr->lock);
296 ctx = idr_find(&mgr->ctx_handles, id);
298 mutex_unlock(&mgr->lock);
302 /* TODO: these two are always zero */
303 out->state.flags = 0x0;
304 out->state.hangs = 0x0;
306 /* determine if a GPU reset has occured since the last call */
307 reset_counter = atomic_read(&adev->gpu_reset_counter);
308 /* TODO: this should ideally return NO, GUILTY, or INNOCENT. */
309 if (ctx->reset_counter_query == reset_counter)
310 out->state.reset_status = AMDGPU_CTX_NO_RESET;
312 out->state.reset_status = AMDGPU_CTX_UNKNOWN_RESET;
313 ctx->reset_counter_query = reset_counter;
315 mutex_unlock(&mgr->lock);
319 static int amdgpu_ctx_query2(struct amdgpu_device *adev,
320 struct amdgpu_fpriv *fpriv, uint32_t id,
321 union drm_amdgpu_ctx_out *out)
323 struct amdgpu_ctx *ctx;
324 struct amdgpu_ctx_mgr *mgr;
329 mgr = &fpriv->ctx_mgr;
330 mutex_lock(&mgr->lock);
331 ctx = idr_find(&mgr->ctx_handles, id);
333 mutex_unlock(&mgr->lock);
337 out->state.flags = 0x0;
338 out->state.hangs = 0x0;
340 if (ctx->reset_counter != atomic_read(&adev->gpu_reset_counter))
341 out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_RESET;
343 if (ctx->vram_lost_counter != atomic_read(&adev->vram_lost_counter))
344 out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST;
346 if (atomic_read(&ctx->guilty))
347 out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_GUILTY;
349 mutex_unlock(&mgr->lock);
353 int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
354 struct drm_file *filp)
358 enum drm_sched_priority priority;
360 union drm_amdgpu_ctx *args = data;
361 struct amdgpu_device *adev = dev->dev_private;
362 struct amdgpu_fpriv *fpriv = filp->driver_priv;
365 id = args->in.ctx_id;
366 priority = amdgpu_to_sched_priority(args->in.priority);
368 /* For backwards compatibility reasons, we need to accept
369 * ioctls with garbage in the priority field */
370 if (priority == DRM_SCHED_PRIORITY_INVALID)
371 priority = DRM_SCHED_PRIORITY_NORMAL;
373 switch (args->in.op) {
374 case AMDGPU_CTX_OP_ALLOC_CTX:
375 r = amdgpu_ctx_alloc(adev, fpriv, filp, priority, &id);
376 args->out.alloc.ctx_id = id;
378 case AMDGPU_CTX_OP_FREE_CTX:
379 r = amdgpu_ctx_free(fpriv, id);
381 case AMDGPU_CTX_OP_QUERY_STATE:
382 r = amdgpu_ctx_query(adev, fpriv, id, &args->out);
384 case AMDGPU_CTX_OP_QUERY_STATE2:
385 r = amdgpu_ctx_query2(adev, fpriv, id, &args->out);
394 struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id)
396 struct amdgpu_ctx *ctx;
397 struct amdgpu_ctx_mgr *mgr;
402 mgr = &fpriv->ctx_mgr;
404 mutex_lock(&mgr->lock);
405 ctx = idr_find(&mgr->ctx_handles, id);
407 kref_get(&ctx->refcount);
408 mutex_unlock(&mgr->lock);
412 int amdgpu_ctx_put(struct amdgpu_ctx *ctx)
417 kref_put(&ctx->refcount, amdgpu_ctx_do_release);
421 int amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx,
422 struct drm_sched_entity *entity,
423 struct dma_fence *fence, uint64_t* handle)
425 struct amdgpu_ctx_ring *cring = to_amdgpu_ctx_ring(entity);
426 uint64_t seq = cring->sequence;
427 struct dma_fence *other = NULL;
430 idx = seq & (amdgpu_sched_jobs - 1);
431 other = cring->fences[idx];
433 BUG_ON(!dma_fence_is_signaled(other));
435 dma_fence_get(fence);
437 spin_lock(&ctx->ring_lock);
438 cring->fences[idx] = fence;
440 spin_unlock(&ctx->ring_lock);
442 dma_fence_put(other);
449 struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx,
450 struct drm_sched_entity *entity,
453 struct amdgpu_ctx_ring *cring = to_amdgpu_ctx_ring(entity);
454 struct dma_fence *fence;
456 spin_lock(&ctx->ring_lock);
459 seq = cring->sequence - 1;
461 if (seq >= cring->sequence) {
462 spin_unlock(&ctx->ring_lock);
463 return ERR_PTR(-EINVAL);
467 if (seq + amdgpu_sched_jobs < cring->sequence) {
468 spin_unlock(&ctx->ring_lock);
472 fence = dma_fence_get(cring->fences[seq & (amdgpu_sched_jobs - 1)]);
473 spin_unlock(&ctx->ring_lock);
478 void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx,
479 enum drm_sched_priority priority)
482 struct amdgpu_device *adev = ctx->adev;
483 struct drm_sched_entity *entity;
484 struct amdgpu_ring *ring;
485 enum drm_sched_priority ctx_prio;
487 ctx->override_priority = priority;
489 ctx_prio = (ctx->override_priority == DRM_SCHED_PRIORITY_UNSET) ?
490 ctx->init_priority : ctx->override_priority;
492 for (i = 0; i < adev->num_rings; i++) {
493 ring = adev->rings[i];
494 entity = &ctx->rings[i].entity;
496 if (ring->funcs->type == AMDGPU_RING_TYPE_KIQ)
499 drm_sched_entity_set_priority(entity, ctx_prio);
503 int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx,
504 struct drm_sched_entity *entity)
506 struct amdgpu_ctx_ring *cring = to_amdgpu_ctx_ring(entity);
507 unsigned idx = cring->sequence & (amdgpu_sched_jobs - 1);
508 struct dma_fence *other = cring->fences[idx];
512 r = dma_fence_wait(other, true);
514 if (r != -ERESTARTSYS)
515 DRM_ERROR("Error (%ld) waiting for fence!\n", r);
524 void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr)
526 mutex_init(&mgr->lock);
527 idr_init(&mgr->ctx_handles);
530 void amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr)
532 struct amdgpu_ctx *ctx;
535 long max_wait = MAX_WAIT_SCHED_ENTITY_Q_EMPTY;
537 idp = &mgr->ctx_handles;
539 mutex_lock(&mgr->lock);
540 idr_for_each_entry(idp, ctx, id) {
543 mutex_unlock(&mgr->lock);
547 for (i = 0; i < ctx->adev->num_rings; i++) {
549 if (ctx->adev->rings[i] == &ctx->adev->gfx.kiq.ring)
552 max_wait = drm_sched_entity_flush(&ctx->rings[i].entity,
556 mutex_unlock(&mgr->lock);
559 void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
561 struct amdgpu_ctx *ctx;
565 idp = &mgr->ctx_handles;
567 idr_for_each_entry(idp, ctx, id) {
572 for (i = 0; i < ctx->adev->num_rings; i++) {
574 if (ctx->adev->rings[i] == &ctx->adev->gfx.kiq.ring)
577 if (kref_read(&ctx->refcount) == 1)
578 drm_sched_entity_fini(&ctx->rings[i].entity);
580 DRM_ERROR("ctx %p is still alive\n", ctx);
585 void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr)
587 struct amdgpu_ctx *ctx;
591 amdgpu_ctx_mgr_entity_fini(mgr);
593 idp = &mgr->ctx_handles;
595 idr_for_each_entry(idp, ctx, id) {
596 if (kref_put(&ctx->refcount, amdgpu_ctx_fini) != 1)
597 DRM_ERROR("ctx %p is still alive\n", ctx);
600 idr_destroy(&mgr->ctx_handles);
601 mutex_destroy(&mgr->lock);