diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 422 |
1 files changed, 12 insertions, 410 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 398abbcbf029..01ee8e2258c8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -34,52 +34,6 @@ | |||
34 | #include "amdgpu_trace.h" | 34 | #include "amdgpu_trace.h" |
35 | 35 | ||
36 | /* | 36 | /* |
37 | * PASID manager | ||
38 | * | ||
39 | * PASIDs are global address space identifiers that can be shared | ||
40 | * between the GPU, an IOMMU and the driver. VMs on different devices | ||
41 | * may use the same PASID if they share the same address | ||
42 | * space. Therefore PASIDs are allocated using a global IDA. VMs are | ||
43 | * looked up from the PASID per amdgpu_device. | ||
44 | */ | ||
45 | static DEFINE_IDA(amdgpu_vm_pasid_ida); | ||
46 | |||
47 | /** | ||
48 | * amdgpu_vm_alloc_pasid - Allocate a PASID | ||
49 | * @bits: Maximum width of the PASID in bits, must be at least 1 | ||
50 | * | ||
51 | * Allocates a PASID of the given width while keeping smaller PASIDs | ||
52 | * available if possible. | ||
53 | * | ||
54 | * Returns a positive integer on success. Returns %-EINVAL if bits==0. | ||
55 | * Returns %-ENOSPC if no PASID was available. Returns %-ENOMEM on | ||
56 | * memory allocation failure. | ||
57 | */ | ||
58 | int amdgpu_vm_alloc_pasid(unsigned int bits) | ||
59 | { | ||
60 | int pasid = -EINVAL; | ||
61 | |||
62 | for (bits = min(bits, 31U); bits > 0; bits--) { | ||
63 | pasid = ida_simple_get(&amdgpu_vm_pasid_ida, | ||
64 | 1U << (bits - 1), 1U << bits, | ||
65 | GFP_KERNEL); | ||
66 | if (pasid != -ENOSPC) | ||
67 | break; | ||
68 | } | ||
69 | |||
70 | return pasid; | ||
71 | } | ||
72 | |||
73 | /** | ||
74 | * amdgpu_vm_free_pasid - Free a PASID | ||
75 | * @pasid: PASID to free | ||
76 | */ | ||
77 | void amdgpu_vm_free_pasid(unsigned int pasid) | ||
78 | { | ||
79 | ida_simple_remove(&amdgpu_vm_pasid_ida, pasid); | ||
80 | } | ||
81 | |||
82 | /* | ||
83 | * GPUVM | 37 | * GPUVM |
84 | * GPUVM is similar to the legacy gart on older asics, however | 38 | * GPUVM is similar to the legacy gart on older asics, however |
85 | * rather than there being a single global gart table | 39 | * rather than there being a single global gart table |
@@ -448,286 +402,6 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev, | |||
448 | } | 402 | } |
449 | 403 | ||
450 | /** | 404 | /** |
451 | * amdgpu_vm_had_gpu_reset - check if reset occured since last use | ||
452 | * | ||
453 | * @adev: amdgpu_device pointer | ||
454 | * @id: VMID structure | ||
455 | * | ||
456 | * Check if GPU reset occured since last use of the VMID. | ||
457 | */ | ||
458 | static bool amdgpu_vm_had_gpu_reset(struct amdgpu_device *adev, | ||
459 | struct amdgpu_vm_id *id) | ||
460 | { | ||
461 | return id->current_gpu_reset_count != | ||
462 | atomic_read(&adev->gpu_reset_counter); | ||
463 | } | ||
464 | |||
465 | static bool amdgpu_vm_reserved_vmid_ready(struct amdgpu_vm *vm, unsigned vmhub) | ||
466 | { | ||
467 | return !!vm->reserved_vmid[vmhub]; | ||
468 | } | ||
469 | |||
470 | /* idr_mgr->lock must be held */ | ||
471 | static int amdgpu_vm_grab_reserved_vmid_locked(struct amdgpu_vm *vm, | ||
472 | struct amdgpu_ring *ring, | ||
473 | struct amdgpu_sync *sync, | ||
474 | struct dma_fence *fence, | ||
475 | struct amdgpu_job *job) | ||
476 | { | ||
477 | struct amdgpu_device *adev = ring->adev; | ||
478 | unsigned vmhub = ring->funcs->vmhub; | ||
479 | uint64_t fence_context = adev->fence_context + ring->idx; | ||
480 | struct amdgpu_vm_id *id = vm->reserved_vmid[vmhub]; | ||
481 | struct amdgpu_vm_id_manager *id_mgr = &adev->vm_manager.id_mgr[vmhub]; | ||
482 | struct dma_fence *updates = sync->last_vm_update; | ||
483 | int r = 0; | ||
484 | struct dma_fence *flushed, *tmp; | ||
485 | bool needs_flush = vm->use_cpu_for_update; | ||
486 | |||
487 | flushed = id->flushed_updates; | ||
488 | if ((amdgpu_vm_had_gpu_reset(adev, id)) || | ||
489 | (atomic64_read(&id->owner) != vm->client_id) || | ||
490 | (job->vm_pd_addr != id->pd_gpu_addr) || | ||
491 | (updates && (!flushed || updates->context != flushed->context || | ||
492 | dma_fence_is_later(updates, flushed))) || | ||
493 | (!id->last_flush || (id->last_flush->context != fence_context && | ||
494 | !dma_fence_is_signaled(id->last_flush)))) { | ||
495 | needs_flush = true; | ||
496 | /* to prevent one context starved by another context */ | ||
497 | id->pd_gpu_addr = 0; | ||
498 | tmp = amdgpu_sync_peek_fence(&id->active, ring); | ||
499 | if (tmp) { | ||
500 | r = amdgpu_sync_fence(adev, sync, tmp, false); | ||
501 | return r; | ||
502 | } | ||
503 | } | ||
504 | |||
505 | /* Good we can use this VMID. Remember this submission as | ||
506 | * user of the VMID. | ||
507 | */ | ||
508 | r = amdgpu_sync_fence(ring->adev, &id->active, fence, false); | ||
509 | if (r) | ||
510 | goto out; | ||
511 | |||
512 | if (updates && (!flushed || updates->context != flushed->context || | ||
513 | dma_fence_is_later(updates, flushed))) { | ||
514 | dma_fence_put(id->flushed_updates); | ||
515 | id->flushed_updates = dma_fence_get(updates); | ||
516 | } | ||
517 | id->pd_gpu_addr = job->vm_pd_addr; | ||
518 | atomic64_set(&id->owner, vm->client_id); | ||
519 | job->vm_needs_flush = needs_flush; | ||
520 | if (needs_flush) { | ||
521 | dma_fence_put(id->last_flush); | ||
522 | id->last_flush = NULL; | ||
523 | } | ||
524 | job->vm_id = id - id_mgr->ids; | ||
525 | trace_amdgpu_vm_grab_id(vm, ring, job); | ||
526 | out: | ||
527 | return r; | ||
528 | } | ||
529 | |||
530 | /** | ||
531 | * amdgpu_vm_grab_id - allocate the next free VMID | ||
532 | * | ||
533 | * @vm: vm to allocate id for | ||
534 | * @ring: ring we want to submit job to | ||
535 | * @sync: sync object where we add dependencies | ||
536 | * @fence: fence protecting ID from reuse | ||
537 | * | ||
538 | * Allocate an id for the vm, adding fences to the sync obj as necessary. | ||
539 | */ | ||
540 | int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, | ||
541 | struct amdgpu_sync *sync, struct dma_fence *fence, | ||
542 | struct amdgpu_job *job) | ||
543 | { | ||
544 | struct amdgpu_device *adev = ring->adev; | ||
545 | unsigned vmhub = ring->funcs->vmhub; | ||
546 | struct amdgpu_vm_id_manager *id_mgr = &adev->vm_manager.id_mgr[vmhub]; | ||
547 | uint64_t fence_context = adev->fence_context + ring->idx; | ||
548 | struct dma_fence *updates = sync->last_vm_update; | ||
549 | struct amdgpu_vm_id *id, *idle; | ||
550 | struct dma_fence **fences; | ||
551 | unsigned i; | ||
552 | int r = 0; | ||
553 | |||
554 | mutex_lock(&id_mgr->lock); | ||
555 | if (amdgpu_vm_reserved_vmid_ready(vm, vmhub)) { | ||
556 | r = amdgpu_vm_grab_reserved_vmid_locked(vm, ring, sync, fence, job); | ||
557 | mutex_unlock(&id_mgr->lock); | ||
558 | return r; | ||
559 | } | ||
560 | fences = kmalloc_array(sizeof(void *), id_mgr->num_ids, GFP_KERNEL); | ||
561 | if (!fences) { | ||
562 | mutex_unlock(&id_mgr->lock); | ||
563 | return -ENOMEM; | ||
564 | } | ||
565 | /* Check if we have an idle VMID */ | ||
566 | i = 0; | ||
567 | list_for_each_entry(idle, &id_mgr->ids_lru, list) { | ||
568 | fences[i] = amdgpu_sync_peek_fence(&idle->active, ring); | ||
569 | if (!fences[i]) | ||
570 | break; | ||
571 | ++i; | ||
572 | } | ||
573 | |||
574 | /* If we can't find a idle VMID to use, wait till one becomes available */ | ||
575 | if (&idle->list == &id_mgr->ids_lru) { | ||
576 | u64 fence_context = adev->vm_manager.fence_context + ring->idx; | ||
577 | unsigned seqno = ++adev->vm_manager.seqno[ring->idx]; | ||
578 | struct dma_fence_array *array; | ||
579 | unsigned j; | ||
580 | |||
581 | for (j = 0; j < i; ++j) | ||
582 | dma_fence_get(fences[j]); | ||
583 | |||
584 | array = dma_fence_array_create(i, fences, fence_context, | ||
585 | seqno, true); | ||
586 | if (!array) { | ||
587 | for (j = 0; j < i; ++j) | ||
588 | dma_fence_put(fences[j]); | ||
589 | kfree(fences); | ||
590 | r = -ENOMEM; | ||
591 | goto error; | ||
592 | } | ||
593 | |||
594 | |||
595 | r = amdgpu_sync_fence(ring->adev, sync, &array->base, false); | ||
596 | dma_fence_put(&array->base); | ||
597 | if (r) | ||
598 | goto error; | ||
599 | |||
600 | mutex_unlock(&id_mgr->lock); | ||
601 | return 0; | ||
602 | |||
603 | } | ||
604 | kfree(fences); | ||
605 | |||
606 | job->vm_needs_flush = vm->use_cpu_for_update; | ||
607 | /* Check if we can use a VMID already assigned to this VM */ | ||
608 | list_for_each_entry_reverse(id, &id_mgr->ids_lru, list) { | ||
609 | struct dma_fence *flushed; | ||
610 | bool needs_flush = vm->use_cpu_for_update; | ||
611 | |||
612 | /* Check all the prerequisites to using this VMID */ | ||
613 | if (amdgpu_vm_had_gpu_reset(adev, id)) | ||
614 | continue; | ||
615 | |||
616 | if (atomic64_read(&id->owner) != vm->client_id) | ||
617 | continue; | ||
618 | |||
619 | if (job->vm_pd_addr != id->pd_gpu_addr) | ||
620 | continue; | ||
621 | |||
622 | if (!id->last_flush || | ||
623 | (id->last_flush->context != fence_context && | ||
624 | !dma_fence_is_signaled(id->last_flush))) | ||
625 | needs_flush = true; | ||
626 | |||
627 | flushed = id->flushed_updates; | ||
628 | if (updates && (!flushed || dma_fence_is_later(updates, flushed))) | ||
629 | needs_flush = true; | ||
630 | |||
631 | /* Concurrent flushes are only possible starting with Vega10 */ | ||
632 | if (adev->asic_type < CHIP_VEGA10 && needs_flush) | ||
633 | continue; | ||
634 | |||
635 | /* Good we can use this VMID. Remember this submission as | ||
636 | * user of the VMID. | ||
637 | */ | ||
638 | r = amdgpu_sync_fence(ring->adev, &id->active, fence, false); | ||
639 | if (r) | ||
640 | goto error; | ||
641 | |||
642 | if (updates && (!flushed || dma_fence_is_later(updates, flushed))) { | ||
643 | dma_fence_put(id->flushed_updates); | ||
644 | id->flushed_updates = dma_fence_get(updates); | ||
645 | } | ||
646 | |||
647 | if (needs_flush) | ||
648 | goto needs_flush; | ||
649 | else | ||
650 | goto no_flush_needed; | ||
651 | |||
652 | }; | ||
653 | |||
654 | /* Still no ID to use? Then use the idle one found earlier */ | ||
655 | id = idle; | ||
656 | |||
657 | /* Remember this submission as user of the VMID */ | ||
658 | r = amdgpu_sync_fence(ring->adev, &id->active, fence, false); | ||
659 | if (r) | ||
660 | goto error; | ||
661 | |||
662 | id->pd_gpu_addr = job->vm_pd_addr; | ||
663 | dma_fence_put(id->flushed_updates); | ||
664 | id->flushed_updates = dma_fence_get(updates); | ||
665 | atomic64_set(&id->owner, vm->client_id); | ||
666 | |||
667 | needs_flush: | ||
668 | job->vm_needs_flush = true; | ||
669 | dma_fence_put(id->last_flush); | ||
670 | id->last_flush = NULL; | ||
671 | |||
672 | no_flush_needed: | ||
673 | list_move_tail(&id->list, &id_mgr->ids_lru); | ||
674 | |||
675 | job->vm_id = id - id_mgr->ids; | ||
676 | trace_amdgpu_vm_grab_id(vm, ring, job); | ||
677 | |||
678 | error: | ||
679 | mutex_unlock(&id_mgr->lock); | ||
680 | return r; | ||
681 | } | ||
682 | |||
683 | static void amdgpu_vm_free_reserved_vmid(struct amdgpu_device *adev, | ||
684 | struct amdgpu_vm *vm, | ||
685 | unsigned vmhub) | ||
686 | { | ||
687 | struct amdgpu_vm_id_manager *id_mgr = &adev->vm_manager.id_mgr[vmhub]; | ||
688 | |||
689 | mutex_lock(&id_mgr->lock); | ||
690 | if (vm->reserved_vmid[vmhub]) { | ||
691 | list_add(&vm->reserved_vmid[vmhub]->list, | ||
692 | &id_mgr->ids_lru); | ||
693 | vm->reserved_vmid[vmhub] = NULL; | ||
694 | atomic_dec(&id_mgr->reserved_vmid_num); | ||
695 | } | ||
696 | mutex_unlock(&id_mgr->lock); | ||
697 | } | ||
698 | |||
699 | static int amdgpu_vm_alloc_reserved_vmid(struct amdgpu_device *adev, | ||
700 | struct amdgpu_vm *vm, | ||
701 | unsigned vmhub) | ||
702 | { | ||
703 | struct amdgpu_vm_id_manager *id_mgr; | ||
704 | struct amdgpu_vm_id *idle; | ||
705 | int r = 0; | ||
706 | |||
707 | id_mgr = &adev->vm_manager.id_mgr[vmhub]; | ||
708 | mutex_lock(&id_mgr->lock); | ||
709 | if (vm->reserved_vmid[vmhub]) | ||
710 | goto unlock; | ||
711 | if (atomic_inc_return(&id_mgr->reserved_vmid_num) > | ||
712 | AMDGPU_VM_MAX_RESERVED_VMID) { | ||
713 | DRM_ERROR("Over limitation of reserved vmid\n"); | ||
714 | atomic_dec(&id_mgr->reserved_vmid_num); | ||
715 | r = -EINVAL; | ||
716 | goto unlock; | ||
717 | } | ||
718 | /* Select the first entry VMID */ | ||
719 | idle = list_first_entry(&id_mgr->ids_lru, struct amdgpu_vm_id, list); | ||
720 | list_del_init(&idle->list); | ||
721 | vm->reserved_vmid[vmhub] = idle; | ||
722 | mutex_unlock(&id_mgr->lock); | ||
723 | |||
724 | return 0; | ||
725 | unlock: | ||
726 | mutex_unlock(&id_mgr->lock); | ||
727 | return r; | ||
728 | } | ||
729 | |||
730 | /** | ||
731 | * amdgpu_vm_check_compute_bug - check whether asic has compute vm bug | 405 | * amdgpu_vm_check_compute_bug - check whether asic has compute vm bug |
732 | * | 406 | * |
733 | * @adev: amdgpu_device pointer | 407 | * @adev: amdgpu_device pointer |
@@ -767,8 +441,8 @@ bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring, | |||
767 | { | 441 | { |
768 | struct amdgpu_device *adev = ring->adev; | 442 | struct amdgpu_device *adev = ring->adev; |
769 | unsigned vmhub = ring->funcs->vmhub; | 443 | unsigned vmhub = ring->funcs->vmhub; |
770 | struct amdgpu_vm_id_manager *id_mgr = &adev->vm_manager.id_mgr[vmhub]; | 444 | struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub]; |
771 | struct amdgpu_vm_id *id; | 445 | struct amdgpu_vmid *id; |
772 | bool gds_switch_needed; | 446 | bool gds_switch_needed; |
773 | bool vm_flush_needed = job->vm_needs_flush || ring->has_compute_vm_bug; | 447 | bool vm_flush_needed = job->vm_needs_flush || ring->has_compute_vm_bug; |
774 | 448 | ||
@@ -783,7 +457,7 @@ bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring, | |||
783 | id->oa_base != job->oa_base || | 457 | id->oa_base != job->oa_base || |
784 | id->oa_size != job->oa_size); | 458 | id->oa_size != job->oa_size); |
785 | 459 | ||
786 | if (amdgpu_vm_had_gpu_reset(adev, id)) | 460 | if (amdgpu_vmid_had_gpu_reset(adev, id)) |
787 | return true; | 461 | return true; |
788 | 462 | ||
789 | return vm_flush_needed || gds_switch_needed; | 463 | return vm_flush_needed || gds_switch_needed; |
@@ -807,8 +481,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_ | |||
807 | { | 481 | { |
808 | struct amdgpu_device *adev = ring->adev; | 482 | struct amdgpu_device *adev = ring->adev; |
809 | unsigned vmhub = ring->funcs->vmhub; | 483 | unsigned vmhub = ring->funcs->vmhub; |
810 | struct amdgpu_vm_id_manager *id_mgr = &adev->vm_manager.id_mgr[vmhub]; | 484 | struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub]; |
811 | struct amdgpu_vm_id *id = &id_mgr->ids[job->vm_id]; | 485 | struct amdgpu_vmid *id = &id_mgr->ids[job->vm_id]; |
812 | bool gds_switch_needed = ring->funcs->emit_gds_switch && ( | 486 | bool gds_switch_needed = ring->funcs->emit_gds_switch && ( |
813 | id->gds_base != job->gds_base || | 487 | id->gds_base != job->gds_base || |
814 | id->gds_size != job->gds_size || | 488 | id->gds_size != job->gds_size || |
@@ -820,7 +494,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_ | |||
820 | unsigned patch_offset = 0; | 494 | unsigned patch_offset = 0; |
821 | int r; | 495 | int r; |
822 | 496 | ||
823 | if (amdgpu_vm_had_gpu_reset(adev, id)) { | 497 | if (amdgpu_vmid_had_gpu_reset(adev, id)) { |
824 | gds_switch_needed = true; | 498 | gds_switch_needed = true; |
825 | vm_flush_needed = true; | 499 | vm_flush_needed = true; |
826 | } | 500 | } |
@@ -876,49 +550,6 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_ | |||
876 | } | 550 | } |
877 | 551 | ||
878 | /** | 552 | /** |
879 | * amdgpu_vm_reset_id - reset VMID to zero | ||
880 | * | ||
881 | * @adev: amdgpu device structure | ||
882 | * @vm_id: vmid number to use | ||
883 | * | ||
884 | * Reset saved GDW, GWS and OA to force switch on next flush. | ||
885 | */ | ||
886 | void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vmhub, | ||
887 | unsigned vmid) | ||
888 | { | ||
889 | struct amdgpu_vm_id_manager *id_mgr = &adev->vm_manager.id_mgr[vmhub]; | ||
890 | struct amdgpu_vm_id *id = &id_mgr->ids[vmid]; | ||
891 | |||
892 | atomic64_set(&id->owner, 0); | ||
893 | id->gds_base = 0; | ||
894 | id->gds_size = 0; | ||
895 | id->gws_base = 0; | ||
896 | id->gws_size = 0; | ||
897 | id->oa_base = 0; | ||
898 | id->oa_size = 0; | ||
899 | } | ||
900 | |||
901 | /** | ||
902 | * amdgpu_vm_reset_all_id - reset VMID to zero | ||
903 | * | ||
904 | * @adev: amdgpu device structure | ||
905 | * | ||
906 | * Reset VMID to force flush on next use | ||
907 | */ | ||
908 | void amdgpu_vm_reset_all_ids(struct amdgpu_device *adev) | ||
909 | { | ||
910 | unsigned i, j; | ||
911 | |||
912 | for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) { | ||
913 | struct amdgpu_vm_id_manager *id_mgr = | ||
914 | &adev->vm_manager.id_mgr[i]; | ||
915 | |||
916 | for (j = 1; j < id_mgr->num_ids; ++j) | ||
917 | amdgpu_vm_reset_id(adev, i, j); | ||
918 | } | ||
919 | } | ||
920 | |||
921 | /** | ||
922 | * amdgpu_vm_bo_find - find the bo_va for a specific vm & bo | 553 | * amdgpu_vm_bo_find - find the bo_va for a specific vm & bo |
923 | * | 554 | * |
924 | * @vm: requested vm | 555 | * @vm: requested vm |
@@ -2819,7 +2450,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
2819 | amdgpu_bo_unref(&root); | 2450 | amdgpu_bo_unref(&root); |
2820 | dma_fence_put(vm->last_update); | 2451 | dma_fence_put(vm->last_update); |
2821 | for (i = 0; i < AMDGPU_MAX_VMHUBS; i++) | 2452 | for (i = 0; i < AMDGPU_MAX_VMHUBS; i++) |
2822 | amdgpu_vm_free_reserved_vmid(adev, vm, i); | 2453 | amdgpu_vmid_free_reserved(adev, vm, i); |
2823 | } | 2454 | } |
2824 | 2455 | ||
2825 | /** | 2456 | /** |
@@ -2861,23 +2492,9 @@ bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev, | |||
2861 | */ | 2492 | */ |
2862 | void amdgpu_vm_manager_init(struct amdgpu_device *adev) | 2493 | void amdgpu_vm_manager_init(struct amdgpu_device *adev) |
2863 | { | 2494 | { |
2864 | unsigned i, j; | 2495 | unsigned i; |
2865 | |||
2866 | for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) { | ||
2867 | struct amdgpu_vm_id_manager *id_mgr = | ||
2868 | &adev->vm_manager.id_mgr[i]; | ||
2869 | 2496 | ||
2870 | mutex_init(&id_mgr->lock); | 2497 | amdgpu_vmid_mgr_init(adev); |
2871 | INIT_LIST_HEAD(&id_mgr->ids_lru); | ||
2872 | atomic_set(&id_mgr->reserved_vmid_num, 0); | ||
2873 | |||
2874 | /* skip over VMID 0, since it is the system VM */ | ||
2875 | for (j = 1; j < id_mgr->num_ids; ++j) { | ||
2876 | amdgpu_vm_reset_id(adev, i, j); | ||
2877 | amdgpu_sync_create(&id_mgr->ids[i].active); | ||
2878 | list_add_tail(&id_mgr->ids[j].list, &id_mgr->ids_lru); | ||
2879 | } | ||
2880 | } | ||
2881 | 2498 | ||
2882 | adev->vm_manager.fence_context = | 2499 | adev->vm_manager.fence_context = |
2883 | dma_fence_context_alloc(AMDGPU_MAX_RINGS); | 2500 | dma_fence_context_alloc(AMDGPU_MAX_RINGS); |
@@ -2918,24 +2535,10 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev) | |||
2918 | */ | 2535 | */ |
2919 | void amdgpu_vm_manager_fini(struct amdgpu_device *adev) | 2536 | void amdgpu_vm_manager_fini(struct amdgpu_device *adev) |
2920 | { | 2537 | { |
2921 | unsigned i, j; | ||
2922 | |||
2923 | WARN_ON(!idr_is_empty(&adev->vm_manager.pasid_idr)); | 2538 | WARN_ON(!idr_is_empty(&adev->vm_manager.pasid_idr)); |
2924 | idr_destroy(&adev->vm_manager.pasid_idr); | 2539 | idr_destroy(&adev->vm_manager.pasid_idr); |
2925 | 2540 | ||
2926 | for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) { | 2541 | amdgpu_vmid_mgr_fini(adev); |
2927 | struct amdgpu_vm_id_manager *id_mgr = | ||
2928 | &adev->vm_manager.id_mgr[i]; | ||
2929 | |||
2930 | mutex_destroy(&id_mgr->lock); | ||
2931 | for (j = 0; j < AMDGPU_NUM_VM; ++j) { | ||
2932 | struct amdgpu_vm_id *id = &id_mgr->ids[j]; | ||
2933 | |||
2934 | amdgpu_sync_free(&id->active); | ||
2935 | dma_fence_put(id->flushed_updates); | ||
2936 | dma_fence_put(id->last_flush); | ||
2937 | } | ||
2938 | } | ||
2939 | } | 2542 | } |
2940 | 2543 | ||
2941 | int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | 2544 | int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) |
@@ -2948,13 +2551,12 @@ int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
2948 | switch (args->in.op) { | 2551 | switch (args->in.op) { |
2949 | case AMDGPU_VM_OP_RESERVE_VMID: | 2552 | case AMDGPU_VM_OP_RESERVE_VMID: |
2950 | /* current, we only have requirement to reserve vmid from gfxhub */ | 2553 | /* current, we only have requirement to reserve vmid from gfxhub */ |
2951 | r = amdgpu_vm_alloc_reserved_vmid(adev, &fpriv->vm, | 2554 | r = amdgpu_vmid_alloc_reserved(adev, &fpriv->vm, AMDGPU_GFXHUB); |
2952 | AMDGPU_GFXHUB); | ||
2953 | if (r) | 2555 | if (r) |
2954 | return r; | 2556 | return r; |
2955 | break; | 2557 | break; |
2956 | case AMDGPU_VM_OP_UNRESERVE_VMID: | 2558 | case AMDGPU_VM_OP_UNRESERVE_VMID: |
2957 | amdgpu_vm_free_reserved_vmid(adev, &fpriv->vm, AMDGPU_GFXHUB); | 2559 | amdgpu_vmid_free_reserved(adev, &fpriv->vm, AMDGPU_GFXHUB); |
2958 | break; | 2560 | break; |
2959 | default: | 2561 | default: |
2960 | return -EINVAL; | 2562 | return -EINVAL; |