All of lore.kernel.org
 help / color / mirror / Atom feed
From: ezequiel.garcia@free-electrons.com (Ezequiel Garcia)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/3] ARM: Introduce atomic MMIO clear/set
Date: Mon, 19 Aug 2013 13:59:56 -0300	[thread overview]
Message-ID: <20130819165955.GA20522@localhost> (raw)
In-Reply-To: <20130812182942.GA28695@mudshark.cambridge.arm.com>

On Mon, Aug 12, 2013 at 07:29:42PM +0100, Will Deacon wrote:
> On Sat, Aug 10, 2013 at 01:43:00PM +0100, Ezequiel Garcia wrote:
> > Some SoC have MMIO regions that are shared across orthogonal
> > subsystems. This commit implements a possible solution for the
> > thread-safe access of such regions through a spinlock-protected API
> > with clear-set semantics.
> > 
> > Concurrent access is protected with a single spinlock for the
> > entire MMIO address space. While this protects shared-registers,
> > it also serializes access to unrelated/unshared registers.
> > 
> > Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
> 
> [...]
> 
> > +void atomic_io_clear_set(void __iomem *reg, u32 clear, u32 set)
> > +{
> > +	spin_lock(&__io_lock);
> > +	writel((readl(reg) & ~clear) | set, reg);
> > +	spin_unlock(&__io_lock);
> > +}
> 
> I appreciate that you've lifted this code from a previous driver, but this
> doesn't really make any sense to me. The spin_unlock operation is
> essentially a store to normal, cacheable memory, whilst the writel is an
> __iowmb followed by a store to device memory.
> 
> This means that you don't have ordering guarantees between the two accesses
> outside of the CPU, potentially giving you:
> 
> 	spin_lock(&__io_lock);
> 	spin_unlock(&__io_lock);
> 	writel((readl(reg) & ~clear) | set, reg);
> 
> which is probably not what you want.
> 
> I suggest adding an iowmb after the writel if you really need this ordering
> to be enforced (but this may have a significant performance impact,
> depending on your SoC).
> 

I don't want to argue with you, given I have zero knowledge about this
ordering issue. However let me ask you a question.

In arch/arm/include/asm/spinlock.h I'm seeing this comment:

""ARMv6 ticket-based spin-locking.
A memory barrier is required after we get a lock, and before we
release it, because V6 CPUs are assumed to have weakly ordered
memory.""

and also:

static inline void arch_spin_unlock(arch_spinlock_t *lock)
{
	smp_mb();
	lock->tickets.owner++;
	dsb_sev();
}

So, knowing this atomic API should work for every ARMv{N}, and not being very
sure what the call to dsb_sev() does. Would you care to explain how the above
is *not* enough to guarantee a memory barrier before the spin unlocking?

Thanks!
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com

WARNING: multiple messages have this Message-ID (diff)
From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
To: Will Deacon <will.deacon@arm.com>
Cc: "linux-arm-kernel@lists.infradead.org" 
	<linux-arm-kernel@lists.infradead.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Lior Amsalem <alior@marvell.com>,
	Thomas Petazzoni <thomas.petazzoni@free-electrons.com>,
	Russell King <linux@arm.linux.org.uk>,
	Jason Cooper <jason@lakedaemon.net>, Andrew Lunn <andrew@lunn.ch>,
	Gregory Clement <gregory.clement@free-electrons.com>,
	Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Subject: Re: [PATCH 1/3] ARM: Introduce atomic MMIO clear/set
Date: Mon, 19 Aug 2013 13:59:56 -0300	[thread overview]
Message-ID: <20130819165955.GA20522@localhost> (raw)
In-Reply-To: <20130812182942.GA28695@mudshark.cambridge.arm.com>

On Mon, Aug 12, 2013 at 07:29:42PM +0100, Will Deacon wrote:
> On Sat, Aug 10, 2013 at 01:43:00PM +0100, Ezequiel Garcia wrote:
> > Some SoC have MMIO regions that are shared across orthogonal
> > subsystems. This commit implements a possible solution for the
> > thread-safe access of such regions through a spinlock-protected API
> > with clear-set semantics.
> > 
> > Concurrent access is protected with a single spinlock for the
> > entire MMIO address space. While this protects shared-registers,
> > it also serializes access to unrelated/unshared registers.
> > 
> > Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
> 
> [...]
> 
> > +void atomic_io_clear_set(void __iomem *reg, u32 clear, u32 set)
> > +{
> > +	spin_lock(&__io_lock);
> > +	writel((readl(reg) & ~clear) | set, reg);
> > +	spin_unlock(&__io_lock);
> > +}
> 
> I appreciate that you've lifted this code from a previous driver, but this
> doesn't really make any sense to me. The spin_unlock operation is
> essentially a store to normal, cacheable memory, whilst the writel is an
> __iowmb followed by a store to device memory.
> 
> This means that you don't have ordering guarantees between the two accesses
> outside of the CPU, potentially giving you:
> 
> 	spin_lock(&__io_lock);
> 	spin_unlock(&__io_lock);
> 	writel((readl(reg) & ~clear) | set, reg);
> 
> which is probably not what you want.
> 
> I suggest adding an iowmb after the writel if you really need this ordering
> to be enforced (but this may have a significant performance impact,
> depending on your SoC).
> 

I don't want to argue with you, given I have zero knowledge about this
ordering issue. However let me ask you a question.

In arch/arm/include/asm/spinlock.h I'm seeing this comment:

""ARMv6 ticket-based spin-locking.
A memory barrier is required after we get a lock, and before we
release it, because V6 CPUs are assumed to have weakly ordered
memory.""

and also:

static inline void arch_spin_unlock(arch_spinlock_t *lock)
{
	smp_mb();
	lock->tickets.owner++;
	dsb_sev();
}

So, knowing this atomic API should work for every ARMv{N}, and not being very
sure what the call to dsb_sev() does. Would you care to explain how the above
is *not* enough to guarantee a memory barrier before the spin unlocking?

Thanks!
-- 
Ezequiel García, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com

  reply	other threads:[~2013-08-19 16:59 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-10 12:42 [PATCH 0/3] Introduce atomic MMIO register clear-set Ezequiel Garcia
2013-08-10 12:42 ` Ezequiel Garcia
2013-08-10 12:43 ` [PATCH 1/3] ARM: Introduce atomic MMIO clear/set Ezequiel Garcia
2013-08-10 12:43   ` Ezequiel Garcia
2013-08-10 12:49   ` Alexander Shiyan
2013-08-10 12:49     ` Alexander Shiyan
2013-08-10 14:02     ` Ezequiel Garcia
2013-08-10 14:02       ` Ezequiel Garcia
2013-08-10 14:09       ` Ezequiel Garcia
2013-08-10 14:09         ` Ezequiel Garcia
2013-08-10 15:43         ` Alexander Shiyan
2013-08-10 15:43           ` Alexander Shiyan
2013-08-10 15:55           ` Ezequiel Garcia
2013-08-10 15:55             ` Ezequiel Garcia
2013-08-12 15:46             ` Ezequiel Garcia
2013-08-12 15:46               ` Ezequiel Garcia
2013-08-12 16:44               ` Sebastian Hesselbarth
2013-08-12 16:44                 ` Sebastian Hesselbarth
2013-08-12 17:09                 ` Ezequiel Garcia
2013-08-12 17:09                   ` Ezequiel Garcia
2013-08-12 18:29   ` Will Deacon
2013-08-12 18:29     ` Will Deacon
2013-08-19 16:59     ` Ezequiel Garcia [this message]
2013-08-19 16:59       ` Ezequiel Garcia
2013-08-20 14:32       ` Matt Sealey
2013-08-20 14:32         ` Matt Sealey
2013-08-20 14:52         ` Ezequiel Garcia
2013-08-20 14:52           ` Ezequiel Garcia
2013-08-20 15:04           ` Will Deacon
2013-08-20 15:04             ` Will Deacon
2013-08-10 12:43 ` [PATCH 2/3] clocksource: orion: Use atomic access for shared registers Ezequiel Garcia
2013-08-10 12:43   ` Ezequiel Garcia
2013-08-10 12:43 ` [PATCH 3/3] watchdog: " Ezequiel Garcia
2013-08-10 12:43   ` Ezequiel Garcia

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=20130819165955.GA20522@localhost \
    --to=ezequiel.garcia@free-electrons.com \
    --cc=linux-arm-kernel@lists.infradead.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 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.