diff options
author | Christian König <christian.koenig@amd.com> | 2017-12-21 09:47:28 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2018-01-10 15:44:53 -0500 |
commit | 3cc1d3ea4a6a81a7108fe27fa42efd86ea64061d (patch) | |
tree | a01d9c0a5dbef816edddfaab3d041b1b225041f8 /drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |
parent | 0abc6878fc2d6990d8b0851b55d3c77ecfdd74e6 (diff) |
drm/amdgpu: simplify huge page handling
Update the PDEs after resetting the huge flag.
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
Acked-by: Felix Kuehling <Felix.Kuehling@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.c | 60 |
1 files changed, 18 insertions, 42 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index c1c5ccdee783..81505870eebc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -946,54 +946,38 @@ static void amdgpu_vm_handle_huge_pages(struct amdgpu_pte_update_params *p, | |||
946 | unsigned nptes, uint64_t dst, | 946 | unsigned nptes, uint64_t dst, |
947 | uint64_t flags) | 947 | uint64_t flags) |
948 | { | 948 | { |
949 | bool use_cpu_update = (p->func == amdgpu_vm_cpu_set_ptes); | ||
950 | uint64_t pd_addr, pde; | 949 | uint64_t pd_addr, pde; |
951 | 950 | ||
952 | /* In the case of a mixed PT the PDE must point to it*/ | 951 | /* In the case of a mixed PT the PDE must point to it*/ |
953 | if (p->adev->asic_type < CHIP_VEGA10 || p->src || | 952 | if (p->adev->asic_type >= CHIP_VEGA10 && !p->src && |
954 | nptes != AMDGPU_VM_PTE_COUNT(p->adev)) { | 953 | nptes == AMDGPU_VM_PTE_COUNT(p->adev)) { |
955 | dst = amdgpu_bo_gpu_offset(entry->base.bo); | ||
956 | flags = AMDGPU_PTE_VALID; | ||
957 | } else { | ||
958 | /* Set the huge page flag to stop scanning at this PDE */ | 954 | /* Set the huge page flag to stop scanning at this PDE */ |
959 | flags |= AMDGPU_PDE_PTE; | 955 | flags |= AMDGPU_PDE_PTE; |
960 | } | 956 | } |
961 | 957 | ||
962 | if (!entry->huge && !(flags & AMDGPU_PDE_PTE)) | 958 | if (!(flags & AMDGPU_PDE_PTE)) { |
959 | if (entry->huge) { | ||
960 | /* Add the entry to the relocated list to update it. */ | ||
961 | entry->huge = false; | ||
962 | spin_lock(&p->vm->status_lock); | ||
963 | list_move(&entry->base.vm_status, &p->vm->relocated); | ||
964 | spin_unlock(&p->vm->status_lock); | ||
965 | } | ||
963 | return; | 966 | return; |
964 | entry->huge = !!(flags & AMDGPU_PDE_PTE); | 967 | } |
965 | 968 | ||
969 | entry->huge = true; | ||
966 | amdgpu_gart_get_vm_pde(p->adev, AMDGPU_VM_PDB0, | 970 | amdgpu_gart_get_vm_pde(p->adev, AMDGPU_VM_PDB0, |
967 | &dst, &flags); | 971 | &dst, &flags); |
968 | 972 | ||
969 | if (use_cpu_update) { | 973 | if (parent->base.bo->shadow) { |
970 | /* In case a huge page is replaced with a system | 974 | pd_addr = amdgpu_bo_gpu_offset(parent->base.bo->shadow); |
971 | * memory mapping, p->pages_addr != NULL and | ||
972 | * amdgpu_vm_cpu_set_ptes would try to translate dst | ||
973 | * through amdgpu_vm_map_gart. But dst is already a | ||
974 | * GPU address (of the page table). Disable | ||
975 | * amdgpu_vm_map_gart temporarily. | ||
976 | */ | ||
977 | dma_addr_t *tmp; | ||
978 | |||
979 | tmp = p->pages_addr; | ||
980 | p->pages_addr = NULL; | ||
981 | |||
982 | pd_addr = (unsigned long)amdgpu_bo_kptr(parent->base.bo); | ||
983 | pde = pd_addr + (entry - parent->entries) * 8; | ||
984 | amdgpu_vm_cpu_set_ptes(p, pde, dst, 1, 0, flags); | ||
985 | |||
986 | p->pages_addr = tmp; | ||
987 | } else { | ||
988 | if (parent->base.bo->shadow) { | ||
989 | pd_addr = amdgpu_bo_gpu_offset(parent->base.bo->shadow); | ||
990 | pde = pd_addr + (entry - parent->entries) * 8; | ||
991 | amdgpu_vm_do_set_ptes(p, pde, dst, 1, 0, flags); | ||
992 | } | ||
993 | pd_addr = amdgpu_bo_gpu_offset(parent->base.bo); | ||
994 | pde = pd_addr + (entry - parent->entries) * 8; | 975 | pde = pd_addr + (entry - parent->entries) * 8; |
995 | amdgpu_vm_do_set_ptes(p, pde, dst, 1, 0, flags); | 976 | p->func(p, pde, dst, 1, 0, flags); |
996 | } | 977 | } |
978 | pd_addr = amdgpu_bo_gpu_offset(parent->base.bo); | ||
979 | pde = pd_addr + (entry - parent->entries) * 8; | ||
980 | p->func(p, pde, dst, 1, 0, flags); | ||
997 | } | 981 | } |
998 | 982 | ||
999 | /** | 983 | /** |
@@ -1205,12 +1189,6 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
1205 | /* padding, etc. */ | 1189 | /* padding, etc. */ |
1206 | ndw = 64; | 1190 | ndw = 64; |
1207 | 1191 | ||
1208 | /* one PDE write for each huge page */ | ||
1209 | if (vm->root.base.bo->shadow) | ||
1210 | ndw += ((nptes >> adev->vm_manager.block_size) + 1) * 6 * 2; | ||
1211 | else | ||
1212 | ndw += ((nptes >> adev->vm_manager.block_size) + 1) * 6; | ||
1213 | |||
1214 | if (pages_addr) { | 1192 | if (pages_addr) { |
1215 | /* copy commands needed */ | 1193 | /* copy commands needed */ |
1216 | ndw += ncmds * adev->vm_manager.vm_pte_funcs->copy_pte_num_dw; | 1194 | ndw += ncmds * adev->vm_manager.vm_pte_funcs->copy_pte_num_dw; |
@@ -1285,8 +1263,6 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
1285 | 1263 | ||
1286 | error_free: | 1264 | error_free: |
1287 | amdgpu_job_free(job); | 1265 | amdgpu_job_free(job); |
1288 | amdgpu_vm_invalidate_level(adev, vm, &vm->root, | ||
1289 | adev->vm_manager.root_level); | ||
1290 | return r; | 1266 | return r; |
1291 | } | 1267 | } |
1292 | 1268 | ||