aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2018-08-16 04:49:41 -0400
committerAlex Deucher <alexander.deucher@amd.com>2019-03-19 16:36:48 -0400
commit780637cbdf8fd614cc85a01c6c810d9d28902a59 (patch)
tree5f077babe5ee86ea1f6a0ec4aaedf340becd3ea7 /drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
parent83cd83972260de1197a80724038c8a14ee7a38f0 (diff)
drm/amdgpu: let amdgpu_vm_clear_bo figure out ats status v2
Instead of providing it from outside figure out the ats status in the function itself from the data structures. v2: simplify finding the right level v3: partially revert changes from v2, more cleanup and split code into more functions. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com> Acked-by: Huang Rui <ray.huang@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.c72
1 files changed, 47 insertions, 25 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index d9a0ac14c4ca..90c6970e080f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -183,6 +183,22 @@ static unsigned amdgpu_vm_num_entries(struct amdgpu_device *adev,
183} 183}
184 184
185/** 185/**
186 * amdgpu_vm_num_ats_entries - return the number of ATS entries in the root PD
187 *
188 * @adev: amdgpu_device pointer
189 *
190 * Returns:
191 * The number of entries in the root page directory which needs the ATS setting.
192 */
193static unsigned amdgpu_vm_num_ats_entries(struct amdgpu_device *adev)
194{
195 unsigned shift;
196
197 shift = amdgpu_vm_level_shift(adev, adev->vm_manager.root_level);
198 return AMDGPU_GMC_HOLE_START >> (shift + AMDGPU_GPU_PAGE_SHIFT);
199}
200
201/**
186 * amdgpu_vm_entries_mask - the mask to get the entry number of a PD/PT 202 * amdgpu_vm_entries_mask - the mask to get the entry number of a PD/PT
187 * 203 *
188 * @adev: amdgpu_device pointer 204 * @adev: amdgpu_device pointer
@@ -747,8 +763,6 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vm)
747 * @adev: amdgpu_device pointer 763 * @adev: amdgpu_device pointer
748 * @vm: VM to clear BO from 764 * @vm: VM to clear BO from
749 * @bo: BO to clear 765 * @bo: BO to clear
750 * @level: level this BO is at
751 * @pte_support_ats: indicate ATS support from PTE
752 * 766 *
753 * Root PD needs to be reserved when calling this. 767 * Root PD needs to be reserved when calling this.
754 * 768 *
@@ -756,10 +770,12 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vm)
756 * 0 on success, errno otherwise. 770 * 0 on success, errno otherwise.
757 */ 771 */
758static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, 772static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
759 struct amdgpu_vm *vm, struct amdgpu_bo *bo, 773 struct amdgpu_vm *vm,
760 unsigned level, bool pte_support_ats) 774 struct amdgpu_bo *bo)
761{ 775{
762 struct ttm_operation_ctx ctx = { true, false }; 776 struct ttm_operation_ctx ctx = { true, false };
777 unsigned level = adev->vm_manager.root_level;
778 struct amdgpu_bo *ancestor = bo;
763 struct dma_fence *fence = NULL; 779 struct dma_fence *fence = NULL;
764 unsigned entries, ats_entries; 780 unsigned entries, ats_entries;
765 struct amdgpu_ring *ring; 781 struct amdgpu_ring *ring;
@@ -767,21 +783,35 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
767 uint64_t addr; 783 uint64_t addr;
768 int r; 784 int r;
769 785
786 /* Figure out our place in the hierarchy */
787 if (ancestor->parent) {
788 ++level;
789 while (ancestor->parent->parent) {
790 ++level;
791 ancestor = ancestor->parent;
792 }
793 }
794
770 entries = amdgpu_bo_size(bo) / 8; 795 entries = amdgpu_bo_size(bo) / 8;
796 if (!vm->pte_support_ats) {
797 ats_entries = 0;
798
799 } else if (!bo->parent) {
800 ats_entries = amdgpu_vm_num_ats_entries(adev);
801 ats_entries = min(ats_entries, entries);
802 entries -= ats_entries;
771 803
772 if (pte_support_ats) { 804 } else {
773 if (level == adev->vm_manager.root_level) { 805 struct amdgpu_vm_pt *pt;
774 ats_entries = amdgpu_vm_level_shift(adev, level); 806
775 ats_entries += AMDGPU_GPU_PAGE_SHIFT; 807 pt = container_of(ancestor->vm_bo, struct amdgpu_vm_pt, base);
776 ats_entries = AMDGPU_GMC_HOLE_START >> ats_entries; 808 ats_entries = amdgpu_vm_num_ats_entries(adev);
777 ats_entries = min(ats_entries, entries); 809 if ((pt - vm->root.entries) >= ats_entries) {
778 entries -= ats_entries; 810 ats_entries = 0;
779 } else { 811 } else {
780 ats_entries = entries; 812 ats_entries = entries;
781 entries = 0; 813 entries = 0;
782 } 814 }
783 } else {
784 ats_entries = 0;
785 } 815 }
786 816
787 ring = container_of(vm->entity.rq->sched, struct amdgpu_ring, sched); 817 ring = container_of(vm->entity.rq->sched, struct amdgpu_ring, sched);
@@ -908,7 +938,6 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
908{ 938{
909 struct amdgpu_vm_pt_cursor cursor; 939 struct amdgpu_vm_pt_cursor cursor;
910 struct amdgpu_bo *pt; 940 struct amdgpu_bo *pt;
911 bool ats = false;
912 uint64_t eaddr; 941 uint64_t eaddr;
913 int r; 942 int r;
914 943
@@ -918,9 +947,6 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
918 947
919 eaddr = saddr + size - 1; 948 eaddr = saddr + size - 1;
920 949
921 if (vm->pte_support_ats)
922 ats = saddr < AMDGPU_GMC_HOLE_START;
923
924 saddr /= AMDGPU_GPU_PAGE_SIZE; 950 saddr /= AMDGPU_GPU_PAGE_SIZE;
925 eaddr /= AMDGPU_GPU_PAGE_SIZE; 951 eaddr /= AMDGPU_GPU_PAGE_SIZE;
926 952
@@ -969,7 +995,7 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
969 995
970 amdgpu_vm_bo_base_init(&entry->base, vm, pt); 996 amdgpu_vm_bo_base_init(&entry->base, vm, pt);
971 997
972 r = amdgpu_vm_clear_bo(adev, vm, pt, cursor.level, ats); 998 r = amdgpu_vm_clear_bo(adev, vm, pt);
973 if (r) 999 if (r)
974 goto error_free_pt; 1000 goto error_free_pt;
975 } 1001 }
@@ -3044,9 +3070,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
3044 3070
3045 amdgpu_vm_bo_base_init(&vm->root.base, vm, root); 3071 amdgpu_vm_bo_base_init(&vm->root.base, vm, root);
3046 3072
3047 r = amdgpu_vm_clear_bo(adev, vm, root, 3073 r = amdgpu_vm_clear_bo(adev, vm, root);
3048 adev->vm_manager.root_level,
3049 vm->pte_support_ats);
3050 if (r) 3074 if (r)
3051 goto error_unreserve; 3075 goto error_unreserve;
3052 3076
@@ -3141,9 +3165,8 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, uns
3141 * changing any other state, in case it fails. 3165 * changing any other state, in case it fails.
3142 */ 3166 */
3143 if (pte_support_ats != vm->pte_support_ats) { 3167 if (pte_support_ats != vm->pte_support_ats) {
3144 r = amdgpu_vm_clear_bo(adev, vm, vm->root.base.bo, 3168 vm->pte_support_ats = pte_support_ats;
3145 adev->vm_manager.root_level, 3169 r = amdgpu_vm_clear_bo(adev, vm, vm->root.base.bo);
3146 pte_support_ats);
3147 if (r) 3170 if (r)
3148 goto free_idr; 3171 goto free_idr;
3149 } 3172 }
@@ -3151,7 +3174,6 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, uns
3151 /* Update VM state */ 3174 /* Update VM state */
3152 vm->use_cpu_for_update = !!(adev->vm_manager.vm_update_mode & 3175 vm->use_cpu_for_update = !!(adev->vm_manager.vm_update_mode &
3153 AMDGPU_VM_USE_CPU_FOR_COMPUTE); 3176 AMDGPU_VM_USE_CPU_FOR_COMPUTE);
3154 vm->pte_support_ats = pte_support_ats;
3155 DRM_DEBUG_DRIVER("VM update mode is %s\n", 3177 DRM_DEBUG_DRIVER("VM update mode is %s\n",
3156 vm->use_cpu_for_update ? "CPU" : "SDMA"); 3178 vm->use_cpu_for_update ? "CPU" : "SDMA");
3157 WARN_ONCE((vm->use_cpu_for_update && !amdgpu_gmc_vram_full_visible(&adev->gmc)), 3179 WARN_ONCE((vm->use_cpu_for_update && !amdgpu_gmc_vram_full_visible(&adev->gmc)),