summaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorEric Dumazet2009-07-03 12:14:27 +0200
committerIngo Molnar2009-07-03 13:26:40 +0200
commitaacf682fd8c66b57383c407eecd9d4a28264ee91 (patch)
tree98179e43e4d15177acb09958d6ef560a46cc88ae /arch/x86
parentx86: atomic64: Move the 32-bit atomic64_t implementation to a .c file (diff)
downloadkernel-qcow2-linux-aacf682fd8c66b57383c407eecd9d4a28264ee91.tar.gz
kernel-qcow2-linux-aacf682fd8c66b57383c407eecd9d4a28264ee91.tar.xz
kernel-qcow2-linux-aacf682fd8c66b57383c407eecd9d4a28264ee91.zip
x86: atomic64: Improve atomic64_read()
Linus noticed that the 32-bit version of atomic64_read() was being overly complex with re-reading the value and doing a retry loop over that. Instead we can just rely on cmpxchg8b returning either the new value or returning the current value. We can use any 'old' value, which will be faster as it can be loaded via immediates. Using some value that is not equal to the real value in memory the instruction gets faster. This also has the advantage that the CPU could avoid dirtying the cacheline. Reported-by: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: David Howells <dhowells@redhat.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Arnd Bergmann <arnd@arndb.de> LKML-Reference: <alpine.LFD.2.01.0907021653030.3210@localhost.localdomain> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/lib/atomic64_32.c8
1 files changed, 2 insertions, 6 deletions
diff --git a/arch/x86/lib/atomic64_32.c b/arch/x86/lib/atomic64_32.c
index d21e725d3d84..afa5d444918b 100644
--- a/arch/x86/lib/atomic64_32.c
+++ b/arch/x86/lib/atomic64_32.c
@@ -67,13 +67,9 @@ void atomic64_set(atomic64_t *ptr, u64 new_val)
*/
u64 atomic64_read(atomic64_t *ptr)
{
- u64 curr_val;
+ u64 old = 1LL << 32;
- do {
- curr_val = __atomic64_read(ptr);
- } while (atomic64_cmpxchg(ptr, curr_val, curr_val) != curr_val);
-
- return curr_val;
+ return cmpxchg8b(&ptr->counter, old, old);
}
/**