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  * Authors: monk liu <monk.liu@amd.com>
23  */
24 
25 #include <drm/drm_auth.h>
26 #include "amdgpu.h"
27 #include "amdgpu_sched.h"
28 #include "amdgpu_ras.h"
29 
30 #define to_amdgpu_ctx_entity(e)	\
31 	container_of((e), struct amdgpu_ctx_entity, entity)
32 
33 const unsigned int amdgpu_ctx_num_entities[AMDGPU_HW_IP_NUM] = {
34 	[AMDGPU_HW_IP_GFX]	=	1,
35 	[AMDGPU_HW_IP_COMPUTE]	=	4,
36 	[AMDGPU_HW_IP_DMA]	=	2,
37 	[AMDGPU_HW_IP_UVD]	=	1,
38 	[AMDGPU_HW_IP_VCE]	=	1,
39 	[AMDGPU_HW_IP_UVD_ENC]	=	1,
40 	[AMDGPU_HW_IP_VCN_DEC]	=	1,
41 	[AMDGPU_HW_IP_VCN_ENC]	=	1,
42 	[AMDGPU_HW_IP_VCN_JPEG]	=	1,
43 };
44 
45 static int amdgpu_ctx_priority_permit(struct drm_file *filp,
46 				      enum drm_sched_priority priority)
47 {
48 	if (priority < 0 || priority >= DRM_SCHED_PRIORITY_MAX)
49 		return -EINVAL;
50 
51 	/* NORMAL and below are accessible by everyone */
52 	if (priority <= DRM_SCHED_PRIORITY_NORMAL)
53 		return 0;
54 
55 	if (capable(CAP_SYS_NICE))
56 		return 0;
57 
58 	if (drm_is_current_master(filp))
59 		return 0;
60 
61 	return -EACCES;
62 }
63 
64 static enum gfx_pipe_priority amdgpu_ctx_sched_prio_to_compute_prio(enum drm_sched_priority prio)
65 {
66 	switch (prio) {
67 	case DRM_SCHED_PRIORITY_HIGH_HW:
68 	case DRM_SCHED_PRIORITY_KERNEL:
69 		return AMDGPU_GFX_PIPE_PRIO_HIGH;
70 	default:
71 		return AMDGPU_GFX_PIPE_PRIO_NORMAL;
72 	}
73 }
74 
75 static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, const u32 hw_ip, const u32 ring)
76 {
77 	struct amdgpu_device *adev = ctx->adev;
78 	struct amdgpu_ctx_entity *entity;
79 	struct drm_gpu_scheduler **scheds = NULL, *sched = NULL;
80 	unsigned num_scheds = 0;
81 	enum gfx_pipe_priority hw_prio;
82 	enum drm_sched_priority priority;
83 	int r;
84 
85 	entity = kcalloc(1, offsetof(typeof(*entity), fences[amdgpu_sched_jobs]),
86 			 GFP_KERNEL);
87 	if (!entity)
88 		return  -ENOMEM;
89 
90 	entity->sequence = 1;
91 	priority = (ctx->override_priority == DRM_SCHED_PRIORITY_UNSET) ?
92 				ctx->init_priority : ctx->override_priority;
93 	switch (hw_ip) {
94 	case AMDGPU_HW_IP_GFX:
95 		sched = &adev->gfx.gfx_ring[0].sched;
96 		scheds = &sched;
97 		num_scheds = 1;
98 		break;
99 	case AMDGPU_HW_IP_COMPUTE:
100 		hw_prio = amdgpu_ctx_sched_prio_to_compute_prio(priority);
101 		scheds = adev->gfx.compute_prio_sched[hw_prio];
102 		num_scheds = adev->gfx.num_compute_sched[hw_prio];
103 		break;
104 	case AMDGPU_HW_IP_DMA:
105 		scheds = adev->sdma.sdma_sched;
106 		num_scheds = adev->sdma.num_sdma_sched;
107 		break;
108 	case AMDGPU_HW_IP_UVD:
109 		sched = &adev->uvd.inst[0].ring.sched;
110 		scheds = &sched;
111 		num_scheds = 1;
112 		break;
113 	case AMDGPU_HW_IP_VCE:
114 		sched = &adev->vce.ring[0].sched;
115 		scheds = &sched;
116 		num_scheds = 1;
117 		break;
118 	case AMDGPU_HW_IP_UVD_ENC:
119 		sched = &adev->uvd.inst[0].ring_enc[0].sched;
120 		scheds = &sched;
121 		num_scheds = 1;
122 		break;
123 	case AMDGPU_HW_IP_VCN_DEC:
124 		sched = drm_sched_pick_best(adev->vcn.vcn_dec_sched,
125 					    adev->vcn.num_vcn_dec_sched);
126 		scheds = &sched;
127 		num_scheds = 1;
128 		break;
129 	case AMDGPU_HW_IP_VCN_ENC:
130 		sched = drm_sched_pick_best(adev->vcn.vcn_enc_sched,
131 					    adev->vcn.num_vcn_enc_sched);
132 		scheds = &sched;
133 		num_scheds = 1;
134 		break;
135 	case AMDGPU_HW_IP_VCN_JPEG:
136 		scheds = adev->jpeg.jpeg_sched;
137 		num_scheds =  adev->jpeg.num_jpeg_sched;
138 		break;
139 	}
140 
141 	r = drm_sched_entity_init(&entity->entity, priority, scheds, num_scheds,
142 				  &ctx->guilty);
143 	if (r)
144 		goto error_free_entity;
145 
146 	ctx->entities[hw_ip][ring] = entity;
147 	return 0;
148 
149 error_free_entity:
150 	kfree(entity);
151 
152 	return r;
153 }
154 
155 static int amdgpu_ctx_init(struct amdgpu_device *adev,
156 			   enum drm_sched_priority priority,
157 			   struct drm_file *filp,
158 			   struct amdgpu_ctx *ctx)
159 {
160 	int r;
161 
162 	r = amdgpu_ctx_priority_permit(filp, priority);
163 	if (r)
164 		return r;
165 
166 	memset(ctx, 0, sizeof(*ctx));
167 
168 	ctx->adev = adev;
169 
170 	kref_init(&ctx->refcount);
171 	spin_lock_init(&ctx->ring_lock);
172 	mutex_init(&ctx->lock);
173 
174 	ctx->reset_counter = atomic_read(&adev->gpu_reset_counter);
175 	ctx->reset_counter_query = ctx->reset_counter;
176 	ctx->vram_lost_counter = atomic_read(&adev->vram_lost_counter);
177 	ctx->init_priority = priority;
178 	ctx->override_priority = DRM_SCHED_PRIORITY_UNSET;
179 
180 	return 0;
181 
182 }
183 
184 static void amdgpu_ctx_fini_entity(struct amdgpu_ctx_entity *entity)
185 {
186 
187 	int i;
188 
189 	if (!entity)
190 		return;
191 
192 	for (i = 0; i < amdgpu_sched_jobs; ++i)
193 		dma_fence_put(entity->fences[i]);
194 
195 	kfree(entity);
196 }
197 
198 static void amdgpu_ctx_fini(struct kref *ref)
199 {
200 	struct amdgpu_ctx *ctx = container_of(ref, struct amdgpu_ctx, refcount);
201 	struct amdgpu_device *adev = ctx->adev;
202 	unsigned i, j;
203 
204 	if (!adev)
205 		return;
206 
207 	for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
208 		for (j = 0; j < AMDGPU_MAX_ENTITY_NUM; ++j) {
209 			amdgpu_ctx_fini_entity(ctx->entities[i][j]);
210 			ctx->entities[i][j] = NULL;
211 		}
212 	}
213 
214 	mutex_destroy(&ctx->lock);
215 	kfree(ctx);
216 }
217 
218 int amdgpu_ctx_get_entity(struct amdgpu_ctx *ctx, u32 hw_ip, u32 instance,
219 			  u32 ring, struct drm_sched_entity **entity)
220 {
221 	int r;
222 
223 	if (hw_ip >= AMDGPU_HW_IP_NUM) {
224 		DRM_ERROR("unknown HW IP type: %d\n", hw_ip);
225 		return -EINVAL;
226 	}
227 
228 	/* Right now all IPs have only one instance - multiple rings. */
229 	if (instance != 0) {
230 		DRM_DEBUG("invalid ip instance: %d\n", instance);
231 		return -EINVAL;
232 	}
233 
234 	if (ring >= amdgpu_ctx_num_entities[hw_ip]) {
235 		DRM_DEBUG("invalid ring: %d %d\n", hw_ip, ring);
236 		return -EINVAL;
237 	}
238 
239 	if (ctx->entities[hw_ip][ring] == NULL) {
240 		r = amdgpu_ctx_init_entity(ctx, hw_ip, ring);
241 		if (r)
242 			return r;
243 	}
244 
245 	*entity = &ctx->entities[hw_ip][ring]->entity;
246 	return 0;
247 }
248 
249 static int amdgpu_ctx_alloc(struct amdgpu_device *adev,
250 			    struct amdgpu_fpriv *fpriv,
251 			    struct drm_file *filp,
252 			    enum drm_sched_priority priority,
253 			    uint32_t *id)
254 {
255 	struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
256 	struct amdgpu_ctx *ctx;
257 	int r;
258 
259 	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
260 	if (!ctx)
261 		return -ENOMEM;
262 
263 	mutex_lock(&mgr->lock);
264 	r = idr_alloc(&mgr->ctx_handles, ctx, 1, AMDGPU_VM_MAX_NUM_CTX, GFP_KERNEL);
265 	if (r < 0) {
266 		mutex_unlock(&mgr->lock);
267 		kfree(ctx);
268 		return r;
269 	}
270 
271 	*id = (uint32_t)r;
272 	r = amdgpu_ctx_init(adev, priority, filp, ctx);
273 	if (r) {
274 		idr_remove(&mgr->ctx_handles, *id);
275 		*id = 0;
276 		kfree(ctx);
277 	}
278 	mutex_unlock(&mgr->lock);
279 	return r;
280 }
281 
282 static void amdgpu_ctx_do_release(struct kref *ref)
283 {
284 	struct amdgpu_ctx *ctx;
285 	u32 i, j;
286 
287 	ctx = container_of(ref, struct amdgpu_ctx, refcount);
288 	for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
289 		for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
290 			if (!ctx->entities[i][j])
291 				continue;
292 
293 			drm_sched_entity_destroy(&ctx->entities[i][j]->entity);
294 		}
295 	}
296 
297 	amdgpu_ctx_fini(ref);
298 }
299 
300 static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, uint32_t id)
301 {
302 	struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr;
303 	struct amdgpu_ctx *ctx;
304 
305 	mutex_lock(&mgr->lock);
306 	ctx = idr_remove(&mgr->ctx_handles, id);
307 	if (ctx)
308 		kref_put(&ctx->refcount, amdgpu_ctx_do_release);
309 	mutex_unlock(&mgr->lock);
310 	return ctx ? 0 : -EINVAL;
311 }
312 
313 static int amdgpu_ctx_query(struct amdgpu_device *adev,
314 			    struct amdgpu_fpriv *fpriv, uint32_t id,
315 			    union drm_amdgpu_ctx_out *out)
316 {
317 	struct amdgpu_ctx *ctx;
318 	struct amdgpu_ctx_mgr *mgr;
319 	unsigned reset_counter;
320 
321 	if (!fpriv)
322 		return -EINVAL;
323 
324 	mgr = &fpriv->ctx_mgr;
325 	mutex_lock(&mgr->lock);
326 	ctx = idr_find(&mgr->ctx_handles, id);
327 	if (!ctx) {
328 		mutex_unlock(&mgr->lock);
329 		return -EINVAL;
330 	}
331 
332 	/* TODO: these two are always zero */
333 	out->state.flags = 0x0;
334 	out->state.hangs = 0x0;
335 
336 	/* determine if a GPU reset has occured since the last call */
337 	reset_counter = atomic_read(&adev->gpu_reset_counter);
338 	/* TODO: this should ideally return NO, GUILTY, or INNOCENT. */
339 	if (ctx->reset_counter_query == reset_counter)
340 		out->state.reset_status = AMDGPU_CTX_NO_RESET;
341 	else
342 		out->state.reset_status = AMDGPU_CTX_UNKNOWN_RESET;
343 	ctx->reset_counter_query = reset_counter;
344 
345 	mutex_unlock(&mgr->lock);
346 	return 0;
347 }
348 
349 static int amdgpu_ctx_query2(struct amdgpu_device *adev,
350 	struct amdgpu_fpriv *fpriv, uint32_t id,
351 	union drm_amdgpu_ctx_out *out)
352 {
353 	struct amdgpu_ctx *ctx;
354 	struct amdgpu_ctx_mgr *mgr;
355 	unsigned long ras_counter;
356 
357 	if (!fpriv)
358 		return -EINVAL;
359 
360 	mgr = &fpriv->ctx_mgr;
361 	mutex_lock(&mgr->lock);
362 	ctx = idr_find(&mgr->ctx_handles, id);
363 	if (!ctx) {
364 		mutex_unlock(&mgr->lock);
365 		return -EINVAL;
366 	}
367 
368 	out->state.flags = 0x0;
369 	out->state.hangs = 0x0;
370 
371 	if (ctx->reset_counter != atomic_read(&adev->gpu_reset_counter))
372 		out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_RESET;
373 
374 	if (ctx->vram_lost_counter != atomic_read(&adev->vram_lost_counter))
375 		out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST;
376 
377 	if (atomic_read(&ctx->guilty))
378 		out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_GUILTY;
379 
380 	/*query ue count*/
381 	ras_counter = amdgpu_ras_query_error_count(adev, false);
382 	/*ras counter is monotonic increasing*/
383 	if (ras_counter != ctx->ras_counter_ue) {
384 		out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_RAS_UE;
385 		ctx->ras_counter_ue = ras_counter;
386 	}
387 
388 	/*query ce count*/
389 	ras_counter = amdgpu_ras_query_error_count(adev, true);
390 	if (ras_counter != ctx->ras_counter_ce) {
391 		out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_RAS_CE;
392 		ctx->ras_counter_ce = ras_counter;
393 	}
394 
395 	mutex_unlock(&mgr->lock);
396 	return 0;
397 }
398 
399 int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
400 		     struct drm_file *filp)
401 {
402 	int r;
403 	uint32_t id;
404 	enum drm_sched_priority priority;
405 
406 	union drm_amdgpu_ctx *args = data;
407 	struct amdgpu_device *adev = dev->dev_private;
408 	struct amdgpu_fpriv *fpriv = filp->driver_priv;
409 
410 	r = 0;
411 	id = args->in.ctx_id;
412 	priority = amdgpu_to_sched_priority(args->in.priority);
413 
414 	/* For backwards compatibility reasons, we need to accept
415 	 * ioctls with garbage in the priority field */
416 	if (priority == DRM_SCHED_PRIORITY_INVALID)
417 		priority = DRM_SCHED_PRIORITY_NORMAL;
418 
419 	switch (args->in.op) {
420 	case AMDGPU_CTX_OP_ALLOC_CTX:
421 		r = amdgpu_ctx_alloc(adev, fpriv, filp, priority, &id);
422 		args->out.alloc.ctx_id = id;
423 		break;
424 	case AMDGPU_CTX_OP_FREE_CTX:
425 		r = amdgpu_ctx_free(fpriv, id);
426 		break;
427 	case AMDGPU_CTX_OP_QUERY_STATE:
428 		r = amdgpu_ctx_query(adev, fpriv, id, &args->out);
429 		break;
430 	case AMDGPU_CTX_OP_QUERY_STATE2:
431 		r = amdgpu_ctx_query2(adev, fpriv, id, &args->out);
432 		break;
433 	default:
434 		return -EINVAL;
435 	}
436 
437 	return r;
438 }
439 
440 struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id)
441 {
442 	struct amdgpu_ctx *ctx;
443 	struct amdgpu_ctx_mgr *mgr;
444 
445 	if (!fpriv)
446 		return NULL;
447 
448 	mgr = &fpriv->ctx_mgr;
449 
450 	mutex_lock(&mgr->lock);
451 	ctx = idr_find(&mgr->ctx_handles, id);
452 	if (ctx)
453 		kref_get(&ctx->refcount);
454 	mutex_unlock(&mgr->lock);
455 	return ctx;
456 }
457 
458 int amdgpu_ctx_put(struct amdgpu_ctx *ctx)
459 {
460 	if (ctx == NULL)
461 		return -EINVAL;
462 
463 	kref_put(&ctx->refcount, amdgpu_ctx_do_release);
464 	return 0;
465 }
466 
467 void amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx,
468 			  struct drm_sched_entity *entity,
469 			  struct dma_fence *fence, uint64_t* handle)
470 {
471 	struct amdgpu_ctx_entity *centity = to_amdgpu_ctx_entity(entity);
472 	uint64_t seq = centity->sequence;
473 	struct dma_fence *other = NULL;
474 	unsigned idx = 0;
475 
476 	idx = seq & (amdgpu_sched_jobs - 1);
477 	other = centity->fences[idx];
478 	if (other)
479 		BUG_ON(!dma_fence_is_signaled(other));
480 
481 	dma_fence_get(fence);
482 
483 	spin_lock(&ctx->ring_lock);
484 	centity->fences[idx] = fence;
485 	centity->sequence++;
486 	spin_unlock(&ctx->ring_lock);
487 
488 	dma_fence_put(other);
489 	if (handle)
490 		*handle = seq;
491 }
492 
493 struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx,
494 				       struct drm_sched_entity *entity,
495 				       uint64_t seq)
496 {
497 	struct amdgpu_ctx_entity *centity = to_amdgpu_ctx_entity(entity);
498 	struct dma_fence *fence;
499 
500 	spin_lock(&ctx->ring_lock);
501 
502 	if (seq == ~0ull)
503 		seq = centity->sequence - 1;
504 
505 	if (seq >= centity->sequence) {
506 		spin_unlock(&ctx->ring_lock);
507 		return ERR_PTR(-EINVAL);
508 	}
509 
510 
511 	if (seq + amdgpu_sched_jobs < centity->sequence) {
512 		spin_unlock(&ctx->ring_lock);
513 		return NULL;
514 	}
515 
516 	fence = dma_fence_get(centity->fences[seq & (amdgpu_sched_jobs - 1)]);
517 	spin_unlock(&ctx->ring_lock);
518 
519 	return fence;
520 }
521 
522 static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx,
523 					    struct amdgpu_ctx_entity *aentity,
524 					    int hw_ip,
525 					    enum drm_sched_priority priority)
526 {
527 	struct amdgpu_device *adev = ctx->adev;
528 	enum gfx_pipe_priority hw_prio;
529 	struct drm_gpu_scheduler **scheds = NULL;
530 	unsigned num_scheds;
531 
532 	/* set sw priority */
533 	drm_sched_entity_set_priority(&aentity->entity, priority);
534 
535 	/* set hw priority */
536 	if (hw_ip == AMDGPU_HW_IP_COMPUTE) {
537 		hw_prio = amdgpu_ctx_sched_prio_to_compute_prio(priority);
538 		scheds = adev->gfx.compute_prio_sched[hw_prio];
539 		num_scheds = adev->gfx.num_compute_sched[hw_prio];
540 		drm_sched_entity_modify_sched(&aentity->entity, scheds,
541 					      num_scheds);
542 	}
543 }
544 
545 void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx,
546 				  enum drm_sched_priority priority)
547 {
548 	enum drm_sched_priority ctx_prio;
549 	unsigned i, j;
550 
551 	ctx->override_priority = priority;
552 
553 	ctx_prio = (ctx->override_priority == DRM_SCHED_PRIORITY_UNSET) ?
554 			ctx->init_priority : ctx->override_priority;
555 	for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
556 		for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
557 			if (!ctx->entities[i][j])
558 				continue;
559 
560 			amdgpu_ctx_set_entity_priority(ctx, ctx->entities[i][j],
561 						       i, ctx_prio);
562 		}
563 	}
564 }
565 
566 int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx,
567 			       struct drm_sched_entity *entity)
568 {
569 	struct amdgpu_ctx_entity *centity = to_amdgpu_ctx_entity(entity);
570 	struct dma_fence *other;
571 	unsigned idx;
572 	long r;
573 
574 	spin_lock(&ctx->ring_lock);
575 	idx = centity->sequence & (amdgpu_sched_jobs - 1);
576 	other = dma_fence_get(centity->fences[idx]);
577 	spin_unlock(&ctx->ring_lock);
578 
579 	if (!other)
580 		return 0;
581 
582 	r = dma_fence_wait(other, true);
583 	if (r < 0 && r != -ERESTARTSYS)
584 		DRM_ERROR("Error (%ld) waiting for fence!\n", r);
585 
586 	dma_fence_put(other);
587 	return r;
588 }
589 
590 void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr)
591 {
592 	mutex_init(&mgr->lock);
593 	idr_init(&mgr->ctx_handles);
594 }
595 
596 long amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr, long timeout)
597 {
598 	struct amdgpu_ctx *ctx;
599 	struct idr *idp;
600 	uint32_t id, i, j;
601 
602 	idp = &mgr->ctx_handles;
603 
604 	mutex_lock(&mgr->lock);
605 	idr_for_each_entry(idp, ctx, id) {
606 		for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
607 			for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
608 				struct drm_sched_entity *entity;
609 
610 				if (!ctx->entities[i][j])
611 					continue;
612 
613 				entity = &ctx->entities[i][j]->entity;
614 				timeout = drm_sched_entity_flush(entity, timeout);
615 			}
616 		}
617 	}
618 	mutex_unlock(&mgr->lock);
619 	return timeout;
620 }
621 
622 void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
623 {
624 	struct amdgpu_ctx *ctx;
625 	struct idr *idp;
626 	uint32_t id, i, j;
627 
628 	idp = &mgr->ctx_handles;
629 
630 	idr_for_each_entry(idp, ctx, id) {
631 		if (kref_read(&ctx->refcount) != 1) {
632 			DRM_ERROR("ctx %p is still alive\n", ctx);
633 			continue;
634 		}
635 
636 		for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
637 			for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
638 				struct drm_sched_entity *entity;
639 
640 				if (!ctx->entities[i][j])
641 					continue;
642 
643 				entity = &ctx->entities[i][j]->entity;
644 				drm_sched_entity_fini(entity);
645 			}
646 		}
647 	}
648 }
649 
650 void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr)
651 {
652 	struct amdgpu_ctx *ctx;
653 	struct idr *idp;
654 	uint32_t id;
655 
656 	amdgpu_ctx_mgr_entity_fini(mgr);
657 
658 	idp = &mgr->ctx_handles;
659 
660 	idr_for_each_entry(idp, ctx, id) {
661 		if (kref_put(&ctx->refcount, amdgpu_ctx_fini) != 1)
662 			DRM_ERROR("ctx %p is still alive\n", ctx);
663 	}
664 
665 	idr_destroy(&mgr->ctx_handles);
666 	mutex_destroy(&mgr->lock);
667 }
668 
669 
670 static void amdgpu_ctx_init_compute_sched(struct amdgpu_device *adev)
671 {
672 	int num_compute_sched_normal = 0;
673 	int num_compute_sched_high = AMDGPU_MAX_COMPUTE_RINGS - 1;
674 	int i;
675 
676 	/* use one drm sched array, gfx.compute_sched to store both high and
677 	 * normal priority drm compute schedulers */
678 	for (i = 0; i < adev->gfx.num_compute_rings; i++) {
679 		if (!adev->gfx.compute_ring[i].has_high_prio)
680 			adev->gfx.compute_sched[num_compute_sched_normal++] =
681 				&adev->gfx.compute_ring[i].sched;
682 		else
683 			adev->gfx.compute_sched[num_compute_sched_high--] =
684 				&adev->gfx.compute_ring[i].sched;
685 	}
686 
687 	/* compute ring only has two priority for now */
688 	i = AMDGPU_GFX_PIPE_PRIO_NORMAL;
689 	adev->gfx.compute_prio_sched[i] = &adev->gfx.compute_sched[0];
690 	adev->gfx.num_compute_sched[i] = num_compute_sched_normal;
691 
692 	i = AMDGPU_GFX_PIPE_PRIO_HIGH;
693 	if (num_compute_sched_high == (AMDGPU_MAX_COMPUTE_RINGS - 1)) {
694 		/* When compute has no high priority rings then use */
695 		/* normal priority sched array */
696 		adev->gfx.compute_prio_sched[i] = &adev->gfx.compute_sched[0];
697 		adev->gfx.num_compute_sched[i] = num_compute_sched_normal;
698 	} else {
699 		adev->gfx.compute_prio_sched[i] =
700 			&adev->gfx.compute_sched[num_compute_sched_high - 1];
701 		adev->gfx.num_compute_sched[i] =
702 			adev->gfx.num_compute_rings - num_compute_sched_normal;
703 	}
704 }
705 
706 void amdgpu_ctx_init_sched(struct amdgpu_device *adev)
707 {
708 	int i, j;
709 
710 	amdgpu_ctx_init_compute_sched(adev);
711 	for (i = 0; i < adev->gfx.num_gfx_rings; i++) {
712 		adev->gfx.gfx_sched[i] = &adev->gfx.gfx_ring[i].sched;
713 		adev->gfx.num_gfx_sched++;
714 	}
715 
716 	for (i = 0; i < adev->sdma.num_instances; i++) {
717 		adev->sdma.sdma_sched[i] = &adev->sdma.instance[i].ring.sched;
718 		adev->sdma.num_sdma_sched++;
719 	}
720 
721 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
722 		if (adev->vcn.harvest_config & (1 << i))
723 			continue;
724 		adev->vcn.vcn_dec_sched[adev->vcn.num_vcn_dec_sched++] =
725 			&adev->vcn.inst[i].ring_dec.sched;
726 	}
727 
728 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
729 		if (adev->vcn.harvest_config & (1 << i))
730 			continue;
731 		for (j = 0; j < adev->vcn.num_enc_rings; ++j)
732 			adev->vcn.vcn_enc_sched[adev->vcn.num_vcn_enc_sched++] =
733 				&adev->vcn.inst[i].ring_enc[j].sched;
734 	}
735 
736 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
737 		if (adev->jpeg.harvest_config & (1 << i))
738 			continue;
739 		adev->jpeg.jpeg_sched[adev->jpeg.num_jpeg_sched++] =
740 			&adev->jpeg.inst[i].ring_dec.sched;
741 	}
742 }
743