diff options
author | Christian König <christian.koenig@amd.com> | 2016-02-08 11:37:38 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-02-12 15:38:16 -0500 |
commit | 2d55e45a038b40c02a426fbcb2a9c6961654c6a0 (patch) | |
tree | 0ede19e0a4ca81e410169a823ea18254fa1efaa3 /drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |
parent | 3ee94136b4d9ef014535fe026d2cfdb6a6d60351 (diff) |
drm/amdgpu: use SDMA round robin for VM updates v3
Distribute the load on both rings.
v2: use a loop for the initialization
v3: agd: rebase on upstream
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-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 | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 5e38b344d56b..264c5968a1d3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -325,13 +325,15 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, | |||
325 | struct amdgpu_vm *vm, | 325 | struct amdgpu_vm *vm, |
326 | struct amdgpu_bo *bo) | 326 | struct amdgpu_bo *bo) |
327 | { | 327 | { |
328 | struct amdgpu_ring *ring = adev->vm_manager.vm_pte_funcs_ring; | 328 | struct amdgpu_ring *ring; |
329 | struct fence *fence = NULL; | 329 | struct fence *fence = NULL; |
330 | struct amdgpu_job *job; | 330 | struct amdgpu_job *job; |
331 | unsigned entries; | 331 | unsigned entries; |
332 | uint64_t addr; | 332 | uint64_t addr; |
333 | int r; | 333 | int r; |
334 | 334 | ||
335 | ring = container_of(vm->entity.sched, struct amdgpu_ring, sched); | ||
336 | |||
335 | r = reservation_object_reserve_shared(bo->tbo.resv); | 337 | r = reservation_object_reserve_shared(bo->tbo.resv); |
336 | if (r) | 338 | if (r) |
337 | return r; | 339 | return r; |
@@ -413,7 +415,7 @@ uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr) | |||
413 | int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, | 415 | int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, |
414 | struct amdgpu_vm *vm) | 416 | struct amdgpu_vm *vm) |
415 | { | 417 | { |
416 | struct amdgpu_ring *ring = adev->vm_manager.vm_pte_funcs_ring; | 418 | struct amdgpu_ring *ring; |
417 | struct amdgpu_bo *pd = vm->page_directory; | 419 | struct amdgpu_bo *pd = vm->page_directory; |
418 | uint64_t pd_addr = amdgpu_bo_gpu_offset(pd); | 420 | uint64_t pd_addr = amdgpu_bo_gpu_offset(pd); |
419 | uint32_t incr = AMDGPU_VM_PTE_COUNT * 8; | 421 | uint32_t incr = AMDGPU_VM_PTE_COUNT * 8; |
@@ -425,6 +427,8 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, | |||
425 | 427 | ||
426 | int r; | 428 | int r; |
427 | 429 | ||
430 | ring = container_of(vm->entity.sched, struct amdgpu_ring, sched); | ||
431 | |||
428 | /* padding, etc. */ | 432 | /* padding, etc. */ |
429 | ndw = 64; | 433 | ndw = 64; |
430 | 434 | ||
@@ -670,7 +674,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
670 | uint32_t flags, uint64_t addr, | 674 | uint32_t flags, uint64_t addr, |
671 | struct fence **fence) | 675 | struct fence **fence) |
672 | { | 676 | { |
673 | struct amdgpu_ring *ring = adev->vm_manager.vm_pte_funcs_ring; | 677 | struct amdgpu_ring *ring; |
674 | void *owner = AMDGPU_FENCE_OWNER_VM; | 678 | void *owner = AMDGPU_FENCE_OWNER_VM; |
675 | unsigned nptes, ncmds, ndw; | 679 | unsigned nptes, ncmds, ndw; |
676 | struct amdgpu_job *job; | 680 | struct amdgpu_job *job; |
@@ -678,6 +682,8 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
678 | struct fence *f = NULL; | 682 | struct fence *f = NULL; |
679 | int r; | 683 | int r; |
680 | 684 | ||
685 | ring = container_of(vm->entity.sched, struct amdgpu_ring, sched); | ||
686 | |||
681 | /* sync to everything on unmapping */ | 687 | /* sync to everything on unmapping */ |
682 | if (!(flags & AMDGPU_PTE_VALID)) | 688 | if (!(flags & AMDGPU_PTE_VALID)) |
683 | owner = AMDGPU_FENCE_OWNER_UNDEFINED; | 689 | owner = AMDGPU_FENCE_OWNER_UNDEFINED; |
@@ -1269,10 +1275,11 @@ void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev, | |||
1269 | */ | 1275 | */ |
1270 | int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) | 1276 | int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) |
1271 | { | 1277 | { |
1272 | struct amdgpu_ring *ring = adev->vm_manager.vm_pte_funcs_ring; | ||
1273 | const unsigned align = min(AMDGPU_VM_PTB_ALIGN_SIZE, | 1278 | const unsigned align = min(AMDGPU_VM_PTB_ALIGN_SIZE, |
1274 | AMDGPU_VM_PTE_COUNT * 8); | 1279 | AMDGPU_VM_PTE_COUNT * 8); |
1275 | unsigned pd_size, pd_entries; | 1280 | unsigned pd_size, pd_entries; |
1281 | unsigned ring_instance; | ||
1282 | struct amdgpu_ring *ring; | ||
1276 | struct amd_sched_rq *rq; | 1283 | struct amd_sched_rq *rq; |
1277 | int i, r; | 1284 | int i, r; |
1278 | 1285 | ||
@@ -1298,6 +1305,10 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
1298 | } | 1305 | } |
1299 | 1306 | ||
1300 | /* create scheduler entity for page table updates */ | 1307 | /* create scheduler entity for page table updates */ |
1308 | |||
1309 | ring_instance = atomic_inc_return(&adev->vm_manager.vm_pte_next_ring); | ||
1310 | ring_instance %= adev->vm_manager.vm_pte_num_rings; | ||
1311 | ring = adev->vm_manager.vm_pte_rings[ring_instance]; | ||
1301 | rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_KERNEL]; | 1312 | rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_KERNEL]; |
1302 | r = amd_sched_entity_init(&ring->sched, &vm->entity, | 1313 | r = amd_sched_entity_init(&ring->sched, &vm->entity, |
1303 | rq, amdgpu_sched_jobs); | 1314 | rq, amdgpu_sched_jobs); |
@@ -1345,11 +1356,10 @@ error_free_sched_entity: | |||
1345 | */ | 1356 | */ |
1346 | void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) | 1357 | void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) |
1347 | { | 1358 | { |
1348 | struct amdgpu_ring *ring = adev->vm_manager.vm_pte_funcs_ring; | ||
1349 | struct amdgpu_bo_va_mapping *mapping, *tmp; | 1359 | struct amdgpu_bo_va_mapping *mapping, *tmp; |
1350 | int i; | 1360 | int i; |
1351 | 1361 | ||
1352 | amd_sched_entity_fini(&ring->sched, &vm->entity); | 1362 | amd_sched_entity_fini(vm->entity.sched, &vm->entity); |
1353 | 1363 | ||
1354 | if (!RB_EMPTY_ROOT(&vm->va)) { | 1364 | if (!RB_EMPTY_ROOT(&vm->va)) { |
1355 | dev_err(adev->dev, "still active bo inside vm\n"); | 1365 | dev_err(adev->dev, "still active bo inside vm\n"); |
@@ -1397,6 +1407,8 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev) | |||
1397 | for (i = 1; i < adev->vm_manager.num_ids; ++i) | 1407 | for (i = 1; i < adev->vm_manager.num_ids; ++i) |
1398 | list_add_tail(&adev->vm_manager.ids[i].list, | 1408 | list_add_tail(&adev->vm_manager.ids[i].list, |
1399 | &adev->vm_manager.ids_lru); | 1409 | &adev->vm_manager.ids_lru); |
1410 | |||
1411 | atomic_set(&adev->vm_manager.vm_pte_next_ring, 0); | ||
1400 | } | 1412 | } |
1401 | 1413 | ||
1402 | /** | 1414 | /** |