diff options
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_vm.c | 36 |
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, | |||
1028 | int radeon_vm_clear_freed(struct radeon_device *rdev, | 1032 | int 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, | |||
1057 | int radeon_vm_clear_invalids(struct radeon_device *rdev, | 1069 | int 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 | ||