linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v0 linux master] i2c/busses: Avoid i2c interrupt status clear race condition.
@ 2020-04-29  3:37 ryan_chen
  2020-04-29  7:53 ` Wolfram Sang
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: ryan_chen @ 2020-04-29  3:37 UTC (permalink / raw)
  To: Brendan Higgins, Benjamin Herrenschmidt, Joel Stanley,
	Andrew Jeffery, linux-i2c, openbmc, linux-arm-kernel,
	linux-aspeed, linux-kernel
  Cc: ryan_chen

In AST2600 there have a slow peripheral bus between CPU
 and i2c controller.
Therefore GIC i2c interrupt status clear have delay timing,
when CPU issue write clear i2c controller interrupt status.
To avoid this issue, the driver need have read after write
 clear at i2c ISR.

Signed-off-by: ryan_chen <ryan_chen@aspeedtech.com>
---
 drivers/i2c/busses/i2c-aspeed.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
index 07c1993274c5..f51702d86a90 100644
--- a/drivers/i2c/busses/i2c-aspeed.c
+++ b/drivers/i2c/busses/i2c-aspeed.c
@@ -603,6 +603,7 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
 	/* Ack all interrupts except for Rx done */
 	writel(irq_received & ~ASPEED_I2CD_INTR_RX_DONE,
 	       bus->base + ASPEED_I2C_INTR_STS_REG);
+	readl(bus->base + ASPEED_I2C_INTR_STS_REG);
 	irq_remaining = irq_received;
 
 #if IS_ENABLED(CONFIG_I2C_SLAVE)
@@ -645,9 +646,11 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
 			irq_received, irq_handled);
 
 	/* Ack Rx done */
-	if (irq_received & ASPEED_I2CD_INTR_RX_DONE)
+	if (irq_received & ASPEED_I2CD_INTR_RX_DONE) {
 		writel(ASPEED_I2CD_INTR_RX_DONE,
 		       bus->base + ASPEED_I2C_INTR_STS_REG);
+		readl(bus->base + ASPEED_I2C_INTR_STS_REG);
+	}
 	spin_unlock(&bus->lock);
 	return irq_remaining ? IRQ_NONE : IRQ_HANDLED;
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v0 linux master] i2c/busses: Avoid i2c interrupt status clear race condition.
  2020-04-29  3:37 [PATCH v0 linux master] i2c/busses: Avoid i2c interrupt status clear race condition ryan_chen
@ 2020-04-29  7:53 ` Wolfram Sang
  2020-04-29  8:12   ` Ryan Chen
  2020-04-30 10:52 ` Benjamin Herrenschmidt
  2020-04-30 14:17 ` Wolfram Sang
  2 siblings, 1 reply; 9+ messages in thread
From: Wolfram Sang @ 2020-04-29  7:53 UTC (permalink / raw)
  To: ryan_chen
  Cc: Brendan Higgins, Benjamin Herrenschmidt, Joel Stanley,
	Andrew Jeffery, linux-i2c, openbmc, linux-arm-kernel,
	linux-aspeed, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1667 bytes --]

On Wed, Apr 29, 2020 at 11:37:37AM +0800, ryan_chen wrote:
> In AST2600 there have a slow peripheral bus between CPU
>  and i2c controller.
> Therefore GIC i2c interrupt status clear have delay timing,
> when CPU issue write clear i2c controller interrupt status.
> To avoid this issue, the driver need have read after write
>  clear at i2c ISR.
> 
> Signed-off-by: ryan_chen <ryan_chen@aspeedtech.com>

v0? is it a prototype?

And is there maybe a Fixes: tag for it?

> ---
>  drivers/i2c/busses/i2c-aspeed.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
> index 07c1993274c5..f51702d86a90 100644
> --- a/drivers/i2c/busses/i2c-aspeed.c
> +++ b/drivers/i2c/busses/i2c-aspeed.c
> @@ -603,6 +603,7 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
>  	/* Ack all interrupts except for Rx done */
>  	writel(irq_received & ~ASPEED_I2CD_INTR_RX_DONE,
>  	       bus->base + ASPEED_I2C_INTR_STS_REG);
> +	readl(bus->base + ASPEED_I2C_INTR_STS_REG);
>  	irq_remaining = irq_received;
>  
>  #if IS_ENABLED(CONFIG_I2C_SLAVE)
> @@ -645,9 +646,11 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
>  			irq_received, irq_handled);
>  
>  	/* Ack Rx done */
> -	if (irq_received & ASPEED_I2CD_INTR_RX_DONE)
> +	if (irq_received & ASPEED_I2CD_INTR_RX_DONE) {
>  		writel(ASPEED_I2CD_INTR_RX_DONE,
>  		       bus->base + ASPEED_I2C_INTR_STS_REG);
> +		readl(bus->base + ASPEED_I2C_INTR_STS_REG);
> +	}
>  	spin_unlock(&bus->lock);
>  	return irq_remaining ? IRQ_NONE : IRQ_HANDLED;
>  }
> -- 
> 2.17.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH v0 linux master] i2c/busses: Avoid i2c interrupt status clear race condition.
  2020-04-29  7:53 ` Wolfram Sang
