lkml.org 
[lkml]   [2010]   [Dec]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subjectcpuops cmpxchg: Provide 64 bit this_cpu_xx for 32 bit x86 using cmpxchg8b
Another patch in the series. This may allow better 64 bit counter
management and avoids preempt on/off. Maybe not since we have an
additional branch and load.

Subject: cpuops: Provide 64 bit this_cpu_xx for 32 bit x86

The 64 bit this_cpu_cmpxchg can be used to create a set of 64 bit operations
so that 64 bit entities can also be handled by the this_cpu ops on 32 bit.

Signed-off-by: Christoph Lameter <cl@linux.com>

---
arch/x86/include/asm/percpu.h | 64 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 63 insertions(+), 1 deletion(-)

Index: linux-2.6/arch/x86/include/asm/percpu.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/percpu.h 2010-12-08 16:02:39.000000000 -0600
+++ linux-2.6/arch/x86/include/asm/percpu.h 2010-12-08 16:12:48.000000000 -0600
@@ -405,7 +405,7 @@ do { \
typeof(pcp) __old = (oval); \
union x { typeof(pcp) n;u64 m; } __new; \
__new.n = (nval); \
- asm("cmpxchg8b %2, "__percpu_arg(1) \
+ asm("cmpxchg8b "__percpu_arg(1) \
: "=A" (__ret), "+m" (pcp) \
: "b" ((u32)__new.m), "c" ((u32)(__new.m >> 32)), "0" (__old) \
: "memory"); \
@@ -415,6 +415,68 @@ do { \
#define this_cpu_cmpxchg_8(pcp, oval, nval) __this_cpu_cmpxchg_8(pcp, oval, nval)
#define irqsafe_cmpxchg_8(pcp, oval, nval) __this_cpu_cmpxchg_8(pcp, oval, nval)

+/*
+ * cmpxchg_8 can be used to create support for the 64 bit operations
+ * that are missing on 32 bit.
+ */
+
+#define this_cpu_write_8(pcp, val) \
+({ \
+ typeof(val) __v = (val); \
+ typeof(val) __o; \
+ do { \
+ __o = this_cpu_read_8(pcp); \
+ } while (this_cpu_cmpxchg_8(pcp, __o, __v) != __o); \
+})
+
+#define this_cpu_add_8(pcp, val) \
+({ \
+ typeof(val) __v = (val); \
+ typeof(val) __o; \
+ do { \
+ __o = this_cpu_read_8(pcp); \
+ } while (this_cpu_cmpxchg_8(pcp, __o, __o + __v) != __o); \
+})
+
+#define this_cpu_and_8(pcp, val) \
+({ \
+ typeof(val) __v = (val); \
+ typeof(val) __o; \
+ do { \
+ __o = this_cpu_read_8(pcp); \
+ } while (this_cpu_cmpxchg_8(pcp, __o, __o & __v) != __o); \
+})
+
+#define this_cpu_or_8(pcp, val) \
+({ \
+ typeof(val) __v = (val); \
+ typeof(val) __o; \
+ do { \
+ __o = this_cpu_read_8(pcp); \
+ } while (this_cpu_cmpxchg_8(pcp, __o, __o | __v) != __o); \
+})
+
+#define this_cpu_xor_8(pcp, val) \
+({ \
+ typeof(val) __v = (val); \
+ typeof(val) __o; \
+ do { \
+ __o = this_cpu_read_8(pcp); \
+ } while (this_cpu_cmpxchg_8(pcp, __o, __o ^ __v) != __o); \
+})
+
+#define this_cpu_inc_return_8(pcp, val) \
+({ \
+ typeof(val) __v = (val); \
+ typeof(val) __o; \
+ typeof(val) __r; \
+ do { \
+ __o = this_cpu_read_8(pcp); \
+ __r = __o + __v; \
+ } while (this_cpu_cmpxchg_8(pcp, __o, __r) != __o); \
+ r; \
+})
+
#endif /* CONFIG_X86_CMPXCHG64 */
#endif /* !CONFIG_X86_64 */



\
 
 \ /
  Last update: 2010-12-08 23:25    [from the cache]
©2003-2011 Jasper Spaans