On 18/08/2020 13.16, Peter Ujfalusi wrote: ... >> +static void dma_issue_pending(struct dma_chan *chan) >> +{ >> + struct ldma_chan *c = to_ldma_chan(chan); >> + struct ldma_dev *d = to_ldma_dev(c->vchan.chan.device); >> + unsigned long flags; >> + >> + if (d->ver == DMA_VER22) { >> + spin_lock_irqsave(&c->vchan.lock, flags); >> + if (vchan_issue_pending(&c->vchan)) { >> + struct virt_dma_desc *vdesc; >> + >> + /* Get the next descriptor */ >> + vdesc = vchan_next_desc(&c->vchan); >> + if (!vdesc) { >> + c->ds = NULL; >> + return; >> + } >> + list_del(&vdesc->node); >> + c->ds = to_lgm_dma_desc(vdesc); > > you have set c->ds in dma_prep_slave_sg and the only way I can see that > you will not leak memory is that the client must terminate_sync() after > each transfer so that the synchronize callback is invoked between each > prep_sg/issue_pending/competion. > >> + spin_unlock_irqrestore(&c->vchan.lock, flags); >> + ldma_chan_desc_hw_cfg(c, c->ds->desc_phys, c->ds->desc_cnt); >> + ldma_chan_irq_en(c); >> + } > > If there is nothing pending, you will leave the spinlock wide open... you leave it locked... > >> + } >> + ldma_chan_on(c); >> +} - Péter Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki