cpuops cmpxchg: Provide 64 bit this_cpu_xx for 32 bit x86 usingcmpxchg8b

From: Christoph Lameter
Date: Wed Dec 08 2010 - 17:22:26 EST


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@xxxxxxxxx>

---
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 */


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/