Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 26333576 authored by Nick Piggin's avatar Nick Piggin Committed by Linus Torvalds
Browse files

bitops: introduce lock ops



Introduce test_and_set_bit_lock / clear_bit_unlock bitops with lock semantics.
Convert all architectures to use the generic implementation.

Signed-off-by: default avatarNick Piggin <npiggin@suse.de>
Acked-By: default avatarDavid Howells <dhowells@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Haavard Skinnemoen <hskinnemoen@atmel.com>
Cc: Bryan Wu <bryan.wu@analog.com>
Cc: Mikael Starvik <starvik@axis.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: "Luck, Tony" <tony.luck@intel.com>
Cc: Hirokazu Takata <takata@linux-m32r.org>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Roman Zippel <zippel@linux-m68k.org>
Cc: Greg Ungerer <gerg@uclinux.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Matthew Wilcox <willy@debian.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Kazumoto Kojima <kkojima@rr.iij4u.or.jp>
Cc: Richard Curnow <rc@rc0.org.uk>
Cc: William Lee Irwin III <wli@holomorphy.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Cc: Miles Bader <uclinux-v850@lsi.nec.co.jp>
Cc: Andi Kleen <ak@muc.de>
Cc: Chris Zankel <chris@zankel.net>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 38048983
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -418,6 +418,20 @@ brothers:
	 */
	 smp_mb__after_clear_bit();

There are two special bitops with lock barrier semantics (acquire/release,
same as spinlocks). These operate in the same way as their non-_lock/unlock
postfixed variants, except that they are to provide acquire/release semantics,
respectively. This means they can be used for bit_spin_trylock and
bit_spin_unlock type operations without specifying any more barriers.

	int test_and_set_bit_lock(unsigned long nr, unsigned long *addr);
	void clear_bit_unlock(unsigned long nr, unsigned long *addr);
	void __clear_bit_unlock(unsigned long nr, unsigned long *addr);

The __clear_bit_unlock version is non-atomic, however it still implements
unlock barrier semantics. This can be useful if the lock itself is protecting
the other bits in the word.

Finally, there are non-atomic versions of the bitmask operations
provided.  They are used in contexts where some other higher-level SMP
locking scheme is being used to protect the bitmask, and thus less
+12 −2
Original line number Diff line number Diff line
@@ -1479,7 +1479,8 @@ kernel.

Any atomic operation that modifies some state in memory and returns information
about the state (old or new) implies an SMP-conditional general memory barrier
(smp_mb()) on each side of the actual operation.  These include:
(smp_mb()) on each side of the actual operation (with the exception of
explicit lock operations, described later).  These include:

	xchg();
	cmpxchg();
@@ -1536,10 +1537,19 @@ If they're used for constructing a lock of some description, then they probably
do need memory barriers as a lock primitive generally has to do things in a
specific order.


Basically, each usage case has to be carefully considered as to whether memory
barriers are needed or not.

The following operations are special locking primitives:

	test_and_set_bit_lock();
	clear_bit_unlock();
	__clear_bit_unlock();

These implement LOCK-class and UNLOCK-class operations. These should be used in
preference to other operations when implementing locking primitives, because
their implementations can be optimised on many architectures.

[!] Note that special memory barrier primitives are available for these
situations because on some CPUs the atomic instructions used imply full memory
barriers, and so barrier instructions are superfluous in conjunction with them,
+1 −0
Original line number Diff line number Diff line
@@ -367,6 +367,7 @@ static inline unsigned int hweight8(unsigned int w)
#else
#include <asm-generic/bitops/hweight.h>
#endif
#include <asm-generic/bitops/lock.h>

#endif /* __KERNEL__ */

+1 −0
Original line number Diff line number Diff line
@@ -286,6 +286,7 @@ static inline int constant_fls(int x)

#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>

/*
 * Ext2 is defined to use little-endian byte ordering.
+1 −0
Original line number Diff line number Diff line
@@ -288,6 +288,7 @@ static inline int ffs(unsigned long word)
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>

#include <asm-generic/bitops/ext2-non-atomic.h>
#include <asm-generic/bitops/ext2-atomic.h>
Loading