Commit 8f6b6d06 authored by Brad Kim's avatar Brad Kim Committed by Vinod Koul
Browse files

dmaengine: sf-pdma: Fix an error that calls callback twice



Because a callback is called twice when DMA transfer complete
the second callback may be possible to access a freed memory
if the first callback routines perform the dma_release_channel function.
So this patch serialized the callback functions

Signed-off-by: default avatarBrad Kim <brad.kim@semifive.com>
Tested-and-reviewed-by: default avatarGreen Wan <green.wan@sifive.com>
Signed-off-by: default avatarBrad Kim <brad.kim@sifive.com>
Link: https://lore.kernel.org/r/20200903111726.3413-1-brad.kim@sifive.com


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 78e7a522
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -295,7 +295,10 @@ static void sf_pdma_donebh_tasklet(unsigned long arg)
	}
	spin_unlock_irqrestore(&chan->lock, flags);

	dmaengine_desc_get_callback_invoke(desc->async_tx, NULL);
	spin_lock_irqsave(&chan->vchan.lock, flags);
	list_del(&chan->desc->vdesc.node);
	vchan_cookie_complete(&chan->desc->vdesc);
	spin_unlock_irqrestore(&chan->vchan.lock, flags);
}

static void sf_pdma_errbh_tasklet(unsigned long arg)
@@ -332,8 +335,7 @@ static irqreturn_t sf_pdma_done_isr(int irq, void *dev_id)
	residue = readq(regs->residue);

	if (!residue) {
		list_del(&chan->desc->vdesc.node);
		vchan_cookie_complete(&chan->desc->vdesc);
		tasklet_hi_schedule(&chan->done_tasklet);
	} else {
		/* submit next trascatioin if possible */
		struct sf_pdma_desc *desc = chan->desc;
@@ -347,8 +349,6 @@ static irqreturn_t sf_pdma_done_isr(int irq, void *dev_id)

	spin_unlock_irqrestore(&chan->vchan.lock, flags);

	tasklet_hi_schedule(&chan->done_tasklet);

	return IRQ_HANDLED;
}