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

Commit eee2775d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'core-rcu-for-linus' of...

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

* 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (28 commits)
  rcu: Move end of special early-boot RCU operation earlier
  rcu: Changes from reviews: avoid casts, fix/add warnings, improve comments
  rcu: Create rcutree plugins to handle hotplug CPU for multi-level trees
  rcu: Remove lockdep annotations from RCU's _notrace() API members
  rcu: Add #ifdef to suppress __rcu_offline_cpu() warning in !HOTPLUG_CPU builds
  rcu: Add CPU-offline processing for single-node configurations
  rcu: Add "notrace" to RCU function headers used by ftrace
  rcu: Remove CONFIG_PREEMPT_RCU
  rcu: Merge preemptable-RCU functionality into hierarchical RCU
  rcu: Simplify rcu_pending()/rcu_check_callbacks() API
  rcu: Use debugfs_remove_recursive() simplify code.
  rcu: Merge per-RCU-flavor initialization into pre-existing macro
  rcu: Fix online/offline indication for rcudata.csv trace file
  rcu: Consolidate sparse and lockdep declarations in include/linux/rcupdate.h
  rcu: Renamings to increase RCU clarity
  rcu: Move private definitions from include/linux/rcutree.h to kernel/rcutree.h
  rcu: Expunge lingering references to CONFIG_CLASSIC_RCU, optimize on !SMP
  rcu: Delay rcu_barrier() wait until beginning of next CPU-hotunplug operation.
  rcu: Fix typo in rcu_irq_exit() comment header
  rcu: Make rcupreempt_trace.c look at offline CPUs
  ...
parents 53e16fbd 7db905e6
Loading
Loading
Loading
Loading
+77 −0
Original line number Diff line number Diff line
@@ -743,3 +743,80 @@ Revised:
	RCU, realtime RCU, sleepable RCU, performance.
"
}

