On 22/06/2016 23:55, Rik van Riel wrote: > > > + hardirq_time = READ_ONCE(per_cpu(cpu_hardirq_time, > > > cpu)); > > Which makes this per_cpu(,cpu) usage somewhat curious. What's wrong > > with __this_cpu_read() ? > > I played around with it a bit, and it seems that > __this_cpu_read does not want to nest inside > READ_ONCE. Nobody else seems to be doing that, > either.
According to arch/x86/include/asm/percpu.h, this_cpu_read always has READ_ONCE semantics, but I cannot find that in include/asm-generic /percpu.h. It probably just works because of all the layers of goo, but something like this (101% untested) would make me feel safer: diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h index 4d9f233c4ba8..d057568f1926 100644 --- a/include/asm-generic/percpu.h +++ b/include/asm-generic/percpu.h @@ -67,7 +67,7 @@ extern void setup_per_cpu_areas(void); #define raw_cpu_generic_to_op(pcp, val, op) \ do { \ - *raw_cpu_ptr(&(pcp)) op val; \ + ACCESS_ONCE(*raw_cpu_ptr(&(pcp))) op val; \ } while (0) #define raw_cpu_generic_add_return(pcp, val) \ @@ -109,7 +109,7 @@ do { ({ \ typeof(pcp) __ret; \ preempt_disable(); \ - __ret = *this_cpu_ptr(&(pcp)); \ + __ret = READ_ONCE(this_cpu_ptr(&(pcp))); \ preempt_enable(); \ __ret; \ }) @@ -118,7 +118,7 @@ do { do { \ unsigned long __flags; \ raw_local_irq_save(__flags); \ - *raw_cpu_ptr(&(pcp)) op val; \ + ACCESS_ONCE(*raw_cpu_ptr(&(pcp))) op val; \ raw_local_irq_restore(__flags); \ } while (0) @@ -168,16 +168,16 @@ do { }) #ifndef raw_cpu_read_1 -#define raw_cpu_read_1(pcp) (*raw_cpu_ptr(&(pcp))) +#define raw_cpu_read_1(pcp) READ_ONCE(raw_cpu_ptr(&(pcp))) #endif #ifndef raw_cpu_read_2 -#define raw_cpu_read_2(pcp) (*raw_cpu_ptr(&(pcp))) +#define raw_cpu_read_2(pcp) READ_ONCE(raw_cpu_ptr(&(pcp))) #endif #ifndef raw_cpu_read_4 -#define raw_cpu_read_4(pcp) (*raw_cpu_ptr(&(pcp))) +#define raw_cpu_read_4(pcp) READ_ONCE(raw_cpu_ptr(&(pcp))) #endif #ifndef raw_cpu_read_8 -#define raw_cpu_read_8(pcp) (*raw_cpu_ptr(&(pcp))) +#define raw_cpu_read_8(pcp) READ_ONCE(raw_cpu_ptr(&(pcp))) #endif #ifndef raw_cpu_write_1 > Back to READ_ONCE(per_cpu(,cpu)) it is... What about READ_ONCE(this_cpu_ptr())? Paolo