[PATCH v2] drm/amdgpu/sdma5: fix wptr overwritten in ->get_wptr()

Christian König ckoenig.leichtzumerken at gmail.com
Tue Jul 14 09:30:42 UTC 2020


Am 14.07.20 um 11:09 schrieb Xiaojie Yuan:
> "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.ma at amd.com>
> Signed-off-by: Xiaojie Yuan <xiaojie.yuan at amd.com>

Reviewed-by: Christian König <christian.koenig at 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;
>   }
>   
>   /**



More information about the amd-gfx mailing list