diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-09 23:23:19 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-09 23:23:19 -0500 |
commit | c30110608cfba7efff3a5e71914aee7c816115c5 (patch) | |
tree | bd7fca47f16826fb4521e16ada1c25971fa42ff2 /Documentation/memory-barriers.txt | |
parent | 9c37f95936b6c169e89733747504879b06e77c24 (diff) | |
parent | d360b78f99e5d1724279644c8eb51d5cf0de4027 (diff) |
Merge branch 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull RCU updates from Ingo Molnar:
"These are the main changes in this cycle:
- Streamline RCU's use of per-CPU variables, shifting from "cpu"
arguments to functions to "this_"-style per-CPU variable
accessors.
- signal-handling RCU updates.
- real-time updates.
- torture-test updates.
- miscellaneous fixes.
- documentation updates"
* 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (34 commits)
rcu: Fix FIXME in rcu_tasks_kthread()
rcu: More info about potential deadlocks with rcu_read_unlock()
rcu: Optimize cond_resched_rcu_qs()
rcu: Add sparse check for RCU_INIT_POINTER()
documentation: memory-barriers.txt: Correct example for reorderings
documentation: Add atomic_long_t to atomic_ops.txt
documentation: Additional restriction for control dependencies
documentation: Document RCU self test boot params
rcutorture: Fix rcu_torture_cbflood() memory leak
rcutorture: Remove obsolete kversion param in kvm.sh
rcutorture: Remove stale test configurations
rcutorture: Enable RCU self test in configs
rcutorture: Add early boot self tests
torture: Run Linux-kernel binary out of results directory
cpu: Avoid puts_pending overflow
rcu: Remove "cpu" argument to rcu_cleanup_after_idle()
rcu: Remove "cpu" argument to rcu_prepare_for_idle()
rcu: Remove "cpu" argument to rcu_needs_cpu()
rcu: Remove "cpu" argument to rcu_note_context_switch()
rcu: Remove "cpu" argument to rcu_preempt_check_callbacks()
...
Diffstat (limited to 'Documentation/memory-barriers.txt')
-rw-r--r-- | Documentation/memory-barriers.txt | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index 4af4cea8cff0..7ee2ae6d5451 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt | |||
@@ -121,22 +121,22 @@ For example, consider the following sequence of events: | |||
121 | The set of accesses as seen by the memory system in the middle can be arranged | 121 | The set of accesses as seen by the memory system in the middle can be arranged |
122 | in 24 different combinations: | 122 | in 24 different combinations: |
123 | 123 | ||
124 | STORE A=3, STORE B=4, x=LOAD A->3, y=LOAD B->4 | 124 | STORE A=3, STORE B=4, y=LOAD A->3, x=LOAD B->4 |
125 | STORE A=3, STORE B=4, y=LOAD B->4, x=LOAD A->3 | 125 | STORE A=3, STORE B=4, x=LOAD B->4, y=LOAD A->3 |
126 | STORE A=3, x=LOAD A->3, STORE B=4, y=LOAD B->4 | 126 | STORE A=3, y=LOAD A->3, STORE B=4, x=LOAD B->4 |
127 | STORE A=3, x=LOAD A->3, y=LOAD B->2, STORE B=4 | 127 | STORE A=3, y=LOAD A->3, x=LOAD B->2, STORE B=4 |
128 | STORE A=3, y=LOAD B->2, STORE B=4, x=LOAD A->3 | 128 | STORE A=3, x=LOAD B->2, STORE B=4, y=LOAD A->3 |
129 | STORE A=3, y=LOAD B->2, x=LOAD A->3, STORE B=4 | 129 | STORE A=3, x=LOAD B->2, y=LOAD A->3, STORE B=4 |
130 | STORE B=4, STORE A=3, x=LOAD A->3, y=LOAD B->4 | 130 | STORE B=4, STORE A=3, y=LOAD A->3, x=LOAD B->4 |
131 | STORE B=4, ... | 131 | STORE B=4, ... |
132 | ... | 132 | ... |
133 | 133 | ||
134 | and can thus result in four different combinations of values: | 134 | and can thus result in four different combinations of values: |
135 | 135 | ||
136 | x == 1, y == 2 | 136 | x == 2, y == 1 |
137 | x == 1, y == 4 | 137 | x == 2, y == 3 |
138 | x == 3, y == 2 | 138 | x == 4, y == 1 |
139 | x == 3, y == 4 | 139 | x == 4, y == 3 |
140 | 140 | ||
141 | 141 | ||
142 | Furthermore, the stores committed by a CPU to the memory system may not be | 142 | Furthermore, the stores committed by a CPU to the memory system may not be |
@@ -694,6 +694,24 @@ Please note once again that the stores to 'b' differ. If they were | |||
694 | identical, as noted earlier, the compiler could pull this store outside | 694 | identical, as noted earlier, the compiler could pull this store outside |
695 | of the 'if' statement. | 695 | of the 'if' statement. |
696 | 696 | ||
697 | You must also be careful not to rely too much on boolean short-circuit | ||
698 | evaluation. Consider this example: | ||
699 | |||
700 | q = ACCESS_ONCE(a); | ||
701 | if (a || 1 > 0) | ||
702 | ACCESS_ONCE(b) = 1; | ||
703 | |||
704 | Because the second condition is always true, the compiler can transform | ||
705 | this example as following, defeating control dependency: | ||
706 | |||
707 | q = ACCESS_ONCE(a); | ||
708 | ACCESS_ONCE(b) = 1; | ||
709 | |||
710 | This example underscores the need to ensure that the compiler cannot | ||
711 | out-guess your code. More generally, although ACCESS_ONCE() does force | ||
712 | the compiler to actually emit code for a given load, it does not force | ||
713 | the compiler to use the results. | ||
714 | |||
697 | Finally, control dependencies do -not- provide transitivity. This is | 715 | Finally, control dependencies do -not- provide transitivity. This is |
698 | demonstrated by two related examples, with the initial values of | 716 | demonstrated by two related examples, with the initial values of |
699 | x and y both being zero: | 717 | x and y both being zero: |