All of lore.kernel.org
 help / color / mirror / Atom feed
From: Catalin Marinas <catalin.marinas@arm.com>
To: Serge Semin <fancer.lancer@gmail.com>
Cc: Jan Bottorff <janb@os.amperecomputing.com>,
	Yann Sionneau <ysionneau@kalrayinc.com>,
	Wolfram Sang <wsa@kernel.org>, Yann Sionneau <yann@sionneau.net>,
	Will Deacon <will@kernel.org>,
	Jarkko Nikula <jarkko.nikula@linux.intel.com>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	Mika Westerberg <mika.westerberg@linux.intel.com>,
	Jan Dabros <jsd@semihalf.com>, Andi Shyti <andi.shyti@kernel.org>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2] i2c: designware: Fix corrupted memory seen in the ISR
Date: Wed, 20 Sep 2023 12:03:00 +0100	[thread overview]
Message-ID: <ZQrRZFLsDGJweWbx@arm.com> (raw)
In-Reply-To: <p7wl7fk4cdyhvw2mfsa6sfc7dhfls3foplmzwj6pzstargt2oh@33zuuznup2gq>

On Wed, Sep 20, 2023 at 12:05:50AM +0300, Serge Semin wrote:
> On Tue, Sep 19, 2023 at 11:54:10AM -0700, Jan Bottorff wrote:
> > On 9/19/2023 7:51 AM, Catalin Marinas wrote:
> > > While smp_* is ok, it really depends on what the regmap_write() does. Is
> > > it a write to a shared peripheral (if not, you may need a DSB)? Does the
> > > regmap_write() caller know this? That's why I think having the barrier
> > > in dw_reg_write() is better.
> > > 
> > > If you do want to stick to a fix in i2c_dw_xfer_init(), you could go for
> > > dma_wmb(). While this is not strictly DMA, it's sharing data with
> > > another coherent agent (a different CPU in this instance). The smp_wmb()
> > > is more about communication via memory not involving I/O. But this still
> > > assumes that the caller knows regmap_write() ends up with an I/O
> > > write*() (potentially relaxed).
> 
> Catalin, thank you very much for your messages. The situation is much
> clearer now. I should have noted that we indeed talking about
> different memory types: Normal and Device memories. Anyway to sum it up
> AFAICS the next situation is happening:
> 1. some data is updated,
> 2. IRQ is activated by means of writel_relaxed() to the
> DW_IC_INTR_MASK register.
> 3. IRQ is raised and being handled, but the data updated in 1. looked
> as corrupted.
> 
> (Jan, correct me if I'm wrong.)
> 
> Since ARM doesn't "guarantee ordering between memory accesses to
> different devices, or usually between accesses of different memory
> types", most likely the CPU core changes 1. and 2. places
> occasionally. So in that case the IRQ handler just doesn't see the
> updated data. What needs to be done is to make sure that 2. always
> happens after 1. is completed. Outer Shareability domain write-barrier
> (DMB(oshst)) does that. Am I right? That's why it's utilized in the
> __io_bw() and __dma_wmb() macros implementation.

Yes.

> Wolfram, Jan seeing the root cause of the problem is in using the
> '_relaxed' accessors for the controller CSRs I assume that the problem
> might be more generic than just for ARMs, since based on [1] these
> accessors "do not guarantee ordering with respect to locking, _normal_
> memory accesses or delay() loops." So theoretically the problem might
> get to be met on any other arch if it implements the semantic with the
> relaxed normal and device memory accesses execution.
> 
> [1] "KERNEL I/O BARRIER EFFECTS" Documentation/memory-barriers.txt
> 
> If so we need to have give up from using the _relaxed accessors at for
> the CSRs which may cause a side effect like IRQ raising. Instead the
> normal IO write should be utilized which "wait for the completion of
> all prior writes to memory either issued by, or propagated to, the
> same thread." [1] Thus I'd suggest the next fix for the problem:
> 
> --- a/drivers/i2c/busses/i2c-designware-common.c
> +++ b/drivers/i2c/busses/i2c-designware-common.c
> @@ -72,7 +72,10 @@ static int dw_reg_write(void *context, unsigned int reg, unsigned int val)
>  {
>  	struct dw_i2c_dev *dev = context;
>  
> -	writel_relaxed(val, dev->base + reg);
> +	if (reg == DW_IC_INTR_MASK)
> +		writel(val, dev->base + reg);
> +	else
> +		writel_relaxed(val, dev->base + reg);
>  
>  	return 0;
>  }
> 
> (and similar changes for dw_reg_write_swab() and dw_reg_write_word().)

This should work as well.

-- 
Catalin

  parent reply	other threads:[~2023-09-20 11:03 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-13 23:29 [PATCH v2] i2c: designware: Fix corrupted memory seen in the ISR Jan Bottorff
2023-09-14 18:46 ` Andy Shevchenko
2023-09-14 18:47   ` Andy Shevchenko
2023-09-14 20:52     ` Jan Bottorff
2023-09-15 12:44 ` Jarkko Nikula
2023-09-15 15:21 ` Serge Semin
2023-09-16  1:47   ` Jan Bottorff
2023-09-17  0:01     ` Serge Semin
2023-09-17 20:08       ` Yann Sionneau
2023-09-18 23:14         ` Serge Semin
2023-09-19  3:45           ` Jan Bottorff
2023-09-19  9:55             ` Catalin Marinas
2023-09-19 10:19               ` Wolfram Sang
2023-09-19 12:38                 ` Yann Sionneau
2023-09-19 14:51                   ` Catalin Marinas
2023-09-19 14:55                     ` Wolfram Sang
2023-09-19 18:54                     ` Jan Bottorff
2023-09-19 21:05                       ` Serge Semin
2023-09-20  9:08                         ` Wolfram Sang
2023-09-20 13:27                           ` Yann Sionneau
2023-09-20 19:14                             ` Jan Bottorff
2023-09-25 12:54                               ` Serge Semin
2023-09-25 19:39                                 ` Jan Bottorff
2023-09-27 19:38                                   ` Wolfram Sang
2023-09-29  8:48                                     ` Jarkko Nikula
2023-10-26 11:18                                       ` Wolfram Sang
2023-10-31  0:12                                         ` Jan Bottorff
2023-10-31  5:51                                           ` Wolfram Sang
2023-10-31  8:44                                           ` Yann Sionneau
2023-10-31 12:10                                             ` Jarkko Nikula
2023-10-31 13:06                                               ` Serge Semin
2023-11-01 16:51                                                 ` Jan Bottorff
2023-09-20 11:03                         ` Catalin Marinas [this message]
2023-09-20 10:44                       ` Catalin Marinas
2023-09-20 11:05                         ` Catalin Marinas

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=ZQrRZFLsDGJweWbx@arm.com \
    --to=catalin.marinas@arm.com \
    --cc=andi.shyti@kernel.org \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=fancer.lancer@gmail.com \
    --cc=janb@os.amperecomputing.com \
    --cc=jarkko.nikula@linux.intel.com \
    --cc=jsd@semihalf.com \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mika.westerberg@linux.intel.com \
    --cc=p.zabel@pengutronix.de \
    --cc=will@kernel.org \
    --cc=wsa@kernel.org \
    --cc=yann@sionneau.net \
    --cc=ysionneau@kalrayinc.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.