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