Commit 46f1ec23 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull RCU updates from Ingo Molnar:
 "The changes in this cycle are:

   - RCU flavor consolidation cleanups and optmizations

   - Documentation updates

   - Miscellaneous fixes

   - SRCU updates

   - RCU-sync flavor consolidation

   - Torture-test updates

   - Linux-kernel memory-consistency-model updates, most notably the
     addition of plain C-language accesses"

* 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (61 commits)
  tools/memory-model: Improve data-race detection
  tools/memory-model: Change definition of rcu-fence
  tools/memory-model: Expand definition of barrier
  tools/memory-model: Do not use "herd" to refer to "herd7"
  tools/memory-model: Fix comment in MP+poonceonces.litmus
  Documentation: atomic_t.txt: Explain ordering provided by smp_mb__{before,after}_atomic()
  rcu: Don't return a value from rcu_assign_pointer()
  rcu: Force inlining of rcu_read_lock()
  rcu: Fix irritating whitespace error in rcu_assign_pointer()
  rcu: Upgrade sync_exp_work_done() to smp_mb()
  rcutorture: Upper case solves the case of the vanishing NULL pointer
  torture: Suppress propagating trace_printk() warning
  rcutorture: Dump trace buffer for callback pipe drain failures
  torture: Add --trust-make to suppress "make clean"
  torture: Make --cpus override idleness calculations
  torture: Run kernel build in source directory
  torture: Add function graph-tracing cheat sheet
  torture: Capture qemu output
  rcutorture: Tweak kvm options
  rcutorture: Add trivial RCU implementation
  ...
parents 223cea6a 83086d65
Loading
Loading
Loading
Loading
+20 −1
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ please read on.
Reference counting on elements of lists which are protected by traditional
reader/writer spinlocks or semaphores are straightforward:

CODE LISTING A:
1.				2.
add()				search_and_reference()
{				{
@@ -28,7 +29,8 @@ add() search_and_reference()
release_referenced()			delete()
{					{
    ...					    write_lock(&list_lock);
    atomic_dec(&el->rc, relfunc)	    ...
    if(atomic_dec_and_test(&el->rc))	    ...
	kfree(el);
    ...					    remove_element
}					    write_unlock(&list_lock);
 					    ...
@@ -44,6 +46,7 @@ search_and_reference() could potentially hold reference to an element which
has already been deleted from the list/array.  Use atomic_inc_not_zero()
in this scenario as follows:

CODE LISTING B:
1.					2.
add()					search_and_reference()
{					{
@@ -79,6 +82,7 @@ search_and_reference() code path. In such cases, the
atomic_dec_and_test() may be moved from delete() to el_free()
as follows:

CODE LISTING C:
1.					2.
add()					search_and_reference()
{					{
@@ -114,6 +118,17 @@ element can therefore safely be freed. This in turn guarantees that if
any reader finds the element, that reader may safely acquire a reference
without checking the value of the reference counter.

A clear advantage of the RCU-based pattern in listing C over the one
in listing B is that any call to search_and_reference() that locates
a given object will succeed in obtaining a reference to that object,
even given a concurrent invocation of delete() for that same object.
Similarly, a clear advantage of both listings B and C over listing A is
that a call to delete() is not delayed even if there are an arbitrarily
large number of calls to search_and_reference() searching for the same
object that delete() was invoked on.  Instead, all that is delayed is
the eventual invocation of kfree(), which is usually not a problem on
modern computer systems, even the small ones.

In cases where delete() can sleep, synchronize_rcu() can be called from
delete(), so that el_free() can be subsumed into delete as follows:

@@ -130,3 +145,7 @@ delete()
    	kfree(el);
    ...
}

As additional examples in the kernel, the pattern in listing C is used by
reference counting of struct pid, while the pattern in listing B is used by
struct posix_acl.
+1 −1
Original line number Diff line number Diff line
@@ -153,7 +153,7 @@ rcupdate.rcu_task_stall_timeout
	This boot/sysfs parameter controls the RCU-tasks stall warning
	interval.  A value of zero or less suppresses RCU-tasks stall
	warnings.  A positive value sets the stall-warning interval
	in jiffies.  An RCU-tasks stall warning starts with the line:
	in seconds.  An RCU-tasks stall warning starts with the line:

		INFO: rcu_tasks detected stalls on tasks:

+4 −4
Original line number Diff line number Diff line
@@ -212,7 +212,7 @@ synchronize_rcu()

rcu_assign_pointer()

	typeof(p) rcu_assign_pointer(p, typeof(p) v);
	void rcu_assign_pointer(p, typeof(p) v);

	Yes, rcu_assign_pointer() -is- implemented as a macro, though it
	would be cool to be able to declare a function in this manner.
@@ -220,9 +220,9 @@ rcu_assign_pointer()

	The updater uses this function to assign a new value to an
	RCU-protected pointer, in order to safely communicate the change
	in value from the updater to the reader.  This function returns
	the new value, and also executes any memory-barrier instructions
	required for a given CPU architecture.
	in value from the updater to the reader.  This macro does not
	evaluate to an rvalue, but it does execute any memory-barrier
	instructions required for a given CPU architecture.

	Perhaps just as important, it serves to document (1) which
	pointers are protected by RCU and (2) the point at which a
+6 −0
Original line number Diff line number Diff line
@@ -3752,6 +3752,12 @@
			the propagation of recent CPU-hotplug changes up
			the rcu_node combining tree.

	rcutree.use_softirq=	[KNL]
			If set to zero, move all RCU_SOFTIRQ processing to
			per-CPU rcuc kthreads.  Defaults to a non-zero
			value, meaning that RCU_SOFTIRQ is used by default.
			Specify rcutree.use_softirq=0 to use rcuc kthreads.

	rcutree.rcu_fanout_exact= [KNL]
			Disable autobalancing of the rcu_node combining
			tree.  This is used by rcutorture, and might
+13 −4
Original line number Diff line number Diff line
@@ -187,8 +187,14 @@ The barriers:

  smp_mb__{before,after}_atomic()

only apply to the RMW ops and can be used to augment/upgrade the ordering
inherent to the used atomic op. These barriers provide a full smp_mb().
only apply to the RMW atomic ops and can be used to augment/upgrade the
ordering inherent to the op. These barriers act almost like a full smp_mb():
smp_mb__before_atomic() orders all earlier accesses against the RMW op
itself and all accesses following it, and smp_mb__after_atomic() orders all
later accesses against the RMW op and all accesses preceding it. However,
accesses between the smp_mb__{before,after}_atomic() and the RMW op are not
ordered, so it is advisable to place the barrier right next to the RMW atomic
op whenever possible.

These helper barriers exist because architectures have varying implicit
ordering on their SMP atomic primitives. For example our TSO architectures
@@ -212,7 +218,9 @@ Further, while something like:
  atomic_dec(&X);

is a 'typical' RELEASE pattern, the barrier is strictly stronger than
a RELEASE. Similarly for something like:
a RELEASE because it orders preceding instructions against both the read
and write parts of the atomic_dec(), and against all following instructions
as well. Similarly, something like:

  atomic_inc(&X);
  smp_mb__after_atomic();
@@ -244,7 +252,8 @@ strictly stronger than ACQUIRE. As illustrated:

This should not happen; but a hypothetical atomic_inc_acquire() --
(void)atomic_fetch_inc_acquire() for instance -- would allow the outcome,
since then:
because it would not order the W part of the RMW against the following
WRITE_ONCE.  Thus:

  P1			P2

Loading