aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2017-01-15 18:18:22 -0500
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2017-04-12 11:23:39 -0400
commitf1387d770527b11c5467ed6b6b3d9c3e5aa12dd4 (patch)
tree3d71b42251a09621cabb90841ac84d949e63d094
parent4495c08e84729385774601b5146d51d9e5849f81 (diff)
doc: Synchronous RCU grace periods are now legal throughout boot
This commit updates the "Early Boot" section of the RCU requirements to describe how synchronous RCU grace periods are now legal throughout the boot process. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
-rw-r--r--Documentation/RCU/Design/Requirements/Requirements.html81
1 files changed, 47 insertions, 34 deletions
diff --git a/Documentation/RCU/Design/Requirements/Requirements.html b/Documentation/RCU/Design/Requirements/Requirements.html
index 21593496aca6..999b3ed3444e 100644
--- a/Documentation/RCU/Design/Requirements/Requirements.html
+++ b/Documentation/RCU/Design/Requirements/Requirements.html
@@ -2154,7 +2154,8 @@ as will <tt>rcu_assign_pointer()</tt>.
2154<p> 2154<p>
2155Although <tt>call_rcu()</tt> may be invoked at any 2155Although <tt>call_rcu()</tt> may be invoked at any
2156time during boot, callbacks are not guaranteed to be invoked until after 2156time during boot, callbacks are not guaranteed to be invoked until after
2157the scheduler is fully up and running. 2157all of RCU's kthreads have been spawned, which occurs at
2158<tt>early_initcall()</tt> time.
2158This delay in callback invocation is due to the fact that RCU does not 2159This delay in callback invocation is due to the fact that RCU does not
2159invoke callbacks until it is fully initialized, and this full initialization 2160invoke callbacks until it is fully initialized, and this full initialization
2160cannot occur until after the scheduler has initialized itself to the 2161cannot occur until after the scheduler has initialized itself to the
@@ -2167,8 +2168,10 @@ on what operations those callbacks could invoke.
2167Perhaps surprisingly, <tt>synchronize_rcu()</tt>, 2168Perhaps surprisingly, <tt>synchronize_rcu()</tt>,
2168<a href="#Bottom-Half Flavor"><tt>synchronize_rcu_bh()</tt></a> 2169<a href="#Bottom-Half Flavor"><tt>synchronize_rcu_bh()</tt></a>
2169(<a href="#Bottom-Half Flavor">discussed below</a>), 2170(<a href="#Bottom-Half Flavor">discussed below</a>),
2170and 2171<a href="#Sched Flavor"><tt>synchronize_sched()</tt></a>,
2171<a href="#Sched Flavor"><tt>synchronize_sched()</tt></a> 2172<tt>synchronize_rcu_expedited()</tt>,
2173<tt>synchronize_rcu_bh_expedited()</tt>, and
2174<tt>synchronize_sched_expedited()</tt>
2172will all operate normally 2175will all operate normally
2173during very early boot, the reason being that there is only one CPU 2176during very early boot, the reason being that there is only one CPU
2174and preemption is disabled. 2177and preemption is disabled.
@@ -2178,45 +2181,55 @@ state and thus a grace period, so the early-boot implementation can
2178be a no-op. 2181be a no-op.
2179 2182
2180<p> 2183<p>
2181Both <tt>synchronize_rcu_bh()</tt> and <tt>synchronize_sched()</tt> 2184However, once the scheduler has spawned its first kthread, this early
2182continue to operate normally through the remainder of boot, courtesy 2185boot trick fails for <tt>synchronize_rcu()</tt> (as well as for
2183of the fact that preemption is disabled across their RCU read-side 2186<tt>synchronize_rcu_expedited()</tt>) in <tt>CONFIG_PREEMPT=y</tt>
2184critical sections and also courtesy of the fact that there is still 2187kernels.
2185only one CPU. 2188The reason is that an RCU read-side critical section might be preempted,
2186However, once the scheduler starts initializing, preemption is enabled. 2189which means that a subsequent <tt>synchronize_rcu()</tt> really does have
2187There is still only a single CPU, but the fact that preemption is enabled 2190to wait for something, as opposed to simply returning immediately.
2188means that the no-op implementation of <tt>synchronize_rcu()</tt> no 2191Unfortunately, <tt>synchronize_rcu()</tt> can't do this until all of
2189longer works in <tt>CONFIG_PREEMPT=y</tt> kernels. 2192its kthreads are spawned, which doesn't happen until some time during
2190Therefore, as soon as the scheduler starts initializing, the early-boot 2193<tt>early_initcalls()</tt> time.
2191fastpath is disabled. 2194But this is no excuse: RCU is nevertheless required to correctly handle
2192This means that <tt>synchronize_rcu()</tt> switches to its runtime 2195synchronous grace periods during this time period, which it currently does.
2193mode of operation where it posts callbacks, which in turn means that 2196Once all of its kthreads are up and running, RCU starts running
2194any call to <tt>synchronize_rcu()</tt> will block until the corresponding 2197normally.
2195callback is invoked.
2196Unfortunately, the callback cannot be invoked until RCU's runtime
2197grace-period machinery is up and running, which cannot happen until
2198the scheduler has initialized itself sufficiently to allow RCU's
2199kthreads to be spawned.
2200Therefore, invoking <tt>synchronize_rcu()</tt> during scheduler
2201initialization can result in deadlock.
2202 2198
2203<table> 2199<table>
2204<tr><th>&nbsp;</th></tr> 2200<tr><th>&nbsp;</th></tr>
2205<tr><th align="left">Quick Quiz:</th></tr> 2201<tr><th align="left">Quick Quiz:</th></tr>
2206<tr><td> 2202<tr><td>
2207 So what happens with <tt>synchronize_rcu()</tt> during 2203 How can RCU possibly handle grace periods before all of its
2208 scheduler initialization for <tt>CONFIG_PREEMPT=n</tt> 2204 kthreads have been spawned???
2209 kernels?
2210</td></tr> 2205</td></tr>
2211<tr><th align="left">Answer:</th></tr> 2206<tr><th align="left">Answer:</th></tr>
2212<tr><td bgcolor="#ffffff"><font color="ffffff"> 2207<tr><td bgcolor="#ffffff"><font color="ffffff">
2213 In <tt>CONFIG_PREEMPT=n</tt> kernel, <tt>synchronize_rcu()</tt> 2208 Very carefully!
2214 maps directly to <tt>synchronize_sched()</tt>. 2209
2215 Therefore, <tt>synchronize_rcu()</tt> works normally throughout 2210 <p>During the &ldquo;dead zone&rdquo; between the time that the
2216 boot in <tt>CONFIG_PREEMPT=n</tt> kernels. 2211 scheduler spawns the first task and the time that all of RCU's
2217 However, your code must also work in <tt>CONFIG_PREEMPT=y</tt> kernels, 2212 kthreads have been spawned, all synchronous grace periods are
2218 so it is still necessary to avoid invoking <tt>synchronize_rcu()</tt> 2213 handled by the expedited grace-period mechanism.
2219 during scheduler initialization. 2214 At runtime, this expedited mechanism relies on workqueues, but
2215 during the dead zone the requesting task itself drives the
2216 desired expedited grace period.
2217 Because dead-zone execution takes place within task context,
2218 everything works.
2219 Once the dead zone ends, expedited grace periods go back to
2220 using workqueues, as is required to avoid problems that would
2221 otherwise occur when a user task received a POSIX signal while
2222 driving an expedited grace period.
2223
2224 <p>And yes, this does mean that it is unhelpful to send POSIX
2225 signals to random tasks between the time that the scheduler
2226 spawns its first kthread and the time that RCU's kthreads
2227 have all been spawned.
2228 If there ever turns out to be a good reason for sending POSIX
2229 signals during that time, appropriate adjustments will be made.
2230 (If it turns out that POSIX signals are sent during this time for
2231 no good reason, other adjustments will be made, appropriate
2232 or otherwise.)
2220</font></td></tr> 2233</font></td></tr>
2221<tr><td>&nbsp;</td></tr> 2234<tr><td>&nbsp;</td></tr>
2222</table> 2235</table>