@ 2020-04-29  8:12   ` Ryan Chen
  2020-04-29  9:03     ` Wolfram Sang
  0 siblings, 1 reply; 9+ messages in thread
From: Ryan Chen @ 2020-04-29  8:12 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Brendan Higgins, Benjamin Herrenschmidt, Joel Stanley,
	Andrew Jeffery, linux-i2c, openbmc, linux-arm-kernel,
	linux-aspeed, linux-kernel

-----Original Message-----
From: Wolfram Sang [mailto:wsa@the-dreams.de] 
Sent: Wednesday, April 29, 2020 3:54 PM
To: Ryan Chen <ryan_chen@aspeedtech.com>
Cc: Brendan Higgins <brendanhiggins@google.com>; Benjamin Herrenschmidt <benh@kernel.crashing.org>; Joel Stanley <joel@jms.id.au>; Andrew Jeffery <andrew@aj.id.au>; linux-i2c@vger.kernel.org; openbmc@lists.ozlabs.org; linux-arm-kernel@lists.infradead.org; linux-aspeed@lists.ozlabs.org; linux-kernel@vger.kernel.org
Subject: Re: [PATCH v0 linux master] i2c/busses: Avoid i2c interrupt status clear race condition.

On Wed, Apr 29, 2020 at 11:37:37AM +0800, ryan_chen wrote:
> In AST2600 there have a slow peripheral bus between CPU  and i2c 
> controller.
> Therefore GIC i2c interrupt status clear have delay timing, when CPU 
> issue write clear i2c controller interrupt status.
> To avoid this issue, the driver need have read after write  clear at 
> i2c ISR.
> 
> Signed-off-by: ryan_chen <ryan_chen@aspeedtech.com>

v0? is it a prototype?
[Ryan Chen] It is not prototype it is official patch.
And is there maybe a Fixes: tag for it?
[Ryan Chen] Yes it is a fix patch.

> ---
>  drivers/i2c/busses/i2c-aspeed.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/i2c/busses/i2c-aspeed.c 
> b/drivers/i2c/busses/i2c-aspeed.c index 07c1993274c5..f51702d86a90 
> 100644
> --- a/drivers/i2c/busses/i2c-aspeed.c
> +++ b/drivers/i2c/busses/i2c-aspeed.c
> @@ -603,6 +603,7 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
>  	/* Ack all interrupts except for Rx done */
>  	writel(irq_received & ~ASPEED_I2CD_INTR_RX_DONE,
>  	       bus->base + ASPEED_I2C_INTR_STS_REG);
> +	readl(bus->base + ASPEED_I2C_INTR_STS_REG);
>  	irq_remaining = irq_received;
>  
>  #if IS_ENABLED(CONFIG_I2C_SLAVE)
> @@ -645,9 +646,11 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
>  			irq_received, irq_handled);
>  
>  	/* Ack Rx done */
> -	if (irq_received & ASPEED_I2CD_INTR_RX_DONE)
> +	if (irq_received & ASPEED_I2CD_INTR_RX_DONE) {
>  		writel(ASPEED_I2CD_INTR_RX_DONE,
>  		       bus->base + ASPEED_I2C_INTR_STS_REG);
> +		readl(bus->base + ASPEED_I2C_INTR_STS_REG);
> +	}
>  	spin_unlock(&bus->lock);
>  	return irq_remaining ? IRQ_NONE : IRQ_HANDLED;  }
> --
> 2.17.1
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v0 linux master] i2c/busses: Avoid i2c interrupt status clear race condition.
  2020-04-29  8:12   ` Ryan Chen
@ 2020-04-29  9:03     ` Wolfram Sang
  2020-04-30 10:55       ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 9+ messages in thread
From: Wolfram Sang @ 2020-04-29  9:03 UTC (permalink / raw)
  To: Ryan Chen
  Cc: Brendan Higgins, Benjamin Herrenschmidt, Joel Stanley,
	Andrew Jeffery, linux-i2c, openbmc, linux-arm-kernel,
	linux-aspeed, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 657 bytes --]


> And is there maybe a Fixes: tag for it?
> [Ryan Chen] Yes it is a fix patch.

I meant this (from submitting-patches.rst):

===

If your patch fixes a bug in a specific commit, e.g. you found an issue using
``git bisect``, please use the 'Fixes:' tag with the first 12 characters of
the SHA-1 ID, and the one line summary.  Do not split the tag across multiple
lines, tags are exempt from the "wrap at 75 columns" rule in order to simplify
parsing scripts.  For example::

        Fixes: 54a4f0239f2e ("KVM: MMU: make kvm_mmu_zap_page() return the number of pages it actually freed")

===

So, is it possible to identify a commit introducing the problem?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v0 linux master] i2c/busses: Avoid i2c interrupt status clear race condition.
  2020-04-29  3:37 [PATCH v0 linux master] i2c/busses: Avoid i2c interrupt status clear race condition ryan_chen
  2020-04-29  7:53 ` Wolfram Sang
@ 2020-04-30 10:52 ` Benjamin Herrenschmidt
  2020-04-30 14:17 ` Wolfram Sang
  2 siblings, 0 replies; 9+ messages in thread
From: Benjamin Herrenschmidt @ 2020-04-30 10:52 UTC (permalink / raw)
  To: ryan_chen, Brendan Higgins, Joel Stanley, Andrew Jeffery,
	linux-i2c, openbmc, linux-arm-kernel, linux-aspeed, linux-kernel

On Wed, 2020-04-29 at 11:37 +0800, ryan_chen wrote:
> In AST2600 there have a slow peripheral bus between CPU
>  and i2c controller.
> Therefore GIC i2c interrupt status clear have delay timing,
> when CPU issue write clear i2c controller interrupt status.
> To avoid this issue, the driver need have read after write
>  clear at i2c ISR.
> 
> Signed-off-by: ryan_chen <ryan_chen@aspeedtech.com>

Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
--


> ---
>  drivers/i2c/busses/i2c-aspeed.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/i2c/busses/i2c-aspeed.c
> b/drivers/i2c/busses/i2c-aspeed.c
> index 07c1993274c5..f51702d86a90 100644
> --- a/drivers/i2c/busses/i2c-aspeed.c
> +++ b/drivers/i2c/busses/i2c-aspeed.c
> @@ -603,6 +603,7 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq,
> void *dev_id)
>  	/* Ack all interrupts except for Rx done */
>  	writel(irq_received & ~ASPEED_I2CD_INTR_RX_DONE,
>  	       bus->base + ASPEED_I2C_INTR_STS_REG);
> +	readl(bus->base + ASPEED_I2C_INTR_STS_REG);
>  	irq_remaining = irq_received;
>  
>  #if IS_ENABLED(CONFIG_I2C_SLAVE)
> @@ -645,9 +646,11 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq,
> void *dev_id)
>  			irq_received, irq_handled);
>  
>  	/* Ack Rx done */
> -	if (irq_received & ASPEED_I2CD_INTR_RX_DONE)
> +	if (irq_received & ASPEED_I2CD_INTR_RX_DONE) {
>  		writel(ASPEED_I2CD_INTR_RX_DONE,
>  		       bus->base + ASPEED_I2C_INTR_STS_REG);
> +		readl(bus->base + ASPEED_I2C_INTR_STS_REG);
> +	}
>  	spin_unlock(&bus->lock);
>  	return irq_remaining ? IRQ_NONE : IRQ_HANDLED;
>  }


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v0 linux master] i2c/busses: Avoid i2c interrupt status clear race condition.
  2020-04-29  9:03     ` Wolfram Sang
@ 2020-04-30 10:55       ` Benjamin Herrenschmidt
  2020-05-05  1:52         ` Ryan Chen
  0 siblings, 1 reply; 9+ messages in thread
From: Benjamin Herrenschmidt @ 2020-04-30 10:55 UTC (permalink / raw)
  To: Wolfram Sang, Ryan Chen
  Cc: Brendan Higgins, Joel Stanley, Andrew Jeffery, linux-i2c,
	openbmc, linux-arm-kernel, linux-aspeed, linux-kernel

On Wed, 2020-04-29 at 11:03 +0200, Wolfram Sang wrote:
> > And is there maybe a Fixes: tag for it?
> > [Ryan Chen] Yes it is a fix patch.
> 
> I meant this (from submitting-patches.rst):

It fixes the original implementation of the driver basically. It's just
a classic posted-write fix. The write to clear the pending interrupt is
asynchronous, so you can get spurrious ones if you return from the
handler before it has percolated to the HW.

