aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/lib
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-07-03 13:56:36 -0400
committerIngo Molnar <mingo@elte.hu>2009-07-03 14:23:55 -0400
commit3a8d1788b37435baf6c296f4ea8beb4fa4955f44 (patch)
tree0db4ee093c0d9c8cb66321945fc024e5b1d3a8fd /arch/x86/lib
parent1fde902d52ee13ab9fab155bbae757fdf7daf0c1 (diff)
x86: atomic64: Improve atomic64_xchg()
Remove the read-first logic from atomic64_xchg() and simplify the loop. This function was the last user of __atomic64_read() - remove it. Also, change the 'real_val' assumption from the somewhat quirky 1ULL << 32 value to the (just as arbitrary, but simpler) value of 0. Reported-by: Linus Torvalds <torvalds@linux-foundation.org> Cc: Eric Dumazet <eric.dumazet@gmail.com> 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: <tip-05118ab8859492ac9ddda0154cf90e37b0a4a0b0@git.kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/lib')
-rw-r--r--arch/x86/lib/atomic64_32.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/arch/x86/lib/atomic64_32.c b/arch/x86/lib/atomic64_32.c
index 6722a092e407..a804f96e90e2 100644
--- a/arch/x86/lib/atomic64_32.c
+++ b/arch/x86/lib/atomic64_32.c
@@ -33,14 +33,23 @@ EXPORT_SYMBOL(atomic64_cmpxchg);
33 * Atomically xchgs the value of @ptr to @new_val and returns 33 * Atomically xchgs the value of @ptr to @new_val and returns
34 * the old value. 34 * the old value.
35 */ 35 */
36
37u64 atomic64_xchg(atomic64_t *ptr, u64 new_val) 36u64 atomic64_xchg(atomic64_t *ptr, u64 new_val)
38{ 37{
39 u64 old_val; 38 /*
39 * Try first with a (possibly incorrect) assumption about
40 * what we have there. We'll do two loops most likely,
41 * but we'll get an ownership MESI transaction straight away
42 * instead of a read transaction followed by a
43 * flush-for-ownership transaction:
44 */
45 u64 old_val, real_val = 0;
40 46
41 do { 47 do {
42 old_val = __atomic64_read(ptr); 48 old_val = real_val;
43 } while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val); 49
50 real_val = atomic64_cmpxchg(ptr, old_val, new_val);
51
52 } while (real_val != old_val);
44 53
45 return old_val; 54 return old_val;
46} 55}
@@ -91,13 +100,13 @@ EXPORT_SYMBOL(atomic64_read);
91noinline u64 atomic64_add_return(u64 delta, atomic64_t *ptr) 100noinline u64 atomic64_add_return(u64 delta, atomic64_t *ptr)
92{ 101{
93 /* 102 /*
94 * Try first with a (probably incorrect) assumption about 103 * Try first with a (possibly incorrect) assumption about
95 * what we have there. We'll do two loops most likely, 104 * what we have there. We'll do two loops most likely,
96 * but we'll get an ownership MESI transaction straight away 105 * but we'll get an ownership MESI transaction straight away
97 * instead of a read transaction followed by a 106 * instead of a read transaction followed by a
98 * flush-for-ownership transaction: 107 * flush-for-ownership transaction:
99 */ 108 */
100 u64 old_val, new_val, real_val = 1ULL << 32; 109 u64 old_val, new_val, real_val = 0;
101 110
102 do { 111 do {
103 old_val = real_val; 112 old_val = real_val;