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