Commit b989ff07 authored by Paul E. McKenney's avatar Paul E. McKenney
Browse files

Merge LKMM and RCU commits

parents 4289ee7d 11ca7a9d
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
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@ Circular Buffers
================

:Author: David Howells <dhowells@redhat.com>
:Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
:Author: Paul E. McKenney <paulmck@linux.ibm.com>


Linux provides a number of features that can be used to implement circular
Loading