aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2016-09-16 09:36:49 -0400
committerAlex Deucher <alexander.deucher@amd.com>2016-10-25 14:38:25 -0400
commitf8991bab1aa2121e33b8569857dfb22e536bc396 (patch)
tree14fd7934fdda92dbe79006fb8e3fbae95504f712 /drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
parent42e8cb5001d317ebbfcd95af26f263af377ff3a5 (diff)
drm/amdgpu: update the shadow PD together with the real one v2
Far less CPU cycles needed for this approach. v2: fix typo Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c134
1 files changed, 69 insertions, 65 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index e2fefbbd3cc8..840ac52f45b6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -612,16 +612,26 @@ static uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr)
612 return result; 612 return result;
613} 613}
614 614
615static int amdgpu_vm_update_pd_or_shadow(struct amdgpu_device *adev, 615/*
616 struct amdgpu_vm *vm, 616 * amdgpu_vm_update_pdes - make sure that page directory is valid
617 bool shadow) 617 *
618 * @adev: amdgpu_device pointer
619 * @vm: requested vm
620 * @start: start of GPU address range
621 * @end: end of GPU address range
622 *
623 * Allocates new page tables if necessary
624 * and updates the page directory.
625 * Returns 0 for success, error for failure.
626 */
627int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
628 struct amdgpu_vm *vm)
618{ 629{
630 struct amdgpu_bo *shadow;
619 struct amdgpu_ring *ring; 631 struct amdgpu_ring *ring;
620 struct amdgpu_bo *pd = shadow ? vm->page_directory->shadow : 632 uint64_t pd_addr, shadow_addr;
621 vm->page_directory;
622 uint64_t pd_addr;
623 uint32_t incr = AMDGPU_VM_PTE_COUNT * 8; 633 uint32_t incr = AMDGPU_VM_PTE_COUNT * 8;
624 uint64_t last_pde = ~0, last_pt = ~0; 634 uint64_t last_pde = ~0, last_pt = ~0, last_shadow = ~0;
625 unsigned count = 0, pt_idx, ndw; 635 unsigned count = 0, pt_idx, ndw;
626 struct amdgpu_job *job; 636 struct amdgpu_job *job;
627 struct amdgpu_pte_update_params params; 637 struct amdgpu_pte_update_params params;
@@ -629,15 +639,8 @@ static int amdgpu_vm_update_pd_or_shadow(struct amdgpu_device *adev,
629 639
630 int r; 640 int r;
631 641
632 if (!pd)
633 return 0;
634
635 r = amdgpu_ttm_bind(&pd->tbo, &pd->tbo.mem);
636 if (r)
637 return r;
638
639 pd_addr = amdgpu_bo_gpu_offset(pd);
640 ring = container_of(vm->entity.sched, struct amdgpu_ring, sched); 642 ring = container_of(vm->entity.sched, struct amdgpu_ring, sched);
643 shadow = vm->page_directory->shadow;
641 644
642 /* padding, etc. */ 645 /* padding, etc. */
643 ndw = 64; 646 ndw = 64;
@@ -645,6 +648,17 @@ static int amdgpu_vm_update_pd_or_shadow(struct amdgpu_device *adev,
645 /* assume the worst case */ 648 /* assume the worst case */
646 ndw += vm->max_pde_used * 6; 649 ndw += vm->max_pde_used * 6;
647 650
651 pd_addr = amdgpu_bo_gpu_offset(vm->page_directory);
652 if (shadow) {
653 r = amdgpu_ttm_bind(&shadow->tbo, &shadow->tbo.mem);
654 if (r)
655 return r;
656 shadow_addr = amdgpu_bo_gpu_offset(shadow);
657 ndw *= 2;
658 } else {
659 shadow_addr = 0;
660 }
661
648 r = amdgpu_job_alloc_with_ib(adev, ndw * 4, &job); 662 r = amdgpu_job_alloc_with_ib(adev, ndw * 4, &job);
649 if (r) 663 if (r)
650 return r; 664 return r;
@@ -662,23 +676,19 @@ static int amdgpu_vm_update_pd_or_shadow(struct amdgpu_device *adev,
662 continue; 676 continue;
663 677
664 if (bo->shadow) { 678 if (bo->shadow) {
665 struct amdgpu_bo *shadow = bo->shadow; 679 struct amdgpu_bo *pt_shadow = bo->shadow;
666 680
667 r = amdgpu_ttm_bind(&shadow->tbo, &shadow->tbo.mem); 681 r = amdgpu_ttm_bind(&pt_shadow->tbo,
682 &pt_shadow->tbo.mem);
668 if (r) 683 if (r)
669 return r; 684 return r;
670 } 685 }
671 686
672 pt = amdgpu_bo_gpu_offset(bo); 687 pt = amdgpu_bo_gpu_offset(bo);
673 if (!shadow) { 688 if (vm->page_tables[pt_idx].addr == pt)
674 if (vm->page_tables[pt_idx].addr == pt) 689 continue;
675 continue; 690
676 vm->page_tables[pt_idx].addr = pt; 691 vm->page_tables[pt_idx].addr = pt;
677 } else {
678 if (vm->page_tables[pt_idx].shadow_addr == pt)
679 continue;
680 vm->page_tables[pt_idx].shadow_addr = pt;
681 }
682 692
683 pde = pd_addr + pt_idx * 8; 693 pde = pd_addr + pt_idx * 8;
684 if (((last_pde + 8 * count) != pde) || 694 if (((last_pde + 8 * count) != pde) ||
@@ -686,6 +696,13 @@ static int amdgpu_vm_update_pd_or_shadow(struct amdgpu_device *adev,
686 (count == AMDGPU_VM_MAX_UPDATE_SIZE)) { 696 (count == AMDGPU_VM_MAX_UPDATE_SIZE)) {
687 697
688 if (count) { 698 if (count) {
699 if (shadow)
700 amdgpu_vm_do_set_ptes(&params,
701 last_shadow,
702 last_pt, count,
703 incr,
704 AMDGPU_PTE_VALID);
705
689 amdgpu_vm_do_set_ptes(&params, last_pde, 706 amdgpu_vm_do_set_ptes(&params, last_pde,
690 last_pt, count, incr, 707 last_pt, count, incr,
691 AMDGPU_PTE_VALID); 708 AMDGPU_PTE_VALID);
@@ -693,34 +710,44 @@ static int amdgpu_vm_update_pd_or_shadow(struct amdgpu_device *adev,
693 710
694 count = 1; 711 count = 1;
695 last_pde = pde; 712 last_pde = pde;
713 last_shadow = shadow_addr + pt_idx * 8;
696 last_pt = pt; 714 last_pt = pt;
697 } else { 715 } else {
698 ++count; 716 ++count;
699 } 717 }
700 } 718 }
701 719
702 if (count) 720 if (count) {
721 if (vm->page_directory->shadow)
722 amdgpu_vm_do_set_ptes(&params, last_shadow, last_pt,
723 count, incr, AMDGPU_PTE_VALID);
724
703 amdgpu_vm_do_set_ptes(&params, last_pde, last_pt, 725 amdgpu_vm_do_set_ptes(&params, last_pde, last_pt,
704 count, incr, AMDGPU_PTE_VALID); 726 count, incr, AMDGPU_PTE_VALID);
727 }
728
729 if (params.ib->length_dw == 0) {
730 amdgpu_job_free(job);
731 return 0;
732 }
705 733
706 if (params.ib->length_dw != 0) { 734 amdgpu_ring_pad_ib(ring, params.ib);
707 amdgpu_ring_pad_ib(ring, params.ib); 735 amdgpu_sync_resv(adev, &job->sync, vm->page_directory->tbo.resv,
708 amdgpu_sync_resv(adev, &job->sync, pd->tbo.resv, 736 AMDGPU_FENCE_OWNER_VM);
737 if (shadow)
738 amdgpu_sync_resv(adev, &job->sync, shadow->tbo.resv,
709 AMDGPU_FENCE_OWNER_VM); 739 AMDGPU_FENCE_OWNER_VM);
710 WARN_ON(params.ib->length_dw > ndw);
711 r = amdgpu_job_submit(job, ring, &vm->entity,
712 AMDGPU_FENCE_OWNER_VM, &fence);
713 if (r)
714 goto error_free;
715 740
716 amdgpu_bo_fence(pd, fence, true); 741 WARN_ON(params.ib->length_dw > ndw);
717 fence_put(vm->page_directory_fence); 742 r = amdgpu_job_submit(job, ring, &vm->entity,
718 vm->page_directory_fence = fence_get(fence); 743 AMDGPU_FENCE_OWNER_VM, &fence);
719 fence_put(fence); 744 if (r)
745 goto error_free;
720 746
721 } else { 747 amdgpu_bo_fence(vm->page_directory, fence, true);
722 amdgpu_job_free(job); 748 fence_put(vm->page_directory_fence);
723 } 749 vm->page_directory_fence = fence_get(fence);
750 fence_put(fence);
724 751
725 return 0; 752 return 0;
726 753
@@ -729,29 +756,6 @@ error_free:
729 return r; 756 return r;
730} 757}
731 758
732/*
733 * amdgpu_vm_update_pdes - make sure that page directory is valid
734 *
735 * @adev: amdgpu_device pointer
736 * @vm: requested vm
737 * @start: start of GPU address range
738 * @end: end of GPU address range
739 *
740 * Allocates new page tables if necessary
741 * and updates the page directory.
742 * Returns 0 for success, error for failure.
743 */
744int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
745 struct amdgpu_vm *vm)
746{
747 int r;
748
749 r = amdgpu_vm_update_pd_or_shadow(adev, vm, true);
750 if (r)
751 return r;
752 return amdgpu_vm_update_pd_or_shadow(adev, vm, false);
753}
754
755/** 759/**
756 * amdgpu_vm_update_ptes - make sure that page tables are valid 760 * amdgpu_vm_update_ptes - make sure that page tables are valid
757 * 761 *