Re: [PATCH] dmaengine: sh: rz-dmac: Fix off-by-one in residue lmdesc lookup
From: Frank Li
Date: Thu Sep 24 2026 - 17:18:02 EST
On Tue, Sep 22, 2026 at 12:20:37PM +0300, Claudiu Beznea wrote:
> From: Tommaso Merciai <tommaso.merciai.xr@xxxxxxxxxxxxxx>
>
> lmdesc->nxla is the address of the next descriptor, so comparing it
> against CRLA, which is the address of the current descriptor,
> finds the descriptor before the active one, not the active one.
> The residue loops below then summed one lmdesc too many on top of
> that.
>
> Compare each descriptor's own address to CRLA instead, and add tb
> after advancing to the next lmdesc.
>
> Fixes: 21323b118c16 ("dmaengine: sh: rz-dmac: Add device_tx_status() callback")
> Fixes: 172bfb57481c ("dmaengine: sh: rz-dmac: Add cyclic DMA support")
> Cc: stable@xxxxxxxxxxxxxxx
> Suggested-by: Claudiu Beznea <claudiu.beznea.uj@xxxxxxxxxxxxxx>
> Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@xxxxxxxxxxxxxx>
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@xxxxxxxxxxxxxx>
> ---
Reviewed-by: Frank Li <Frank.Li@xxxxxxx>
> drivers/dma/sh/rz-dmac.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c
> index ca76f1bb45c4..fdd7131e890a 100644
> --- a/drivers/dma/sh/rz-dmac.c
> +++ b/drivers/dma/sh/rz-dmac.c
> @@ -937,7 +937,7 @@ static u32 rz_dmac_calculate_residue_bytes_in_vd(struct rz_dmac_chan *channel,
> struct rz_dmac *dmac = to_rz_dmac(chan->device);
> u32 residue = 0, i = 0;
>
> - while (lmdesc->nxla != crla) {
> + while (rz_dmac_lmdesc_addr(channel, lmdesc) != crla) {
> lmdesc = rz_dmac_get_next_lmdesc(channel->lmdesc.base, lmdesc);
> if (++i >= DMAC_NR_LMDESC)
> return 0;
> @@ -948,13 +948,13 @@ static u32 rz_dmac_calculate_residue_bytes_in_vd(struct rz_dmac_chan *channel,
> u32 start_lmdesc_addr = rz_dmac_lmdesc_addr(channel, desc->start_lmdesc);
>
> while (lmdesc->nxla != start_lmdesc_addr) {
> - residue += lmdesc->tb;
> lmdesc = rz_dmac_get_next_lmdesc(channel->lmdesc.base, lmdesc);
> + residue += lmdesc->tb;
> }
> } else {
> while (lmdesc->chcfg & CHCFG_DEM) {
> - residue += lmdesc->tb;
> lmdesc = rz_dmac_get_next_lmdesc(channel->lmdesc.base, lmdesc);
> + residue += lmdesc->tb;
> }
> }
>
> --
> 2.43.0
>