diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_gart.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_gart.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index b3720054614d..bb3b7fe05ccd 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -814,7 +814,7 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
814 | return -EINVAL; | 814 | return -EINVAL; |
815 | } | 815 | } |
816 | 816 | ||
817 | if (bo_va->valid) | 817 | if (bo_va->valid && mem) |
818 | return 0; | 818 | return 0; |
819 | 819 | ||
820 | ngpu_pages = radeon_bo_ngpu_pages(bo); | 820 | ngpu_pages = radeon_bo_ngpu_pages(bo); |
@@ -859,11 +859,27 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
859 | struct radeon_bo *bo) | 859 | struct radeon_bo *bo) |
860 | { | 860 | { |
861 | struct radeon_bo_va *bo_va; | 861 | struct radeon_bo_va *bo_va; |
862 | int r; | ||
862 | 863 | ||
863 | bo_va = radeon_bo_va(bo, vm); | 864 | bo_va = radeon_bo_va(bo, vm); |
864 | if (bo_va == NULL) | 865 | if (bo_va == NULL) |
865 | return 0; | 866 | return 0; |
866 | 867 | ||
868 | /* wait for va use to end */ | ||
869 | while (bo_va->fence) { | ||
870 | r = radeon_fence_wait(bo_va->fence, false); | ||
871 | if (r) { | ||
872 | DRM_ERROR("error while waiting for fence: %d\n", r); | ||
873 | } | ||
874 | if (r == -EDEADLK) { | ||
875 | r = radeon_gpu_reset(rdev); | ||
876 | if (!r) | ||
877 | continue; | ||
878 | } | ||
879 | break; | ||
880 | } | ||
881 | radeon_fence_unref(&bo_va->fence); | ||
882 | |||
867 | mutex_lock(&rdev->vm_manager.lock); | 883 | mutex_lock(&rdev->vm_manager.lock); |
868 | mutex_lock(&vm->mutex); | 884 | mutex_lock(&vm->mutex); |
869 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); | 885 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); |
@@ -934,7 +950,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) | |||
934 | } | 950 | } |
935 | 951 | ||
936 | /** | 952 | /** |
937 | * radeon_vm_init - tear down a vm instance | 953 | * radeon_vm_fini - tear down a vm instance |
938 | * | 954 | * |
939 | * @rdev: radeon_device pointer | 955 | * @rdev: radeon_device pointer |
940 | * @vm: requested vm | 956 | * @vm: requested vm |
@@ -952,12 +968,15 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
952 | radeon_vm_unbind_locked(rdev, vm); | 968 | radeon_vm_unbind_locked(rdev, vm); |
953 | mutex_unlock(&rdev->vm_manager.lock); | 969 | mutex_unlock(&rdev->vm_manager.lock); |
954 | 970 | ||
955 | /* remove all bo */ | 971 | /* remove all bo at this point non are busy any more because unbind |
972 | * waited for the last vm fence to signal | ||
973 | */ | ||
956 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); | 974 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); |
957 | if (!r) { | 975 | if (!r) { |
958 | bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm); | 976 | bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm); |
959 | list_del_init(&bo_va->bo_list); | 977 | list_del_init(&bo_va->bo_list); |
960 | list_del_init(&bo_va->vm_list); | 978 | list_del_init(&bo_va->vm_list); |
979 | radeon_fence_unref(&bo_va->fence); | ||
961 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); | 980 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); |
962 | kfree(bo_va); | 981 | kfree(bo_va); |
963 | } | 982 | } |
@@ -969,6 +988,7 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
969 | r = radeon_bo_reserve(bo_va->bo, false); | 988 | r = radeon_bo_reserve(bo_va->bo, false); |
970 | if (!r) { | 989 | if (!r) { |
971 | list_del_init(&bo_va->bo_list); | 990 | list_del_init(&bo_va->bo_list); |
991 | radeon_fence_unref(&bo_va->fence); | ||
972 | radeon_bo_unreserve(bo_va->bo); | 992 | radeon_bo_unreserve(bo_va->bo); |
973 | kfree(bo_va); | 993 | kfree(bo_va); |
974 | } | 994 | } |