aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/radeon/radeon.h3
-rw-r--r--drivers/gpu/drm/radeon/radeon_vm.c36
2 files changed, 33 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index da1c549fc732..b59a4de76174 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -929,6 +929,9 @@ struct radeon_vm {
929 929
930 struct rb_root va; 930 struct rb_root va;
931 931
932 /* protecting invalidated and freed */
933 spinlock_t status_lock;
934
932 /* BOs moved, but not yet updated in the PT */ 935 /* BOs moved, but not yet updated in the PT */
933 struct list_head invalidated; 936 struct list_head invalidated;
934 937
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c
index 6bc3821522a1..cde48c42b30a 100644
--- a/drivers/gpu/drm/radeon/radeon_vm.c
+++ b/drivers/gpu/drm/radeon/radeon_vm.c
@@ -487,7 +487,9 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev,
487 tmp->vm = vm; 487 tmp->vm = vm;
488 tmp->addr = bo_va->addr; 488 tmp->addr = bo_va->addr;
489 tmp->bo = radeon_bo_ref(bo_va->bo); 489 tmp->bo = radeon_bo_ref(bo_va->bo);
490 spin_lock(&vm->status_lock);
490 list_add(&tmp->vm_status, &vm->freed); 491 list_add(&tmp->vm_status, &vm->freed);
492 spin_unlock(&vm->status_lock);
491 } 493 }
492 494
493 interval_tree_remove(&bo_va->it, &vm->va); 495 interval_tree_remove(&bo_va->it, &vm->va);
@@ -913,7 +915,9 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
913 return -EINVAL; 915 return -EINVAL;
914 } 916 }
915 917
918 spin_lock(&vm->status_lock);
916 list_del_init(&bo_va->vm_status); 919 list_del_init(&bo_va->vm_status);
920 spin_unlock(&vm->status_lock);
917 921
918 bo_va->flags &= ~RADEON_VM_PAGE_VALID; 922 bo_va->flags &= ~RADEON_VM_PAGE_VALID;
919 bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM; 923 bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM;
@@ -1028,17 +1032,25 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
1028int radeon_vm_clear_freed(struct radeon_device *rdev, 1032int radeon_vm_clear_freed(struct radeon_device *rdev,
1029 struct radeon_vm *vm) 1033 struct radeon_vm *vm)
1030{ 1034{
1031 struct radeon_bo_va *bo_va, *tmp; 1035 struct radeon_bo_va *bo_va;
1032 int r; 1036 int r;
1033 1037
1034 list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { 1038 spin_lock(&vm->status_lock);
1039 while (!list_empty(&vm->freed)) {
1040 bo_va = list_first_entry(&vm->freed,
1041 struct radeon_bo_va, vm_status);
1042 spin_unlock(&vm->status_lock);
1043
1035 r = radeon_vm_bo_update(rdev, bo_va, NULL); 1044 r = radeon_vm_bo_update(rdev, bo_va, NULL);
1036 radeon_bo_unref(&bo_va->bo); 1045 radeon_bo_unref(&bo_va->bo);
1037 radeon_fence_unref(&bo_va->last_pt_update); 1046 radeon_fence_unref(&bo_va->last_pt_update);
1038 kfree(bo_va); 1047 kfree(bo_va);
1039 if (r) 1048 if (r)
1040 return r; 1049 return r;
1050
1051 spin_lock(&vm->status_lock);
1041 } 1052 }
1053 spin_unlock(&vm->status_lock);
1042 return 0; 1054 return 0;
1043 1055
1044} 1056}
@@ -1057,14 +1069,23 @@ int radeon_vm_clear_freed(struct radeon_device *rdev,
1057int radeon_vm_clear_invalids(struct radeon_device *rdev, 1069int radeon_vm_clear_invalids(struct radeon_device *rdev,
1058 struct radeon_vm *vm) 1070 struct radeon_vm *vm)
1059{ 1071{
1060 struct radeon_bo_va *bo_va, *tmp; 1072 struct radeon_bo_va *bo_va;
1061 int r; 1073 int r;
1062 1074
1063 list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, vm_status) { 1075 spin_lock(&vm->status_lock);
1076 while (!list_empty(&vm->invalidated)) {
1077 bo_va = list_first_entry(&vm->invalidated,
1078 struct radeon_bo_va, vm_status);
1079 spin_unlock(&vm->status_lock);
1080
1064 r = radeon_vm_bo_update(rdev, bo_va, NULL); 1081 r = radeon_vm_bo_update(rdev, bo_va, NULL);
1065 if (r) 1082 if (r)
1066 return r; 1083 return r;
1084
1085 spin_lock(&vm->status_lock);
1067 } 1086 }
1087 spin_unlock(&vm->status_lock);
1088
1068 return 0; 1089 return 0;
1069} 1090}
1070 1091
@@ -1087,6 +1108,7 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev,
1087 1108
1088 mutex_lock(&vm->mutex); 1109 mutex_lock(&vm->mutex);
1089 interval_tree_remove(&bo_va->it, &vm->va); 1110 interval_tree_remove(&bo_va->it, &vm->va);
1111 spin_lock(&vm->status_lock);
1090 list_del(&bo_va->vm_status); 1112 list_del(&bo_va->vm_status);
1091 1113
1092 if (bo_va->addr) { 1114 if (bo_va->addr) {
@@ -1096,6 +1118,7 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev,
1096 radeon_fence_unref(&bo_va->last_pt_update); 1118 radeon_fence_unref(&bo_va->last_pt_update);
1097 kfree(bo_va); 1119 kfree(bo_va);
1098 } 1120 }
1121 spin_unlock(&vm->status_lock);
1099 1122
1100 mutex_unlock(&vm->mutex); 1123 mutex_unlock(&vm->mutex);
1101} 1124}
@@ -1116,10 +1139,10 @@ void radeon_vm_bo_invalidate(struct radeon_device *rdev,
1116 1139
1117 list_for_each_entry(bo_va, &bo->va, bo_list) { 1140 list_for_each_entry(bo_va, &bo->va, bo_list) {
1118 if (bo_va->addr) { 1141 if (bo_va->addr) {
1119 mutex_lock(&bo_va->vm->mutex); 1142 spin_lock(&bo_va->vm->status_lock);
1120 list_del(&bo_va->vm_status); 1143 list_del(&bo_va->vm_status);
1121 list_add(&bo_va->vm_status, &bo_va->vm->invalidated); 1144 list_add(&bo_va->vm_status, &bo_va->vm->invalidated);
1122 mutex_unlock(&bo_va->vm->mutex); 1145 spin_unlock(&bo_va->vm->status_lock);
1123 } 1146 }
1124 } 1147 }
1125} 1148}
@@ -1147,6 +1170,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm)
1147 } 1170 }
1148 mutex_init(&vm->mutex); 1171 mutex_init(&vm->mutex);
1149 vm->va = RB_ROOT; 1172 vm->va = RB_ROOT;
1173 spin_lock_init(&vm->status_lock);
1150 INIT_LIST_HEAD(&vm->invalidated); 1174 INIT_LIST_HEAD(&vm->invalidated);
1151 INIT_LIST_HEAD(&vm->freed); 1175 INIT_LIST_HEAD(&vm->freed);
1152 1176