@@ -302,6 +302,11 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
#endif
+/* Is this type a native word size -- useful for atomic operations */
+#ifndef __native_word
+# define __native_word(t) (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
+#endif
+
/* Compile time object size, -1 for unknown */
#ifndef __compiletime_object_size
# define __compiletime_object_size(obj) -1
@@ -267,12 +267,33 @@ do { \
* used.
*/
-#define _this_cpu_generic_read(pcp) \
-({ typeof(pcp) ret__; \
+#define __this_cpu_generic_read_nopreempt(pcp) \
+({ \
+ typeof(pcp) __ret; \
preempt_disable(); \
- ret__ = *this_cpu_ptr(&(pcp)); \
+ __ret = ACCESS_ONCE(*this_cpu_ptr(&(pcp))); \
preempt_enable(); \
- ret__; \
+ __ret; \
+})
+
+#define __this_cpu_generic_read_noirq(pcp) \
+({ \
+ typeof(pcp) __ret; \
+ unsigned long __flags; \
+ raw_local_irq_save(__flags); \
+ __ret = *this_cpu_ptr(&(pcp)); \
+ raw_local_irq_restore(__flags); \
+ __ret; \
+})
+
+#define _this_cpu_generic_read(pcp) \
+({ \
+ typeof(pcp) __ret; \
+ if (__native_word(pcp)) \
+ __ret = __this_cpu_generic_read_nopreempt(pcp); \
+ else \
+ __ret = __this_cpu_generic_read_noirq(pcp); \
+ __ret; \
})
#ifndef this_cpu_read