"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

Suggested-by: Le Ma <le...@amd.com>
Signed-off-by: Xiaojie Yuan <xiaojie.y...@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 26 ++++++++------------------
 drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 26 ++++++++------------------
 2 files changed, 16 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c 
b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
index abb0ab653b10..e2232dd12d8e 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
@@ -315,30 +315,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)
 {
        struct amdgpu_device *adev = ring->adev;
-       u64 *wptr = NULL;
-       uint64_t local_wptr = 0;
+       u64 wptr;
 
        if (ring->use_doorbell) {
                /* XXX check if swapping is necessary on BE */
-               wptr = ((u64 *)&adev->wb.wb[ring->wptr_offs]);
-               DRM_DEBUG("wptr/doorbell before shift == 0x%016llx\n", *wptr);
-               *wptr = (*wptr) >> 2;
-               DRM_DEBUG("wptr/doorbell after shift == 0x%016llx\n", *wptr);
+               wptr = READ_ONCE(*((u64 *)&adev->wb.wb[ring->wptr_offs]));
+               DRM_DEBUG("wptr/doorbell before shift == 0x%016llx\n", wptr);
        } else {
-               u32 lowbit, highbit;
-
-               wptr = &local_wptr;
-               lowbit = RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, 
mmSDMA0_GFX_RB_WPTR)) >> 2;
-               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;
+               wptr = RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, 
mmSDMA0_GFX_RB_WPTR_HI));
+               wptr = wptr << 32;
+               wptr |= RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, 
mmSDMA0_GFX_RB_WPTR));
+               DRM_DEBUG("wptr before shift [%i] wptr == 0x%016llx\n", 
ring->me, wptr);
        }
 
-       return *wptr;
+       return wptr >> 2;
 }
 
 /**
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c 
b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
index 1ef14b610a4f..824f3e23c3d9 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
@@ -262,30 +262,20 @@ static uint64_t sdma_v5_2_ring_get_rptr(struct 
amdgpu_ring *ring)
 static uint64_t sdma_v5_2_ring_get_wptr(struct amdgpu_ring *ring)
 {
        struct amdgpu_device *adev = ring->adev;
-       u64 *wptr = NULL;
-       uint64_t local_wptr = 0;
+       u64 wptr;
 
        if (ring->use_doorbell) {
                /* XXX check if swapping is necessary on BE */
-               wptr = ((u64 *)&adev->wb.wb[ring->wptr_offs]);
-               DRM_DEBUG("wptr/doorbell before shift == 0x%016llx\n", *wptr);
-               *wptr = (*wptr) >> 2;
-               DRM_DEBUG("wptr/doorbell after shift == 0x%016llx\n", *wptr);
+               wptr = READ_ONCE(*((u64 *)&adev->wb.wb[ring->wptr_offs]));
+               DRM_DEBUG("wptr/doorbell before shift == 0x%016llx\n", wptr);
        } else {
-               u32 lowbit, highbit;
-
-               wptr = &local_wptr;
-               lowbit = RREG32(sdma_v5_2_get_reg_offset(adev, ring->me, 
mmSDMA0_GFX_RB_WPTR)) >> 2;
-               highbit = RREG32(sdma_v5_2_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;
+               wptr = RREG32(sdma_v5_2_get_reg_offset(adev, ring->me, 
mmSDMA0_GFX_RB_WPTR_HI));
+               wptr = wptr << 32;
+               wptr |= RREG32(sdma_v5_2_get_reg_offset(adev, ring->me, 
mmSDMA0_GFX_RB_WPTR));
+               DRM_DEBUG("wptr before shift [%i] wptr == 0x%016llx\n", 
ring->me, wptr);
        }
 
-       return *wptr;
+       return wptr >> 2;
 }
 
 /**
-- 
2.20.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to