aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2018-09-11 05:50:57 -0400
committerAlex Deucher <alexander.deucher@amd.com>2018-09-19 13:38:41 -0400
commit403009bfba45163887398652762ed1fc6645181c (patch)
tree55d50f036ed77a19acffb3f736190878c6130280 /drivers/gpu/drm/amd/amdgpu
parentc33adbc7285f72dbd86aedba858e9570cd9f9c99 (diff)
drm/amdgpu: fix shadow BO restoring
Don't grab the reservation lock any more and simplify the handling quite a bit. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Huang Rui <ray.huang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c109
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_object.c46
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_object.h8
3 files changed, 43 insertions, 120 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 0267fae316d7..bd79d0a31942 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -2951,54 +2951,6 @@ static int amdgpu_device_ip_post_soft_reset(struct amdgpu_device *adev)
2951} 2951}
2952 2952
2953/** 2953/**
2954 * amdgpu_device_recover_vram_from_shadow - restore shadowed VRAM buffers
2955 *
2956 * @adev: amdgpu_device pointer
2957 * @ring: amdgpu_ring for the engine handling the buffer operations
2958 * @bo: amdgpu_bo buffer whose shadow is being restored
2959 * @fence: dma_fence associated with the operation
2960 *
2961 * Restores the VRAM buffer contents from the shadow in GTT. Used to
2962 * restore things like GPUVM page tables after a GPU reset where
2963 * the contents of VRAM might be lost.
2964 * Returns 0 on success, negative error code on failure.
2965 */
2966static int amdgpu_device_recover_vram_from_shadow(struct amdgpu_device *adev,
2967 struct amdgpu_ring *ring,
2968 struct amdgpu_bo *bo,
2969 struct dma_fence **fence)
2970{
2971 uint32_t domain;
2972 int r;
2973
2974 if (!bo->shadow)
2975 return 0;
2976
2977 r = amdgpu_bo_reserve(bo, true);
2978 if (r)
2979 return r;
2980 domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
2981 /* if bo has been evicted, then no need to recover */
2982 if (domain == AMDGPU_GEM_DOMAIN_VRAM) {
2983 r = amdgpu_bo_validate(bo->shadow);
2984 if (r) {
2985 DRM_ERROR("bo validate failed!\n");
2986 goto err;
2987 }
2988
2989 r = amdgpu_bo_restore_from_shadow(adev, ring, bo,
2990 NULL, fence, true);
2991 if (r) {
2992 DRM_ERROR("recover page table failed!\n");
2993 goto err;
2994 }
2995 }
2996err:
2997 amdgpu_bo_unreserve(bo);
2998 return r;
2999}
3000
3001/**
3002 * amdgpu_device_recover_vram - Recover some VRAM contents 2954 * amdgpu_device_recover_vram - Recover some VRAM contents
3003 * 2955 *
3004 * @adev: amdgpu_device pointer 2956 * @adev: amdgpu_device pointer
@@ -3006,16 +2958,15 @@ err:
3006 * Restores the contents of VRAM buffers from the shadows in GTT. Used to 2958 * Restores the contents of VRAM buffers from the shadows in GTT. Used to
3007 * restore things like GPUVM page tables after a GPU reset where 2959 * restore things like GPUVM page tables after a GPU reset where
3008 * the contents of VRAM might be lost. 2960 * the contents of VRAM might be lost.
3009 * Returns 0 on success, 1 on failure. 2961 *
2962 * Returns:
2963 * 0 on success, negative error code on failure.
3010 */ 2964 */
3011static int amdgpu_device_recover_vram(struct amdgpu_device *adev) 2965static int amdgpu_device_recover_vram(struct amdgpu_device *adev)
3012{ 2966{
3013 struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
3014 struct amdgpu_bo *bo, *tmp;
3015 struct dma_fence *fence = NULL, *next = NULL; 2967 struct dma_fence *fence = NULL, *next = NULL;
3016 long r = 1; 2968 struct amdgpu_bo *shadow;
3017 int i = 0; 2969 long r = 1, tmo;
3018 long tmo;
3019 2970
3020 if (amdgpu_sriov_runtime(adev)) 2971 if (amdgpu_sriov_runtime(adev))
3021 tmo = msecs_to_jiffies(8000); 2972 tmo = msecs_to_jiffies(8000);
@@ -3024,44 +2975,40 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev)
3024 2975
3025 DRM_INFO("recover vram bo from shadow start\n"); 2976 DRM_INFO("recover vram bo from shadow start\n");
3026 mutex_lock(&adev->shadow_list_lock); 2977 mutex_lock(&adev->shadow_list_lock);
3027 list_for_each_entry_safe(bo, tmp, &adev->shadow_list, shadow_list) { 2978 list_for_each_entry(shadow, &adev->shadow_list, shadow_list) {
3028 next = NULL; 2979
3029 amdgpu_device_recover_vram_from_shadow(adev, ring, bo, &next); 2980 /* No need to recover an evicted BO */
2981 if (shadow->tbo.mem.mem_type != TTM_PL_TT ||
2982 shadow->parent->tbo.mem.mem_type != TTM_PL_VRAM)
2983 continue;
2984
2985 r = amdgpu_bo_restore_shadow(shadow, &next);
2986 if (r)
2987 break;
2988
3030 if (fence) { 2989 if (fence) {
3031 r = dma_fence_wait_timeout(fence, false, tmo); 2990 r = dma_fence_wait_timeout(fence, false, tmo);
3032 if (r == 0) 2991 dma_fence_put(fence);
3033 pr_err("wait fence %p[%d] timeout\n", fence, i); 2992 fence = next;
3034 else if (r < 0) 2993 if (r <= 0)
3035 pr_err("wait fence %p[%d] interrupted\n", fence, i);
3036 if (r < 1) {
3037 dma_fence_put(fence);
3038 fence = next;
3039 break; 2994 break;
3040 } 2995 } else {
3041 i++; 2996 fence = next;
3042 } 2997 }
3043
3044 dma_fence_put(fence);
3045 fence = next;
3046 } 2998 }
3047 mutex_unlock(&adev->shadow_list_lock); 2999 mutex_unlock(&adev->shadow_list_lock);
3048 3000
3049 if (fence) { 3001 if (fence)
3050 r = dma_fence_wait_timeout(fence, false, tmo); 3002 tmo = dma_fence_wait_timeout(fence, false, tmo);
3051 if (r == 0)
3052 pr_err("wait fence %p[%d] timeout\n", fence, i);
3053 else if (r < 0)
3054 pr_err("wait fence %p[%d] interrupted\n", fence, i);
3055
3056 }
3057 dma_fence_put(fence); 3003 dma_fence_put(fence);
3058 3004
3059 if (r > 0) 3005 if (r <= 0 || tmo <= 0) {
3060 DRM_INFO("recover vram bo from shadow done\n");
3061 else
3062 DRM_ERROR("recover vram bo from shadow failed\n"); 3006 DRM_ERROR("recover vram bo from shadow failed\n");
3007 return -EIO;
3008 }
3063 3009
3064 return (r > 0) ? 0 : 1; 3010 DRM_INFO("recover vram bo from shadow done\n");
3011 return 0;
3065} 3012}
3066 3013
3067/** 3014/**
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 524c21d56f75..113738cbb32c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -553,7 +553,7 @@ static int amdgpu_bo_create_shadow(struct amdgpu_device *adev,
553 if (!r) { 553 if (!r) {
554 bo->shadow->parent = amdgpu_bo_ref(bo); 554 bo->shadow->parent = amdgpu_bo_ref(bo);
555 mutex_lock(&adev->shadow_list_lock); 555 mutex_lock(&adev->shadow_list_lock);
556 list_add_tail(&bo->shadow_list, &adev->shadow_list); 556 list_add_tail(&bo->shadow->shadow_list, &adev->shadow_list);
557 mutex_unlock(&adev->shadow_list_lock); 557 mutex_unlock(&adev->shadow_list_lock);
558 } 558 }
559 559
@@ -685,13 +685,10 @@ retry:
685} 685}
686 686
687/** 687/**
688 * amdgpu_bo_restore_from_shadow - restore an &amdgpu_bo buffer object 688 * amdgpu_bo_restore_shadow - restore an &amdgpu_bo shadow
689 * @adev: amdgpu device object 689 *
690 * @ring: amdgpu_ring for the engine handling the buffer operations 690 * @shadow: &amdgpu_bo shadow to be restored
691 * @bo: &amdgpu_bo buffer to be restored
692 * @resv: reservation object with embedded fence
693 * @fence: dma_fence associated with the operation 691 * @fence: dma_fence associated with the operation
694 * @direct: whether to submit the job directly
695 * 692 *
696 * Copies a buffer object's shadow content back to the object. 693 * Copies a buffer object's shadow content back to the object.
697 * This is used for recovering a buffer from its shadow in case of a gpu 694 * This is used for recovering a buffer from its shadow in case of a gpu
@@ -700,36 +697,19 @@ retry:
700 * Returns: 697 * Returns:
701 * 0 for success or a negative error code on failure. 698 * 0 for success or a negative error code on failure.
702 */ 699 */
703int amdgpu_bo_restore_from_shadow(struct amdgpu_device *adev, 700int amdgpu_bo_restore_shadow(struct amdgpu_bo *shadow, struct dma_fence **fence)
704 struct amdgpu_ring *ring,
705 struct amdgpu_bo *bo,
706 struct reservation_object *resv,
707 struct dma_fence **fence,
708 bool direct)
709 701
710{ 702{
711 struct amdgpu_bo *shadow = bo->shadow; 703 struct amdgpu_device *adev = amdgpu_ttm_adev(shadow->tbo.bdev);
712 uint64_t bo_addr, shadow_addr; 704 struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
713 int r; 705 uint64_t shadow_addr, parent_addr;
714
715 if (!shadow)
716 return -EINVAL;
717
718 bo_addr = amdgpu_bo_gpu_offset(bo);
719 shadow_addr = amdgpu_bo_gpu_offset(bo->shadow);
720
721 r = reservation_object_reserve_shared(bo->tbo.resv);
722 if (r)
723 goto err;
724 706
725 r = amdgpu_copy_buffer(ring, shadow_addr, bo_addr, 707 shadow_addr = amdgpu_bo_gpu_offset(shadow);
726 amdgpu_bo_size(bo), resv, fence, 708 parent_addr = amdgpu_bo_gpu_offset(shadow->parent);
727 direct, false);
728 if (!r)
729 amdgpu_bo_fence(bo, *fence, true);
730 709
731err: 710 return amdgpu_copy_buffer(ring, shadow_addr, parent_addr,
732 return r; 711 amdgpu_bo_size(shadow), NULL, fence,
712 true, false);
733} 713}
734 714
735/** 715/**
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
index 64337ff2ad63..7d3312d0da11 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -273,12 +273,8 @@ int amdgpu_bo_backup_to_shadow(struct amdgpu_device *adev,
273 struct reservation_object *resv, 273 struct reservation_object *resv,
274 struct dma_fence **fence, bool direct); 274 struct dma_fence **fence, bool direct);
275int amdgpu_bo_validate(struct amdgpu_bo *bo); 275int amdgpu_bo_validate(struct amdgpu_bo *bo);
276int amdgpu_bo_restore_from_shadow(struct amdgpu_device *adev, 276int amdgpu_bo_restore_shadow(struct amdgpu_bo *shadow,
277 struct amdgpu_ring *ring, 277 struct dma_fence **fence);
278 struct amdgpu_bo *bo,
279 struct reservation_object *resv,
280 struct dma_fence **fence,
281 bool direct);
282uint32_t amdgpu_bo_get_preferred_pin_domain(struct amdgpu_device *adev, 278uint32_t amdgpu_bo_get_preferred_pin_domain(struct amdgpu_device *adev,
283 uint32_t domain); 279 uint32_t domain);
284 280