Commit d6ffe606 authored by Mikulas Patocka's avatar Mikulas Patocka Committed by Linus Torvalds

provide arch_test_bit_acquire for architectures that define test_bit

Some architectures define their own arch_test_bit and they also need
arch_test_bit_acquire, otherwise they won't compile.  We also clean up
the code by using the generic test_bit if that is equivalent to the
arch-specific version.
Signed-off-by: default avatarMikulas Patocka <mpatocka@redhat.com>
Cc: stable@vger.kernel.org
Fixes: 8238b457 ("wait_on_bit: add an acquire memory barrier")
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent e022620b
...@@ -283,11 +283,8 @@ arch___test_and_change_bit(unsigned long nr, volatile unsigned long *addr) ...@@ -283,11 +283,8 @@ arch___test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
return (old & mask) != 0; return (old & mask) != 0;
} }
static __always_inline bool #define arch_test_bit generic_test_bit
arch_test_bit(unsigned long nr, const volatile unsigned long *addr) #define arch_test_bit_acquire generic_test_bit_acquire
{
return (1UL & (((const int *) addr)[nr >> 5] >> (nr & 31))) != 0UL;
}
/* /*
* ffz = Find First Zero in word. Undefined if no zero exists, * ffz = Find First Zero in word. Undefined if no zero exists,
......
...@@ -179,6 +179,21 @@ arch_test_bit(unsigned long nr, const volatile unsigned long *addr) ...@@ -179,6 +179,21 @@ arch_test_bit(unsigned long nr, const volatile unsigned long *addr)
return retval; return retval;
} }
static __always_inline bool
arch_test_bit_acquire(unsigned long nr, const volatile unsigned long *addr)
{
int retval;
asm volatile(
"{P0 = tstbit(%1,%2); if (P0.new) %0 = #1; if (!P0.new) %0 = #0;}\n"
: "=&r" (retval)
: "r" (addr[BIT_WORD(nr)]), "r" (nr % BITS_PER_LONG)
: "p0", "memory"
);
return retval;
}
/* /*
* ffz - find first zero in word. * ffz - find first zero in word.
* @word: The word to search * @word: The word to search
......
...@@ -331,11 +331,8 @@ arch___test_and_change_bit(unsigned long nr, volatile unsigned long *addr) ...@@ -331,11 +331,8 @@ arch___test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
return (old & bit) != 0; return (old & bit) != 0;
} }
static __always_inline bool #define arch_test_bit generic_test_bit
arch_test_bit(unsigned long nr, const volatile unsigned long *addr) #define arch_test_bit_acquire generic_test_bit_acquire
{
return 1 & (((const volatile __u32 *) addr)[nr >> 5] >> (nr & 31));
}
/** /**
* ffz - find the first zero bit in a long word * ffz - find the first zero bit in a long word
......
...@@ -157,11 +157,8 @@ arch___change_bit(unsigned long nr, volatile unsigned long *addr) ...@@ -157,11 +157,8 @@ arch___change_bit(unsigned long nr, volatile unsigned long *addr)
change_bit(nr, addr); change_bit(nr, addr);
} }
static __always_inline bool #define arch_test_bit generic_test_bit
arch_test_bit(unsigned long nr, const volatile unsigned long *addr) #define arch_test_bit_acquire generic_test_bit_acquire
{
return (addr[nr >> 5] & (1UL << (nr & 31))) != 0;
}
static inline int bset_reg_test_and_set_bit(int nr, static inline int bset_reg_test_and_set_bit(int nr,
volatile unsigned long *vaddr) volatile unsigned long *vaddr)
......
...@@ -176,14 +176,8 @@ arch___test_and_change_bit(unsigned long nr, volatile unsigned long *addr) ...@@ -176,14 +176,8 @@ arch___test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
return old & mask; return old & mask;
} }
static __always_inline bool #define arch_test_bit generic_test_bit
arch_test_bit(unsigned long nr, const volatile unsigned long *addr) #define arch_test_bit_acquire generic_test_bit_acquire
{
const volatile unsigned long *p = __bitops_word(nr, addr);
unsigned long mask = __bitops_mask(nr);
return *p & mask;
}
static inline bool arch_test_and_set_bit_lock(unsigned long nr, static inline bool arch_test_and_set_bit_lock(unsigned long nr,
volatile unsigned long *ptr) volatile unsigned long *ptr)
......
...@@ -135,16 +135,8 @@ arch___test_and_change_bit(unsigned long nr, volatile unsigned long *addr) ...@@ -135,16 +135,8 @@ arch___test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
return (old & mask) != 0; return (old & mask) != 0;
} }
/** #define arch_test_bit generic_test_bit
* arch_test_bit - Determine whether a bit is set #define arch_test_bit_acquire generic_test_bit_acquire
* @nr: bit number to test
* @addr: Address to start counting from
*/
static __always_inline bool
arch_test_bit(unsigned long nr, const volatile unsigned long *addr)
{
return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
}
#include <asm-generic/bitops/non-instrumented-non-atomic.h> #include <asm-generic/bitops/non-instrumented-non-atomic.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment