Skip to content

Commit

Permalink
Merge branches 'array.2015.05.27a', 'doc.2015.05.27a', 'fixes.2015.05…
Browse files Browse the repository at this point in the history
….27a', 'hotplug.2015.05.27a', 'init.2015.05.27a', 'tiny.2015.05.27a' and 'torture.2015.05.27a' into HEAD

array.2015.05.27a:  Remove all uses of RCU-protected array indexes.
doc.2015.05.27a:  Docuemntation updates.
fixes.2015.05.27a:  Miscellaneous fixes.
hotplug.2015.05.27a:  CPU-hotplug updates.
init.2015.05.27a:  Initialization/Kconfig updates.
tiny.2015.05.27a:  Updates to Tiny RCU.
torture.2015.05.27a:  Torture-testing updates.
  • Loading branch information
Paul E. McKenney committed May 27, 2015
7 parents 29c6820 + ed38446 + f517700 + 927da9d + 1ce46ee + 6e91f8c + 7d3bb54 commit 0868aa2
Show file tree
Hide file tree
Showing 49 changed files with 582 additions and 342 deletions.
5 changes: 5 additions & 0 deletions Documentation/RCU/rcu_dereference.txt
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@ o Be very careful about comparing pointers obtained from
pointer. Note that the volatile cast in rcu_dereference()
will normally prevent the compiler from knowing too much.

However, please note that if the compiler knows that the
pointer takes on only one of two values, a not-equal
comparison will provide exactly the information that the
compiler needs to deduce the value of the pointer.

o Disable any value-speculation optimizations that your compiler
might provide, especially if you are making use of feedback-based
optimizations that take data collected from prior runs. Such
Expand Down
4 changes: 3 additions & 1 deletion Documentation/RCU/whatisRCU.txt
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,9 @@ rcu_dereference()
If you are going to be fetching multiple fields from the
RCU-protected structure, using the local variable is of
course preferred. Repeated rcu_dereference() calls look
ugly and incur unnecessary overhead on Alpha CPUs.
ugly, do not guarantee that the same pointer will be returned
if an update happened while in the critical section, and incur
unnecessary overhead on Alpha CPUs.

Note that the value returned by rcu_dereference() is valid
only within the enclosing RCU read-side critical section.
Expand Down
33 changes: 30 additions & 3 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2992,11 +2992,34 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
Set maximum number of finished RCU callbacks to
process in one batch.

rcutree.dump_tree= [KNL]
Dump the structure of the rcu_node combining tree
out at early boot. This is used for diagnostic
purposes, to verify correct tree setup.

rcutree.gp_cleanup_delay= [KNL]
Set the number of jiffies to delay each step of
RCU grace-period cleanup. This only has effect
when CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP is set.

rcutree.gp_init_delay= [KNL]
Set the number of jiffies to delay each step of
RCU grace-period initialization. This only has
effect when CONFIG_RCU_TORTURE_TEST_SLOW_INIT is
set.
effect when CONFIG_RCU_TORTURE_TEST_SLOW_INIT
is set.

rcutree.gp_preinit_delay= [KNL]
Set the number of jiffies to delay each step of
RCU grace-period pre-initialization, that is,
the propagation of recent CPU-hotplug changes up
the rcu_node combining tree. This only has effect
when CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT is set.

rcutree.rcu_fanout_exact= [KNL]
Disable autobalancing of the rcu_node combining
tree. This is used by rcutorture, and might
possibly be useful for architectures having high
cache-to-cache transfer latencies.

rcutree.rcu_fanout_leaf= [KNL]
Increase the number of CPUs assigned to each
Expand Down Expand Up @@ -3101,7 +3124,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
test, hence the "fake".

rcutorture.nreaders= [KNL]
Set number of RCU readers.
Set number of RCU readers. The value -1 selects
N-1, where N is the number of CPUs. A value
"n" less than -1 selects N-n-2, where N is again
the number of CPUs. For example, -2 selects N
(the number of CPUs), -3 selects N+1, and so on.

