History log of /arch/arm/include/asm/spinlock.h
Revision Date Author Comments
7c8746a9eb287642deaad0e7c2cdf482dce5e4be 07-Feb-2014 Will Deacon <will.deacon@arm.com> ARM: 7955/1: spinlock: ensure we have a compiler barrier before sev

When unlocking a spinlock, we require the following, strictly ordered
sequence of events:

<barrier> /* dmb */
<unlock>
<barrier> /* dsb */
<sev>

Whilst the code does indeed reflect this in terms of the architecture,
the final <barrier> + <sev> have been contracted into a single inline
asm without a "memory" clobber, therefore the compiler is at liberty to
reorder the unlock to the end of the above sequence. In such a case,
a waiting CPU may be woken up before the lock has been unlocked, leading
to extremely poor performance.

This patch reworks the dsb_sev() function to make use of the dsb()
macro and ensure ordering against the unlock.

Cc: <stable@vger.kernel.org>
Reported-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
0cbad9c9dfe0c38e8ec7385b39087c005a6dee3e 09-Oct-2013 Will Deacon <will.deacon@arm.com> ARM: 7854/1: lockref: add support for lockless lockrefs using cmpxchg64

Our spinlocks are only 32-bit (2x16-bit tickets) and, on processors
with 64-bit atomic instructions, cmpxchg64 makes use of the double-word
exclusive accessors.

This patch wires up the cmpxchg-based lockless lockref implementation
for ARM.

Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
9bb17be062de6f5a9c9643258951aa0935652ec3 02-Jul-2013 Will Deacon <will.deacon@arm.com> ARM: locks: prefetch the destination word for write prior to strex

The cost of changing a cacheline from shared to exclusive state can be
significant, especially when this is triggered by an exclusive store,
since it may result in having to retry the transaction.

This patch prefixes our {spin,read,write}_[try]lock implementations with
pldw instructions (on CPUs which support them) to try and grab the line
in exclusive state from the start. arch_rwlock_t is changed to avoid
using a volatile member, since this generates compiler warnings when
falling back on the __builtin_prefetch intrinsic which expects a const
void * argument.

Acked-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
27a84793e42084392181ef2ef51a954f1cf0c519 02-Jul-2013 Will Deacon <will.deacon@arm.com> ARM: smp_on_up: move inline asm ALT_SMP patching macro out of spinlock.h

Patching UP/SMP alternatives inside inline assembly blocks is useful
outside of the spinlock implementation, where it is used for sev and wfe.

This patch lifts the macro into processor.h and gives it a scarier name
to (a) avoid conflicts in the global namespace and (b) to try and deter
its usage unless you "know what you're doing". The W macro for generating
wide instructions when targetting Thumb-2 is also made available under
the name WASM, to reduce the potential for conflicts with other headers.

Acked-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
00efaa0250939dc148e2d3104fb3c18395d24a2d 12-Aug-2013 Will Deacon <will.deacon@arm.com> ARM: 7812/1: rwlocks: retry trylock operation if strex fails on free lock

Commit 15e7e5c1ebf5 ("ARM: 7749/1: spinlock: retry trylock operation if
strex fails on free lock") modifying our arch_spin_trylock to retry the
acquisition if the lock appeared uncontended, but the strex failed.

This patch does the same for rwlocks, which were missed by the original
patch.

Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
afa31d8eb86fc2f25083e675d57ac8173a98f999 12-Aug-2013 Will Deacon <will.deacon@arm.com> ARM: 7811/1: locks: use early clobber in arch_spin_trylock

The res variable is written before we've finished with the input
operands (namely the lock address), so ensure that we mark it as `early
clobber' to avoid unintended register sharing.

Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
73a6fdc48bf52e93c26874dc8c0f0f8d5585a809 13-May-2013 Will Deacon <will.deacon@arm.com> ARM: spinlock: use inner-shareable dsb variant prior to sev instruction

When unlocking a spinlock, we use the sev instruction to signal other
CPUs waiting on the lock. Since sev is not a memory access instruction,
we require a dsb in order to ensure that the sev is not issued ahead
of the store placing the lock in an unlocked state.

However, as sev is only concerned with other processors in a
multiprocessor system, we can restrict the scope of the preceding dsb
to the inner-shareable domain. Furthermore, we can restrict the scope to
consider only stores, since there are no independent loads on the unlock
path.

A side-effect of this change is that a spin_unlock operation no longer
forces completion of pending TLB invalidation, something which we rely
on when unlocking runqueues to ensure that CPU migration during TLB
maintenance routines doesn't cause us to continue before the operation
has completed.

This patch adds the -ishst suffix to the ARMv7 definition of dsb_sev()
and adds an inner-shareable dsb to the context-switch path when running
a preemptible, SMP, v7 kernel.

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
15e7e5c1ebf556cd620c9b091e121091ac760f6d 05-Jun-2013 Will Deacon <will.deacon@arm.com> ARM: 7749/1: spinlock: retry trylock operation if strex fails on free lock

An exclusive store instruction may fail for reasons other than lock
contention (e.g. a cache eviction during the critical section) so, in
line with other architectures using similar exclusive instructions
(alpha, mips, powerpc), retry the trylock operation if the lock appears
to be free but the strex reported failure.

Reported-by: Tony Thompson <anthony.thompson@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
20e260b6f4f717c100620122f626a2c06a4cfd72 24-Jan-2013 Will Deacon <will.deacon@arm.com> ARM: 7632/1: spinlock: avoid exclusive accesses on unlock() path

When unlocking a spinlock, all we need to do is increment the owner
field of the lock. Since only one CPU can be performing an unlock()
operation for a given lock, this doesn't need to be exclusive.

This patch simplifies arch_spin_unlock to use non-exclusive accesses
when updating the owner field of the lock.

Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
881ccccb6bd3f0e1fff8b9addbe0de90e0b16166 06-Jul-2012 Will Deacon <will.deacon@arm.com> ARM: 7447/1: rwlocks: remove unused branch labels from trylock routines

The ARM arch_{read,write}_trylock implementations include unused
backwards branch labels, since we don't retry the locking operation
if the exclusive store fails.

This patch removes the labels.

Acked-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
546c2896a42202dbc7d02f7c6ec9948ac1bf511b 06-Jul-2012 Will Deacon <will.deacon@arm.com> ARM: 7446/1: spinlock: use ticket algorithm for ARMv6+ locking implementation

Ticket spinlocks ensure locking fairness by introducing a FIFO-like
nature to the granting of lock acquisitions and also reducing the
thundering herd effect when spinning on a lock by allowing the cacheline
to remain in a shared state amongst the waiting CPUs. This is especially
important on systems where memory-access times are not necessarily
uniform when accessing the lock structure (for example, on a
multi-cluster platform where the lock is allocated into L1 when a CPU
releases it).

This patch implements the ticket spinlock algorithm for ARM, replacing
the simpler implementation for ARMv6+ processors.

Reviewed-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
603605abae9ee731bdafb2af83a487d98a568815 23-May-2011 Marc Zyngier <Marc.Zyngier@arm.com> ARM: 6939/1: fix missing 'cpu_relax()' declaration

ARM build fails with the following symptom:

CC arch/arm/kernel/asm-offsets.s
In file included from include/linux/seqlock.h:29,
from include/linux/time.h:8,
from include/linux/timex.h:56,
from include/linux/sched.h:57,
from arch/arm/kernel/asm-offsets.c:13:
include/linux/spinlock.h: In function 'spin_unlock_wait':
include/linux/spinlock.h:360: error: implicit declaration of function 'cpu_relax'
make[1]: *** [arch/arm/kernel/asm-offsets.s] Error 1

Fix it by including <asm/processor.h>.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
917692f5f7ec63de3b093c825913d68e910db282 09-Feb-2011 Dave Martin <dave.martin@linaro.org> ARM: 6655/1: Correct WFE() in asm/spinlock.h for Thumb-2

The content for ALT_SMP() in the definition of WFE() expands to 6
bytes (IT cc ; WFEcc.W), which breaks the assumptions of the fixup
code, leading to lockups when the affected code gets run.

This patch works around the problem by explicitly using an
IT + WFEcc.N pair.

Signed-off-by: Dave Martin <dave.martin@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
000d9c78eb5cd7f18e3d6a381d66e606bc9b8196 15-Jan-2011 Russell King <rmk+kernel@arm.linux.org.uk> ARM: v6k: remove CPU_32v6K dependencies in asm/spinlock.h

SMP requires at least the ARMv6K extensions to be present, so if we're
running on SMP, the WFE and SEV instructions must be available.

However, when we run on UP, the v6K extensions may not be available,
and so we don't want WFE/SEV to be in the instruction stream. Use the
SMP alternatives infrastructure to replace these instructions with NOPs
if we build for SMP but run on UP.

Tested-by: Tony Lindgren <tony@atomide.com>
Tested-by: Sourav Poddar <sourav.poddar@ti.com>
Tested-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
c5113b61baf7a9a8616eca83e20847e7fecdc679 25-Jan-2010 Rabin Vincent <rabin@rab.in> ARM: 5897/1: spinlock: don't use deprecated barriers on ARMv7

On ARMv7, the use of the cp15 operations for barriers is deprecated
in favour of the isb, dsb, and dmb instructions. Change the locking
functions to use the appropriate type of dsb for the architecture
being built for.

Signed-off-by: Rabin Vincent <rabin@rab.in>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
e5931943d02bf751b1ec849c0d2ade23d76a8d41 03-Dec-2009 Thomas Gleixner <tglx@linutronix.de> locking: Convert raw_rwlock functions to arch_rwlock

Name space cleanup for rwlock functions. No functional change.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Acked-by: David S. Miller <davem@davemloft.net>
Acked-by: Ingo Molnar <mingo@elte.hu>
Cc: linux-arch@vger.kernel.org
fb3a6bbc912b12347614e5742c7c61416cdb0ca0 03-Dec-2009 Thomas Gleixner <tglx@linutronix.de> locking: Convert raw_rwlock to arch_rwlock

Not strictly necessary for -rt as -rt does not have non sleeping
rwlocks, but it's odd to not have a consistent naming convention.

No functional change.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Acked-by: David S. Miller <davem@davemloft.net>
Acked-by: Ingo Molnar <mingo@elte.hu>
Cc: linux-arch@vger.kernel.org
0199c4e68d1f02894bdefe4b5d9e9ee4aedd8d62 02-Dec-2009 Thomas Gleixner <tglx@linutronix.de> locking: Convert __raw_spin* functions to arch_spin*

Name space cleanup. No functional change.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Acked-by: David S. Miller <davem@davemloft.net>
Acked-by: Ingo Molnar <mingo@elte.hu>
Cc: linux-arch@vger.kernel.org
445c89514be242b1b0080056d50bdc1b72adeb5c 02-Dec-2009 Thomas Gleixner <tglx@linutronix.de> locking: Convert raw_spinlock to arch_spinlock

The raw_spin* namespace was taken by lockdep for the architecture
specific implementations. raw_spin_* would be the ideal name space for
the spinlocks which are not converted to sleeping locks in preempt-rt.

Linus suggested to convert the raw_ to arch_ locks and cleanup the
name space instead of using an artifical name like core_spin,
atomic_spin or whatever

No functional change.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Acked-by: David S. Miller <davem@davemloft.net>
Acked-by: Ingo Molnar <mingo@elte.hu>
Cc: linux-arch@vger.kernel.org
f5f7eac41db827a47b2163330eecd7bb55ae9f12 03-Apr-2009 Robin Holt <holt@sgi.com> Allow rwlocks to re-enable interrupts

Pass the original flags to rwlock arch-code, so that it can re-enable
interrupts if implemented for that architecture.

Initially, make __raw_read_lock_flags and __raw_write_lock_flags stubs
which just do the same thing as non-flags variants.

Signed-off-by: Petr Tesarik <ptesarik@suse.cz>
Signed-off-by: Robin Holt <holt@sgi.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: <linux-arch@vger.kernel.org>
Acked-by: Ingo Molnar <mingo@elte.hu>
Cc: "Luck, Tony" <tony.luck@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
4baa9922430662431231ac637adedddbb0cfb2d7 02-Aug-2008 Russell King <rmk@dyn-67.arm.linux.org.uk> [ARM] move include/asm-arm to arch/arm/include/asm

Move platform independent header files to arch/arm/include/asm, leaving
those in asm/arch* and asm/plat* alone.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>