Commit 05051496 authored by Xiaojie Yuan's avatar Xiaojie Yuan Committed by Alex Deucher

drm/amdgpu/sdma5: fix wptr overwritten in ->get_wptr()

"u64 *wptr" points to the the wptr value in write back buffer and
"*wptr = (*wptr) >> 2;" results in the value being overwritten each time
when ->get_wptr() is called.

umr uses /sys/kernel/debug/dri/0/amdgpu_ring_sdma0 to get rptr/wptr and
decode ring content and it is affected by this issue.

fix and simplify the logic similar as sdma_v4_0_ring_get_wptr().

v2: fix for sdma5.2 as well
v3: drop sdma 5.2 changes for 5.8 and stable
Suggested-by: default avatarLe Ma <le.ma@amd.com>
Signed-off-by: default avatarXiaojie Yuan <xiaojie.yuan@amd.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
parent 98a34cf9
...@@ -314,30 +314,20 @@ static uint64_t sdma_v5_0_ring_get_rptr(struct amdgpu_ring *ring) ...@@ -314,30 +314,20 @@ static uint64_t sdma_v5_0_ring_get_rptr(struct amdgpu_ring *ring)
static uint64_t sdma_v5_0_ring_get_wptr(struct amdgpu_ring *ring) static uint64_t sdma_v5_0_ring_get_wptr(struct amdgpu_ring *ring)
{ {
struct amdgpu_device *adev = ring->adev; struct amdgpu_device *adev = ring->adev;
u64 *wptr = NULL; u64 wptr;
uint64_t local_wptr = 0;
if (ring->use_doorbell) { if (ring->use_doorbell) {
/* XXX check if swapping is necessary on BE */ /* XXX check if swapping is necessary on BE */
wptr = ((u64 *)&adev->wb.wb[ring->wptr_offs]); wptr = READ_ONCE(*((u64 *)&adev->wb.wb[ring->wptr_offs]));
DRM_DEBUG("wptr/doorbell before shift == 0x%016llx\n", *wptr); DRM_DEBUG("wptr/doorbell before shift == 0x%016llx\n", wptr);
*wptr = (*wptr) >> 2;
DRM_DEBUG("wptr/doorbell after shift == 0x%016llx\n", *wptr);
} else { } else {
u32 lowbit, highbit; wptr = RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI));
wptr = wptr << 32;
wptr = &local_wptr; wptr |= RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR));
lowbit = RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR)) >> 2; DRM_DEBUG("wptr before shift [%i] wptr == 0x%016llx\n", ring->me, wptr);
highbit = RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI)) >> 2;
DRM_DEBUG("wptr [%i]high== 0x%08x low==0x%08x\n",
ring->me, highbit, lowbit);
*wptr = highbit;
*wptr = (*wptr) << 32;
*wptr |= lowbit;
} }
return *wptr; return wptr >> 2;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment