Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

Merge branches 'bigrtm.2012.07.04a', 'doctorture.2012.07.02a',...

Merge branches 'bigrtm.2012.07.04a', 'doctorture.2012.07.02a', 'fixes.2012.07.06a' and 'fnh.2012.07.02a' into HEAD

bigrtm: First steps towards getting RCU out of the way of
	tens-of-microseconds real-time response on systems compiled
	with NR_CPUS=4096.  Also cleanups for and increased concurrency
	of rcu_barrier() family of primitives.
doctorture: rcutorture and documentation improvements.
fixes:  Miscellaneous fixes.
fnh: RCU_FAST_NO_HZ fixes and improvements.
Loading
Loading
Loading
Loading
+20 −19
Original line number Original line Diff line number Diff line
@@ -162,9 +162,9 @@ over a rather long period of time, but improvements are always welcome!
		when publicizing a pointer to a structure that can
		when publicizing a pointer to a structure that can
		be traversed by an RCU read-side critical section.
		be traversed by an RCU read-side critical section.


5.	If call_rcu(), or a related primitive such as call_rcu_bh() or
5.	If call_rcu(), or a related primitive such as call_rcu_bh(),
	call_rcu_sched(), is used, the callback function must be
	call_rcu_sched(), or call_srcu() is used, the callback function
	written to be called from softirq context.  In particular,
	must be written to be called from softirq context.  In particular,
	it cannot block.
	it cannot block.


6.	Since synchronize_rcu() can block, it cannot be called from
6.	Since synchronize_rcu() can block, it cannot be called from
@@ -202,11 +202,12 @@ over a rather long period of time, but improvements are always welcome!
	updater uses call_rcu_sched() or synchronize_sched(), then
	updater uses call_rcu_sched() or synchronize_sched(), then
	the corresponding readers must disable preemption, possibly
	the corresponding readers must disable preemption, possibly
	by calling rcu_read_lock_sched() and rcu_read_unlock_sched().
	by calling rcu_read_lock_sched() and rcu_read_unlock_sched().
	If the updater uses synchronize_srcu(), the the corresponding
	If the updater uses synchronize_srcu() or call_srcu(),
	readers must use srcu_read_lock() and srcu_read_unlock(),
	the the corresponding readers must use srcu_read_lock() and
	and with the same srcu_struct.	The rules for the expedited
	srcu_read_unlock(), and with the same srcu_struct.  The rules for
	primitives are the same as for their non-expedited counterparts.
	the expedited primitives are the same as for their non-expedited
	Mixing things up will result in confusion and broken kernels.
	counterparts.  Mixing things up will result in confusion and
	broken kernels.


	One exception to this rule: rcu_read_lock() and rcu_read_unlock()
	One exception to this rule: rcu_read_lock() and rcu_read_unlock()
	may be substituted for rcu_read_lock_bh() and rcu_read_unlock_bh()
	may be substituted for rcu_read_lock_bh() and rcu_read_unlock_bh()
@@ -333,14 +334,14 @@ over a rather long period of time, but improvements are always welcome!
	victim CPU from ever going offline.)
	victim CPU from ever going offline.)


14.	SRCU (srcu_read_lock(), srcu_read_unlock(), srcu_dereference(),
14.	SRCU (srcu_read_lock(), srcu_read_unlock(), srcu_dereference(),
	synchronize_srcu(), and synchronize_srcu_expedited()) may only
	synchronize_srcu(), synchronize_srcu_expedited(), and call_srcu())
	be invoked from process context.  Unlike other forms of RCU, it
	may only be invoked from process context.  Unlike other forms of
	-is- permissible to block in an SRCU read-side critical section
	RCU, it -is- permissible to block in an SRCU read-side critical
	(demarked by srcu_read_lock() and srcu_read_unlock()), hence the
	section (demarked by srcu_read_lock() and srcu_read_unlock()),
	"SRCU": "sleepable RCU".  Please note that if you don't need
	hence the "SRCU": "sleepable RCU".  Please note that if you
	to sleep in read-side critical sections, you should be using
	don't need to sleep in read-side critical sections, you should be
	RCU rather than SRCU, because RCU is almost always faster and
	using RCU rather than SRCU, because RCU is almost always faster
	easier to use than is SRCU.
	and easier to use than is SRCU.


	If you need to enter your read-side critical section in a
	If you need to enter your read-side critical section in a
	hardirq or exception handler, and then exit that same read-side
	hardirq or exception handler, and then exit that same read-side
@@ -353,8 +354,8 @@ over a rather long period of time, but improvements are always welcome!
	cleanup_srcu_struct().	These are passed a "struct srcu_struct"
	cleanup_srcu_struct().	These are passed a "struct srcu_struct"
	that defines the scope of a given SRCU domain.	Once initialized,
	that defines the scope of a given SRCU domain.	Once initialized,
	the srcu_struct is passed to srcu_read_lock(), srcu_read_unlock()
	the srcu_struct is passed to srcu_read_lock(), srcu_read_unlock()
	synchronize_srcu(), and synchronize_srcu_expedited().  A given
	synchronize_srcu(), synchronize_srcu_expedited(), and call_srcu().
	synchronize_srcu() waits only for SRCU read-side critical
	A given synchronize_srcu() waits only for SRCU read-side critical
	sections governed by srcu_read_lock() and srcu_read_unlock()
	sections governed by srcu_read_lock() and srcu_read_unlock()
	calls that have been passed the same srcu_struct.  This property
	calls that have been passed the same srcu_struct.  This property
	is what makes sleeping read-side critical sections tolerable --
	is what makes sleeping read-side critical sections tolerable --
@@ -374,7 +375,7 @@ over a rather long period of time, but improvements are always welcome!
	requiring SRCU's read-side deadlock immunity or low read-side
	requiring SRCU's read-side deadlock immunity or low read-side
	realtime latency.
	realtime latency.


	Note that, rcu_assign_pointer() relates to SRCU just as they do
	Note that, rcu_assign_pointer() relates to SRCU just as it does
	to other forms of RCU.
	to other forms of RCU.


15.	The whole point of call_rcu(), synchronize_rcu(), and friends
15.	The whole point of call_rcu(), synchronize_rcu(), and friends
+4 −11
Original line number Original line Diff line number Diff line
@@ -79,8 +79,6 @@ complete. Pseudo-code using rcu_barrier() is as follows:
   2. Execute rcu_barrier().
   2. Execute rcu_barrier().
   3. Allow the module to be unloaded.
   3. Allow the module to be unloaded.


Quick Quiz #1: Why is there no srcu_barrier()?

The rcutorture module makes use of rcu_barrier in its exit function
The rcutorture module makes use of rcu_barrier in its exit function
as follows:
as follows:


@@ -162,7 +160,7 @@ for any pre-existing callbacks to complete.
Then lines 55-62 print status and do operation-specific cleanup, and
Then lines 55-62 print status and do operation-specific cleanup, and
then return, permitting the module-unload operation to be completed.
then return, permitting the module-unload operation to be completed.


Quick Quiz #2: Is there any other situation where rcu_barrier() might
Quick Quiz #1: Is there any other situation where rcu_barrier() might
	be required?
	be required?


Your module might have additional complications. For example, if your
Your module might have additional complications. For example, if your
@@ -242,7 +240,7 @@ reaches zero, as follows:
 4 complete(&rcu_barrier_completion);
 4 complete(&rcu_barrier_completion);
 5 }
 5 }


Quick Quiz #3: What happens if CPU 0's rcu_barrier_func() executes
Quick Quiz #2: What happens if CPU 0's rcu_barrier_func() executes
	immediately (thus incrementing rcu_barrier_cpu_count to the
	immediately (thus incrementing rcu_barrier_cpu_count to the
	value one), but the other CPU's rcu_barrier_func() invocations
	value one), but the other CPU's rcu_barrier_func() invocations
	are delayed for a full grace period? Couldn't this result in
	are delayed for a full grace period? Couldn't this result in
@@ -259,12 +257,7 @@ so that your module may be safely unloaded.


Answers to Quick Quizzes
Answers to Quick Quizzes


Quick Quiz #1: Why is there no srcu_barrier()?
Quick Quiz #1: Is there any other situation where rcu_barrier() might