I assume it's just more visible on the 2600 because of the cores are
significantly faster but the IO bus is still as dumb.

Ryan: You could always add a Fixed-by: tag that specifies the commit
that added the initial driver...

Cheers,
Ben.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v0 linux master] i2c/busses: Avoid i2c interrupt status clear race condition.
  2020-04-29  3:37 [PATCH v0 linux master] i2c/busses: Avoid i2c interrupt status clear race condition ryan_chen
  2020-04-29  7:53 ` Wolfram Sang
  2020-04-30 10:52 ` Benjamin Herrenschmidt
@ 2020-04-30 14:17 ` Wolfram Sang
  2020-05-05  1:51   ` Ryan Chen
  2 siblings, 1 reply; 9+ messages in thread
From: Wolfram Sang @ 2020-04-30 14:17 UTC (permalink / raw)
  To: ryan_chen
  Cc: Brendan Higgins, Benjamin Herrenschmidt, Joel Stanley,
	Andrew Jeffery, linux-i2c, openbmc, linux-arm-kernel,
	linux-aspeed, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 568 bytes --]

On Wed, Apr 29, 2020 at 11:37:37AM +0800, ryan_chen wrote:
> In AST2600 there have a slow peripheral bus between CPU
>  and i2c controller.
> Therefore GIC i2c interrupt status clear have delay timing,
> when CPU issue write clear i2c controller interrupt status.
> To avoid this issue, the driver need have read after write
>  clear at i2c ISR.
> 
> Signed-off-by: ryan_chen <ryan_chen@aspeedtech.com>

Applied to for-current with a Fixes tag, thanks! Please, try to add one
next time and please also check how the subsystem formats the $subject
line.


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH v0 linux master] i2c/busses: Avoid i2c interrupt status clear race condition.
  2020-04-30 14:17 ` Wolfram Sang
@ 2020-05-05  1:51   ` Ryan Chen
  0 siblings, 0 replies; 9+ messages in thread
From: Ryan Chen @ 2020-05-05  1:51 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Brendan Higgins, Benjamin Herrenschmidt, Joel Stanley,
	Andrew Jeffery, linux-i2c, openbmc, linux-arm-kernel,
	linux-aspeed, linux-kernel

> In AST2600 there have a slow peripheral bus between CPU  and i2c 
> controller.
> Therefore GIC i2c interrupt status clear have delay timing, when CPU 
> issue write clear i2c controller interrupt status.
> To avoid this issue, the driver need have read after write  clear at 
> i2c ISR.
> 
> Signed-off-by: ryan_chen <ryan_chen@aspeedtech.com>

>Applied to for-current with a Fixes tag, thanks! Please, try to add one next time and please also check how the subsystem formats the $subject line.
[Ryan Chen] Thanks your review, will add fixes tag at subject. 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH v0 linux master] i2c/busses: Avoid i2c interrupt status clear race condition.
  2020-04-30 10:55       ` Benjamin Herrenschmidt
@ 2020-05-05  1:52         ` Ryan Chen
  0 siblings, 0 replies; 9+ messages in thread
From: Ryan Chen @ 2020-05-05  1:52 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Wolfram Sang
  Cc: Brendan Higgins, Joel Stanley, Andrew Jeffery, linux-i2c,
	openbmc, linux-arm-kernel, linux-aspeed, linux-kernel

> > And is there maybe a Fixes: tag for it?
> > [Ryan Chen] Yes it is a fix patch.
> 
> I meant this (from submitting-patches.rst):

>It fixes the original implementation of the driver basically. It's just a classic posted-write fix. The write to clear the pending interrupt is asynchronous, so you can get spurrious ones if you return from the handler before it has percolated to the HW.

>I assume it's just more visible on the 2600 because of the cores are significantly faster but the IO bus is still as dumb.

>Ryan: You could always add a Fixed-by: tag that specifies the commit that added the initial driver...
[Ryan Chen] Thanks Ben.


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-05-05  1:52 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-29  3:37 [PATCH v0 linux master] i2c/busses: Avoid i2c interrupt status clear race condition ryan_chen
2020-04-29  7:53 ` Wolfram Sang
2020-04-29  8:12   ` Ryan Chen
2020-04-29  9:03     ` Wolfram Sang
2020-04-30 10:55       ` Benjamin Herrenschmidt
2020-05-05  1:52         ` Ryan Chen
2020-04-30 10:52 ` Benjamin Herrenschmidt
2020-04-30 14:17 ` Wolfram Sang
2020-05-05  1:51   ` Ryan Chen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).