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 | |
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')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/cik_sdma.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | 8 |
6 files changed, 43 insertions, 11 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 76aa7898eeb2..55fcc929b476 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -942,7 +942,9 @@ struct amdgpu_vm_manager { | |||
942 | bool enabled; | 942 | bool enabled; |
943 | /* vm pte handling */ | 943 | /* vm pte handling */ |
944 | const struct amdgpu_vm_pte_funcs *vm_pte_funcs; | 944 | const struct amdgpu_vm_pte_funcs *vm_pte_funcs; |
945 | struct amdgpu_ring *vm_pte_funcs_ring; | 945 | struct amdgpu_ring *vm_pte_rings[AMDGPU_MAX_RINGS]; |
946 | unsigned vm_pte_num_rings; | ||
947 | atomic_t vm_pte_next_ring; | ||
946 | }; | 948 | }; |
947 | 949 | ||
948 | void amdgpu_vm_manager_init(struct amdgpu_device *adev); | 950 | void amdgpu_vm_manager_init(struct amdgpu_device *adev); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index f0fb938457d9..6bdb891b9ddc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -1403,7 +1403,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, | |||
1403 | adev->mman.buffer_funcs = NULL; | 1403 | adev->mman.buffer_funcs = NULL; |
1404 | adev->mman.buffer_funcs_ring = NULL; | 1404 | adev->mman.buffer_funcs_ring = NULL; |
1405 | adev->vm_manager.vm_pte_funcs = NULL; | 1405 | adev->vm_manager.vm_pte_funcs = NULL; |
1406 | adev->vm_manager.vm_pte_funcs_ring = NULL; | 1406 | adev->vm_manager.vm_pte_num_rings = 0; |
1407 | adev->gart.gart_funcs = NULL; | 1407 | adev->gart.gart_funcs = NULL; |
1408 | adev->fence_context = fence_context_alloc(AMDGPU_MAX_RINGS); | 1408 | adev->fence_context = fence_context_alloc(AMDGPU_MAX_RINGS); |
1409 | 1409 | ||
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 | /** |
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index 5e8566a22425..7ba34522c833 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c | |||
@@ -1371,8 +1371,14 @@ static const struct amdgpu_vm_pte_funcs cik_sdma_vm_pte_funcs = { | |||
1371 | 1371 | ||
1372 | static void cik_sdma_set_vm_pte_funcs(struct amdgpu_device *adev) | 1372 | static void cik_sdma_set_vm_pte_funcs(struct amdgpu_device *adev) |
1373 | { | 1373 | { |
1374 | unsigned i; | ||
1375 | |||
1374 | if (adev->vm_manager.vm_pte_funcs == NULL) { | 1376 | if (adev->vm_manager.vm_pte_funcs == NULL) { |
1375 | adev->vm_manager.vm_pte_funcs = &cik_sdma_vm_pte_funcs; | 1377 | adev->vm_manager.vm_pte_funcs = &cik_sdma_vm_pte_funcs; |
1376 | adev->vm_manager.vm_pte_funcs_ring = &adev->sdma.instance[0].ring; | 1378 | for (i = 0; i < adev->sdma.num_instances; i++) |
1379 | adev->vm_manager.vm_pte_rings[i] = | ||
1380 | &adev->sdma.instance[i].ring; | ||
1381 | |||
1382 | adev->vm_manager.vm_pte_num_rings = adev->sdma.num_instances; | ||
1377 | } | 1383 | } |
1378 | } | 1384 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index 4ae1058c96c6..c895af79d4bb 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | |||
@@ -1376,8 +1376,14 @@ static const struct amdgpu_vm_pte_funcs sdma_v2_4_vm_pte_funcs = { | |||
1376 | 1376 | ||
1377 | static void sdma_v2_4_set_vm_pte_funcs(struct amdgpu_device *adev) | 1377 | static void sdma_v2_4_set_vm_pte_funcs(struct amdgpu_device *adev) |
1378 | { | 1378 | { |
1379 | unsigned i; | ||
1380 | |||
1379 | if (adev->vm_manager.vm_pte_funcs == NULL) { | 1381 | if (adev->vm_manager.vm_pte_funcs == NULL) { |
1380 | adev->vm_manager.vm_pte_funcs = &sdma_v2_4_vm_pte_funcs; | 1382 | adev->vm_manager.vm_pte_funcs = &sdma_v2_4_vm_pte_funcs; |
1381 | adev->vm_manager.vm_pte_funcs_ring = &adev->sdma.instance[0].ring; | 1383 | for (i = 0; i < adev->sdma.num_instances; i++) |
1384 | adev->vm_manager.vm_pte_rings[i] = | ||
1385 | &adev->sdma.instance[i].ring; | ||
1386 | |||
1387 | adev->vm_manager.vm_pte_num_rings = adev->sdma.num_instances; | ||
1382 | } | 1388 | } |
1383 | } | 1389 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index c45f7926091d..dcb3efdd1bd9 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | |||
@@ -1643,8 +1643,14 @@ static const struct amdgpu_vm_pte_funcs sdma_v3_0_vm_pte_funcs = { | |||
1643 | 1643 | ||
1644 | static void sdma_v3_0_set_vm_pte_funcs(struct amdgpu_device *adev) | 1644 | static void sdma_v3_0_set_vm_pte_funcs(struct amdgpu_device *adev) |
1645 | { | 1645 | { |
1646 | unsigned i; | ||
1647 | |||
1646 | if (adev->vm_manager.vm_pte_funcs == NULL) { | 1648 | if (adev->vm_manager.vm_pte_funcs == NULL) { |
1647 | adev->vm_manager.vm_pte_funcs = &sdma_v3_0_vm_pte_funcs; | 1649 | adev->vm_manager.vm_pte_funcs = &sdma_v3_0_vm_pte_funcs; |
1648 | adev->vm_manager.vm_pte_funcs_ring = &adev->sdma.instance[0].ring; | 1650 | for (i = 0; i < adev->sdma.num_instances; i++) |
1651 | adev->vm_manager.vm_pte_rings[i] = | ||
1652 | &adev->sdma.instance[i].ring; | ||
1653 | |||
1654 | adev->vm_manager.vm_pte_num_rings = adev->sdma.num_instances; | ||
1649 | } | 1655 | } |
1650 | } | 1656 | } |