Commit 97b43032 authored by Paul E. McKenney's avatar Paul E. McKenney Committed by Linus Torvalds

Immunize rcu_dereference() against crazy compiler writers

Turns out that compiler writers are a bit more aggressive about optimizing
than one might expect.  This patch prevents a number of such optimizations
from messing up rcu_deference().  This is not merely a theoretical problem, as
evidenced by the rmb() in mce_log().
Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
Acked-by: default avatarJosh Triplett <josh@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent f6b450d4
...@@ -231,6 +231,18 @@ extern struct lockdep_map rcu_lock_map; ...@@ -231,6 +231,18 @@ extern struct lockdep_map rcu_lock_map;
local_bh_enable(); \ local_bh_enable(); \
} while(0) } while(0)
/*
* Prevent the compiler from merging or refetching accesses. The compiler
* is also forbidden from reordering successive instances of ACCESS_ONCE(),
* but only when the compiler is aware of some particular ordering. One way
* to make the compiler aware of ordering is to put the two invocations of
* ACCESS_ONCE() in different C statements.
*
* This macro does absolutely -nothing- to prevent the CPU from reordering,
* merging, or refetching absolutely anything at any time.
*/
#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
/** /**
* rcu_dereference - fetch an RCU-protected pointer in an * rcu_dereference - fetch an RCU-protected pointer in an
* RCU read-side critical section. This pointer may later * RCU read-side critical section. This pointer may later
...@@ -242,7 +254,7 @@ extern struct lockdep_map rcu_lock_map; ...@@ -242,7 +254,7 @@ extern struct lockdep_map rcu_lock_map;
*/ */
#define rcu_dereference(p) ({ \ #define rcu_dereference(p) ({ \
typeof(p) _________p1 = p; \ typeof(p) _________p1 = ACCESS_ONCE(p); \
smp_read_barrier_depends(); \ smp_read_barrier_depends(); \
(_________p1); \ (_________p1); \
}) })
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment