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 13:08:13 -0500 |
commit | 81d75a30c6ed006a314f5c760196d04758660ca6 (patch) | |
tree | fcdfce8c4b048aab55b101845e8a53155eb7c55e /drivers/gpu | |
parent | 9c97b5ab4a91c18c2e7654f044cbff446cfd979b (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 670fefb56945..5a5f04d0902d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -956,6 +956,8 @@ struct amdgpu_vm { | |||
956 | struct amdgpu_vm_id ids[AMDGPU_MAX_RINGS]; | 956 | struct amdgpu_vm_id ids[AMDGPU_MAX_RINGS]; |
957 | /* for interval tree */ | 957 | /* for interval tree */ |
958 | spinlock_t it_lock; | 958 | spinlock_t it_lock; |
959 | /* protecting freed */ | ||
960 | spinlock_t freed_lock; | ||
959 | }; | 961 | }; |
960 | 962 | ||
961 | struct amdgpu_vm_manager { | 963 | 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 a582ef553499..b53d273eb7a1 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 | } |
@@ -1155,10 +1159,13 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, | |||
1155 | spin_unlock(&vm->it_lock); | 1159 | spin_unlock(&vm->it_lock); |
1156 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); | 1160 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); |
1157 | 1161 | ||
1158 | if (valid) | 1162 | if (valid) { |
1163 | spin_lock(&vm->freed_lock); | ||
1159 | list_add(&mapping->list, &vm->freed); | 1164 | list_add(&mapping->list, &vm->freed); |
1160 | else | 1165 | spin_unlock(&vm->freed_lock); |
1166 | } else { | ||
1161 | kfree(mapping); | 1167 | kfree(mapping); |
1168 | } | ||
1162 | 1169 | ||
1163 | return 0; | 1170 | return 0; |
1164 | } | 1171 | } |
@@ -1191,7 +1198,9 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, | |||
1191 | interval_tree_remove(&mapping->it, &vm->va); | 1198 | interval_tree_remove(&mapping->it, &vm->va); |
1192 | spin_unlock(&vm->it_lock); | 1199 | spin_unlock(&vm->it_lock); |
1193 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); | 1200 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); |
1201 | spin_lock(&vm->freed_lock); | ||
1194 | list_add(&mapping->list, &vm->freed); | 1202 | list_add(&mapping->list, &vm->freed); |
1203 | spin_unlock(&vm->freed_lock); | ||
1195 | } | 1204 | } |
1196 | list_for_each_entry_safe(mapping, next, &bo_va->invalids, list) { | 1205 | list_for_each_entry_safe(mapping, next, &bo_va->invalids, list) { |
1197 | list_del(&mapping->list); | 1206 | list_del(&mapping->list); |
@@ -1252,6 +1261,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
1252 | INIT_LIST_HEAD(&vm->cleared); | 1261 | INIT_LIST_HEAD(&vm->cleared); |
1253 | INIT_LIST_HEAD(&vm->freed); | 1262 | INIT_LIST_HEAD(&vm->freed); |
1254 | spin_lock_init(&vm->it_lock); | 1263 | spin_lock_init(&vm->it_lock); |
1264 | spin_lock_init(&vm->freed_lock); | ||
1255 | pd_size = amdgpu_vm_directory_size(adev); | 1265 | pd_size = amdgpu_vm_directory_size(adev); |
1256 | pd_entries = amdgpu_vm_num_pdes(adev); | 1266 | pd_entries = amdgpu_vm_num_pdes(adev); |
1257 | 1267 | ||