DMA Engine development
 help / color / mirror / Atom feed
From: Lukas Wunner <lukas@wunner.de>
To: Vinod Koul <vkoul@kernel.org>, Eric Anholt <eric@anholt.net>,
	Stefan Wahren <stefan.wahren@i2se.com>
Cc: Frank Pavlic <f.pavlic@kunbus.de>,
	Martin Sperl <kernel@martin.sperl.org>,
	Florian Meier <florian.meier@koalo.de>,
	dmaengine@vger.kernel.org, linux-rpi-kernel@lists.infradead.org,
	Tiejun Chen <tiejun.china@gmail.com>,
	linux-rt-users@vger.kernel.org
Subject: [1/5] dmaengine: bcm2835: Fix interrupt race on RT
Date: Thu, 17 Jan 2019 09:26:56 +0100	[thread overview]
Message-ID: <20190117082656.isv3ld2jg3jyzogf@wunner.de> (raw)

On Sat, Dec 22, 2018 at 08:28:45AM +0100, Lukas Wunner wrote:
> That MMIO read is needed to write the same value to the CS register that
> it currently has, thereby preserving the ACTIVE flag while clearing the
> INT and END flags.  Note that the transaction may finish between reading
> and writing the CS register, and in that case the write changes the
> ACTIVE flag from 0 to 1.  But that's harmless, the chip will notice that
> NEXTCONBK is 0 and self-clear the ACTIVE flag again.

Further experimentation has shown that the chip does not self-clear the
ACTIVE flag if it is set on an idle channel, contrary to what I have
written above. Consequently that flag cannot be used to determine idleness
of a channel reliably. A workaround is to check whether the register
containing the current control block's address is zero. I have amended
the patch accordingly and it is currently undergoing stresstesting until
Monday.  So I should be able to post an updated version of the series
next week.

I have also updated the patch to fix the following remaining race:

> @@ -477,11 +479,17 @@ static irqreturn_t bcm2835_dma_callback(int irq, void *data)
>  	spin_lock_irqsave(&c->vc.lock, flags);
>  
>  	/* Acknowledge interrupt */
> -	writel(BCM2835_DMA_INT, c->chan_base + BCM2835_DMA_CS);
> +	cs = readl(c->chan_base + BCM2835_DMA_CS);
> +	writel(cs, c->chan_base + BCM2835_DMA_CS);
>  
>  	d = c->desc;
>  
> -	if (d) {
> +	/*
> +	 * If this IRQ handler is threaded, clients may terminate descriptors
> +	 * and issue new ones before the IRQ handler runs.  Avoid finalizing
> +	 * such a newly issued descriptor by checking the END flag.
> +	 */
> +	if (d && cs & BCM2835_DMA_END) {
>  		if (d->cyclic) {
>  			/* call the cyclic callback */
>  			vchan_cyclic_callback(&d->vd);

The descriptor may be finished between the read and the write of the
CS register, and in that case the interrupt for the finished descriptor
will be acknowledged but the descriptor will not be finalized because
END was not yet set when the register was read. I haven't seen this
race in the real world but it's definitely not correct and I've fixed
it as well for v2.

Thanks,

Lukas

             reply	other threads:[~2019-01-17  8:26 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-17  8:26 Lukas Wunner [this message]
  -- strict thread matches above, loose matches on Subject: below --
2019-01-07  8:32 [1/5] dmaengine: bcm2835: Fix interrupt race on RT Lukas Wunner
2019-01-07  7:00 Vinod Koul
2018-12-22  7:28 Lukas Wunner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190117082656.isv3ld2jg3jyzogf@wunner.de \
    --to=lukas@wunner.de \
    --cc=dmaengine@vger.kernel.org \
    --cc=eric@anholt.net \
    --cc=f.pavlic@kunbus.de \
    --cc=florian.meier@koalo.de \
    --cc=kernel@martin.sperl.org \
    --cc=linux-rpi-kernel@lists.infradead.org \
    --cc=linux-rt-users@vger.kernel.org \
    --cc=stefan.wahren@i2se.com \
    --cc=tiejun.china@gmail.com \
    --cc=vkoul@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox