diff options
author | jimqu <Jim.Qu@amd.com> | 2015-12-04 04:17:00 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2015-12-04 12:23:38 -0500 |
commit | 9c4153b1eef9bc8da6a624252a3a25790b705136 (patch) | |
tree | 0de7e307e7317d669e9698e30e719ebb32c7f315 /drivers/gpu | |
parent | eb64526f5a5a382df7018a3e69061b9e3f20e32d (diff) |
drm/amdgpu: add spin lock to protect freed list in vm (v2)
there is a protection fault about freed list when OCL test.
add a spin lock to protect it.
v2: drop changes in vm_fini
Signed-off-by: JimQu <jim.qu@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 16 |
2 files changed, 15 insertions, 3 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 5f975030bb72..3b5d3706f0cb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -955,6 +955,8 @@ struct amdgpu_vm { | |||
955 | struct amdgpu_vm_id ids[AMDGPU_MAX_RINGS]; | 955 | struct amdgpu_vm_id ids[AMDGPU_MAX_RINGS]; |
956 | /* for interval tree */ | 956 | /* for interval tree */ |
957 | spinlock_t it_lock; | 957 | spinlock_t it_lock; |
958 | /* protecting freed */ | ||
959 | spinlock_t freed_lock; | ||
958 | }; | 960 | }; |
959 | 961 | ||
960 | struct amdgpu_vm_manager { | 962 | struct amdgpu_vm_manager { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index ae037e5b6ad0..fce4c6d952c8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -885,17 +885,21 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, | |||
885 | struct amdgpu_bo_va_mapping *mapping; | 885 | struct amdgpu_bo_va_mapping *mapping; |
886 | int r; | 886 | int r; |
887 | 887 | ||
888 | spin_lock(&vm->freed_lock); | ||
888 | while (!list_empty(&vm->freed)) { | 889 | while (!list_empty(&vm->freed)) { |
889 | mapping = list_first_entry(&vm->freed, | 890 | mapping = list_first_entry(&vm->freed, |
890 | struct amdgpu_bo_va_mapping, list); | 891 | struct amdgpu_bo_va_mapping, list); |
891 | list_del(&mapping->list); | 892 | list_del(&mapping->list); |
892 | 893 | spin_unlock(&vm->freed_lock); | |
893 | r = amdgpu_vm_bo_update_mapping(adev, vm, mapping, 0, 0, NULL); | 894 | r = amdgpu_vm_bo_update_mapping(adev, vm, mapping, 0, 0, NULL); |
894 | kfree(mapping); | 895 | kfree(mapping); |
895 | if (r) | 896 | if (r) |
896 | return r; | 897 | return r; |
897 | 898 | ||
899 | spin_lock(&vm->freed_lock); | ||
898 | } | 900 | } |
901 | spin_unlock(&vm->freed_lock); | ||
902 | |||
899 | return 0; | 903 | return 0; |
900 | 904 | ||
901 | } | 905 | } |
@@ -1150,10 +1154,13 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, | |||
1150 | spin_unlock(&vm->it_lock); | 1154 | spin_unlock(&vm->it_lock); |
1151 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); | 1155 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); |
1152 | 1156 | ||
1153 | if (valid) | 1157 | if (valid) { |
1158 | spin_lock(&vm->freed_lock); | ||
1154 | list_add(&mapping->list, &vm->freed); | 1159 | list_add(&mapping->list, &vm->freed); |
1155 | else | 1160 | spin_unlock(&vm->freed_lock); |
1161 | } else { | ||
1156 | kfree(mapping); | 1162 | kfree(mapping); |
1163 | } | ||
1157 | 1164 | ||
1158 | return 0; | 1165 | return 0; |
1159 | } | 1166 | } |
@@ -1186,7 +1193,9 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, | |||
1186 | interval_tree_remove(&mapping->it, &vm->va); | 1193 | interval_tree_remove(&mapping->it, &vm->va); |
1187 | spin_unlock(&vm->it_lock); | 1194 | spin_unlock(&vm->it_lock); |
1188 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); | 1195 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); |
1196 | spin_lock(&vm->freed_lock); | ||
1189 | list_add(&mapping->list, &vm->freed); | 1197 | list_add(&mapping->list, &vm->freed); |
1198 | spin_unlock(&vm->freed_lock); | ||
1190 | } | 1199 | } |
1191 | list_for_each_entry_safe(mapping, next, &bo_va->invalids, list) { | 1200 | list_for_each_entry_safe(mapping, next, &bo_va->invalids, list) { |
1192 | list_del(&mapping->list); | 1201 | list_del(&mapping->list); |
@@ -1247,6 +1256,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
1247 | INIT_LIST_HEAD(&vm->cleared); | 1256 | INIT_LIST_HEAD(&vm->cleared); |
1248 | INIT_LIST_HEAD(&vm->freed); | 1257 | INIT_LIST_HEAD(&vm->freed); |
1249 | spin_lock_init(&vm->it_lock); | 1258 | spin_lock_init(&vm->it_lock); |
1259 | spin_lock_init(&vm->freed_lock); | ||
1250 | pd_size = amdgpu_vm_directory_size(adev); | 1260 | pd_size = amdgpu_vm_directory_size(adev); |
1251 | pd_entries = amdgpu_vm_num_pdes(adev); | 1261 | pd_entries = amdgpu_vm_num_pdes(adev); |
1252 | 1262 | ||