diff options
author | Christian König <christian.koenig@amd.com> | 2014-07-18 03:24:53 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2014-08-05 08:53:49 -0400 |
commit | e31ad969bbbf0271b537d88f886c2ba3a7ee7059 (patch) | |
tree | 14f2ef577a1bb69141280726dc1a2d782078721b /drivers/gpu/drm/radeon/radeon_vm.c | |
parent | c08abf11900e19b14dd3a0cc3d105bd74519cd18 (diff) |
drm/radeon: invalidate moved BOs in the VM (v2)
Don't wait for the BO to be used again, just
update the PT on the next VM use.
v2: remove stray semicolon.
Signed-off-by: Christian König <christian.koenig@amd.com>
Tested-by: Michel Dänzer <michel.daenzer@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_vm.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_vm.c | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 2a2509e7ba87..906c8ae867ac 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c | |||
@@ -329,7 +329,7 @@ struct radeon_bo_va *radeon_vm_bo_add(struct radeon_device *rdev, | |||
329 | bo_va->soffset = 0; | 329 | bo_va->soffset = 0; |
330 | bo_va->eoffset = 0; | 330 | bo_va->eoffset = 0; |
331 | bo_va->flags = 0; | 331 | bo_va->flags = 0; |
332 | bo_va->valid = false; | 332 | bo_va->addr = 0; |
333 | bo_va->ref_count = 1; | 333 | bo_va->ref_count = 1; |
334 | INIT_LIST_HEAD(&bo_va->bo_list); | 334 | INIT_LIST_HEAD(&bo_va->bo_list); |
335 | INIT_LIST_HEAD(&bo_va->vm_list); | 335 | INIT_LIST_HEAD(&bo_va->vm_list); |
@@ -486,7 +486,7 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, | |||
486 | bo_va->soffset = soffset; | 486 | bo_va->soffset = soffset; |
487 | bo_va->eoffset = eoffset; | 487 | bo_va->eoffset = eoffset; |
488 | bo_va->flags = flags; | 488 | bo_va->flags = flags; |
489 | bo_va->valid = false; | 489 | bo_va->addr = 0; |
490 | list_move(&bo_va->vm_list, head); | 490 | list_move(&bo_va->vm_list, head); |
491 | 491 | ||
492 | soffset = (soffset / RADEON_GPU_PAGE_SIZE) >> radeon_vm_block_size; | 492 | soffset = (soffset / RADEON_GPU_PAGE_SIZE) >> radeon_vm_block_size; |
@@ -847,15 +847,13 @@ int radeon_vm_bo_update(struct radeon_device *rdev, | |||
847 | uint64_t addr; | 847 | uint64_t addr; |
848 | int r; | 848 | int r; |
849 | 849 | ||
850 | |||
851 | if (!bo_va->soffset) { | 850 | if (!bo_va->soffset) { |
852 | dev_err(rdev->dev, "bo %p don't has a mapping in vm %p\n", | 851 | dev_err(rdev->dev, "bo %p don't has a mapping in vm %p\n", |
853 | bo_va->bo, vm); | 852 | bo_va->bo, vm); |
854 | return -EINVAL; | 853 | return -EINVAL; |
855 | } | 854 | } |
856 | 855 | ||
857 | if ((bo_va->valid && mem) || (!bo_va->valid && mem == NULL)) | 856 | list_del_init(&bo_va->vm_status); |
858 | return 0; | ||
859 | 857 | ||
860 | bo_va->flags &= ~RADEON_VM_PAGE_VALID; | 858 | bo_va->flags &= ~RADEON_VM_PAGE_VALID; |
861 | bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM; | 859 | bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM; |
@@ -864,7 +862,6 @@ int radeon_vm_bo_update(struct radeon_device *rdev, | |||
864 | addr = mem->start << PAGE_SHIFT; | 862 | addr = mem->start << PAGE_SHIFT; |
865 | if (mem->mem_type != TTM_PL_SYSTEM) { | 863 | if (mem->mem_type != TTM_PL_SYSTEM) { |
866 | bo_va->flags |= RADEON_VM_PAGE_VALID; | 864 | bo_va->flags |= RADEON_VM_PAGE_VALID; |
867 | bo_va->valid = true; | ||
868 | } | 865 | } |
869 | if (mem->mem_type == TTM_PL_TT) { | 866 | if (mem->mem_type == TTM_PL_TT) { |
870 | bo_va->flags |= RADEON_VM_PAGE_SYSTEM; | 867 | bo_va->flags |= RADEON_VM_PAGE_SYSTEM; |
@@ -876,9 +873,12 @@ int radeon_vm_bo_update(struct radeon_device *rdev, | |||
876 | } | 873 | } |
877 | } else { | 874 | } else { |
878 | addr = 0; | 875 | addr = 0; |
879 | bo_va->valid = false; | ||
880 | } | 876 | } |
881 | 877 | ||
878 | if (addr == bo_va->addr) | ||
879 | return 0; | ||
880 | bo_va->addr = addr; | ||
881 | |||
882 | trace_radeon_vm_bo_update(bo_va); | 882 | trace_radeon_vm_bo_update(bo_va); |
883 | 883 | ||
884 | nptes = (bo_va->eoffset - bo_va->soffset) / RADEON_GPU_PAGE_SIZE; | 884 | nptes = (bo_va->eoffset - bo_va->soffset) / RADEON_GPU_PAGE_SIZE; |
@@ -941,7 +941,6 @@ int radeon_vm_clear_freed(struct radeon_device *rdev, | |||
941 | int r; | 941 | int r; |
942 | 942 | ||
943 | list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { | 943 | list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { |
944 | list_del(&bo_va->vm_status); | ||
945 | r = radeon_vm_bo_update(rdev, bo_va, NULL); | 944 | r = radeon_vm_bo_update(rdev, bo_va, NULL); |
946 | kfree(bo_va); | 945 | kfree(bo_va); |
947 | if (r) | 946 | if (r) |
@@ -952,6 +951,31 @@ int radeon_vm_clear_freed(struct radeon_device *rdev, | |||
952 | } | 951 | } |
953 | 952 | ||
954 | /** | 953 | /** |
954 | * radeon_vm_clear_invalids - clear invalidated BOs in the PT | ||
955 | * | ||
956 | * @rdev: radeon_device pointer | ||
957 | * @vm: requested vm | ||
958 | * | ||
959 | * Make sure all invalidated BOs are cleared in the PT. | ||
960 | * Returns 0 for success. | ||
961 | * | ||
962 | * PTs have to be reserved and mutex must be locked! | ||
963 | */ | ||
964 | int radeon_vm_clear_invalids(struct radeon_device *rdev, | ||
965 | struct radeon_vm *vm) | ||
966 | { | ||
967 | struct radeon_bo_va *bo_va, *tmp; | ||
968 | int r; | ||
969 | |||
970 | list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, vm_status) { | ||
971 | r = radeon_vm_bo_update(rdev, bo_va, NULL); | ||
972 | if (r) | ||
973 | return r; | ||
974 | } | ||
975 | return 0; | ||
976 | } | ||
977 | |||
978 | /** | ||
955 | * radeon_vm_bo_rmv - remove a bo to a specific vm | 979 | * radeon_vm_bo_rmv - remove a bo to a specific vm |
956 | * | 980 | * |
957 | * @rdev: radeon_device pointer | 981 | * @rdev: radeon_device pointer |
@@ -970,8 +994,9 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
970 | 994 | ||
971 | mutex_lock(&vm->mutex); | 995 | mutex_lock(&vm->mutex); |
972 | list_del(&bo_va->vm_list); | 996 | list_del(&bo_va->vm_list); |
997 | list_del(&bo_va->vm_status); | ||
973 | 998 | ||
974 | if (bo_va->soffset) { | 999 | if (bo_va->addr) { |
975 | bo_va->bo = NULL; | 1000 | bo_va->bo = NULL; |
976 | list_add(&bo_va->vm_status, &vm->freed); | 1001 | list_add(&bo_va->vm_status, &vm->freed); |
977 | } else { | 1002 | } else { |
@@ -996,7 +1021,12 @@ void radeon_vm_bo_invalidate(struct radeon_device *rdev, | |||
996 | struct radeon_bo_va *bo_va; | 1021 | struct radeon_bo_va *bo_va; |
997 | 1022 | ||
998 | list_for_each_entry(bo_va, &bo->va, bo_list) { | 1023 | list_for_each_entry(bo_va, &bo->va, bo_list) { |
999 | bo_va->valid = false; | 1024 | if (bo_va->addr) { |
1025 | mutex_lock(&bo_va->vm->mutex); | ||
1026 | list_del(&bo_va->vm_status); | ||
1027 | list_add(&bo_va->vm_status, &bo_va->vm->invalidated); | ||
1028 | mutex_unlock(&bo_va->vm->mutex); | ||
1029 | } | ||
1000 | } | 1030 | } |
1001 | } | 1031 | } |
1002 | 1032 | ||
@@ -1022,6 +1052,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) | |||
1022 | vm->last_id_use = NULL; | 1052 | vm->last_id_use = NULL; |
1023 | mutex_init(&vm->mutex); | 1053 | mutex_init(&vm->mutex); |
1024 | INIT_LIST_HEAD(&vm->va); | 1054 | INIT_LIST_HEAD(&vm->va); |
1055 | INIT_LIST_HEAD(&vm->invalidated); | ||
1025 | INIT_LIST_HEAD(&vm->freed); | 1056 | INIT_LIST_HEAD(&vm->freed); |
1026 | 1057 | ||
1027 | pd_size = radeon_vm_directory_size(rdev); | 1058 | pd_size = radeon_vm_directory_size(rdev); |