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

drm/amdgpu: rework amdgpu_cs_find_mapping

Use the VM instead of the BO list to find the BO for a virtual address.

This fixes UVD/VCE in physical mode with VM local BOs.

Signed-off-by: Christian König <christian.koenig@amd.com>
Acked-by: Leo Liu <leo.liu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Christian König and committed by
Alex Deucher
aebc5e6f 9cca0b8e

+30 -32
+10 -32
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
··· 1479 1479 uint64_t addr, struct amdgpu_bo **bo, 1480 1480 struct amdgpu_bo_va_mapping **map) 1481 1481 { 1482 + struct amdgpu_fpriv *fpriv = parser->filp->driver_priv; 1483 + struct amdgpu_vm *vm = &fpriv->vm; 1482 1484 struct amdgpu_bo_va_mapping *mapping; 1483 - unsigned i; 1484 1485 int r; 1485 - 1486 - if (!parser->bo_list) 1487 - return 0; 1488 1486 1489 1487 addr /= AMDGPU_GPU_PAGE_SIZE; 1490 1488 1491 - for (i = 0; i < parser->bo_list->num_entries; i++) { 1492 - struct amdgpu_bo_list_entry *lobj; 1489 + mapping = amdgpu_vm_bo_lookup_mapping(vm, addr); 1490 + if (!mapping || !mapping->bo_va || !mapping->bo_va->base.bo) 1491 + return -EINVAL; 1493 1492 1494 - lobj = &parser->bo_list->array[i]; 1495 - if (!lobj->bo_va) 1496 - continue; 1493 + *bo = mapping->bo_va->base.bo; 1494 + *map = mapping; 1497 1495 1498 - list_for_each_entry(mapping, &lobj->bo_va->valids, list) { 1499 - if (mapping->start > addr || 1500 - addr > mapping->last) 1501 - continue; 1496 + /* Double check that the BO is reserved by this CS */ 1497 + if (READ_ONCE((*bo)->tbo.resv->lock.ctx) != &parser->ticket) 1498 + return -EINVAL; 1502 1499 1503 - *bo = lobj->bo_va->base.bo; 1504 - *map = mapping; 1505 - goto found; 1506 - } 1507 - 1508 - list_for_each_entry(mapping, &lobj->bo_va->invalids, list) { 1509 - if (mapping->start > addr || 1510 - addr > mapping->last) 1511 - continue; 1512 - 1513 - *bo = lobj->bo_va->base.bo; 1514 - *map = mapping; 1515 - goto found; 1516 - } 1517 - } 1518 - 1519 - return -EINVAL; 1520 - 1521 - found: 1522 1500 r = amdgpu_ttm_bind(&(*bo)->tbo, &(*bo)->tbo.mem); 1523 1501 if (unlikely(r)) 1524 1502 return r;
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
··· 35 35 36 36 /* bo virtual addresses in a vm */ 37 37 struct amdgpu_bo_va_mapping { 38 + struct amdgpu_bo_va *bo_va; 38 39 struct list_head list; 39 40 struct rb_node rb; 40 41 uint64_t start;
+17
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 2086 2086 struct amdgpu_vm *vm = bo_va->base.vm; 2087 2087 struct amdgpu_bo *bo = bo_va->base.bo; 2088 2088 2089 + mapping->bo_va = bo_va; 2089 2090 list_add(&mapping->list, &bo_va->invalids); 2090 2091 amdgpu_vm_it_insert(mapping, &vm->va); 2091 2092 ··· 2264 2263 2265 2264 list_del(&mapping->list); 2266 2265 amdgpu_vm_it_remove(mapping, &vm->va); 2266 + mapping->bo_va = NULL; 2267 2267 trace_amdgpu_vm_bo_unmap(bo_va, mapping); 2268 2268 2269 2269 if (valid) ··· 2350 2348 if (tmp->last > eaddr) 2351 2349 tmp->last = eaddr; 2352 2350 2351 + tmp->bo_va = NULL; 2353 2352 list_add(&tmp->list, &vm->freed); 2354 2353 trace_amdgpu_vm_bo_unmap(NULL, tmp); 2355 2354 } ··· 2374 2371 } 2375 2372 2376 2373 return 0; 2374 + } 2375 + 2376 + /** 2377 + * amdgpu_vm_bo_lookup_mapping - find mapping by address 2378 + * 2379 + * @vm: the requested VM 2380 + * 2381 + * Find a mapping by it's address. 2382 + */ 2383 + struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm, 2384 + uint64_t addr) 2385 + { 2386 + return amdgpu_vm_it_iter_first(&vm->va, addr, addr); 2377 2387 } 2378 2388 2379 2389 /** ··· 2414 2398 list_for_each_entry_safe(mapping, next, &bo_va->valids, list) { 2415 2399 list_del(&mapping->list); 2416 2400 amdgpu_vm_it_remove(mapping, &vm->va); 2401 + mapping->bo_va = NULL; 2417 2402 trace_amdgpu_vm_bo_unmap(bo_va, mapping); 2418 2403 list_add(&mapping->list, &vm->freed); 2419 2404 }
+2
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
··· 276 276 int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev, 277 277 struct amdgpu_vm *vm, 278 278 uint64_t saddr, uint64_t size); 279 + struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm, 280 + uint64_t addr); 279 281 void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, 280 282 struct amdgpu_bo_va *bo_va); 281 283 void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev,