All of lore.kernel.org
 help / color / mirror / Atom feed
From: Russell King - ARM Linux admin <linux@armlinux.org.uk>
To: Lucas Stach <l.stach@pengutronix.de>
Cc: Michael Olbrich <m.olbrich@pengutronix.de>,
	Vinod Koul <vinod.koul@intel.com>,
	linux-arm-kernel@lists.infradead.org, dmaengine@vger.kernel.org
Subject: Re: [BUG] imx-sdma: readl_relaxed_poll_timeout_atomic() conversion
Date: Mon, 24 Jun 2019 13:15:33 +0100	[thread overview]
Message-ID: <20190624121533.3sd6mmxjfktllp2j@shell.armlinux.org.uk> (raw)
In-Reply-To: <1561378450.2587.3.camel@pengutronix.de>

On Mon, Jun 24, 2019 at 02:14:10PM +0200, Lucas Stach wrote:
> Hi Russell,
> 
> Am Samstag, den 22.06.2019, 19:42 +0100 schrieb Russell King - ARM Linux admin:
> > On Sat, Jun 22, 2019 at 08:10:29PM +0200, Michael Olbrich wrote:
> > > On Sat, Jun 22, 2019 at 05:53:18PM +0100, Russell King - ARM Linux admin wrote:
> > > > Old code:
> > > > 
> > > > -       while (!(ret = readl_relaxed(sdma->regs + SDMA_H_INTR) & 1)) {
> > > > -               if (timeout-- <= 0)
> > > > -                       break;
> > > > -               udelay(1);
> > > > -       }
> > > > 
> > > > So, while bit 0 is _clear_ the loop continues to poll.
> > > > 
> > > > 
> > > > New code:
> > > > 
> > > > +       ret = readl_relaxed_poll_timeout_atomic(sdma->regs + SDMA_H_STATSTOP,
> > > > +                                               reg, !(reg & 1), 1, 500);
> > > > 
> > > > Doesn't really tell us what the termination condition is (because of
> > > > the obfuscation taking away the details), but if we dig into the
> > > > macro maze:
> > > > 
> > > > #define readl_relaxed_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \
> > > >         readx_poll_timeout_atomic(readl_relaxed, addr, val, cond, delay_us, timeout_us)
> > > > 
> > > > #define readx_poll_timeout_atomic(op, addr, val, cond, delay_us, timeout_us) \
> > > > ({ \
> > > >         u64 __timeout_us = (timeout_us); \
> > > >         unsigned long __delay_us = (delay_us); \
> > > >         ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
> > > >         for (;;) { \
> > > >                 (val) = op(addr); \
> > > >                 if (cond) \
> > > >                         break; \
> > > > 
> > > > "cond" is passed in to here unmodified, so this becomes:
> > > > 
> > > > 	for (;;) {
> > > > > > > 		reg = readl_relaxed(sdma->regs + SDMA_H_STATSTOP);
> > > > > > > 		if (!(reg & 1))
> > > > > > > 			break;
> > > > 
> > > > So, if bit 0 of this register is clear, we terminate the loop.
> > > > 
> > > > Seems to me like this is a great illustration why using a helper
> > > > _introduces_ bugs, because it hides the detail about what the exit
> > > > condition for the embedded loop actually is, and leads to this kind
> > > > of error.
> > > > 
> > > > In any case, the conversion is obviously incorrect.
> > > > 
> > > > I occasionally see the "Timeout waiting for CH0 ready" error during
> > > > boot on a cbi4, which, given the above, means that we did end up
> > > > seeing bit 1 set (so according to the old code, we waited
> > > > successfully.)
> > > 
> > > The old code was polling SDMA_H_INTR so it waited for the bit to be set.
> > > The new code (as documented in the commit message) polls SDMA_H_STATSTOP
> > > instead.
> > > I believe this register is called SDMAARM_STOP_STAT in the reference
> > > manual. And the documentation states: "Reading this register yields the
> > > current state of the HE[i] bits".
> > > And from the documentation of the SDMA "DONE" instruction:
> > > "Clear HE bit for the current channel, send an interrupt to the Arm
> > > platform for the current channel and reschedule."
> > > 
> > > My interpretation of this is, that waiting for the bit in SDMA_H_STATSTOP
> > > to become zero has the same effect as waiting for the bit in SDMA_H_INTR to
> > > be set. Or am I missing something?
> > 
> > So, why do all my iMX6 platforms now randomly spit out:
> > 
> > "imx-sdma 20ec000.sdma: Timeout waiting for CH0 ready"
> 
> This is due to a DT misconfiguration which was uncovered with a recent
> driver change (25aaa75df1e6 dmaengine: imx-sdma: add clock ratio 1:1
> check) and fixed with (941acd566b18 dmaengine: imx-sdma: Only check
> ratio on parts that support 1:1). Please switch to a recent stable
> kernel, 5.1.5 has the fix included.

Please point to the fix, thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up

WARNING: multiple messages have this Message-ID (diff)
From: Russell King - ARM Linux admin <linux@armlinux.org.uk>
To: Lucas Stach <l.stach@pengutronix.de>
Cc: Vinod Koul <vinod.koul@intel.com>,
	dmaengine@vger.kernel.org,
	Michael Olbrich <m.olbrich@pengutronix.de>,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [BUG] imx-sdma: readl_relaxed_poll_timeout_atomic() conversion
Date: Mon, 24 Jun 2019 13:15:33 +0100	[thread overview]
Message-ID: <20190624121533.3sd6mmxjfktllp2j@shell.armlinux.org.uk> (raw)
In-Reply-To: <1561378450.2587.3.camel@pengutronix.de>

On Mon, Jun 24, 2019 at 02:14:10PM +0200, Lucas Stach wrote:
> Hi Russell,
> 
> Am Samstag, den 22.06.2019, 19:42 +0100 schrieb Russell King - ARM Linux admin:
> > On Sat, Jun 22, 2019 at 08:10:29PM +0200, Michael Olbrich wrote:
> > > On Sat, Jun 22, 2019 at 05:53:18PM +0100, Russell King - ARM Linux admin wrote:
> > > > Old code:
> > > > 
> > > > -       while (!(ret = readl_relaxed(sdma->regs + SDMA_H_INTR) & 1)) {
> > > > -               if (timeout-- <= 0)
> > > > -                       break;
> > > > -               udelay(1);
> > > > -       }
> > > > 
> > > > So, while bit 0 is _clear_ the loop continues to poll.
> > > > 
> > > > 
> > > > New code:
> > > > 
> > > > +       ret = readl_relaxed_poll_timeout_atomic(sdma->regs + SDMA_H_STATSTOP,
> > > > +                                               reg, !(reg & 1), 1, 500);
> > > > 
> > > > Doesn't really tell us what the termination condition is (because of
> > > > the obfuscation taking away the details), but if we dig into the
> > > > macro maze:
> > > > 
> > > > #define readl_relaxed_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \
> > > >         readx_poll_timeout_atomic(readl_relaxed, addr, val, cond, delay_us, timeout_us)
> > > > 
> > > > #define readx_poll_timeout_atomic(op, addr, val, cond, delay_us, timeout_us) \
> > > > ({ \
> > > >         u64 __timeout_us = (timeout_us); \
> > > >         unsigned long __delay_us = (delay_us); \
> > > >         ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
> > > >         for (;;) { \
> > > >                 (val) = op(addr); \
> > > >                 if (cond) \
> > > >                         break; \
> > > > 
> > > > "cond" is passed in to here unmodified, so this becomes:
> > > > 
> > > > 	for (;;) {
> > > > > > > 		reg = readl_relaxed(sdma->regs + SDMA_H_STATSTOP);
> > > > > > > 		if (!(reg & 1))
> > > > > > > 			break;
> > > > 
> > > > So, if bit 0 of this register is clear, we terminate the loop.
> > > > 
> > > > Seems to me like this is a great illustration why using a helper
> > > > _introduces_ bugs, because it hides the detail about what the exit
> > > > condition for the embedded loop actually is, and leads to this kind
> > > > of error.
> > > > 
> > > > In any case, the conversion is obviously incorrect.
> > > > 
> > > > I occasionally see the "Timeout waiting for CH0 ready" error during
> > > > boot on a cbi4, which, given the above, means that we did end up
> > > > seeing bit 1 set (so according to the old code, we waited
> > > > successfully.)
> > > 
> > > The old code was polling SDMA_H_INTR so it waited for the bit to be set.
> > > The new code (as documented in the commit message) polls SDMA_H_STATSTOP
> > > instead.
> > > I believe this register is called SDMAARM_STOP_STAT in the reference
> > > manual. And the documentation states: "Reading this register yields the
> > > current state of the HE[i] bits".
> > > And from the documentation of the SDMA "DONE" instruction:
> > > "Clear HE bit for the current channel, send an interrupt to the Arm
> > > platform for the current channel and reschedule."
> > > 
> > > My interpretation of this is, that waiting for the bit in SDMA_H_STATSTOP
> > > to become zero has the same effect as waiting for the bit in SDMA_H_INTR to
> > > be set. Or am I missing something?
> > 
> > So, why do all my iMX6 platforms now randomly spit out:
> > 
> > "imx-sdma 20ec000.sdma: Timeout waiting for CH0 ready"
> 
> This is due to a DT misconfiguration which was uncovered with a recent
> driver change (25aaa75df1e6 dmaengine: imx-sdma: add clock ratio 1:1
> check) and fixed with (941acd566b18 dmaengine: imx-sdma: Only check
> ratio on parts that support 1:1). Please switch to a recent stable
> kernel, 5.1.5 has the fix included.

Please point to the fix, thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2019-06-24 12:15 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-22 16:53 [BUG] imx-sdma: readl_relaxed_poll_timeout_atomic() conversion Russell King - ARM Linux admin
2019-06-22 16:53 ` Russell King - ARM Linux admin
2019-06-22 18:02 ` [PATCH] dmaengine: imx-sdma: fix incorrect conversion to readl_relaxed_poll_timeout_atomic() Russell King
2019-06-22 18:02   ` Russell King
2019-06-22 18:10 ` [BUG] imx-sdma: readl_relaxed_poll_timeout_atomic() conversion Michael Olbrich
2019-06-22 18:10   ` Michael Olbrich
2019-06-22 18:42   ` Russell King - ARM Linux admin
2019-06-22 18:42     ` Russell King - ARM Linux admin
2019-06-22 18:51     ` Russell King - ARM Linux admin
2019-06-22 18:51       ` Russell King - ARM Linux admin
2019-06-24 12:14     ` Lucas Stach
2019-06-24 12:14       ` Lucas Stach
2019-06-24 12:15       ` Russell King - ARM Linux admin [this message]
2019-06-24 12:15         ` Russell King - ARM Linux admin
2019-06-24 12:52         ` Lucas Stach
2019-06-24 12:52           ` Lucas Stach
2019-06-22 18:55 ` [PATCH v2] dmaengine: imx-sdma: fix incorrect conversion to readl_relaxed_poll_timeout_atomic() Russell King
2019-06-22 18:55   ` Russell King
2019-06-22 19:26   ` Russell King - ARM Linux admin
2019-06-22 19:26     ` Russell King - ARM Linux admin
2019-06-22 20:26     ` Russell King - ARM Linux admin
2019-06-22 20:26       ` Russell King - ARM Linux admin
2019-06-23 13:29       ` Fabio Estevam
2019-06-23 13:29         ` Fabio Estevam
2019-06-25  9:00         ` Robin Gong
2019-06-25  9:00           ` Robin Gong

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=20190624121533.3sd6mmxjfktllp2j@shell.armlinux.org.uk \
    --to=linux@armlinux.org.uk \
    --cc=dmaengine@vger.kernel.org \
    --cc=l.stach@pengutronix.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=m.olbrich@pengutronix.de \
    --cc=vinod.koul@intel.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.