diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_device.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 109 |
1 files changed, 28 insertions, 81 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 | */ | ||
2966 | static 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 | } | ||
2996 | err: | ||
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 | */ |
3011 | static int amdgpu_device_recover_vram(struct amdgpu_device *adev) | 2965 | static 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 | /** |