@article{PaulEMcKenney2008RCUOSR
,author="Paul E. McKenney and Jonathan Walpole"
,title="Introducing technology into the {Linux} kernel: a case study"
,Year="2008"
,journal="SIGOPS Oper. Syst. Rev."
,volume="42"
,number="5"
,pages="4--17"
,issn="0163-5980"
,doi={http://doi.acm.org/10.1145/1400097.1400099}
,publisher="ACM"
,address="New York, NY, USA"
,annotation={
	Linux changed RCU to a far greater degree than RCU has changed Linux.
}
}

@unpublished{PaulEMcKenney2008HierarchicalRCU
,Author="Paul E. McKenney"
,Title="Hierarchical {RCU}"
,month="November"
,day="3"
,year="2008"
,note="Available:
\url{http://lwn.net/Articles/305782/}
[Viewed November 6, 2008]"
,annotation="
	RCU with combining-tree-based grace-period detection,
	permitting it to handle thousands of CPUs.
"
}

@conference{PaulEMcKenney2009MaliciousURCU
,Author="Paul E. McKenney"
,Title="Using a Malicious User-Level {RCU} to Torture {RCU}-Based Algorithms"
,Booktitle="linux.conf.au 2009"
,month="January"
,year="2009"
,address="Hobart, Australia"
,note="Available:
\url{http://www.rdrop.com/users/paulmck/RCU/urcutorture.2009.01.22a.pdf}
[Viewed February 2, 2009]"
,annotation="
	Realtime RCU and torture-testing RCU uses.
"
}

@unpublished{MathieuDesnoyers2009URCU
,Author="Mathieu Desnoyers"
,Title="[{RFC} git tree] Userspace {RCU} (urcu) for {Linux}"
,month="February"
,day="5"
,year="2009"
,note="Available:
\url{http://lkml.org/lkml/2009/2/5/572}
\url{git://lttng.org/userspace-rcu.git}
[Viewed February 20, 2009]"
,annotation="
	Mathieu Desnoyers's user-space RCU implementation.
	git://lttng.org/userspace-rcu.git
"
}

@unpublished{PaulEMcKenney2009BloatWatchRCU
,Author="Paul E. McKenney"
,Title="{RCU}: The {Bloatwatch} Edition"
,month="March"
,day="17"
,year="2009"
,note="Available:
\url{http://lwn.net/Articles/323929/}
[Viewed March 20, 2009]"
,annotation="
	Uniprocessor assumptions allow simplified RCU implementation.
"
}
+25 −9
Original line number Diff line number Diff line
@@ -2,14 +2,13 @@ RCU on Uniprocessor Systems


A common misconception is that, on UP systems, the call_rcu() primitive
may immediately invoke its function, and that the synchronize_rcu()
primitive may return immediately.  The basis of this misconception
may immediately invoke its function.  The basis of this misconception
is that since there is only one CPU, it should not be necessary to
wait for anything else to get done, since there are no other CPUs for
anything else to be happening on.  Although this approach will -sort- -of-
work a surprising amount of the time, it is a very bad idea in general.
This document presents three examples that demonstrate exactly how bad an
idea this is.
This document presents three examples that demonstrate exactly how bad
an idea this is.


Example 1: softirq Suicide
@@ -82,11 +81,18 @@ Quick Quiz #2: What locking restriction must RCU callbacks respect?

Summary

Permitting call_rcu() to immediately invoke its arguments or permitting
synchronize_rcu() to immediately return breaks RCU, even on a UP system.
So do not do it!  Even on a UP system, the RCU infrastructure -must-
respect grace periods, and -must- invoke callbacks from a known environment
in which no locks are held.
Permitting call_rcu() to immediately invoke its arguments breaks RCU,
even on a UP system.  So do not do it!  Even on a UP system, the RCU
infrastructure -must- respect grace periods, and -must- invoke callbacks
from a known environment in which no locks are held.

It -is- safe for synchronize_sched() and synchronize_rcu_bh() to return
immediately on an UP system.  It is also safe for synchronize_rcu()
to return immediately on UP systems, except when running preemptable
RCU.

Quick Quiz #3: Why can't synchronize_rcu() return immediately on
	UP systems running preemptable RCU?


Answer to Quick Quiz #1:
@@ -117,3 +123,13 @@ Answer to Quick Quiz #2:
	callbacks acquire locks directly.  However, a great many RCU
	callbacks do acquire locks -indirectly-, for example, via
	the kfree() primitive.

Answer to Quick Quiz #3:
	Why can't synchronize_rcu() return immediately on UP systems
	running preemptable RCU?

	Because some other task might have been preempted in the middle
	of an RCU read-side critical section.  If synchronize_rcu()
	simply immediately returned, it would prematurely signal the
	end of the grace period, which would come as a nasty shock to
	that other thread when it started running again.
+15 −5
Original line number Diff line number Diff line
@@ -11,7 +11,10 @@ over a rather long period of time, but improvements are always welcome!
	structure is updated more than about 10% of the time, then
	you should strongly consider some other approach, unless
	detailed performance measurements show that RCU is nonetheless
	the right tool for the job.
	the right tool for the job.  Yes, you might think of RCU
	as simply cutting overhead off of the readers and imposing it
	on the writers.  That is exactly why normal uses of RCU will
	do much more reading than updating.

	Another exception is where performance is not an issue, and RCU
	provides a simpler implementation.  An example of this situation
@@ -240,10 +243,11 @@ over a rather long period of time, but improvements are always welcome!
	instead need to use synchronize_irq() or synchronize_sched().

12.	Any lock acquired by an RCU callback must be acquired elsewhere
	with irq disabled, e.g., via spin_lock_irqsave().  Failing to
	disable irq on a given acquisition of that lock will result in
	deadlock as soon as the RCU callback happens to interrupt that
	acquisition's critical section.
	with softirq disabled, e.g., via spin_lock_irqsave(),
	spin_lock_bh(), etc.  Failing to disable irq on a given
	acquisition of that lock will result in deadlock as soon as the
	RCU callback happens to interrupt that acquisition's critical
	section.

13.	RCU callbacks can be and are executed in parallel.  In many cases,
	the callback code simply wrappers around kfree(), so that this
@@ -310,3 +314,9 @@ over a rather long period of time, but improvements are always welcome!
	Because these primitives only wait for pre-existing readers,
	it is the caller's responsibility to guarantee safety to
	any subsequent readers.

16.	The various RCU read-side primitives do -not- contain memory
	barriers.  The CPU (and in some cases, the compiler) is free
	to reorder code into and out of RCU read-side critical sections.
	It is the responsibility of the RCU update-side primitives to
	deal with this.
+5 −5
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ o How can the updater tell when a grace period has completed
	executed in user mode, or executed in the idle loop, we can
	safely free up that item.

	Preemptible variants of RCU (CONFIG_PREEMPT_RCU) get the
	Preemptible variants of RCU (CONFIG_TREE_PREEMPT_RCU) get the
	same effect, but require that the readers manipulate CPU-local
	counters.  These counters allow limited types of blocking
	within RCU read-side critical sections.  SRCU also uses
@@ -79,10 +79,10 @@ o I hear that RCU is patented? What is with that?
o	I hear that RCU needs work in order to support realtime kernels?

	This work is largely completed.  Realtime-friendly RCU can be
	enabled via the CONFIG_PREEMPT_RCU kernel configuration parameter.
	However, work is in progress for enabling priority boosting of
	preempted RCU read-side critical sections.  This is needed if you
	have CPU-bound realtime threads.
	enabled via the CONFIG_TREE_PREEMPT_RCU kernel configuration
	parameter.  However, work is in progress for enabling priority
	boosting of preempted RCU read-side critical sections.	This is
	needed if you have CPU-bound realtime threads.

o	Where can I find more information on RCU?

+7 −0
Original line number Diff line number Diff line
@@ -170,6 +170,13 @@ module invokes call_rcu() from timers, you will need to first cancel all
the timers, and only then invoke rcu_barrier() to wait for any remaining
RCU callbacks to complete.

Of course, if you module uses call_rcu_bh(), you will need to invoke
rcu_barrier_bh() before unloading.  Similarly, if your module uses
call_rcu_sched(), you will need to invoke rcu_barrier_sched() before
unloading.  If your module uses call_rcu(), call_rcu_bh(), -and-
call_rcu_sched(), then you will need to invoke each of rcu_barrier(),
rcu_barrier_bh(), and rcu_barrier_sched().


Implementing rcu_barrier()

Loading