Answer: Since there is no call_srcu(), there can be no outstanding SRCU
	callbacks. Therefore, there is no need to wait for them.

Quick Quiz #2: Is there any other situation where rcu_barrier() might
	be required?
	be required?


Answer: Interestingly enough, rcu_barrier() was not originally
Answer: Interestingly enough, rcu_barrier() was not originally
@@ -278,7 +271,7 @@ Answer: Interestingly enough, rcu_barrier() was not originally
	implementing rcutorture, and found that rcu_barrier() solves
	implementing rcutorture, and found that rcu_barrier() solves
	this problem as well.
	this problem as well.


Quick Quiz #3: What happens if CPU 0's rcu_barrier_func() executes
Quick Quiz #2: What happens if CPU 0's rcu_barrier_func() executes
	immediately (thus incrementing rcu_barrier_cpu_count to the
	immediately (thus incrementing rcu_barrier_cpu_count to the
	value one), but the other CPU's rcu_barrier_func() invocations
	value one), but the other CPU's rcu_barrier_func() invocations
	are delayed for a full grace period? Couldn't this result in
	are delayed for a full grace period? Couldn't this result in
+9 −0
Original line number Original line Diff line number Diff line
@@ -174,11 +174,20 @@ torture_type The type of RCU to test, with string values as follows:
			and synchronize_rcu_bh_expedited().
			and synchronize_rcu_bh_expedited().


		"srcu": srcu_read_lock(), srcu_read_unlock() and
		"srcu": srcu_read_lock(), srcu_read_unlock() and
			call_srcu().

		"srcu_sync": srcu_read_lock(), srcu_read_unlock() and
			synchronize_srcu().
			synchronize_srcu().


		"srcu_expedited": srcu_read_lock(), srcu_read_unlock() and
		"srcu_expedited": srcu_read_lock(), srcu_read_unlock() and
			synchronize_srcu_expedited().
			synchronize_srcu_expedited().


		"srcu_raw": srcu_read_lock_raw(), srcu_read_unlock_raw(),
			and call_srcu().

		"srcu_raw_sync": srcu_read_lock_raw(), srcu_read_unlock_raw(),
			and synchronize_srcu().

		"sched": preempt_disable(), preempt_enable(), and
		"sched": preempt_disable(), preempt_enable(), and
			call_rcu_sched().
			call_rcu_sched().


+3 −3
Original line number Original line Diff line number Diff line
@@ -833,9 +833,9 @@ sched: Critical sections Grace period Barrier


SRCU:	Critical sections	Grace period		Barrier
SRCU:	Critical sections	Grace period		Barrier


	srcu_read_lock		synchronize_srcu	N/A
	srcu_read_lock		synchronize_srcu	srcu_barrier
	srcu_read_unlock	synchronize_srcu_expedited
	srcu_read_unlock	call_srcu
	srcu_read_lock_raw
	srcu_read_lock_raw	synchronize_srcu_expedited
	srcu_read_unlock_raw
	srcu_read_unlock_raw
	srcu_dereference
	srcu_dereference


+2 −2
Original line number Original line Diff line number Diff line
@@ -168,8 +168,8 @@ extern struct cred init_cred;
	.children	= LIST_HEAD_INIT(tsk.children),			\
	.children	= LIST_HEAD_INIT(tsk.children),			\
	.sibling	= LIST_HEAD_INIT(tsk.sibling),			\
	.sibling	= LIST_HEAD_INIT(tsk.sibling),			\
	.group_leader	= &tsk,						\
	.group_leader	= &tsk,						\
	RCU_INIT_POINTER(.real_cred, &init_cred),			\
	RCU_POINTER_INITIALIZER(real_cred, &init_cred),			\
	RCU_INIT_POINTER(.cred, &init_cred),				\
	RCU_POINTER_INITIALIZER(cred, &init_cred),			\
	.comm		= INIT_TASK_COMM,				\
	.comm		= INIT_TASK_COMM,				\
	.thread		= INIT_THREAD,					\
	.thread		= INIT_THREAD,					\
	.fs		= &init_fs,					\
	.fs		= &init_fs,					\
Loading