Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: Enable seq64 manager and fix bugs

- Enable the seq64 mapping sequence.
- Fix wflinfo va conflict and other bugs.

v1:
- The seq64 area needs to be included in the AMDGPU_VA_RESERVED_SIZE
otherwise the areas will conflict with user space allocations (Alex)

- It needs to be mapped read only in the user VM (Alex)

v2:
- Instead of just one define for TOP/BOTTOM
reserved space separate them into two (Christian)

- Fix the CPU and VA calculations and while at it
also cleanup error handling and kerneldoc (Christian)

Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>

authored by

Arunpravin Paneer Selvam and committed by
Alex Deucher
00a11f97 059e7c6b

+68 -52
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
··· 30 30 { 31 31 uint64_t addr = adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT; 32 32 33 - addr -= AMDGPU_VA_RESERVED_SIZE; 33 + addr -= AMDGPU_VA_RESERVED_CSA_SIZE; 34 34 addr = amdgpu_gmc_sign_extend(addr); 35 35 36 36 return addr;
+3 -3
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
··· 709 709 uint64_t vm_size; 710 710 int r = 0; 711 711 712 - if (args->va_address < AMDGPU_VA_RESERVED_SIZE) { 712 + if (args->va_address < AMDGPU_VA_RESERVED_BOTTOM) { 713 713 dev_dbg(dev->dev, 714 714 "va_address 0x%llx is in reserved area 0x%llx\n", 715 - args->va_address, AMDGPU_VA_RESERVED_SIZE); 715 + args->va_address, AMDGPU_VA_RESERVED_BOTTOM); 716 716 return -EINVAL; 717 717 } 718 718 ··· 728 728 args->va_address &= AMDGPU_GMC_HOLE_MASK; 729 729 730 730 vm_size = adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE; 731 - vm_size -= AMDGPU_VA_RESERVED_SIZE; 731 + vm_size -= AMDGPU_VA_RESERVED_TOP; 732 732 if (args->va_address + args->map_size > vm_size) { 733 733 dev_dbg(dev->dev, 734 734 "va_address 0x%llx is in top reserved area 0x%llx\n",
+6 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
··· 894 894 dev_info->ids_flags |= AMDGPU_IDS_FLAGS_CONFORMANT_TRUNC_COORD; 895 895 896 896 vm_size = adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE; 897 - vm_size -= AMDGPU_VA_RESERVED_SIZE; 897 + vm_size -= AMDGPU_VA_RESERVED_TOP; 898 898 899 899 /* Older VCE FW versions are buggy and can handle only 40bits */ 900 900 if (adev->vce.fw_version && 901 901 adev->vce.fw_version < AMDGPU_VCE_FW_53_45) 902 902 vm_size = min(vm_size, 1ULL << 40); 903 903 904 - dev_info->virtual_address_offset = AMDGPU_VA_RESERVED_SIZE; 904 + dev_info->virtual_address_offset = AMDGPU_VA_RESERVED_BOTTOM; 905 905 dev_info->virtual_address_max = 906 906 min(vm_size, AMDGPU_GMC_HOLE_START); 907 907 ··· 1378 1378 if (r) 1379 1379 goto error_vm; 1380 1380 } 1381 + 1382 + r = amdgpu_seq64_map(adev, &fpriv->vm, &fpriv->seq64_va); 1383 + if (r) 1384 + goto error_vm; 1381 1385 1382 1386 mutex_init(&fpriv->bo_list_lock); 1383 1387 idr_init_base(&fpriv->bo_list_handles, 1);
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
··· 1398 1398 goto error_fini; 1399 1399 } 1400 1400 1401 - ctx_data.meta_data_gpu_addr = AMDGPU_VA_RESERVED_SIZE; 1401 + ctx_data.meta_data_gpu_addr = AMDGPU_VA_RESERVED_BOTTOM; 1402 1402 r = amdgpu_mes_ctx_map_meta_data(adev, vm, &ctx_data); 1403 1403 if (r) { 1404 1404 DRM_ERROR("failed to map ctx meta data\n");
+38 -32
drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c
··· 36 36 */ 37 37 38 38 /** 39 + * amdgpu_seq64_get_va_base - Get the seq64 va base address 40 + * 41 + * @adev: amdgpu_device pointer 42 + * 43 + * Returns: 44 + * va base address on success 45 + */ 46 + static inline u64 amdgpu_seq64_get_va_base(struct amdgpu_device *adev) 47 + { 48 + u64 addr = adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT; 49 + 50 + addr -= AMDGPU_VA_RESERVED_TOP; 51 + 52 + return addr; 53 + } 54 + 55 + /** 39 56 * amdgpu_seq64_map - Map the seq64 memory to VM 40 57 * 41 58 * @adev: amdgpu_device pointer 42 59 * @vm: vm pointer 43 60 * @bo_va: bo_va pointer 44 - * @seq64_addr: seq64 vaddr start address 45 - * @size: seq64 pool size 46 61 * 47 62 * Map the seq64 memory to the given VM. 48 63 * ··· 65 50 * 0 on success or a negative error code on failure 66 51 */ 67 52 int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm, 68 - struct amdgpu_bo_va **bo_va, u64 seq64_addr, 69 - uint32_t size) 53 + struct amdgpu_bo_va **bo_va) 70 54 { 71 55 struct amdgpu_bo *bo; 72 56 struct drm_exec exec; 57 + u64 seq64_addr; 73 58 int r; 74 59 75 60 bo = adev->seq64.sbo; ··· 92 77 goto error; 93 78 } 94 79 95 - r = amdgpu_vm_bo_map(adev, *bo_va, seq64_addr, 0, size, 96 - AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE | 97 - AMDGPU_PTE_EXECUTABLE); 80 + seq64_addr = amdgpu_seq64_get_va_base(adev); 81 + r = amdgpu_vm_bo_map(adev, *bo_va, seq64_addr, 0, AMDGPU_VA_RESERVED_SEQ64_SIZE, 82 + AMDGPU_PTE_READABLE); 98 83 if (r) { 99 84 DRM_ERROR("failed to do bo_map on userq sem, err=%d\n", r); 100 85 amdgpu_vm_bo_del(adev, *bo_va); ··· 159 144 * amdgpu_seq64_alloc - Allocate a 64 bit memory 160 145 * 161 146 * @adev: amdgpu_device pointer 162 - * @gpu_addr: allocated gpu VA start address 163 - * @cpu_addr: allocated cpu VA start address 147 + * @va: VA to access the seq in process address space 148 + * @cpu_addr: CPU address to access the seq 164 149 * 165 150 * Alloc a 64 bit memory from seq64 pool. 166 151 * 167 152 * Returns: 168 153 * 0 on success or a negative error code on failure 169 154 */ 170 - int amdgpu_seq64_alloc(struct amdgpu_device *adev, u64 *gpu_addr, 171 - u64 **cpu_addr) 155 + int amdgpu_seq64_alloc(struct amdgpu_device *adev, u64 *va, u64 **cpu_addr) 172 156 { 173 157 unsigned long bit_pos; 174 - u32 offset; 175 158 176 159 bit_pos = find_first_zero_bit(adev->seq64.used, adev->seq64.num_sem); 160 + if (bit_pos >= adev->seq64.num_sem) 161 + return -ENOSPC; 177 162 178 - if (bit_pos < adev->seq64.num_sem) { 179 - __set_bit(bit_pos, adev->seq64.used); 180 - offset = bit_pos << 6; /* convert to qw offset */ 181 - } else { 182 - return -EINVAL; 183 - } 184 - 185 - *gpu_addr = offset + AMDGPU_SEQ64_VADDR_START; 186 - *cpu_addr = offset + adev->seq64.cpu_base_addr; 163 + __set_bit(bit_pos, adev->seq64.used); 164 + *va = bit_pos * sizeof(u64) + amdgpu_seq64_get_va_base(adev); 165 + *cpu_addr = bit_pos + adev->seq64.cpu_base_addr; 187 166 188 167 return 0; 189 168 } ··· 186 177 * amdgpu_seq64_free - Free the given 64 bit memory 187 178 * 188 179 * @adev: amdgpu_device pointer 189 - * @gpu_addr: gpu start address to be freed 180 + * @va: gpu start address to be freed 190 181 * 191 182 * Free the given 64 bit memory from seq64 pool. 192 - * 193 183 */ 194 - void amdgpu_seq64_free(struct amdgpu_device *adev, u64 gpu_addr) 184 + void amdgpu_seq64_free(struct amdgpu_device *adev, u64 va) 195 185 { 196 - u32 offset; 186 + unsigned long bit_pos; 197 187 198 - offset = gpu_addr - AMDGPU_SEQ64_VADDR_START; 199 - 200 - offset >>= 6; 201 - if (offset < adev->seq64.num_sem) 202 - __clear_bit(offset, adev->seq64.used); 188 + bit_pos = (va - amdgpu_seq64_get_va_base(adev)) / sizeof(u64); 189 + if (bit_pos < adev->seq64.num_sem) 190 + __clear_bit(bit_pos, adev->seq64.used); 203 191 } 204 192 205 193 /** ··· 235 229 * AMDGPU_MAX_SEQ64_SLOTS * sizeof(u64) * 8 = AMDGPU_MAX_SEQ64_SLOTS 236 230 * 64bit slots 237 231 */ 238 - r = amdgpu_bo_create_kernel(adev, AMDGPU_SEQ64_SIZE, 232 + r = amdgpu_bo_create_kernel(adev, AMDGPU_VA_RESERVED_SEQ64_SIZE, 239 233 PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT, 240 234 &adev->seq64.sbo, NULL, 241 235 (void **)&adev->seq64.cpu_base_addr); ··· 244 238 return r; 245 239 } 246 240 247 - memset(adev->seq64.cpu_base_addr, 0, AMDGPU_SEQ64_SIZE); 241 + memset(adev->seq64.cpu_base_addr, 0, AMDGPU_VA_RESERVED_SEQ64_SIZE); 248 242 249 243 adev->seq64.num_sem = AMDGPU_MAX_SEQ64_SLOTS; 250 244 memset(&adev->seq64.used, 0, sizeof(adev->seq64.used));
+4 -5
drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.h
··· 25 25 #ifndef __AMDGPU_SEQ64_H__ 26 26 #define __AMDGPU_SEQ64_H__ 27 27 28 - #define AMDGPU_SEQ64_SIZE (2ULL << 20) 29 - #define AMDGPU_MAX_SEQ64_SLOTS (AMDGPU_SEQ64_SIZE / (sizeof(u64) * 8)) 30 - #define AMDGPU_SEQ64_VADDR_OFFSET 0x50000 31 - #define AMDGPU_SEQ64_VADDR_START (AMDGPU_VA_RESERVED_SIZE + AMDGPU_SEQ64_VADDR_OFFSET) 28 + #include "amdgpu_vm.h" 29 + 30 + #define AMDGPU_MAX_SEQ64_SLOTS (AMDGPU_VA_RESERVED_SEQ64_SIZE / sizeof(u64)) 32 31 33 32 struct amdgpu_seq64 { 34 33 struct amdgpu_bo *sbo; ··· 41 42 int amdgpu_seq64_alloc(struct amdgpu_device *adev, u64 *gpu_addr, u64 **cpu_addr); 42 43 void amdgpu_seq64_free(struct amdgpu_device *adev, u64 gpu_addr); 43 44 int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm, 44 - struct amdgpu_bo_va **bo_va, u64 seq64_addr, uint32_t size); 45 + struct amdgpu_bo_va **bo_va); 45 46 void amdgpu_seq64_unmap(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv); 46 47 47 48 #endif
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
··· 358 358 359 359 memset(test->ring_data_cpu_addr, 0, sizeof(struct umsch_mm_test_ring_data)); 360 360 361 - test->ring_data_gpu_addr = AMDGPU_VA_RESERVED_SIZE; 361 + test->ring_data_gpu_addr = AMDGPU_VA_RESERVED_BOTTOM; 362 362 r = map_ring_data(adev, test->vm, test->ring_data_obj, &test->bo_va, 363 363 test->ring_data_gpu_addr, sizeof(struct umsch_mm_test_ring_data)); 364 364 if (r)
+5 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
··· 136 136 #define AMDGPU_IS_MMHUB1(x) ((x) >= AMDGPU_MMHUB1_START && (x) < AMDGPU_MAX_VMHUBS) 137 137 138 138 /* Reserve 2MB at top/bottom of address space for kernel use */ 139 - #define AMDGPU_VA_RESERVED_SIZE (2ULL << 20) 139 + #define AMDGPU_VA_RESERVED_CSA_SIZE (2ULL << 20) 140 + #define AMDGPU_VA_RESERVED_SEQ64_SIZE (2ULL << 20) 141 + #define AMDGPU_VA_RESERVED_BOTTOM (2ULL << 20) 142 + #define AMDGPU_VA_RESERVED_TOP (AMDGPU_VA_RESERVED_SEQ64_SIZE + \ 143 + AMDGPU_VA_RESERVED_CSA_SIZE) 140 144 141 145 /* See vm_update_mode */ 142 146 #define AMDGPU_VM_USE_CPU_FOR_GFX (1 << 0)
+3 -2
drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
··· 435 435 WREG32(mmVM_PRT_CNTL, tmp); 436 436 437 437 if (enable) { 438 - uint32_t low = AMDGPU_VA_RESERVED_SIZE >> AMDGPU_GPU_PAGE_SHIFT; 438 + uint32_t low = AMDGPU_VA_RESERVED_BOTTOM >> 439 + AMDGPU_GPU_PAGE_SHIFT; 439 440 uint32_t high = adev->vm_manager.max_pfn - 440 - (AMDGPU_VA_RESERVED_SIZE >> AMDGPU_GPU_PAGE_SHIFT); 441 + (AMDGPU_VA_RESERVED_TOP >> AMDGPU_GPU_PAGE_SHIFT); 441 442 442 443 WREG32(mmVM_PRT_APERTURE0_LOW_ADDR, low); 443 444 WREG32(mmVM_PRT_APERTURE1_LOW_ADDR, low);
+3 -2
drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
··· 563 563 WREG32(mmVM_PRT_CNTL, tmp); 564 564 565 565 if (enable) { 566 - uint32_t low = AMDGPU_VA_RESERVED_SIZE >> AMDGPU_GPU_PAGE_SHIFT; 566 + uint32_t low = AMDGPU_VA_RESERVED_BOTTOM >> 567 + AMDGPU_GPU_PAGE_SHIFT; 567 568 uint32_t high = adev->vm_manager.max_pfn - 568 - (AMDGPU_VA_RESERVED_SIZE >> AMDGPU_GPU_PAGE_SHIFT); 569 + (AMDGPU_VA_RESERVED_TOP >> AMDGPU_GPU_PAGE_SHIFT); 569 570 570 571 WREG32(mmVM_PRT_APERTURE0_LOW_ADDR, low); 571 572 WREG32(mmVM_PRT_APERTURE1_LOW_ADDR, low);
+3 -2
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
··· 777 777 WREG32(mmVM_PRT_CNTL, tmp); 778 778 779 779 if (enable) { 780 - uint32_t low = AMDGPU_VA_RESERVED_SIZE >> AMDGPU_GPU_PAGE_SHIFT; 780 + uint32_t low = AMDGPU_VA_RESERVED_BOTTOM >> 781 + AMDGPU_GPU_PAGE_SHIFT; 781 782 uint32_t high = adev->vm_manager.max_pfn - 782 - (AMDGPU_VA_RESERVED_SIZE >> AMDGPU_GPU_PAGE_SHIFT); 783 + (AMDGPU_VA_RESERVED_TOP >> AMDGPU_GPU_PAGE_SHIFT); 783 784 784 785 WREG32(mmVM_PRT_APERTURE0_LOW_ADDR, low); 785 786 WREG32(mmVM_PRT_APERTURE1_LOW_ADDR, low);