On 14-11-23, 13:22, Thomas Pfaff wrote: > From: Thomas Pfaff <tpfaff@xxxxxxx> > > In kernel 6.1, atc_advance_work and atc_handle_error are checking for the > next dma transfer inside active list, but the descriptor is taken from the > queue instead. Sorry that is not how this works. Please send the patch for mainline and add a stable tag to the patches. They will be backported to stable kernels Also, your patch threading is broken, they appear disjoint and not as a series Thanks > > Signed-off-by: Thomas Pfaff <tpfaff@xxxxxxx> > --- > diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c > index 858bd64f1313..68c1bfbefc5c 100644 > --- a/drivers/dma/at_hdmac.c > +++ b/drivers/dma/at_hdmac.c > @@ -490,6 +490,27 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc) > } > } > > +/** > + * atc_start_next - start next pending transaction if any > + * @atchan: channel where the transaction ended > + * > + * Called with atchan->lock held > + */ > +static void atc_start_next(struct at_dma_chan *atchan) > +{ > + struct at_desc *desc = NULL; > + > + if (!list_empty(&atchan->active_list)) > + desc = atc_first_active(atchan); > + else if (!list_empty(&atchan->queue)) { > + desc = atc_first_queued(atchan); > + list_move_tail(&desc->desc_node, &atchan->active_list); > + } > + > + if (desc) > + atc_dostart(atchan, desc); > +} > + > /** > * atc_advance_work - at the end of a transaction, move forward > * @atchan: channel where the transaction ended > @@ -513,11 +534,7 @@ static void atc_advance_work(struct at_dma_chan *atchan) > > /* advance work */ > spin_lock_irqsave(&atchan->lock, flags); > - if (!list_empty(&atchan->active_list)) { > - desc = atc_first_queued(atchan); > - list_move_tail(&desc->desc_node, &atchan->active_list); > - atc_dostart(atchan, desc); > - } > + atc_start_next(atchan); > spin_unlock_irqrestore(&atchan->lock, flags); > } > > @@ -529,7 +546,6 @@ static void atc_advance_work(struct at_dma_chan *atchan) > static void atc_handle_error(struct at_dma_chan *atchan) > { > struct at_desc *bad_desc; > - struct at_desc *desc; > struct at_desc *child; > unsigned long flags; > > @@ -543,11 +559,7 @@ static void atc_handle_error(struct at_dma_chan *atchan) > list_del_init(&bad_desc->desc_node); > > /* Try to restart the controller */ > - if (!list_empty(&atchan->active_list)) { > - desc = atc_first_queued(atchan); > - list_move_tail(&desc->desc_node, &atchan->active_list); > - atc_dostart(atchan, desc); > - } > + atc_start_next(atchan); > > /* > * KERN_CRITICAL may seem harsh, but since this only happens > -- ~Vinod