diff options
author | Christian König <christian.koenig@amd.com> | 2014-07-30 15:04:57 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2014-08-05 08:53:54 -0400 |
commit | ee26d83ff030fd2a9952a2c91b94c75819f86973 (patch) | |
tree | c43944990fc628d55f60be7f302424082ff2b162 | |
parent | 512d8afc5d971be1e32596c6ad0a68abe1373cd9 (diff) |
drm/radeon: take a BO reference on VM cleanup
This closes a small window where the GPU might have accessed freed up memory.
Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_vm.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 759038800d10..d520ab71b748 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c | |||
@@ -450,6 +450,7 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, | |||
450 | tmp->it.last = bo_va->it.last; | 450 | tmp->it.last = bo_va->it.last; |
451 | tmp->vm = vm; | 451 | tmp->vm = vm; |
452 | tmp->addr = bo_va->addr; | 452 | tmp->addr = bo_va->addr; |
453 | tmp->bo = radeon_bo_ref(bo_va->bo); | ||
453 | list_add(&tmp->vm_status, &vm->freed); | 454 | list_add(&tmp->vm_status, &vm->freed); |
454 | } | 455 | } |
455 | 456 | ||
@@ -932,6 +933,7 @@ int radeon_vm_clear_freed(struct radeon_device *rdev, | |||
932 | 933 | ||
933 | list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { | 934 | list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { |
934 | r = radeon_vm_bo_update(rdev, bo_va, NULL); | 935 | r = radeon_vm_bo_update(rdev, bo_va, NULL); |
936 | radeon_bo_unref(&bo_va->bo); | ||
935 | kfree(bo_va); | 937 | kfree(bo_va); |
936 | if (r) | 938 | if (r) |
937 | return r; | 939 | return r; |
@@ -987,7 +989,7 @@ void radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
987 | list_del(&bo_va->vm_status); | 989 | list_del(&bo_va->vm_status); |
988 | 990 | ||
989 | if (bo_va->addr) { | 991 | if (bo_va->addr) { |
990 | bo_va->bo = NULL; | 992 | bo_va->bo = radeon_bo_ref(bo_va->bo); |
991 | list_add(&bo_va->vm_status, &vm->freed); | 993 | list_add(&bo_va->vm_status, &vm->freed); |
992 | } else { | 994 | } else { |
993 | kfree(bo_va); | 995 | kfree(bo_va); |
@@ -1098,8 +1100,10 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
1098 | kfree(bo_va); | 1100 | kfree(bo_va); |
1099 | } | 1101 | } |
1100 | } | 1102 | } |
1101 | list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) | 1103 | list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { |
1104 | radeon_bo_unref(&bo_va->bo); | ||
1102 | kfree(bo_va); | 1105 | kfree(bo_va); |
1106 | } | ||
1103 | 1107 | ||
1104 | for (i = 0; i < radeon_vm_num_pdes(rdev); i++) | 1108 | for (i = 0; i < radeon_vm_num_pdes(rdev); i++) |
1105 | radeon_bo_unref(&vm->page_tables[i].bo); | 1109 | radeon_bo_unref(&vm->page_tables[i].bo); |