aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2015-07-30 05:53:42 -0400
committerAlex Deucher <alexander.deucher@amd.com>2015-08-17 16:50:49 -0400
commit7fc11959018f8ba2d92025679a72339da18a74ad (patch)
treef9c4f07e2bcd901175d2fb3c7538f02d7138f82f /drivers/gpu/drm
parent7f06c236b964db3d8d086c5a0087b2eb4de3bf7a (diff)
drm/amdgpu: stop using addr to check for BO move v3
It is theoretically possible that a swapped out BO gets the same GTT address, but different backing pages while being swapped in. Instead just use another VA state to note updated areas. Ported from not upstream yet radeon commit with the same name. v2: fix some bugs in the original implementation found in the radeon code. v3: squash in VCE/UVD fix Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h15
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c11
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c67
3 files changed, 59 insertions, 34 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 98b47601b30a..5b8e1aeae13b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -539,14 +539,16 @@ struct amdgpu_bo_va_mapping {
539struct amdgpu_bo_va { 539struct amdgpu_bo_va {
540 /* protected by bo being reserved */ 540 /* protected by bo being reserved */
541 struct list_head bo_list; 541 struct list_head bo_list;
542 uint64_t addr;
543 struct amdgpu_fence *last_pt_update; 542 struct amdgpu_fence *last_pt_update;
544 unsigned ref_count; 543 unsigned ref_count;
545 544
546 /* protected by vm mutex */ 545 /* protected by vm mutex and spinlock */
547 struct list_head mappings;
548 struct list_head vm_status; 546 struct list_head vm_status;
549 547
548 /* mappings for this bo_va */
549 struct list_head invalids;
550 struct list_head valids;
551
550 /* constant after initialization */ 552 /* constant after initialization */
551 struct amdgpu_vm *vm; 553 struct amdgpu_vm *vm;
552 struct amdgpu_bo *bo; 554 struct amdgpu_bo *bo;
@@ -964,13 +966,16 @@ struct amdgpu_vm {
964 966
965 struct rb_root va; 967 struct rb_root va;
966 968
967 /* protecting invalidated and freed */ 969 /* protecting invalidated */
968 spinlock_t status_lock; 970 spinlock_t status_lock;
969 971
970 /* BOs moved, but not yet updated in the PT */ 972 /* BOs moved, but not yet updated in the PT */
971 struct list_head invalidated; 973 struct list_head invalidated;
972 974
973 /* BOs freed, but not yet updated in the PT */ 975 /* BOs cleared in the PT because of a move */
976 struct list_head cleared;
977
978 /* BO mappings freed, but not yet updated in the PT */
974 struct list_head freed; 979 struct list_head freed;
975 980
976 /* contains the page directory */ 981 /* contains the page directory */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 40e85bfcdf91..fe81b46266d9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1009,7 +1009,16 @@ amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
1009 if (!reloc->bo_va) 1009 if (!reloc->bo_va)
1010 continue; 1010 continue;
1011 1011
1012 list_for_each_entry(mapping, &reloc->bo_va->mappings, list) { 1012 list_for_each_entry(mapping, &reloc->bo_va->valids, list) {
1013 if (mapping->it.start > addr ||
1014 addr > mapping->it.last)
1015 continue;
1016
1017 *bo = reloc->bo_va->bo;
1018 return mapping;
1019 }
1020
1021 list_for_each_entry(mapping, &reloc->bo_va->invalids, list) {
1013 if (mapping->it.start > addr || 1022 if (mapping->it.start > addr ||
1014 addr > mapping->it.last) 1023 addr > mapping->it.last)
1015 continue; 1024 continue;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 5624d4484fb6..f2166320a5e5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -951,21 +951,24 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,
951 addr = 0; 951 addr = 0;
952 } 952 }
953 953
954 if (addr == bo_va->addr)
955 return 0;
956
957 flags = amdgpu_ttm_tt_pte_flags(adev, bo_va->bo->tbo.ttm, mem); 954 flags = amdgpu_ttm_tt_pte_flags(adev, bo_va->bo->tbo.ttm, mem);
958 955
959 list_for_each_entry(mapping, &bo_va->mappings, list) { 956 spin_lock(&vm->status_lock);
957 if (!list_empty(&bo_va->vm_status))
958 list_splice_init(&bo_va->valids, &bo_va->invalids);
959 spin_unlock(&vm->status_lock);
960
961 list_for_each_entry(mapping, &bo_va->invalids, list) {
960 r = amdgpu_vm_bo_update_mapping(adev, vm, mapping, addr, 962 r = amdgpu_vm_bo_update_mapping(adev, vm, mapping, addr,
961 flags, &bo_va->last_pt_update); 963 flags, &bo_va->last_pt_update);
962 if (r) 964 if (r)
963 return r; 965 return r;
964 } 966 }
965 967
966 bo_va->addr = addr;
967 spin_lock(&vm->status_lock); 968 spin_lock(&vm->status_lock);
968 list_del_init(&bo_va->vm_status); 969 list_del_init(&bo_va->vm_status);
970 if (!mem)
971 list_add(&bo_va->vm_status, &vm->cleared);
969 spin_unlock(&vm->status_lock); 972 spin_unlock(&vm->status_lock);
970 973
971 return 0; 974 return 0;
@@ -1065,10 +1068,10 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
1065 } 1068 }
1066 bo_va->vm = vm; 1069 bo_va->vm = vm;
1067 bo_va->bo = bo; 1070 bo_va->bo = bo;
1068 bo_va->addr = 0;
1069 bo_va->ref_count = 1; 1071 bo_va->ref_count = 1;
1070 INIT_LIST_HEAD(&bo_va->bo_list); 1072 INIT_LIST_HEAD(&bo_va->bo_list);
1071 INIT_LIST_HEAD(&bo_va->mappings); 1073 INIT_LIST_HEAD(&bo_va->valids);
1074 INIT_LIST_HEAD(&bo_va->invalids);
1072 INIT_LIST_HEAD(&bo_va->vm_status); 1075 INIT_LIST_HEAD(&bo_va->vm_status);
1073 1076
1074 mutex_lock(&vm->mutex); 1077 mutex_lock(&vm->mutex);
@@ -1157,12 +1160,10 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
1157 mapping->offset = offset; 1160 mapping->offset = offset;
1158 mapping->flags = flags; 1161 mapping->flags = flags;
1159 1162
1160 list_add(&mapping->list, &bo_va->mappings); 1163 list_add(&mapping->list, &bo_va->invalids);
1161 interval_tree_insert(&mapping->it, &vm->va); 1164 interval_tree_insert(&mapping->it, &vm->va);
1162 trace_amdgpu_vm_bo_map(bo_va, mapping); 1165 trace_amdgpu_vm_bo_map(bo_va, mapping);
1163 1166
1164 bo_va->addr = 0;
1165
1166 /* Make sure the page tables are allocated */ 1167 /* Make sure the page tables are allocated */
1167 saddr >>= amdgpu_vm_block_size; 1168 saddr >>= amdgpu_vm_block_size;
1168 eaddr >>= amdgpu_vm_block_size; 1169 eaddr >>= amdgpu_vm_block_size;
@@ -1243,17 +1244,27 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
1243{ 1244{
1244 struct amdgpu_bo_va_mapping *mapping; 1245 struct amdgpu_bo_va_mapping *mapping;
1245 struct amdgpu_vm *vm = bo_va->vm; 1246 struct amdgpu_vm *vm = bo_va->vm;
1247 bool valid = true;
1246 1248
1247 saddr /= AMDGPU_GPU_PAGE_SIZE; 1249 saddr /= AMDGPU_GPU_PAGE_SIZE;
1248 1250
1249 list_for_each_entry(mapping, &bo_va->mappings, list) { 1251 list_for_each_entry(mapping, &bo_va->valids, list) {
1250 if (mapping->it.start == saddr) 1252 if (mapping->it.start == saddr)
1251 break; 1253 break;
1252 } 1254 }
1253 1255
1254 if (&mapping->list == &bo_va->mappings) { 1256 if (&mapping->list == &bo_va->valids) {
1255 amdgpu_bo_unreserve(bo_va->bo); 1257 valid = false;
1256 return -ENOENT; 1258
1259 list_for_each_entry(mapping, &bo_va->invalids, list) {
1260 if (mapping->it.start == saddr)
1261 break;
1262 }
1263
1264 if (&mapping->list == &bo_va->invalids) {
1265 amdgpu_bo_unreserve(bo_va->bo);
1266 return -ENOENT;
1267 }
1257 } 1268 }
1258 1269
1259 mutex_lock(&vm->mutex); 1270 mutex_lock(&vm->mutex);
@@ -1261,12 +1272,10 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
1261 interval_tree_remove(&mapping->it, &vm->va); 1272 interval_tree_remove(&mapping->it, &vm->va);
1262 trace_amdgpu_vm_bo_unmap(bo_va, mapping); 1273 trace_amdgpu_vm_bo_unmap(bo_va, mapping);
1263 1274
1264 if (bo_va->addr) { 1275 if (valid)
1265 /* clear the old address */
1266 list_add(&mapping->list, &vm->freed); 1276 list_add(&mapping->list, &vm->freed);
1267 } else { 1277 else
1268 kfree(mapping); 1278 kfree(mapping);
1269 }
1270 mutex_unlock(&vm->mutex); 1279 mutex_unlock(&vm->mutex);
1271 amdgpu_bo_unreserve(bo_va->bo); 1280 amdgpu_bo_unreserve(bo_va->bo);
1272 1281
@@ -1297,15 +1306,18 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
1297 list_del(&bo_va->vm_status); 1306 list_del(&bo_va->vm_status);
1298 spin_unlock(&vm->status_lock); 1307 spin_unlock(&vm->status_lock);
1299 1308
1300 list_for_each_entry_safe(mapping, next, &bo_va->mappings, list) { 1309 list_for_each_entry_safe(mapping, next, &bo_va->valids, list) {
1301 list_del(&mapping->list); 1310 list_del(&mapping->list);
1302 interval_tree_remove(&mapping->it, &vm->va); 1311 interval_tree_remove(&mapping->it, &vm->va);
1303 trace_amdgpu_vm_bo_unmap(bo_va, mapping); 1312 trace_amdgpu_vm_bo_unmap(bo_va, mapping);
1304 if (bo_va->addr) 1313 list_add(&mapping->list, &vm->freed);
1305 list_add(&mapping->list, &vm->freed); 1314 }
1306 else 1315 list_for_each_entry_safe(mapping, next, &bo_va->invalids, list) {
1307 kfree(mapping); 1316 list_del(&mapping->list);
1317 interval_tree_remove(&mapping->it, &vm->va);
1318 kfree(mapping);
1308 } 1319 }
1320
1309 amdgpu_fence_unref(&bo_va->last_pt_update); 1321 amdgpu_fence_unref(&bo_va->last_pt_update);
1310 kfree(bo_va); 1322 kfree(bo_va);
1311 1323
@@ -1327,12 +1339,10 @@ void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev,
1327 struct amdgpu_bo_va *bo_va; 1339 struct amdgpu_bo_va *bo_va;
1328 1340
1329 list_for_each_entry(bo_va, &bo->va, bo_list) { 1341 list_for_each_entry(bo_va, &bo->va, bo_list) {
1330 if (bo_va->addr) { 1342 spin_lock(&bo_va->vm->status_lock);
1331 spin_lock(&bo_va->vm->status_lock); 1343 if (list_empty(&bo_va->vm_status))
1332 list_del(&bo_va->vm_status);
1333 list_add(&bo_va->vm_status, &bo_va->vm->invalidated); 1344 list_add(&bo_va->vm_status, &bo_va->vm->invalidated);
1334 spin_unlock(&bo_va->vm->status_lock); 1345 spin_unlock(&bo_va->vm->status_lock);
1335 }
1336 } 1346 }
1337} 1347}
1338 1348
@@ -1360,6 +1370,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
1360 vm->va = RB_ROOT; 1370 vm->va = RB_ROOT;
1361 spin_lock_init(&vm->status_lock); 1371 spin_lock_init(&vm->status_lock);
1362 INIT_LIST_HEAD(&vm->invalidated); 1372 INIT_LIST_HEAD(&vm->invalidated);
1373 INIT_LIST_HEAD(&vm->cleared);
1363 INIT_LIST_HEAD(&vm->freed); 1374 INIT_LIST_HEAD(&vm->freed);
1364 1375
1365 pd_size = amdgpu_vm_directory_size(adev); 1376 pd_size = amdgpu_vm_directory_size(adev);