aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2014-11-19 08:01:26 -0500
committerAlex Deucher <alexander.deucher@amd.com>2014-11-20 13:00:18 -0500
commit94214635f09c9211023730acdff9342fdf100aee (patch)
treedb9bc6136929cfad3959c6b23c435420f5382afb
parent7c42bc1aa23fc061a6ff9c2bd9208817bd54ea04 (diff)
drm/radeon: fence BO_VAs manually
This allows us to finally remove the VM fence and so allow concurrent use of it from different engines. Signed-off-by: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/radeon.h7
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_vm.c17
3 files changed, 14 insertions, 16 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 79f5f5bf4c0c..3207bb60715e 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -456,6 +456,7 @@ struct radeon_bo_va {
456 struct list_head bo_list; 456 struct list_head bo_list;
457 uint32_t flags; 457 uint32_t flags;
458 uint64_t addr; 458 uint64_t addr;
459 struct radeon_fence *last_pt_update;
459 unsigned ref_count; 460 unsigned ref_count;
460 461
461 /* protected by vm mutex */ 462 /* protected by vm mutex */
@@ -915,6 +916,8 @@ struct radeon_vm_id {
915}; 916};
916 917
917struct radeon_vm { 918struct radeon_vm {
919 struct mutex mutex;
920
918 struct rb_root va; 921 struct rb_root va;
919 922
920 /* BOs moved, but not yet updated in the PT */ 923 /* BOs moved, but not yet updated in the PT */
@@ -932,10 +935,6 @@ struct radeon_vm {
932 935
933 struct radeon_bo_va *ib_bo_va; 936 struct radeon_bo_va *ib_bo_va;
934 937
935 struct mutex mutex;
936 /* last fence for cs using this vm */
937 struct radeon_fence *fence;
938
939 /* for id and flush management per ring */ 938 /* for id and flush management per ring */
940 struct radeon_vm_id ids[RADEON_NUM_RINGS]; 939 struct radeon_vm_id ids[RADEON_NUM_RINGS];
941}; 940};
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index 30437aa00014..75f22e5e999f 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -505,6 +505,9 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *p,
505 if (r) 505 if (r)
506 return r; 506 return r;
507 507
508 radeon_sync_resv(p->rdev, &p->ib.sync, vm->page_directory->tbo.resv,
509 true);
510
508 r = radeon_vm_clear_freed(rdev, vm); 511 r = radeon_vm_clear_freed(rdev, vm);
509 if (r) 512 if (r)
510 return r; 513 return r;
@@ -536,6 +539,8 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *p,
536 r = radeon_vm_bo_update(rdev, bo_va, &bo->tbo.mem); 539 r = radeon_vm_bo_update(rdev, bo_va, &bo->tbo.mem);
537 if (r) 540 if (r)
538 return r; 541 return r;
542
543 radeon_sync_fence(&p->ib.sync, bo_va->last_pt_update);
539 } 544 }
540 545
541 return radeon_vm_clear_invalids(rdev, vm); 546 return radeon_vm_clear_invalids(rdev, vm);
@@ -580,7 +585,6 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
580 DRM_ERROR("Failed to sync rings: %i\n", r); 585 DRM_ERROR("Failed to sync rings: %i\n", r);
581 goto out; 586 goto out;
582 } 587 }
583 radeon_sync_fence(&parser->ib.sync, vm->fence);
584 588
585 if ((rdev->family >= CHIP_TAHITI) && 589 if ((rdev->family >= CHIP_TAHITI) &&
586 (parser->chunk_const_ib_idx != -1)) { 590 (parser->chunk_const_ib_idx != -1)) {
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c
index e38efe4962f3..f45761469e95 100644
--- a/drivers/gpu/drm/radeon/radeon_vm.c
+++ b/drivers/gpu/drm/radeon/radeon_vm.c
@@ -275,9 +275,6 @@ void radeon_vm_fence(struct radeon_device *rdev,
275{ 275{
276 unsigned vm_id = vm->ids[fence->ring].id; 276 unsigned vm_id = vm->ids[fence->ring].id;
277 277
278 radeon_fence_unref(&vm->fence);
279 vm->fence = radeon_fence_ref(fence);
280
281 radeon_fence_unref(&rdev->vm_manager.active[vm_id]); 278 radeon_fence_unref(&rdev->vm_manager.active[vm_id]);
282 rdev->vm_manager.active[vm_id] = radeon_fence_ref(fence); 279 rdev->vm_manager.active[vm_id] = radeon_fence_ref(fence);
283 280
@@ -707,8 +704,6 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev,
707 } 704 }
708 ib.fence->is_vm_update = true; 705 ib.fence->is_vm_update = true;
709 radeon_bo_fence(pd, ib.fence, false); 706 radeon_bo_fence(pd, ib.fence, false);
710 radeon_fence_unref(&vm->fence);
711 vm->fence = radeon_fence_ref(ib.fence);
712 } 707 }
713 radeon_ib_free(rdev, &ib); 708 radeon_ib_free(rdev, &ib);
714 709
@@ -999,8 +994,8 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
999 } 994 }
1000 ib.fence->is_vm_update = true; 995 ib.fence->is_vm_update = true;
1001 radeon_vm_fence_pts(vm, bo_va->it.start, bo_va->it.last + 1, ib.fence); 996 radeon_vm_fence_pts(vm, bo_va->it.start, bo_va->it.last + 1, ib.fence);
1002 radeon_fence_unref(&vm->fence); 997 radeon_fence_unref(&bo_va->last_pt_update);
1003 vm->fence = radeon_fence_ref(ib.fence); 998 bo_va->last_pt_update = radeon_fence_ref(ib.fence);
1004 radeon_ib_free(rdev, &ib); 999 radeon_ib_free(rdev, &ib);
1005 1000
1006 return 0; 1001 return 0;
@@ -1026,6 +1021,7 @@ int radeon_vm_clear_freed(struct radeon_device *rdev,
1026 list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { 1021 list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) {
1027 r = radeon_vm_bo_update(rdev, bo_va, NULL); 1022 r = radeon_vm_bo_update(rdev, bo_va, NULL);
1028 radeon_bo_unref(&bo_va->bo); 1023 radeon_bo_unref(&bo_va->bo);
1024 radeon_fence_unref(&bo_va->last_pt_update);
1029 kfree(bo_va); 1025 kfree(bo_va);
1030 if (r) 1026 if (r)
1031 return r; 1027 return r;
@@ -1084,6 +1080,7 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev,
1084 bo_va->bo = radeon_bo_ref(bo_va->bo); 1080 bo_va->bo = radeon_bo_ref(bo_va->bo);
1085 list_add(&bo_va->vm_status, &vm->freed); 1081 list_add(&bo_va->vm_status, &vm->freed);
1086 } else { 1082 } else {
1083 radeon_fence_unref(&bo_va->last_pt_update);
1087 kfree(bo_va); 1084 kfree(bo_va);
1088 } 1085 }
1089 1086
@@ -1130,8 +1127,6 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm)
1130 int i, r; 1127 int i, r;
1131 1128
1132 vm->ib_bo_va = NULL; 1129 vm->ib_bo_va = NULL;
1133 vm->fence = NULL;
1134
1135 for (i = 0; i < RADEON_NUM_RINGS; ++i) { 1130 for (i = 0; i < RADEON_NUM_RINGS; ++i) {
1136 vm->ids[i].id = 0; 1131 vm->ids[i].id = 0;
1137 vm->ids[i].flushed_updates = NULL; 1132 vm->ids[i].flushed_updates = NULL;
@@ -1192,11 +1187,13 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm)
1192 if (!r) { 1187 if (!r) {
1193 list_del_init(&bo_va->bo_list); 1188 list_del_init(&bo_va->bo_list);
1194 radeon_bo_unreserve(bo_va->bo); 1189 radeon_bo_unreserve(bo_va->bo);
1190 radeon_fence_unref(&bo_va->last_pt_update);
1195 kfree(bo_va); 1191 kfree(bo_va);
1196 } 1192 }
1197 } 1193 }
1198 list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { 1194 list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) {
1199 radeon_bo_unref(&bo_va->bo); 1195 radeon_bo_unref(&bo_va->bo);
1196 radeon_fence_unref(&bo_va->last_pt_update);
1200 kfree(bo_va); 1197 kfree(bo_va);
1201 } 1198 }
1202 1199
@@ -1206,8 +1203,6 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm)
1206 1203
1207 radeon_bo_unref(&vm->page_directory); 1204 radeon_bo_unref(&vm->page_directory);
1208 1205
1209 radeon_fence_unref(&vm->fence);
1210
1211 for (i = 0; i < RADEON_NUM_RINGS; ++i) { 1206 for (i = 0; i < RADEON_NUM_RINGS; ++i) {
1212 radeon_fence_unref(&vm->ids[i].flushed_updates); 1207 radeon_fence_unref(&vm->ids[i].flushed_updates);
1213 radeon_fence_unref(&vm->ids[i].last_id_use); 1208 radeon_fence_unref(&vm->ids[i].last_id_use);