rcutorture.object_debug= [KNL]
Enable debug-object double-call_rcu() testing.
Expand Down
62 changes: 36 additions & 26 deletions Documentation/memory-barriers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -617,16 +617,16 @@ case what's actually required is:
However, stores are not speculated. This means that ordering -is- provided
for load-store control dependencies, as in the following example:

q = ACCESS_ONCE(a);
q = READ_ONCE_CTRL(a);
if (q) {
ACCESS_ONCE(b) = p;
}

Control dependencies pair normally with other types of barriers.
That said, please note that ACCESS_ONCE() is not optional! Without the
ACCESS_ONCE(), might combine the load from 'a' with other loads from
'a', and the store to 'b' with other stores to 'b', with possible highly
counterintuitive effects on ordering.
Control dependencies pair normally with other types of barriers. That
said, please note that READ_ONCE_CTRL() is not optional! Without the
READ_ONCE_CTRL(), the compiler might combine the load from 'a' with
other loads from 'a', and the store to 'b' with other stores to 'b',
with possible highly counterintuitive effects on ordering.

Worse yet, if the compiler is able to prove (say) that the value of
variable 'a' is always non-zero, it would be well within its rights
Expand All @@ -636,12 +636,15 @@ as follows:
q = a;
b = p; /* BUG: Compiler and CPU can both reorder!!! */

So don't leave out the ACCESS_ONCE().
Finally, the READ_ONCE_CTRL() includes an smp_read_barrier_depends()
that DEC Alpha needs in order to respect control depedencies.

So don't leave out the READ_ONCE_CTRL().

It is tempting to try to enforce ordering on identical stores on both
branches of the "if" statement as follows:

q = ACCESS_ONCE(a);
q = READ_ONCE_CTRL(a);
if (q) {
barrier();
ACCESS_ONCE(b) = p;
Expand All @@ -655,7 +658,7 @@ branches of the "if" statement as follows:
Unfortunately, current compilers will transform this as follows at high
optimization levels:

q = ACCESS_ONCE(a);
q = READ_ONCE_CTRL(a);
barrier();
ACCESS_ONCE(b) = p; /* BUG: No ordering vs. load from a!!! */
if (q) {
Expand Down Expand Up @@ -685,7 +688,7 @@ memory barriers, for example, smp_store_release():
In contrast, without explicit memory barriers, two-legged-if control
ordering is guaranteed only when the stores differ, for example:

q = ACCESS_ONCE(a);
q = READ_ONCE_CTRL(a);
if (q) {
ACCESS_ONCE(b) = p;
do_something();
Expand All @@ -694,14 +697,14 @@ ordering is guaranteed only when the stores differ, for example:
do_something_else();
}

The initial ACCESS_ONCE() is still required to prevent the compiler from
proving the value of 'a'.
The initial READ_ONCE_CTRL() is still required to prevent the compiler
from proving the value of 'a'.

In addition, you need to be careful what you do with the local variable 'q',
otherwise the compiler might be able to guess the value and again remove
the needed conditional. For example:

q = ACCESS_ONCE(a);
q = READ_ONCE_CTRL(a);
if (q % MAX) {
ACCESS_ONCE(b) = p;
do_something();
Expand All @@ -714,7 +717,7 @@ If MAX is defined to be 1, then the compiler knows that (q % MAX) is
equal to zero, in which case the compiler is within its rights to
transform the above code into the following:

q = ACCESS_ONCE(a);
q = READ_ONCE_CTRL(a);
ACCESS_ONCE(b) = p;
do_something_else();

Expand All @@ -725,7 +728,7 @@ is gone, and the barrier won't bring it back. Therefore, if you are
relying on this ordering, you should make sure that MAX is greater than
one, perhaps as follows:

q = ACCESS_ONCE(a);
q = READ_ONCE_CTRL(a);
BUILD_BUG_ON(MAX <= 1); /* Order load from a with store to b. */
if (q % MAX) {
ACCESS_ONCE(b) = p;
Expand All @@ -742,14 +745,15 @@ of the 'if' statement.
You must also be careful not to rely too much on boolean short-circuit
evaluation. Consider this example:

q = ACCESS_ONCE(a);
q = READ_ONCE_CTRL(a);
if (a || 1 > 0)
ACCESS_ONCE(b) = 1;

Because the second condition is always true, the compiler can transform
this example as following, defeating control dependency:
Because the first condition cannot fault and the second condition is
always true, the compiler can transform this example as following,
defeating control dependency:

q = ACCESS_ONCE(a);
q = READ_ONCE_CTRL(a);
ACCESS_ONCE(b) = 1;

This example underscores the need to ensure that the compiler cannot
Expand All @@ -762,8 +766,8 @@ demonstrated by two related examples, with the initial values of
x and y both being zero:

CPU 0 CPU 1
===================== =====================
r1 = ACCESS_ONCE(x); r2 = ACCESS_ONCE(y);
======================= =======================
r1 = READ_ONCE_CTRL(x); r2 = READ_ONCE_CTRL(y);
if (r1 > 0) if (r2 > 0)
ACCESS_ONCE(y) = 1; ACCESS_ONCE(x) = 1;

Expand All @@ -783,14 +787,21 @@ But because control dependencies do -not- provide transitivity, the above
assertion can fail after the combined three-CPU example completes. If you
need the three-CPU example to provide ordering, you will need smp_mb()
between the loads and stores in the CPU 0 and CPU 1 code fragments,
that is, just before or just after the "if" statements.
that is, just before or just after the "if" statements. Furthermore,
the original two-CPU example is very fragile and should be avoided.

These two examples are the LB and WWC litmus tests from this paper:
http://www.cl.cam.ac.uk/users/pes20/ppc-supplemental/test6.pdf and this
site: https://www.cl.cam.ac.uk/~pes20/ppcmem/index.html.

In summary:

(*) Control dependencies must be headed by READ_ONCE_CTRL().
Or, as a much less preferable alternative, interpose
be headed by READ_ONCE() or an ACCESS_ONCE() read and must
have smp_read_barrier_depends() between this read and the
control-dependent write.

(*) Control dependencies can order prior loads against later stores.
However, they do -not- guarantee any other sort of ordering:
Not prior loads against later loads, nor prior stores against
Expand Down Expand Up @@ -1784,10 +1795,9 @@ for each construct. These operations all imply certain barriers:

Memory operations issued before the ACQUIRE may be completed after
the ACQUIRE operation has completed. An smp_mb__before_spinlock(),
combined with a following ACQUIRE, orders prior loads against
subsequent loads and stores and also orders prior stores against
subsequent stores. Note that this is weaker than smp_mb()! The
smp_mb__before_spinlock() primitive is free on many architectures.
combined with a following ACQUIRE, orders prior stores against
subsequent loads and stores. Note that this is weaker than smp_mb()!
The smp_mb__before_spinlock() primitive is free on many architectures.

(2) RELEASE operation implication:

Expand Down
1 change: 1 addition & 0 deletions arch/powerpc/include/asm/barrier.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,6 @@ do { \

#define smp_mb__before_atomic() smp_mb()
#define smp_mb__after_atomic() smp_mb()
#define smp_mb__before_spinlock() smp_mb()

#endif /* _ASM_POWERPC_BARRIER_H */
16 changes: 16 additions & 0 deletions include/linux/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,22 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
#define WRITE_ONCE(x, val) \
({ typeof(x) __val = (val); __write_once_size(&(x), &__val, sizeof(__val)); __val; })

/**
* READ_ONCE_CTRL - Read a value heading a control dependency
* @x: The value to be read, heading the control dependency
*
* Control dependencies are tricky. See Documentation/memory-barriers.txt
* for important information on how to use them. Note that in many cases,
* use of smp_load_acquire() will be much simpler. Control dependencies
* should be avoided except on the hottest of hotpaths.
*/
#define READ_ONCE_CTRL(x) \
({ \
typeof(x) __val = READ_ONCE(x); \
smp_read_barrier_depends(); /* Enforce control dependency. */ \
__val; \
})

#endif /* __KERNEL__ */

#endif /* __ASSEMBLY__ */
Expand Down
4 changes: 2 additions & 2 deletions include/linux/rculist.h
Original file line number Diff line number Diff line change
Expand Up @@ -549,8 +549,8 @@ static inline void hlist_add_behind_rcu(struct hlist_node *n,
*/
#define hlist_for_each_entry_from_rcu(pos, member) \
for (; pos; \
pos = hlist_entry_safe(rcu_dereference((pos)->member.next),\
typeof(*(pos)), member))
pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu( \
&(pos)->member)), typeof(*(pos)), member))

#endif /* __KERNEL__ */
#endif
8 changes: 2 additions & 6 deletions include/linux/rcupdate.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,10 +292,6 @@ void rcu_sched_qs(void);
void rcu_bh_qs(void);
void rcu_check_callbacks(int user);
struct notifier_block;
void rcu_idle_enter(void);
void rcu_idle_exit(void);
void rcu_irq_enter(void);
void rcu_irq_exit(void);
int rcu_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu);

Expand Down Expand Up @@ -1103,13 +1099,13 @@ static inline notrace void rcu_read_unlock_sched_notrace(void)
#define kfree_rcu(ptr, rcu_head) \
__kfree_rcu(&((ptr)->rcu_head), offsetof(typeof(*(ptr)), rcu_head))

#if defined(CONFIG_TINY_RCU) || defined(CONFIG_RCU_NOCB_CPU_ALL)
#ifdef CONFIG_TINY_RCU
static inline int rcu_needs_cpu(unsigned long *delta_jiffies)
{
*delta_jiffies = ULONG_MAX;
return 0;
}
#endif /* #if defined(CONFIG_TINY_RCU) || defined(CONFIG_RCU_NOCB_CPU_ALL) */
#endif /* #ifdef CONFIG_TINY_RCU */

#if defined(CONFIG_RCU_NOCB_CPU_ALL)
static inline bool rcu_is_nocb_cpu(int cpu) { return true; }
Expand Down
16 changes: 16 additions & 0 deletions include/linux/rcutiny.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,22 @@ static inline void rcu_cpu_stall_reset(void)
{
}

static inline void rcu_idle_enter(void)
{
}

static inline void rcu_idle_exit(void)
{
}

static inline void rcu_irq_enter(void)
{
}

static inline void rcu_irq_exit(void)
{
}

static inline void exit_rcu(void)
{
}
Expand Down
7 changes: 5 additions & 2 deletions include/linux/rcutree.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@
#define __LINUX_RCUTREE_H

void rcu_note_context_switch(void);
#ifndef CONFIG_RCU_NOCB_CPU_ALL
int rcu_needs_cpu(unsigned long *delta_jiffies);
#endif /* #ifndef CONFIG_RCU_NOCB_CPU_ALL */
void rcu_cpu_stall_reset(void);

/*
Expand Down Expand Up @@ -93,6 +91,11 @@ void rcu_force_quiescent_state(void);
void rcu_bh_force_quiescent_state(void);
void rcu_sched_force_quiescent_state(void);

void rcu_idle_enter(void);
void rcu_idle_exit(void);
void rcu_irq_enter(void);
void rcu_irq_exit(void);

void exit_rcu(void);

void rcu_scheduler_starting(void);
Expand Down
2 changes: 1 addition & 1 deletion include/linux/spinlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ do { \
/*
* Despite its name it doesn't necessarily has to be a full barrier.
* It should only guarantee that a STORE before the critical section
* can not be reordered with a LOAD inside this section.
* can not be reordered with LOADs and STOREs inside this section.
* spin_lock() is the one-way barrier, this LOAD can not escape out
* of the region. So the default implementation simply ensures that
* a STORE can not move into the critical section, smp_wmb() should
Expand Down
Loading

0 comments on commit 0868aa2

Please sign in to comment.