aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2017-01-31 01:45:42 -0500
committerIngo Molnar <mingo@kernel.org>2017-01-31 01:45:42 -0500
commita8709fa4a06d4af5f86e3660839531cbe0f2a19b (patch)
tree4deb2947a93294e4771265a60c508598a98cb494
parentf9a42e0d58cf0fe3d902e63d4582f2ea4cd2bb8b (diff)
parent31945aa9f14085c81cb3257e51bb210698b78626 (diff)
Merge branch 'for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu into core/rcu
Pull RCU changes from Paul E. McKenney: - Dynticks updates, consolidating open-coded counter accesses into a well-defined API - SRCU updates: Simplify algorithm, add formal verification - Documentation updates - Miscellaneous fixes - Torture-test updates Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--Documentation/RCU/Design/Data-Structures/Data-Structures.html5
-rw-r--r--Documentation/RCU/Design/Expedited-Grace-Periods/ExpRCUFlow.svg830
-rw-r--r--Documentation/RCU/Design/Expedited-Grace-Periods/ExpSchedFlow.svg826
-rw-r--r--Documentation/RCU/Design/Expedited-Grace-Periods/Expedited-Grace-Periods.html626
-rw-r--r--Documentation/RCU/Design/Expedited-Grace-Periods/Funnel0.svg275
-rw-r--r--Documentation/RCU/Design/Expedited-Grace-Periods/Funnel1.svg275
-rw-r--r--Documentation/RCU/Design/Expedited-Grace-Periods/Funnel2.svg287
-rw-r--r--Documentation/RCU/Design/Expedited-Grace-Periods/Funnel3.svg323
-rw-r--r--Documentation/RCU/Design/Expedited-Grace-Periods/Funnel4.svg323
-rw-r--r--Documentation/RCU/Design/Expedited-Grace-Periods/Funnel5.svg335
-rw-r--r--Documentation/RCU/Design/Expedited-Grace-Periods/Funnel6.svg335
-rw-r--r--Documentation/RCU/Design/Expedited-Grace-Periods/Funnel7.svg347
-rw-r--r--Documentation/RCU/Design/Expedited-Grace-Periods/Funnel8.svg311
-rw-r--r--Documentation/RCU/Design/Requirements/Requirements.html12
-rw-r--r--Documentation/RCU/trace.txt5
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt7
-rw-r--r--Documentation/memory-barriers.txt70
-rw-r--r--include/linux/llist.h37
-rw-r--r--include/linux/rcupdate.h12
-rw-r--r--include/linux/rcutiny.h6
-rw-r--r--include/linux/srcu.h10
-rw-r--r--include/trace/events/rcu.h10
-rw-r--r--init/Kconfig14
-rw-r--r--kernel/locking/lockdep.c12
-rw-r--r--kernel/locking/locktorture.c6
-rw-r--r--kernel/membarrier.c4
-rw-r--r--kernel/rcu/rcutorture.c19
-rw-r--r--kernel/rcu/srcu.c143
-rw-r--r--kernel/rcu/tiny.c2
-rw-r--r--kernel/rcu/tree.c262
-rw-r--r--kernel/rcu/tree.h15
-rw-r--r--kernel/rcu/tree_exp.h38
-rw-r--r--kernel/rcu/tree_plugin.h7
-rw-r--r--kernel/rcu/tree_trace.c5
-rw-r--r--kernel/rcu/update.c6
-rw-r--r--lib/Kconfig.debug1
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/CFcommon3
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/TINY011
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/TINY023
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/TREE013
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/TREE024
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/TREE033
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/TREE044
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/TREE053
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/TREE063
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/TREE073
-rw-r--r--tools/testing/selftests/rcutorture/configs/rcu/TREE084
-rw-r--r--tools/testing/selftests/rcutorture/doc/TREE_RCU-kconfig.txt33
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/.gitignore1
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/Makefile16
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/delay.h0
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/export.h0
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/mutex.h0
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/percpu.h0
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/preempt.h0
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/rcupdate.h0
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/sched.h0
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/smp.h0
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/workqueue.h0
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/uapi/linux/types.h0
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/include/linux/.gitignore1
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/include/linux/kconfig.h1
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/include/linux/types.h155
-rwxr-xr-xtools/testing/selftests/rcutorture/formal/srcu-cbmc/modify_srcu.awk375
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/assume.h16
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h41
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/bug_on.h13
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/combined_source.c13
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/config.h27
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/include_srcu.c31
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/int_typedefs.h33
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/locks.h220
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/misc.c11
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/misc.h58
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/percpu.h92
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/preempt.c78
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/preempt.h58
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/simple_sync_srcu.c50
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/workqueues.h102
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/.gitignore1
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/Makefile11
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/assert_end.fail1
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/force.fail1
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/force2.fail1
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/force3.fail1
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/main.pass0
-rw-r--r--tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/test.c72
-rwxr-xr-xtools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/test_script.sh102
88 files changed, 7150 insertions, 300 deletions
diff --git a/Documentation/RCU/Design/Data-Structures/Data-Structures.html b/Documentation/RCU/Design/Data-Structures/Data-Structures.html
index 7eb47ac25ad7..d583c653a703 100644
--- a/Documentation/RCU/Design/Data-Structures/Data-Structures.html
+++ b/Documentation/RCU/Design/Data-Structures/Data-Structures.html
@@ -4,7 +4,7 @@
4 <head><title>A Tour Through TREE_RCU's Data Structures [LWN.net]</title> 4 <head><title>A Tour Through TREE_RCU's Data Structures [LWN.net]</title>
5 <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> 5 <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
6 6
7 <p>January 27, 2016</p> 7 <p>December 18, 2016</p>
8 <p>This article was contributed by Paul E.&nbsp;McKenney</p> 8 <p>This article was contributed by Paul E.&nbsp;McKenney</p>
9 9
10<h3>Introduction</h3> 10<h3>Introduction</h3>
@@ -31,9 +31,6 @@ to each other.
31 Accessor Functions</a> 31 Accessor Functions</a>
32</ol> 32</ol>
33 33
34At the end we have the
35<a href="#Answers to Quick Quizzes">answers to the quick quizzes</a>.
36
37<h3><a name="Data-Structure Relationships">Data-Structure Relationships</a></h3> 34<h3><a name="Data-Structure Relationships">Data-Structure Relationships</a></h3>
38 35
39<p>RCU is for all intents and purposes a large state machine, and its 36<p>RCU is for all intents and purposes a large state machine, and its
diff --git a/Documentation/RCU/Design/Expedited-Grace-Periods/ExpRCUFlow.svg b/Documentation/RCU/Design/Expedited-Grace-Periods/ExpRCUFlow.svg
new file mode 100644
index 000000000000..7c6c90bd02c9
--- /dev/null
+++ b/Documentation/RCU/Design/Expedited-Grace-Periods/ExpRCUFlow.svg
@@ -0,0 +1,830 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Creator: fig2dev Version 3.2 Patchlevel 5e -->
3
4<!-- CreationDate: Wed Dec 9 17:39:46 2015 -->
5
6<!-- Magnification: 3.000 -->
7
8<svg
9 xmlns:dc="http://purl.org/dc/elements/1.1/"
10 xmlns:cc="http://creativecommons.org/ns#"
11 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
12 xmlns:svg="http://www.w3.org/2000/svg"
13 xmlns="http://www.w3.org/2000/svg"
14 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
15 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
16 width="952.6817"
17 height="1219.6219"
18 viewBox="-66 -66 12729.905 16296.808"
19 id="svg2"
20 version="1.1"
21 inkscape:version="0.48.4 r9939"
22 sodipodi:docname="ExpRCUFlow.svg">
23 <metadata
24 id="metadata94">
25 <rdf:RDF>
26 <cc:Work
27 rdf:about="">
28 <dc:format>image/svg+xml</dc:format>
29 <dc:type
30 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
31 <dc:title />
32 </cc:Work>
33 </rdf:RDF>
34 </metadata>
35 <defs
36 id="defs92">
37 <marker
38 inkscape:stockid="Arrow2Lend"
39 orient="auto"
40 refY="0"
41 refX="0"
42 id="Arrow2Lend"
43 style="overflow:visible">
44 <path
45 id="path4146"
46 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
47 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
48 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
49 inkscape:connector-curvature="0" />
50 </marker>
51 <marker
52 inkscape:stockid="Arrow1Mend"
53 orient="auto"
54 refY="0"
55 refX="0"
56 id="Arrow1Mend"
57 style="overflow:visible">
58 <path
59 id="path3852"
60 d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
61 style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
62 transform="matrix(-0.4,0,0,-0.4,-4,0)"
63 inkscape:connector-curvature="0" />
64 </marker>
65 <marker
66 inkscape:stockid="Arrow1Mend"
67 orient="auto"
68 refY="0"
69 refX="0"
70 id="Arrow1Mend-9"
71 style="overflow:visible">
72 <path
73 inkscape:connector-curvature="0"
74 id="path3852-7"
75 d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
76 style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
77 transform="matrix(-0.4,0,0,-0.4,-4,0)" />
78 </marker>
79 <marker
80 inkscape:stockid="Arrow2Lend"
81 orient="auto"
82 refY="0"
83 refX="0"
84 id="Arrow2Lend-7"
85 style="overflow:visible">
86 <path
87 inkscape:connector-curvature="0"
88 id="path4146-6"
89 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
90 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
91 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
92 </marker>
93 <marker
94 inkscape:stockid="Arrow2Lend"
95 orient="auto"
96 refY="0"
97 refX="0"
98 id="Arrow2Lend-1"
99 style="overflow:visible">
100 <path
101 inkscape:connector-curvature="0"
102 id="path4146-4"
103 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
104 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
105 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
106 </marker>
107 <marker
108 inkscape:stockid="Arrow2Lend"
109 orient="auto"
110 refY="0"
111 refX="0"
112 id="Arrow2Lend-16"
113 style="overflow:visible">
114 <path
115 inkscape:connector-curvature="0"
116 id="path4146-8"
117 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
118 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
119 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
120 </marker>
121 <marker
122 inkscape:stockid="Arrow2Lend"
123 orient="auto"
124 refY="0"
125 refX="0"
126 id="Arrow2Lend-160"
127 style="overflow:visible">
128 <path
129 inkscape:connector-curvature="0"
130 id="path4146-5"
131 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
132 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
133 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
134 </marker>
135 <marker
136 inkscape:stockid="Arrow2Lend"
137 orient="auto"
138 refY="0"
139 refX="0"
140 id="Arrow2Lend-78"
141 style="overflow:visible">
142 <path
143 inkscape:connector-curvature="0"
144 id="path4146-66"
145 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
146 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
147 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
148 </marker>
149 <marker
150 inkscape:stockid="Arrow2Lend"
151 orient="auto"
152 refY="0"
153 refX="0"
154 id="Arrow2Lend-8"
155 style="overflow:visible">
156 <path
157 inkscape:connector-curvature="0"
158 id="path4146-56"
159 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
160 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
161 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
162 </marker>
163 <marker
164 inkscape:stockid="Arrow2Lend"
165 orient="auto"
166 refY="0"
167 refX="0"
168 id="Arrow2Lend-19"
169 style="overflow:visible">
170 <path
171 inkscape:connector-curvature="0"
172 id="path4146-89"
173 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
174 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
175 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
176 </marker>
177 <marker
178 inkscape:stockid="Arrow2Lend"
179 orient="auto"
180 refY="0"
181 refX="0"
182 id="Arrow2Lend-85"
183 style="overflow:visible">
184 <path
185 inkscape:connector-curvature="0"
186 id="path4146-3"
187 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
188 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
189 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
190 </marker>
191 <marker
192 inkscape:stockid="Arrow2Lend"
193 orient="auto"
194 refY="0"
195 refX="0"
196 id="Arrow2Lend-73"
197 style="overflow:visible">
198 <path
199 inkscape:connector-curvature="0"
200 id="path4146-55"
201 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
202 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
203 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
204 </marker>
205 <marker
206 inkscape:stockid="Arrow2Lend"
207 orient="auto"
208 refY="0"
209 refX="0"
210 id="Arrow2Lend-5"
211 style="overflow:visible">
212 <path
213 inkscape:connector-curvature="0"
214 id="path4146-88"
215 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
216 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
217 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
218 </marker>
219 <marker
220 inkscape:stockid="Arrow2Lend"
221 orient="auto"
222 refY="0"
223 refX="0"
224 id="Arrow2Lend-198"
225 style="overflow:visible">
226 <path
227 inkscape:connector-curvature="0"
228 id="path4146-2"
229 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
230 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
231 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
232 </marker>
233 <marker
234 inkscape:stockid="Arrow2Lend"
235 orient="auto"
236 refY="0"
237 refX="0"
238 id="Arrow2Lend-4"
239 style="overflow:visible">
240 <path
241 inkscape:connector-curvature="0"
242 id="path4146-22"
243 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
244 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
245 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
246 </marker>
247 <marker
248 inkscape:stockid="Arrow2Lend"
249 orient="auto"
250 refY="0"
251 refX="0"
252 id="marker5072"
253 style="overflow:visible">
254 <path
255 inkscape:connector-curvature="0"
256 id="path5074"
257 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
258 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
259 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
260 </marker>
261 <marker
262 inkscape:stockid="Arrow2Lend"
263 orient="auto"
264 refY="0"
265 refX="0"
266 id="Arrow2Lend-87"
267 style="overflow:visible">
268 <path
269 inkscape:connector-curvature="0"
270 id="path4146-63"
271 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
272 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
273 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
274 </marker>
275 <marker
276 inkscape:stockid="Arrow2Lend"
277 orient="auto"
278 refY="0"
279 refX="0"
280 id="Arrow2Lend-6"
281 style="overflow:visible">
282 <path
283 inkscape:connector-curvature="0"
284 id="path4146-26"
285 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
286 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
287 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
288 </marker>
289 <marker
290 inkscape:stockid="Arrow2Lend"
291 orient="auto"
292 refY="0"
293 refX="0"
294 id="Arrow2Lend-0"
295 style="overflow:visible">
296 <path
297 inkscape:connector-curvature="0"
298 id="path4146-51"
299 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
300 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
301 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
302 </marker>
303 </defs>
304 <sodipodi:namedview
305 pagecolor="#ffffff"
306 bordercolor="#666666"
307 borderopacity="1"
308 objecttolerance="10"
309 gridtolerance="10"
310 guidetolerance="10"
311 inkscape:pageopacity="0"
312 inkscape:pageshadow="2"
313 inkscape:window-width="1090"
314 inkscape:window-height="1148"
315 id="namedview90"
316 showgrid="true"
317 inkscape:zoom="0.80021373"
318 inkscape:cx="462.49289"
319 inkscape:cy="623.19585"
320 inkscape:window-x="557"
321 inkscape:window-y="24"
322 inkscape:window-maximized="0"
323 inkscape:current-layer="g4"
324 inkscape:snap-grids="false"
325 fit-margin-top="5"
326 fit-margin-right="5"
327 fit-margin-bottom="5"
328 fit-margin-left="5" />
329 <g
330 style="fill:none;stroke-width:0.025in"
331 id="g4"
332 transform="translate(23.312813,523.41305)">
333 <!-- Line: box -->
334 <!-- Line: box -->
335 <!-- Line: box -->
336 <!-- Line: box -->
337 <!-- Line: box -->
338 <!-- Line: box -->
339 <!-- Line: box -->
340 <!-- Line -->
341 <!-- Arrowhead on XXXpoint 11475 2250 - 11475 3465-->
342 <!-- Line: box -->
343 <!-- Line: box -->
344 <!-- Line: box -->
345 <!-- Line: box -->
346 <!-- Line: box -->
347 <!-- Line -->
348 <!-- Arrowhead on XXXpoint 11475 5625 - 11475 6840-->
349 <!-- Line -->
350 <!-- Arrowhead on XXXpoint 7875 225 - 10665 225-->
351 <!-- Line -->
352 <!-- Arrowhead on XXXpoint 9675 675 - 7785 675-->
353 <!-- Line -->
354 <!-- Arrowhead on XXXpoint 9675 4725 - 10665 4725-->
355 <!-- Line -->
356 <!-- Arrowhead on XXXpoint 9225 5175 - 10665 5175-->
357 <!-- Line -->
358 <!-- Arrowhead on XXXpoint 8775 11475 - 10665 11475-->
359 <!-- Line: box -->
360 <!-- Line -->
361 <!-- Arrowhead on XXXpoint 11475 9000 - 11475 10215-->
362 <!-- Text -->
363 <!-- Text -->
364 <!-- Text -->
365 <!-- Text -->
366 <!-- Text -->
367 <!-- Text -->
368 <!-- Text -->
369 <!-- Text -->
370 <!-- Text -->
371 <!-- Text -->
372 <!-- Text -->
373 <!-- Text -->
374 <!-- Text -->
375 <g
376 id="g4104"
377 transform="translate(-1068.9745,0)">
378 <rect
379 transform="matrix(-0.70710678,0.70710678,-0.70710678,-0.70710678,0,0)"
380 y="-7383.8755"
381 x="-6124.8989"
382 height="1966.2251"
383 width="1953.6969"
384 id="rect3032-1-0"
385 style="fill:#96ff96;fill-opacity:1;stroke:#000000;stroke-width:45.00382233;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
386 <text
387 sodipodi:linespacing="125%"
388 id="text4098"
389 y="818.40338"
390 x="8168.2671"
391 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
392 xml:space="preserve"><tspan
393 y="818.40338"
394 x="8168.2671"
395 id="tspan4100"
396 sodipodi:role="line">Idle or</tspan><tspan
397 id="tspan4102"
398 y="1152.4579"
399 x="8168.2671"
400 sodipodi:role="line">offline?</tspan></text>
401 </g>
402 <g
403 id="g4114"
404 transform="translate(0,147.96969)">
405 <rect
406 id="rect6"
407 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
408 rx="0"
409 height="1475.6636"
410 width="4401.7612"
411 y="0"
412 x="0" />
413 <text
414 sodipodi:linespacing="125%"
415 id="text4110"
416 y="835.11212"
417 x="2206.4917"
418 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
419 xml:space="preserve"><tspan
420 y="835.11212"
421 x="2206.4917"
422 id="tspan4112"
423 sodipodi:role="line">CPU N Start</tspan></text>
424 </g>
425 <path
426 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Lend)"
427 d="M 4432.5052,897.4924 5684.8749,880.79414"
428 id="path4119"
429 inkscape:connector-curvature="0"
430 sodipodi:nodetypes="cc" />
431 <path
432 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Lend)"
433 d="M 8503.0006,874.12161 9755.3703,857.42334"
434 id="path4119-8"
435 inkscape:connector-curvature="0"
436 sodipodi:nodetypes="cc" />
437 <text
438 xml:space="preserve"
439 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
440 x="8617.0977"
441 y="705.50983"
442 id="text4593"
443 sodipodi:linespacing="125%"><tspan
444 sodipodi:role="line"
445 id="tspan4595"
446 x="8617.0977"
447 y="705.50983">Y</tspan></text>
448 <g
449 style="fill:none;stroke-width:0.025in"
450 id="g4114-9"
451 transform="translate(9722.4732,131.27105)">
452 <rect
453 id="rect6-0"
454 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
455 rx="0"
456 height="1425.5687"
457 width="2748.6331"
458 y="0"
459 x="80.17308" />
460 <text
461 sodipodi:linespacing="125%"
462 id="text4110-5"
463 y="835.11212"
464 x="1460.1007"
465 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
466 xml:space="preserve"><tspan
467 y="835.11212"
468 x="1460.1007"
469 id="tspan4112-9"
470 sodipodi:role="line">Done</tspan></text>
471 </g>
472 <g
473 style="fill:none;stroke-width:0.025in"
474 id="g4114-5"
475 transform="translate(0,3705.3456)">
476 <rect
477 id="rect6-1"
478 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
479 rx="0"
480 height="1475.6636"
481 width="4401.7612"
482 y="0"
483 x="0" />
484 <text
485 sodipodi:linespacing="125%"
486 id="text4110-9"
487 y="835.11212"
488 x="2206.4917"
489 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
490 xml:space="preserve"><tspan
491 y="835.11212"
492 x="2206.4917"
493 sodipodi:role="line"
494 id="tspan4776">Send IPI to CPU N</tspan></text>
495 </g>
496 <path
497 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Lend)"
498 d="M 7102.5627,2263.5171 4430.8404,3682.8694"
499 id="path4119-3"
500 inkscape:connector-curvature="0"
501 sodipodi:nodetypes="cc" />
502 <g
503 style="fill:none;stroke-width:0.025in"
504 id="g4104-1"
505 transform="translate(-1065.3349,6403.5782)">
506 <rect
507 transform="matrix(-0.70710678,0.70710678,-0.70710678,-0.70710678,0,0)"
508 y="-7383.8755"
509 x="-6124.8989"
510 height="1966.2251"
511 width="1953.6969"
512 id="rect3032-1-0-6"
513 style="fill:#96ff96;fill-opacity:1;stroke:#000000;stroke-width:45.00382233;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
514 <text
515 sodipodi:linespacing="125%"
516 id="text4098-3"
517 y="482.00006"
518 x="8168.2671"
519 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
520 xml:space="preserve"><tspan
521 id="tspan4102-8"
522 y="482.00006"
523 x="8168.2671"
524 sodipodi:role="line">In RCU</tspan><tspan
525 y="816.05457"
526 x="8168.2671"
527 sodipodi:role="line"
528 id="tspan4833">read-side</tspan><tspan
529 y="1150.109"
530 x="8168.2671"
531 sodipodi:role="line"
532 id="tspan4835">critical</tspan><tspan
533 y="1484.1636"
534 x="8168.2671"
535 sodipodi:role="line"
536 id="tspan4837">section?</tspan></text>
537 </g>
538 <text
539 xml:space="preserve"
540 style="font-size:267.24362183px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
541 x="6463.0864"
542 y="2285.6765"
543 id="text4593-0"
544 sodipodi:linespacing="125%"><tspan
545 sodipodi:role="line"
546 id="tspan4595-6"
547 x="6463.0864"
548 y="2285.6765">N</tspan></text>
549 <path
550 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:40.08654108, 80.17308215;stroke-dashoffset:0;marker-end:url(#Arrow2Lend)"
551 d="m 2189.1897,5219.361 16.6983,1252.3697"
552 id="path4119-0"
553 inkscape:connector-curvature="0"
554 sodipodi:nodetypes="cc" />
555 <g
556 style="fill:none;stroke-width:0.025in"
557 id="g4114-5-2"
558 transform="translate(0,6551.5479)">
559 <rect
560 id="rect6-1-7"
561 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
562 rx="0"
563 height="1475.6636"
564 width="4401.7612"
565 y="0"
566 x="0" />
567 <text
568 sodipodi:linespacing="125%"
569 id="text4110-9-5"
570 y="835.11212"
571 x="2206.4917"
572 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
573 xml:space="preserve"><tspan
574 y="835.11212"
575 x="2206.4917"
576 sodipodi:role="line"
577 id="tspan4776-5">IPI Handler</tspan></text>
578 </g>
579 <path
580 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Lend)"
581 d="m 4432.5052,7297.9678 1252.3697,-16.6982"
582 id="path4119-2"
583 inkscape:connector-curvature="0"
584 sodipodi:nodetypes="cc" />
585 <path
586 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Lend)"
587 d="m 8503.0013,7278.6595 1252.369,-16.6982"
588 id="path4119-8-7"
589 inkscape:connector-curvature="0"
590 sodipodi:nodetypes="cc" />
591 <text
592 xml:space="preserve"
593 style="font-size:267.24362183px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
594 x="8617.0977"
595 y="7110.0186"
596 id="text4593-4"
597 sodipodi:linespacing="125%"><tspan
598 sodipodi:role="line"
599 id="tspan4595-0"
600 x="8617.0977"
601 y="7110.0186">N</tspan></text>
602 <g
603 style="fill:none;stroke-width:0.025in"
604 id="g4114-9-3"
605 transform="translate(9722.4732,6535.809)">
606 <rect
607 id="rect6-0-7"
608 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
609 rx="0"
610 height="1425.5687"
611 width="2748.6331"
612 y="29.467337"
613 x="80.17308" />
614 <text
615 sodipodi:linespacing="125%"
616 id="text4110-5-7"
617 y="503.71591"
618 x="1460.1007"
619 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
620 xml:space="preserve"><tspan
621 y="503.71591"
622 x="1460.1007"
623 id="tspan4112-9-0"
624 sodipodi:role="line">Report CPU</tspan><tspan
625 y="837.77039"
626 x="1460.1007"
627 sodipodi:role="line"
628 id="tspan4923">Quiescent</tspan><tspan
629 y="1171.825"
630 x="1460.1007"
631 sodipodi:role="line"
632 id="tspan4925">State</tspan></text>
633 </g>
634 <path
635 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:40.08654335, 80.17308669;stroke-dashoffset:0;marker-end:url(#Arrow2Lend)"
636 d="m 7102.5627,8725.7454 16.6983,1252.3697"
637 id="path4119-0-0"
638 inkscape:connector-curvature="0"
639 sodipodi:nodetypes="cc" />
640 <text
641 xml:space="preserve"
642 style="font-size:267.24362183px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
643 x="6797.0522"
644 y="9018.6807"
645 id="text4593-3"
646 sodipodi:linespacing="125%"><tspan
647 sodipodi:role="line"
648 id="tspan4595-2"
649 x="6797.0522"
650 y="9018.6807">Y</tspan></text>
651 <g
652 style="fill:none;stroke-width:0.025in"
653 id="g4114-9-3-8"
654 transform="translate(-80.17308,11381.108)">
655 <rect
656 id="rect6-0-7-5"
657 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
658 rx="0"
659 height="1425.5687"
660 width="2748.6331"
661 y="29.467337"
662 x="80.17308" />
663 <text
664 sodipodi:linespacing="125%"
665 id="text4110-5-7-6"
666 y="841.88086"
667 x="1460.1007"
668 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
669 xml:space="preserve"><tspan
670 y="841.88086"
671 x="1460.1007"
672 sodipodi:role="line"
673 id="tspan4925-1">rcu_read_unlock()</tspan></text>
674 </g>
675 <path
676 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:40.08654562, 80.17309124;stroke-dashoffset:0;marker-end:url(#Arrow2Lend)"
677 d="m 1362.6256,10071.26 16.6983,1252.369"
678 id="path4119-0-0-7"
679 inkscape:connector-curvature="0"
680 sodipodi:nodetypes="cc" />
681 <path
682 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#Arrow2Lend)"
683 d="m 1362.6256,12883.919 16.6983,1252.369"
684 id="path4119-0-0-7-7"
685 inkscape:connector-curvature="0"
686 sodipodi:nodetypes="cc" />
687 <g
688 style="fill:none;stroke-width:0.025in"
689 id="g4114-9-3-8-1"
690 transform="translate(9722.4732,11389.458)">
691 <rect
692 id="rect6-0-7-5-1"
693 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
694 rx="0"
695 height="1425.5687"
696 width="2748.6331"
697 y="29.467337"
698 x="80.17308" />
699 <text
700 sodipodi:linespacing="125%"
701 id="text4110-5-7-6-2"
702 y="841.88086"
703 x="1460.1007"
704 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
705 xml:space="preserve"><tspan
706 y="841.88086"
707 x="1460.1007"
708 sodipodi:role="line"
709 id="tspan4925-1-2">Context Switch</tspan></text>
710 </g>
711 <path
712 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:40.08654789, 80.17309578;stroke-dashoffset:0;marker-end:url(#Arrow2Lend)"
713 d="m 11165.272,10071.26 16.698,1252.369"
714 id="path4119-0-0-7-8"
715 inkscape:connector-curvature="0"
716 sodipodi:nodetypes="cc" />
717 <g
718 style="fill:none;stroke-width:0.025in"
719 id="g4114-9-3-9"
720 transform="translate(-80.17308,14163.046)">
721 <rect
722 id="rect6-0-7-1"
723 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
724 rx="0"
725 height="1425.5687"
726 width="2748.6331"
727 y="29.467337"
728 x="80.17308" />
729 <text
730 sodipodi:linespacing="125%"
731 id="text4110-5-7-3"
732 y="503.71591"
733 x="1460.1007"
734 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
735 xml:space="preserve"><tspan
736 y="503.71591"
737 x="1460.1007"
738 id="tspan4112-9-0-4"
739 sodipodi:role="line">Report CPU</tspan><tspan
740 y="837.77039"
741 x="1460.1007"
742 sodipodi:role="line"
743 id="tspan4923-3">and Task</tspan><tspan
744 y="1171.825"
745 x="1460.1007"
746 sodipodi:role="line"
747 id="tspan4925-9">Quiescent States</tspan></text>
748 </g>
749 <g
750 style="fill:none;stroke-width:0.025in"
751 id="g4114-9-3-8-1-8"
752 transform="translate(5663.2978,11389.458)">
753 <rect
754 id="rect6-0-7-5-1-1"
755 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
756 rx="0"
757 height="1425.5687"
758 width="2748.6331"
759 y="29.467337"
760 x="80.17308" />
761 <text
762 sodipodi:linespacing="125%"
763 id="text4110-5-7-6-2-4"
764 y="841.88086"
765 x="1460.1007"
766 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
767 xml:space="preserve"><tspan
768 y="841.88086"
769 x="1460.1007"
770 sodipodi:role="line"
771 id="tspan4925-1-2-4">Enqueue Task</tspan></text>
772 </g>
773 <path
774 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Lend)"
775 d="M 9827.612,12141.988 8575.243,12125.29"
776 id="path4119-8-7-5"
777 inkscape:connector-curvature="0"
778 sodipodi:nodetypes="cc" />
779 <path
780 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#Arrow2Lend)"
781 d="m 7106.0965,12818.962 16.6983,1252.369"
782 id="path4119-0-0-7-7-5"
783 inkscape:connector-curvature="0"
784 sodipodi:nodetypes="cc" />
785 <g
786 style="fill:none;stroke-width:0.025in"
787 id="g4114-9-3-9-2"
788 transform="translate(5663.2978,14098.088)">
789 <rect
790 id="rect6-0-7-1-8"
791 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
792 rx="0"
793 height="1425.5687"
794 width="2748.6331"
795 y="29.467337"
796 x="80.17308" />
797 <text
798 sodipodi:linespacing="125%"
799 id="text4110-5-7-3-4"
800 y="503.71591"
801 x="1460.1007"
802 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
803 xml:space="preserve"><tspan
804 y="503.71591"
805 x="1460.1007"
806 sodipodi:role="line"
807 id="tspan4923-3-2">Report CPU</tspan><tspan
808 y="837.77039"
809 x="1460.1007"
810 sodipodi:role="line"
811 id="tspan4925-9-9">Quiescent</tspan><tspan
812 y="1171.825"
813 x="1460.1007"
814 sodipodi:role="line"
815 id="tspan5239">State</tspan></text>
816 </g>
817 <path
818 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:40.08654562, 80.17309124;stroke-dashoffset:0;marker-end:url(#Arrow2Lend)"
819 d="M 5733.305,14095.542 2761.014,12809.774"
820 id="path4119-0-0-2"
821 inkscape:connector-curvature="0"
822 sodipodi:nodetypes="cc" />
823 <path
824 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:40.08654107, 80.17308214;stroke-dashoffset:0"
825 d="m 1353.3524,10079.499 9701.6916,0 100.189,-16.698"
826 id="path5265"
827 inkscape:connector-curvature="0"
828 sodipodi:nodetypes="ccc" />
829 </g>
830</svg>
diff --git a/Documentation/RCU/Design/Expedited-Grace-Periods/ExpSchedFlow.svg b/Documentation/RCU/Design/Expedited-Grace-Periods/ExpSchedFlow.svg
new file mode 100644
index 000000000000..e4233ac93c2b
--- /dev/null
+++ b/Documentation/RCU/Design/Expedited-Grace-Periods/ExpSchedFlow.svg
@@ -0,0 +1,826 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Creator: fig2dev Version 3.2 Patchlevel 5e -->
3
4<!-- CreationDate: Wed Dec 9 17:39:46 2015 -->
5
6<!-- Magnification: 3.000 -->
7
8<svg
9 xmlns:dc="http://purl.org/dc/elements/1.1/"
10 xmlns:cc="http://creativecommons.org/ns#"
11 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
12 xmlns:svg="http://www.w3.org/2000/svg"
13 xmlns="http://www.w3.org/2000/svg"
14 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
15 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
16 width="952.6817"
17 height="1425.6191"
18 viewBox="-66 -66 12729.905 19049.38"
19 id="svg2"
20 version="1.1"
21 inkscape:version="0.48.4 r9939"
22 sodipodi:docname="ExpSchedFlow.svg">
23 <metadata
24 id="metadata94">
25 <rdf:RDF>
26 <cc:Work
27 rdf:about="">
28 <dc:format>image/svg+xml</dc:format>
29 <dc:type
30 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
31 <dc:title />
32 </cc:Work>
33 </rdf:RDF>
34 </metadata>
35 <defs
36 id="defs92">
37 <marker
38 inkscape:stockid="Arrow2Lend"
39 orient="auto"
40 refY="0"
41 refX="0"
42 id="Arrow2Lend"
43 style="overflow:visible">
44 <path
45 id="path4146"
46 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
47 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
48 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
49 inkscape:connector-curvature="0" />
50 </marker>
51 <marker
52 inkscape:stockid="Arrow1Mend"
53 orient="auto"
54 refY="0"
55 refX="0"
56 id="Arrow1Mend"
57 style="overflow:visible">
58 <path
59 id="path3852"
60 d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
61 style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
62 transform="matrix(-0.4,0,0,-0.4,-4,0)"
63 inkscape:connector-curvature="0" />
64 </marker>
65 <marker
66 inkscape:stockid="Arrow1Mend"
67 orient="auto"
68 refY="0"
69 refX="0"
70 id="Arrow1Mend-9"
71 style="overflow:visible">
72 <path
73 inkscape:connector-curvature="0"
74 id="path3852-7"
75 d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
76 style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
77 transform="matrix(-0.4,0,0,-0.4,-4,0)" />
78 </marker>
79 <marker
80 inkscape:stockid="Arrow2Lend"
81 orient="auto"
82 refY="0"
83 refX="0"
84 id="Arrow2Lend-7"
85 style="overflow:visible">
86 <path
87 inkscape:connector-curvature="0"
88 id="path4146-6"
89 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
90 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
91 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
92 </marker>
93 <marker
94 inkscape:stockid="Arrow2Lend"
95 orient="auto"
96 refY="0"
97 refX="0"
98 id="Arrow2Lend-1"
99 style="overflow:visible">
100 <path
101 inkscape:connector-curvature="0"
102 id="path4146-4"
103 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
104 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
105 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
106 </marker>
107 <marker
108 inkscape:stockid="Arrow2Lend"
109 orient="auto"
110 refY="0"
111 refX="0"
112 id="Arrow2Lend-16"
113 style="overflow:visible">
114 <path
115 inkscape:connector-curvature="0"
116 id="path4146-8"
117 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
118 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
119 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
120 </marker>
121 <marker
122 inkscape:stockid="Arrow2Lend"
123 orient="auto"
124 refY="0"
125 refX="0"
126 id="Arrow2Lend-160"
127 style="overflow:visible">
128 <path
129 inkscape:connector-curvature="0"
130 id="path4146-5"
131 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
132 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
133 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
134 </marker>
135 <marker
136 inkscape:stockid="Arrow2Lend"
137 orient="auto"
138 refY="0"
139 refX="0"
140 id="Arrow2Lend-78"
141 style="overflow:visible">
142 <path
143 inkscape:connector-curvature="0"
144 id="path4146-66"
145 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
146 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
147 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
148 </marker>
149 <marker
150 inkscape:stockid="Arrow2Lend"
151 orient="auto"
152 refY="0"
153 refX="0"
154 id="Arrow2Lend-8"
155 style="overflow:visible">
156 <path
157 inkscape:connector-curvature="0"
158 id="path4146-56"
159 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
160 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
161 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
162 </marker>
163 <marker
164 inkscape:stockid="Arrow2Lend"
165 orient="auto"
166 refY="0"
167 refX="0"
168 id="Arrow2Lend-19"
169 style="overflow:visible">
170 <path
171 inkscape:connector-curvature="0"
172 id="path4146-89"
173 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
174 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
175 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
176 </marker>
177 <marker
178 inkscape:stockid="Arrow2Lend"
179 orient="auto"
180 refY="0"
181 refX="0"
182 id="Arrow2Lend-85"
183 style="overflow:visible">
184 <path
185 inkscape:connector-curvature="0"
186 id="path4146-3"
187 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
188 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
189 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
190 </marker>
191 <marker
192 inkscape:stockid="Arrow2Lend"
193 orient="auto"
194 refY="0"
195 refX="0"
196 id="Arrow2Lend-73"
197 style="overflow:visible">
198 <path
199 inkscape:connector-curvature="0"
200 id="path4146-55"
201 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
202 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
203 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
204 </marker>
205 <marker
206 inkscape:stockid="Arrow2Lend"
207 orient="auto"
208 refY="0"
209 refX="0"
210 id="Arrow2Lend-5"
211 style="overflow:visible">
212 <path
213 inkscape:connector-curvature="0"
214 id="path4146-88"
215 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
216 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
217 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
218 </marker>
219 <marker
220 inkscape:stockid="Arrow2Lend"
221 orient="auto"
222 refY="0"
223 refX="0"
224 id="Arrow2Lend-198"
225 style="overflow:visible">
226 <path
227 inkscape:connector-curvature="0"
228 id="path4146-2"
229 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
230 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
231 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
232 </marker>
233 <marker
234 inkscape:stockid="Arrow2Lend"
235 orient="auto"
236 refY="0"
237 refX="0"
238 id="Arrow2Lend-4"
239 style="overflow:visible">
240 <path
241 inkscape:connector-curvature="0"
242 id="path4146-22"
243 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
244 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
245 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
246 </marker>
247 <marker
248 inkscape:stockid="Arrow2Lend"
249 orient="auto"
250 refY="0"
251 refX="0"
252 id="marker5072"
253 style="overflow:visible">
254 <path
255 inkscape:connector-curvature="0"
256 id="path5074"
257 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
258 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
259 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
260 </marker>
261 <marker
262 inkscape:stockid="Arrow2Lend"
263 orient="auto"
264 refY="0"
265 refX="0"
266 id="Arrow2Lend-87"
267 style="overflow:visible">
268 <path
269 inkscape:connector-curvature="0"
270 id="path4146-63"
271 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
272 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
273 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
274 </marker>
275 <marker
276 inkscape:stockid="Arrow2Lend"
277 orient="auto"
278 refY="0"
279 refX="0"
280 id="Arrow2Lend-6"
281 style="overflow:visible">
282 <path
283 inkscape:connector-curvature="0"
284 id="path4146-26"
285 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
286 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
287 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
288 </marker>
289 <marker
290 inkscape:stockid="Arrow2Lend"
291 orient="auto"
292 refY="0"
293 refX="0"
294 id="Arrow2Lend-0"
295 style="overflow:visible">
296 <path
297 inkscape:connector-curvature="0"
298 id="path4146-51"
299 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
300 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
301 transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
302 </marker>
303 <marker
304 inkscape:stockid="Arrow2Lend"
305 orient="auto"
306 refY="0"
307 refX="0"
308 id="Arrow2Lend-58"
309 style="overflow:visible">
310 <path
311 id="path4146-61"
312 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
313 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
314 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
315 inkscape:connector-curvature="0" />
316 </marker>
317 </defs>
318 <sodipodi:namedview
319 pagecolor="#ffffff"
320 bordercolor="#666666"
321 borderopacity="1"
322 objecttolerance="10"
323 gridtolerance="10"
324 guidetolerance="10"
325 inkscape:pageopacity="0"
326 inkscape:pageshadow="2"
327 inkscape:window-width="1090"
328 inkscape:window-height="1148"
329 id="namedview90"
330 showgrid="true"
331 inkscape:zoom="0.80021373"
332 inkscape:cx="462.49289"
333 inkscape:cy="473.6718"
334 inkscape:window-x="770"
335 inkscape:window-y="24"
336 inkscape:window-maximized="0"
337 inkscape:current-layer="g4114-9-3-9"
338 inkscape:snap-grids="false"
339 fit-margin-top="5"
340 fit-margin-right="5"
341 fit-margin-bottom="5"
342 fit-margin-left="5" />
343 <g
344 style="fill:none;stroke-width:0.025in"
345 id="g4"
346 transform="translate(23.312814,523.41265)">
347 <!-- Line: box -->
348 <!-- Line: box -->
349 <!-- Line: box -->
350 <!-- Line: box -->
351 <!-- Line: box -->
352 <!-- Line: box -->
353 <!-- Line: box -->
354 <!-- Line -->
355 <!-- Arrowhead on XXXpoint 11475 2250 - 11475 3465-->
356 <!-- Line: box -->
357 <!-- Line: box -->
358 <!-- Line: box -->
359 <!-- Line: box -->
360 <!-- Line: box -->
361 <!-- Line -->
362 <!-- Arrowhead on XXXpoint 11475 5625 - 11475 6840-->
363 <!-- Line -->
364 <!-- Arrowhead on XXXpoint 7875 225 - 10665 225-->
365 <!-- Line -->
366 <!-- Arrowhead on XXXpoint 9675 675 - 7785 675-->
367 <!-- Line -->
368 <!-- Arrowhead on XXXpoint 9675 4725 - 10665 4725-->
369 <!-- Line -->
370 <!-- Arrowhead on XXXpoint 9225 5175 - 10665 5175-->
371 <!-- Line -->
372 <!-- Arrowhead on XXXpoint 8775 11475 - 10665 11475-->
373 <!-- Line: box -->
374 <!-- Line -->
375 <!-- Arrowhead on XXXpoint 11475 9000 - 11475 10215-->
376 <!-- Text -->
377 <!-- Text -->
378 <!-- Text -->
379 <!-- Text -->
380 <!-- Text -->
381 <!-- Text -->
382 <!-- Text -->
383 <!-- Text -->
384 <!-- Text -->
385 <!-- Text -->
386 <!-- Text -->
387 <!-- Text -->
388 <!-- Text -->
389 <g
390 id="g4104"
391 transform="translate(-1068.9745,0)">
392 <rect
393 transform="matrix(-0.70710678,0.70710678,-0.70710678,-0.70710678,0,0)"
394 y="-7383.8755"
395 x="-6124.8989"
396 height="1966.2251"
397 width="1953.6969"
398 id="rect3032-1-0"
399 style="fill:#96ff96;fill-opacity:1;stroke:#000000;stroke-width:45.00382233;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
400 <text
401 sodipodi:linespacing="125%"
402 id="text4098"
403 y="818.40338"
404 x="8168.2671"
405 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
406 xml:space="preserve"><tspan
407 y="818.40338"
408 x="8168.2671"
409 id="tspan4100"
410 sodipodi:role="line">Idle or</tspan><tspan
411 id="tspan4102"
412 y="1152.4579"
413 x="8168.2671"
414 sodipodi:role="line">offline?</tspan></text>
415 </g>
416 <g
417 id="g4114"
418 transform="translate(0,147.96969)">
419 <rect
420 id="rect6"
421 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
422 rx="0"
423 height="1475.6636"
424 width="4401.7612"
425 y="0"
426 x="0" />
427 <text
428 sodipodi:linespacing="125%"
429 id="text4110"
430 y="835.11212"
431 x="2206.4917"
432 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
433 xml:space="preserve"><tspan
434 y="835.11212"
435 x="2206.4917"
436 id="tspan4112"
437 sodipodi:role="line">CPU N Start</tspan></text>
438 </g>
439 <path
440 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Lend)"
441 d="M 4432.5052,897.4924 5684.8749,880.79414"
442 id="path4119"
443 inkscape:connector-curvature="0"
444 sodipodi:nodetypes="cc" />
445 <path
446 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Lend)"
447 d="M 8503.0006,874.12161 9755.3703,857.42334"
448 id="path4119-8"
449 inkscape:connector-curvature="0"
450 sodipodi:nodetypes="cc" />
451 <text
452 xml:space="preserve"
453 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
454 x="8617.0977"
455 y="705.50983"
456 id="text4593"
457 sodipodi:linespacing="125%"><tspan
458 sodipodi:role="line"
459 id="tspan4595"
460 x="8617.0977"
461 y="705.50983">Y</tspan></text>
462 <g
463 style="fill:none;stroke-width:0.025in"
464 id="g4114-9"
465 transform="translate(9722.4732,131.27105)">
466 <rect
467 id="rect6-0"
468 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
469 rx="0"
470 height="1425.5687"
471 width="2748.6331"
472 y="0"
473 x="80.17308" />
474 <text
475 sodipodi:linespacing="125%"
476 id="text4110-5"
477 y="835.11212"
478 x="1460.1007"
479 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
480 xml:space="preserve"><tspan
481 y="835.11212"
482 x="1460.1007"
483 id="tspan4112-9"
484 sodipodi:role="line">Done</tspan></text>
485 </g>
486 <g
487 style="fill:none;stroke-width:0.025in"
488 id="g4114-5"
489 transform="translate(0,3705.3456)">
490 <rect
491 id="rect6-1"
492 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
493 rx="0"
494 height="1475.6636"
495 width="4401.7612"
496 y="0"
497 x="0" />
498 <text
499 sodipodi:linespacing="125%"
500 id="text4110-9"
501 y="835.11212"
502 x="2206.4917"
503 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
504 xml:space="preserve"><tspan
505 y="835.11212"
506 x="2206.4917"
507 sodipodi:role="line"
508 id="tspan4776">Send IPI to CPU N</tspan></text>
509 </g>
510 <path
511 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Lend)"
512 d="M 7102.5627,2263.5171 4430.8404,3682.8694"
513 id="path4119-3"
514 inkscape:connector-curvature="0"
515 sodipodi:nodetypes="cc" />
516 <g
517 style="fill:none;stroke-width:0.025in"
518 id="g4104-1"
519 transform="translate(-1065.3349,6403.5782)">
520 <rect
521 transform="matrix(-0.70710678,0.70710678,-0.70710678,-0.70710678,0,0)"
522 y="-7383.8755"
523 x="-6124.8989"
524 height="1966.2251"
525 width="1953.6969"
526 id="rect3032-1-0-6"
527 style="fill:#96ff96;fill-opacity:1;stroke:#000000;stroke-width:45.00382233;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
528 <text
529 sodipodi:linespacing="125%"
530 id="text4098-3"
531 y="985.4306"
532 x="8168.2671"
533 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
534 xml:space="preserve"><tspan
535 y="985.4306"
536 x="8168.2671"
537 sodipodi:role="line"
538 id="tspan3109">CPU idle?</tspan></text>
539 </g>
540 <text
541 xml:space="preserve"
542 style="font-size:267.24362183px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
543 x="6463.0864"
544 y="2285.6765"
545 id="text4593-0"
546 sodipodi:linespacing="125%"><tspan
547 sodipodi:role="line"
548 id="tspan4595-6"
549 x="6463.0864"
550 y="2285.6765">N</tspan></text>
551 <path
552 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:40.08654108, 80.17308215;stroke-dashoffset:0;marker-end:url(#Arrow2Lend)"
553 d="m 2189.1897,5219.361 16.6983,1252.3697"
554 id="path4119-0"
555 inkscape:connector-curvature="0"
556 sodipodi:nodetypes="cc" />
557 <g
558 style="fill:none;stroke-width:0.025in"
559 id="g4114-5-2"
560 transform="translate(0,6551.5479)">
561 <rect
562 id="rect6-1-7"
563 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
564 rx="0"
565 height="1475.6636"
566 width="4401.7612"
567 y="0"
568 x="0" />
569 <text
570 sodipodi:linespacing="125%"
571 id="text4110-9-5"
572 y="835.11212"
573 x="2206.4917"
574 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
575 xml:space="preserve"><tspan
576 y="835.11212"
577 x="2206.4917"
578 sodipodi:role="line"
579 id="tspan4776-5">IPI Handler</tspan></text>
580 </g>
581 <path
582 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Lend)"
583 d="m 4432.5052,7297.9678 1252.3697,-16.6982"
584 id="path4119-2"
585 inkscape:connector-curvature="0"
586 sodipodi:nodetypes="cc" />
587 <path
588 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Lend)"
589 d="m 8503.0013,7278.6595 1252.369,-16.6982"
590 id="path4119-8-7"
591 inkscape:connector-curvature="0"
592 sodipodi:nodetypes="cc" />
593 <text
594 xml:space="preserve"
595 style="font-size:267.24362183px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
596 x="8617.0977"
597 y="7110.0186"
598 id="text4593-4"
599 sodipodi:linespacing="125%"><tspan
600 sodipodi:role="line"
601 id="tspan4595-0"
602 x="8617.0977"
603 y="7110.0186">Y</tspan></text>
604 <g
605 style="fill:none;stroke-width:0.025in"
606 id="g4114-9-3"
607 transform="translate(9722.4732,6535.809)">
608 <rect
609 id="rect6-0-7"
610 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
611 rx="0"
612 height="1425.5687"
613 width="2748.6331"
614 y="29.467337"
615 x="80.17308" />
616 <text
617 sodipodi:linespacing="125%"
618 id="text4110-5-7"
619 y="503.71591"
620 x="1460.1007"
621 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
622 xml:space="preserve"><tspan
623 y="503.71591"
624 x="1460.1007"
625 id="tspan4112-9-0"
626 sodipodi:role="line">Report CPU</tspan><tspan
627 y="837.77039"
628 x="1460.1007"
629 sodipodi:role="line"
630 id="tspan4923">Quiescent</tspan><tspan
631 y="1171.825"
632 x="1460.1007"
633 sodipodi:role="line"
634 id="tspan4925">State</tspan></text>
635 </g>
636 <path
637 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:40.08654335, 80.17308669;stroke-dashoffset:0;marker-end:url(#Arrow2Lend)"
638 d="m 7102.5627,11478.337 16.6983,1252.35"
639 id="path4119-0-0"
640 inkscape:connector-curvature="0"
641 sodipodi:nodetypes="cc" />
642 <text
643 xml:space="preserve"
644 style="font-size:267.24362183px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
645 x="6797.0522"
646 y="9018.6807"
647 id="text4593-3"
648 sodipodi:linespacing="125%"><tspan
649 sodipodi:role="line"
650 id="tspan4595-2"
651 x="6797.0522"
652 y="9018.6807">N</tspan></text>
653 <g
654 style="fill:none;stroke-width:0.025in"
655 id="g4114-9-3-8"
656 transform="translate(-80.17308,14133.68)">
657 <rect
658 id="rect6-0-7-5"
659 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
660 rx="0"
661 height="1425.5687"
662 width="2748.6331"
663 y="29.467337"
664 x="80.17308" />
665 <text
666 sodipodi:linespacing="125%"
667 id="text4110-5-7-6"
668 y="841.88086"
669 x="1460.1007"
670 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
671 xml:space="preserve"><tspan
672 y="841.88086"
673 x="1460.1007"
674 sodipodi:role="line"
675 id="tspan4925-1">Context Switch</tspan></text>
676 </g>
677 <path
678 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:40.08654562, 80.17309124;stroke-dashoffset:0;marker-end:url(#Arrow2Lend)"
679 d="m 1362.6256,12823.832 16.6983,1252.369"
680 id="path4119-0-0-7"
681 inkscape:connector-curvature="0"
682 sodipodi:nodetypes="cc" />
683 <path
684 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#Arrow2Lend)"
685 d="m 1362.6256,15636.491 16.6983,1252.369"
686 id="path4119-0-0-7-7"
687 inkscape:connector-curvature="0"
688 sodipodi:nodetypes="cc" />
689 <g
690 style="fill:none;stroke-width:0.025in"
691 id="g4114-9-3-8-1"
692 transform="translate(9722.4732,14142.03)">
693 <rect
694 id="rect6-0-7-5-1"
695 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
696 rx="0"
697 height="1425.5687"
698 width="2748.6331"
699 y="29.467337"
700 x="80.17308" />
701 <text
702 sodipodi:linespacing="125%"
703 id="text4110-5-7-6-2"
704 y="841.88086"
705 x="1460.1007"
706 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
707 xml:space="preserve"><tspan
708 y="841.88086"
709 x="1460.1007"
710 sodipodi:role="line"
711 id="tspan4925-1-2">CPU Offline</tspan></text>
712 </g>
713 <path
714 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:40.08654789, 80.17309578;stroke-dashoffset:0;marker-end:url(#Arrow2Lend)"
715 d="m 11165.272,12823.832 16.698,1252.369"
716 id="path4119-0-0-7-8"
717 inkscape:connector-curvature="0"
718 sodipodi:nodetypes="cc" />
719 <g
720 style="fill:none;stroke-width:0.025in"
721 id="g4114-9-3-9"
722 transform="translate(-80.17308,16915.618)">
723 <rect
724 id="rect6-0-7-1"
725 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
726 rx="0"
727 height="1425.5687"
728 width="2748.6331"
729 y="29.467337"
730 x="80.17308" />
731 <text
732 sodipodi:linespacing="125%"
733 id="text4110-5-7-3"
734 y="505.47754"
735 x="1460.1007"
736 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
737 xml:space="preserve"><tspan
738 y="505.47754"
739 x="1460.1007"
740 id="tspan4112-9-0-4"
741 sodipodi:role="line">Report CPU</tspan><tspan
742 y="839.53204"
743 x="1460.1007"
744 sodipodi:role="line"
745 id="tspan4925-9">Quiescent</tspan><tspan
746 y="1173.5865"
747 x="1460.1007"
748 sodipodi:role="line"
749 id="tspan3168">State</tspan></text>
750 </g>
751 <path
752 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#Arrow2Lend)"
753 d="m 11165.272,15571.534 16.698,1252.369"
754 id="path4119-0-0-7-7-5"
755 inkscape:connector-curvature="0"
756 sodipodi:nodetypes="cc" />
757 <g
758 style="fill:none;stroke-width:0.025in"
759 id="g4114-9-3-9-2"
760 transform="translate(9722.4732,16850.66)">
761 <rect
762 id="rect6-0-7-1-8"
763 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
764 rx="0"
765 height="1425.5687"
766 width="2748.6331"
767 y="29.467337"
768 x="80.17308" />
769 <text
770 sodipodi:linespacing="125%"
771 id="text4110-5-7-3-4"
772 y="503.71591"
773 x="1460.1007"
774 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
775 xml:space="preserve"><tspan
776 y="503.71591"
777 x="1460.1007"
778 sodipodi:role="line"
779 id="tspan4923-3-2">Report CPU</tspan><tspan
780 y="837.77039"
781 x="1460.1007"
782 sodipodi:role="line"
783 id="tspan4925-9-9">Quiescent</tspan><tspan
784 y="1171.825"
785 x="1460.1007"
786 sodipodi:role="line"
787 id="tspan5239">State</tspan></text>
788 </g>
789 <path
790 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:40.08654107, 80.17308214;stroke-dashoffset:0"
791 d="m 1353.3524,12832.071 9701.6916,0 100.189,-16.698"
792 id="path5265"
793 inkscape:connector-curvature="0"
794 sodipodi:nodetypes="ccc" />
795 <path
796 style="fill:none;stroke:#000000;stroke-width:40.08654022;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker-end:url(#Arrow2Lend)"
797 d="m 7112.6465,8669.1867 16.6983,1252.369"
798 id="path4119-0-0-7-7-5-7"
799 inkscape:connector-curvature="0"
800 sodipodi:nodetypes="cc" />
801 <g
802 style="fill:none;stroke-width:0.025in"
803 id="g4114-9-3-8-1-8-3"
804 transform="translate(5663.1399,9972.3627)">
805 <rect
806 id="rect6-0-7-5-1-1-9"
807 style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
808 rx="0"
809 height="1425.5687"
810 width="2748.6331"
811 y="29.467337"
812 x="80.17308" />
813 <text
814 sodipodi:linespacing="125%"
815 id="text4110-5-7-6-2-4-0"
816 y="841.88086"
817 x="1460.1007"
818 style="font-size:267.24359131px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
819 xml:space="preserve"><tspan
820 y="841.88086"
821 x="1460.1007"
822 sodipodi:role="line"
823 id="tspan4925-1-2-4-5">reched_cpu()</tspan></text>
824 </g>
825 </g>
826</svg>
diff --git a/Documentation/RCU/Design/Expedited-Grace-Periods/Expedited-Grace-Periods.html b/Documentation/RCU/Design/Expedited-Grace-Periods/Expedited-Grace-Periods.html
new file mode 100644
index 000000000000..7a3194c5559a
--- /dev/null
+++ b/Documentation/RCU/Design/Expedited-Grace-Periods/Expedited-Grace-Periods.html
@@ -0,0 +1,626 @@
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2 "http://www.w3.org/TR/html4/loose.dtd">
3 <html>
4 <head><title>A Tour Through TREE_RCU's Expedited Grace Periods</title>
5 <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
6
7<h2>Introduction</h2>
8
9This document describes RCU's expedited grace periods.
10Unlike RCU's normal grace periods, which accept long latencies to attain
11high efficiency and minimal disturbance, expedited grace periods accept
12lower efficiency and significant disturbance to attain shorter latencies.
13
14<p>
15There are three flavors of RCU (RCU-bh, RCU-preempt, and RCU-sched),
16but only two flavors of expedited grace periods because the RCU-bh
17expedited grace period maps onto the RCU-sched expedited grace period.
18Each of the remaining two implementations is covered in its own section.
19
20<ol>
21<li> <a href="#Expedited Grace Period Design">
22 Expedited Grace Period Design</a>
23<li> <a href="#RCU-preempt Expedited Grace Periods">
24 RCU-preempt Expedited Grace Periods</a>
25<li> <a href="#RCU-sched Expedited Grace Periods">
26 RCU-sched Expedited Grace Periods</a>
27<li> <a href="#Expedited Grace Period and CPU Hotplug">
28 Expedited Grace Period and CPU Hotplug</a>
29<li> <a href="#Expedited Grace Period Refinements">
30 Expedited Grace Period Refinements</a>
31</ol>
32
33<h2><a name="Expedited Grace Period Design">
34Expedited Grace Period Design</a></h2>
35
36<p>
37The expedited RCU grace periods cannot be accused of being subtle,
38given that they for all intents and purposes hammer every CPU that
39has not yet provided a quiescent state for the current expedited
40grace period.
41The one saving grace is that the hammer has grown a bit smaller
42over time: The old call to <tt>try_stop_cpus()</tt> has been
43replaced with a set of calls to <tt>smp_call_function_single()</tt>,
44each of which results in an IPI to the target CPU.
45The corresponding handler function checks the CPU's state, motivating
46a faster quiescent state where possible, and triggering a report
47of that quiescent state.
48As always for RCU, once everything has spent some time in a quiescent
49state, the expedited grace period has completed.
50
51<p>
52The details of the <tt>smp_call_function_single()</tt> handler's
53operation depend on the RCU flavor, as described in the following
54sections.
55
56<h2><a name="RCU-preempt Expedited Grace Periods">
57RCU-preempt Expedited Grace Periods</a></h2>
58
59<p>
60The overall flow of the handling of a given CPU by an RCU-preempt
61expedited grace period is shown in the following diagram:
62
63<p><img src="ExpRCUFlow.svg" alt="ExpRCUFlow.svg" width="55%">
64
65<p>
66The solid arrows denote direct action, for example, a function call.
67The dotted arrows denote indirect action, for example, an IPI
68or a state that is reached after some time.
69
70<p>
71If a given CPU is offline or idle, <tt>synchronize_rcu_expedited()</tt>
72will ignore it because idle and offline CPUs are already residing
73in quiescent states.
74Otherwise, the expedited grace period will use
75<tt>smp_call_function_single()</tt> to send the CPU an IPI, which
76is handled by <tt>sync_rcu_exp_handler()</tt>.
77
78<p>
79However, because this is preemptible RCU, <tt>sync_rcu_exp_handler()</tt>
80can check to see if the CPU is currently running in an RCU read-side
81critical section.
82If not, the handler can immediately report a quiescent state.
83Otherwise, it sets flags so that the outermost <tt>rcu_read_unlock()</tt>
84invocation will provide the needed quiescent-state report.
85This flag-setting avoids the previous forced preemption of all
86CPUs that might have RCU read-side critical sections.
87In addition, this flag-setting is done so as to avoid increasing
88the overhead of the common-case fastpath through the scheduler.
89
90<p>
91Again because this is preemptible RCU, an RCU read-side critical section
92can be preempted.
93When that happens, RCU will enqueue the task, which will the continue to
94block the current expedited grace period until it resumes and finds its
95outermost <tt>rcu_read_unlock()</tt>.
96The CPU will report a quiescent state just after enqueuing the task because
97the CPU is no longer blocking the grace period.
98It is instead the preempted task doing the blocking.
99The list of blocked tasks is managed by <tt>rcu_preempt_ctxt_queue()</tt>,
100which is called from <tt>rcu_preempt_note_context_switch()</tt>, which
101in turn is called from <tt>rcu_note_context_switch()</tt>, which in
102turn is called from the scheduler.
103
104<table>
105<tr><th>&nbsp;</th></tr>
106<tr><th align="left">Quick Quiz:</th></tr>
107<tr><td>
108 Why not just have the expedited grace period check the
109 state of all the CPUs?
110 After all, that would avoid all those real-time-unfriendly IPIs.
111</td></tr>
112<tr><th align="left">Answer:</th></tr>
113<tr><td bgcolor="#ffffff"><font color="ffffff">
114 Because we want the RCU read-side critical sections to run fast,
115 which means no memory barriers.
116 Therefore, it is not possible to safely check the state from some
117 other CPU.
118 And even if it was possible to safely check the state, it would
119 still be necessary to IPI the CPU to safely interact with the
120 upcoming <tt>rcu_read_unlock()</tt> invocation, which means that
121 the remote state testing would not help the worst-case
122 latency that real-time applications care about.
123
124 <p><font color="ffffff">One way to prevent your real-time
125 application from getting hit with these IPIs is to
126 build your kernel with <tt>CONFIG_NO_HZ_FULL=y</tt>.
127 RCU would then perceive the CPU running your application
128 as being idle, and it would be able to safely detect that
129 state without needing to IPI the CPU.
130</font></td></tr>
131<tr><td>&nbsp;</td></tr>
132</table>
133
134<p>
135Please note that this is just the overall flow:
136Additional complications can arise due to races with CPUs going idle
137or offline, among other things.
138
139<h2><a name="RCU-sched Expedited Grace Periods">
140RCU-sched Expedited Grace Periods</a></h2>
141
142<p>
143The overall flow of the handling of a given CPU by an RCU-sched
144expedited grace period is shown in the following diagram:
145
146<p><img src="ExpSchedFlow.svg" alt="ExpSchedFlow.svg" width="55%">
147
148<p>
149As with RCU-preempt's <tt>synchronize_rcu_expedited()</tt>,
150<tt>synchronize_sched_expedited()</tt> ignores offline and
151idle CPUs, again because they are in remotely detectable
152quiescent states.
153However, the <tt>synchronize_rcu_expedited()</tt> handler
154is <tt>sync_sched_exp_handler()</tt>, and because the
155<tt>rcu_read_lock_sched()</tt> and <tt>rcu_read_unlock_sched()</tt>
156leave no trace of their invocation, in general it is not possible to tell
157whether or not the current CPU is in an RCU read-side critical section.
158The best that <tt>sync_sched_exp_handler()</tt> can do is to check
159for idle, on the off-chance that the CPU went idle while the IPI
160was in flight.
161If the CPU is idle, then tt>sync_sched_exp_handler()</tt> reports
162the quiescent state.
163
164<p>
165Otherwise, the handler invokes <tt>resched_cpu()</tt>, which forces
166a future context switch.
167At the time of the context switch, the CPU reports the quiescent state.
168Should the CPU go offline first, it will report the quiescent state
169at that time.
170
171<h2><a name="Expedited Grace Period and CPU Hotplug">
172Expedited Grace Period and CPU Hotplug</a></h2>
173
174<p>
175The expedited nature of expedited grace periods require a much tighter
176interaction with CPU hotplug operations than is required for normal
177grace periods.
178In addition, attempting to IPI offline CPUs will result in splats, but
179failing to IPI online CPUs can result in too-short grace periods.
180Neither option is acceptable in production kernels.
181
182<p>
183The interaction between expedited grace periods and CPU hotplug operations
184is carried out at several levels:
185
186<ol>
187<li> The number of CPUs that have ever been online is tracked
188 by the <tt>rcu_state</tt> structure's <tt>-&gt;ncpus</tt>
189 field.
190 The <tt>rcu_state</tt> structure's <tt>-&gt;ncpus_snap</tt>
191 field tracks the number of CPUs that have ever been online
192 at the beginning of an RCU expedited grace period.
193 Note that this number never decreases, at least in the absence
194 of a time machine.
195<li> The identities of the CPUs that have ever been online is
196 tracked by the <tt>rcu_node</tt> structure's
197 <tt>-&gt;expmaskinitnext</tt> field.
198 The <tt>rcu_node</tt> structure's <tt>-&gt;expmaskinit</tt>
199 field tracks the identities of the CPUs that were online
200 at least once at the beginning of the most recent RCU
201 expedited grace period.
202 The <tt>rcu_state</tt> structure's <tt>-&gt;ncpus</tt> and
203 <tt>-&gt;ncpus_snap</tt> fields are used to detect when
204 new CPUs have come online for the first time, that is,
205 when the <tt>rcu_node</tt> structure's <tt>-&gt;expmaskinitnext</tt>
206 field has changed since the beginning of the last RCU
207 expedited grace period, which triggers an update of each
208 <tt>rcu_node</tt> structure's <tt>-&gt;expmaskinit</tt>
209 field from its <tt>-&gt;expmaskinitnext</tt> field.
210<li> Each <tt>rcu_node</tt> structure's <tt>-&gt;expmaskinit</tt>
211 field is used to initialize that structure's
212 <tt>-&gt;expmask</tt> at the beginning of each RCU
213 expedited grace period.
214 This means that only those CPUs that have been online at least
215 once will be considered for a given grace period.
216<li> Any CPU that goes offline will clear its bit in its leaf
217 <tt>rcu_node</tt> structure's <tt>-&gt;qsmaskinitnext</tt>
218 field, so any CPU with that bit clear can safely be ignored.
219 However, it is possible for a CPU coming online or going offline
220 to have this bit set for some time while <tt>cpu_online</tt>
221 returns <tt>false</tt>.
222<li> For each non-idle CPU that RCU believes is currently online, the grace
223 period invokes <tt>smp_call_function_single()</tt>.
224 If this succeeds, the CPU was fully online.
225 Failure indicates that the CPU is in the process of coming online
226 or going offline, in which case it is necessary to wait for a
227 short time period and try again.
228 The purpose of this wait (or series of waits, as the case may be)
229 is to permit a concurrent CPU-hotplug operation to complete.
230<li> In the case of RCU-sched, one of the last acts of an outgoing CPU
231 is to invoke <tt>rcu_report_dead()</tt>, which
232 reports a quiescent state for that CPU.
233 However, this is likely paranoia-induced redundancy. <!-- @@@ -->
234</ol>
235
236<table>
237<tr><th>&nbsp;</th></tr>
238<tr><th align="left">Quick Quiz:</th></tr>
239<tr><td>
240 Why all the dancing around with multiple counters and masks
241 tracking CPUs that were once online?
242 Why not just have a single set of masks tracking the currently
243 online CPUs and be done with it?
244</td></tr>
245<tr><th align="left">Answer:</th></tr>
246<tr><td bgcolor="#ffffff"><font color="ffffff">
247 Maintaining single set of masks tracking the online CPUs <i>sounds</i>
248 easier, at least until you try working out all the race conditions
249 between grace-period initialization and CPU-hotplug operations.
250 For example, suppose initialization is progressing down the
251 tree while a CPU-offline operation is progressing up the tree.
252 This situation can result in bits set at the top of the tree
253 that have no counterparts at the bottom of the tree.
254 Those bits will never be cleared, which will result in
255 grace-period hangs.
256 In short, that way lies madness, to say nothing of a great many
257 bugs, hangs, and deadlocks.
258
259 <p><font color="ffffff">
260 In contrast, the current multi-mask multi-counter scheme ensures
261 that grace-period initialization will always see consistent masks
262 up and down the tree, which brings significant simplifications
263 over the single-mask method.
264
265 <p><font color="ffffff">
266 This is an instance of
267 <a href="http://www.cs.columbia.edu/~library/TR-repository/reports/reports-1992/cucs-039-92.ps.gz"><font color="ffffff">
268 deferring work in order to avoid synchronization</a>.
269 Lazily recording CPU-hotplug events at the beginning of the next
270 grace period greatly simplifies maintenance of the CPU-tracking
271 bitmasks in the <tt>rcu_node</tt> tree.
272</font></td></tr>
273<tr><td>&nbsp;</td></tr>
274</table>
275
276<h2><a name="Expedited Grace Period Refinements">
277Expedited Grace Period Refinements</a></h2>
278
279<ol>
280<li> <a href="#Idle-CPU Checks">Idle-CPU checks</a>.
281<li> <a href="#Batching via Sequence Counter">
282 Batching via sequence counter</a>.
283<li> <a href="#Funnel Locking and Wait/Wakeup">
284 Funnel locking and wait/wakeup</a>.
285<li> <a href="#Use of Workqueues">Use of Workqueues</a>.
286<li> <a href="#Stall Warnings">Stall warnings</a>.
287</ol>
288
289<h3><a name="Idle-CPU Checks">Idle-CPU Checks</a></h3>
290
291<p>
292Each expedited grace period checks for idle CPUs when initially forming
293the mask of CPUs to be IPIed and again just before IPIing a CPU
294(both checks are carried out by <tt>sync_rcu_exp_select_cpus()</tt>).
295If the CPU is idle at any time between those two times, the CPU will
296not be IPIed.
297Instead, the task pushing the grace period forward will include the
298idle CPUs in the mask passed to <tt>rcu_report_exp_cpu_mult()</tt>.
299
300<p>
301For RCU-sched, there is an additional check for idle in the IPI
302handler, <tt>sync_sched_exp_handler()</tt>.
303If the IPI has interrupted the idle loop, then
304<tt>sync_sched_exp_handler()</tt> invokes <tt>rcu_report_exp_rdp()</tt>
305to report the corresponding quiescent state.
306
307<p>
308For RCU-preempt, there is no specific check for idle in the
309IPI handler (<tt>sync_rcu_exp_handler()</tt>), but because
310RCU read-side critical sections are not permitted within the
311idle loop, if <tt>sync_rcu_exp_handler()</tt> sees that the CPU is within
312RCU read-side critical section, the CPU cannot possibly be idle.
313Otherwise, <tt>sync_rcu_exp_handler()</tt> invokes
314<tt>rcu_report_exp_rdp()</tt> to report the corresponding quiescent
315state, regardless of whether or not that quiescent state was due to
316the CPU being idle.
317
318<p>
319In summary, RCU expedited grace periods check for idle when building
320the bitmask of CPUs that must be IPIed, just before sending each IPI,
321and (either explicitly or implicitly) within the IPI handler.
322
323<h3><a name="Batching via Sequence Counter">
324Batching via Sequence Counter</a></h3>
325
326<p>
327If each grace-period request was carried out separately, expedited
328grace periods would have abysmal scalability and
329problematic high-load characteristics.
330Because each grace-period operation can serve an unlimited number of
331updates, it is important to <i>batch</i> requests, so that a single
332expedited grace-period operation will cover all requests in the
333corresponding batch.
334
335<p>
336This batching is controlled by a sequence counter named
337<tt>-&gt;expedited_sequence</tt> in the <tt>rcu_state</tt> structure.
338This counter has an odd value when there is an expedited grace period
339in progress and an even value otherwise, so that dividing the counter
340value by two gives the number of completed grace periods.
341During any given update request, the counter must transition from
342even to odd and then back to even, thus indicating that a grace
343period has elapsed.
344Therefore, if the initial value of the counter is <tt>s</tt>,
345the updater must wait until the counter reaches at least the
346value <tt>(s+3)&amp;~0x1</tt>.
347This counter is managed by the following access functions:
348
349<ol>
350<li> <tt>rcu_exp_gp_seq_start()</tt>, which marks the start of
351 an expedited grace period.
352<li> <tt>rcu_exp_gp_seq_end()</tt>, which marks the end of an
353 expedited grace period.
354<li> <tt>rcu_exp_gp_seq_snap()</tt>, which obtains a snapshot of
355 the counter.
356<li> <tt>rcu_exp_gp_seq_done()</tt>, which returns <tt>true</tt>
357 if a full expedited grace period has elapsed since the
358 corresponding call to <tt>rcu_exp_gp_seq_snap()</tt>.
359</ol>
360
361<p>
362Again, only one request in a given batch need actually carry out
363a grace-period operation, which means there must be an efficient
364way to identify which of many concurrent reqeusts will initiate
365the grace period, and that there be an efficient way for the
366remaining requests to wait for that grace period to complete.
367However, that is the topic of the next section.
368
369<h3><a name="Funnel Locking and Wait/Wakeup">
370Funnel Locking and Wait/Wakeup</a></h3>
371
372<p>
373The natural way to sort out which of a batch of updaters will initiate
374the expedited grace period is to use the <tt>rcu_node</tt> combining
375tree, as implemented by the <tt>exp_funnel_lock()</tt> function.
376The first updater corresponding to a given grace period arriving
377at a given <tt>rcu_node</tt> structure records its desired grace-period
378sequence number in the <tt>-&gt;exp_seq_rq</tt> field and moves up
379to the next level in the tree.
380Otherwise, if the <tt>-&gt;exp_seq_rq</tt> field already contains
381the sequence number for the desired grace period or some later one,
382the updater blocks on one of four wait queues in the
383<tt>-&gt;exp_wq[]</tt> array, using the second-from-bottom
384and third-from bottom bits as an index.
385An <tt>-&gt;exp_lock</tt> field in the <tt>rcu_node</tt> structure
386synchronizes access to these fields.
387
388<p>
389An empty <tt>rcu_node</tt> tree is shown in the following diagram,
390with the white cells representing the <tt>-&gt;exp_seq_rq</tt> field
391and the red cells representing the elements of the
392<tt>-&gt;exp_wq[]</tt> array.
393
394<p><img src="Funnel0.svg" alt="Funnel0.svg" width="75%">
395
396<p>
397The next diagram shows the situation after the arrival of Task&nbsp;A
398and Task&nbsp;B at the leftmost and rightmost leaf <tt>rcu_node</tt>
399structures, respectively.
400The current value of the <tt>rcu_state</tt> structure's
401<tt>-&gt;expedited_sequence</tt> field is zero, so adding three and
402clearing the bottom bit results in the value two, which both tasks
403record in the <tt>-&gt;exp_seq_rq</tt> field of their respective
404<tt>rcu_node</tt> structures:
405
406<p><img src="Funnel1.svg" alt="Funnel1.svg" width="75%">
407
408<p>
409Each of Tasks&nbsp;A and&nbsp;B will move up to the root
410<tt>rcu_node</tt> structure.
411Suppose that Task&nbsp;A wins, recording its desired grace-period sequence
412number and resulting in the state shown below:
413
414<p><img src="Funnel2.svg" alt="Funnel2.svg" width="75%">
415
416<p>
417Task&nbsp;A now advances to initiate a new grace period, while Task&nbsp;B
418moves up to the root <tt>rcu_node</tt> structure, and, seeing that
419its desired sequence number is already recorded, blocks on
420<tt>-&gt;exp_wq[1]</tt>.
421
422<table>
423<tr><th>&nbsp;</th></tr>
424<tr><th align="left">Quick Quiz:</th></tr>
425<tr><td>
426 Why <tt>-&gt;exp_wq[1]</tt>?
427 Given that the value of these tasks' desired sequence number is
428 two, so shouldn't they instead block on <tt>-&gt;exp_wq[2]</tt>?
429</td></tr>
430<tr><th align="left">Answer:</th></tr>
431<tr><td bgcolor="#ffffff"><font color="ffffff">
432 No.
433
434 <p><font color="ffffff">
435 Recall that the bottom bit of the desired sequence number indicates
436 whether or not a grace period is currently in progress.
437 It is therefore necessary to shift the sequence number right one
438 bit position to obtain the number of the grace period.
439 This results in <tt>-&gt;exp_wq[1]</tt>.
440</font></td></tr>
441<tr><td>&nbsp;</td></tr>
442</table>
443
444<p>
445If Tasks&nbsp;C and&nbsp;D also arrive at this point, they will compute the
446same desired grace-period sequence number, and see that both leaf
447<tt>rcu_node</tt> structures already have that value recorded.
448They will therefore block on their respective <tt>rcu_node</tt>
449structures' <tt>-&gt;exp_wq[1]</tt> fields, as shown below:
450
451<p><img src="Funnel3.svg" alt="Funnel3.svg" width="75%">
452
453<p>
454Task&nbsp;A now acquires the <tt>rcu_state</tt> structure's
455<tt>-&gt;exp_mutex</tt> and initiates the grace period, which
456increments <tt>-&gt;expedited_sequence</tt>.
457Therefore, if Tasks&nbsp;E and&nbsp;F arrive, they will compute
458a desired sequence number of 4 and will record this value as
459shown below:
460
461<p><img src="Funnel4.svg" alt="Funnel4.svg" width="75%">
462
463<p>
464Tasks&nbsp;E and&nbsp;F will propagate up the <tt>rcu_node</tt>
465combining tree, with Task&nbsp;F blocking on the root <tt>rcu_node</tt>
466structure and Task&nbsp;E wait for Task&nbsp;A to finish so that
467it can start the next grace period.
468The resulting state is as shown below:
469
470<p><img src="Funnel5.svg" alt="Funnel5.svg" width="75%">
471
472<p>
473Once the grace period completes, Task&nbsp;A
474starts waking up the tasks waiting for this grace period to complete,
475increments the <tt>-&gt;expedited_sequence</tt>,
476acquires the <tt>-&gt;exp_wake_mutex</tt> and then releases the
477<tt>-&gt;exp_mutex</tt>.
478This results in the following state:
479
480<p><img src="Funnel6.svg" alt="Funnel6.svg" width="75%">
481
482<p>
483Task&nbsp;E can then acquire <tt>-&gt;exp_mutex</tt> and increment
484<tt>-&gt;expedited_sequence</tt> to the value three.
485If new tasks&nbsp;G and&nbsp;H arrive and moves up the combining tree at the
486same time, the state will be as follows:
487
488<p><img src="Funnel7.svg" alt="Funnel7.svg" width="75%">
489
490<p>
491Note that three of the root <tt>rcu_node</tt> structure's
492waitqueues are now occupied.
493However, at some point, Task&nbsp;A will wake up the
494tasks blocked on the <tt>-&gt;exp_wq</tt> waitqueues, resulting
495in the following state:
496
497<p><img src="Funnel8.svg" alt="Funnel8.svg" width="75%">
498
499<p>
500Execution will continue with Tasks&nbsp;E and&nbsp;H completing
501their grace periods and carrying out their wakeups.
502
503<table>
504<tr><th>&nbsp;</th></tr>
505<tr><th align="left">Quick Quiz:</th></tr>
506<tr><td>
507 What happens if Task&nbsp;A takes so long to do its wakeups
508 that Task&nbsp;E's grace period completes?
509</td></tr>
510<tr><th align="left">Answer:</th></tr>
511<tr><td bgcolor="#ffffff"><font color="ffffff">
512 Then Task&nbsp;E will block on the <tt>-&gt;exp_wake_mutex</tt>,
513 which will also prevent it from releasing <tt>-&gt;exp_mutex</tt>,
514 which in turn will prevent the next grace period from starting.
515 This last is important in preventing overflow of the
516 <tt>-&gt;exp_wq[]</tt> array.
517</font></td></tr>
518<tr><td>&nbsp;</td></tr>
519</table>
520
521<h3><a name="Use of Workqueues">Use of Workqueues</a></h3>
522
523<p>
524In earlier implementations, the task requesting the expedited
525grace period also drove it to completion.
526This straightforward approach had the disadvantage of needing to
527account for signals sent to user tasks,
528so more recent implemementations use the Linux kernel's
529<a href="https://www.kernel.org/doc/Documentation/workqueue.txt">workqueues</a>.
530
531<p>
532The requesting task still does counter snapshotting and funnel-lock
533processing, but the task reaching the top of the funnel lock
534does a <tt>schedule_work()</tt> (from <tt>_synchronize_rcu_expedited()</tt>
535so that a workqueue kthread does the actual grace-period processing.
536Because workqueue kthreads do not accept signals, grace-period-wait
537processing need not allow for signals.
538
539In addition, this approach allows wakeups for the previous expedited
540grace period to be overlapped with processing for the next expedited
541grace period.
542Because there are only four sets of waitqueues, it is necessary to
543ensure that the previous grace period's wakeups complete before the
544next grace period's wakeups start.
545This is handled by having the <tt>-&gt;exp_mutex</tt>
546guard expedited grace-period processing and the
547<tt>-&gt;exp_wake_mutex</tt> guard wakeups.
548The key point is that the <tt>-&gt;exp_mutex</tt> is not released
549until the first wakeup is complete, which means that the
550<tt>-&gt;exp_wake_mutex</tt> has already been acquired at that point.
551This approach ensures that the previous grace period's wakeups can
552be carried out while the current grace period is in process, but
553that these wakeups will complete before the next grace period starts.
554This means that only three waitqueues are required, guaranteeing that
555the four that are provided are sufficient.
556
557<h3><a name="Stall Warnings">Stall Warnings</a></h3>
558
559<p>
560Expediting grace periods does nothing to speed things up when RCU
561readers take too long, and therefore expedited grace periods check
562for stalls just as normal grace periods do.
563
564<table>
565<tr><th>&nbsp;</th></tr>
566<tr><th align="left">Quick Quiz:</th></tr>
567<tr><td>
568 But why not just let the normal grace-period machinery
569 detect the stalls, given that a given reader must block
570 both normal and expedited grace periods?
571</td></tr>
572<tr><th align="left">Answer:</th></tr>
573<tr><td bgcolor="#ffffff"><font color="ffffff">
574 Because it is quite possible that at a given time there
575 is no normal grace period in progress, in which case the
576 normal grace period cannot emit a stall warning.
577</font></td></tr>
578<tr><td>&nbsp;</td></tr>
579</table>
580
581The <tt>synchronize_sched_expedited_wait()</tt> function loops waiting
582for the expedited grace period to end, but with a timeout set to the
583current RCU CPU stall-warning time.
584If this time is exceeded, any CPUs or <tt>rcu_node</tt> structures
585blocking the current grace period are printed.
586Each stall warning results in another pass through the loop, but the
587second and subsequent passes use longer stall times.
588
589<h3><a name="Summary">
590Summary</a></h3>
591
592<p>
593Expedited grace periods use a sequence-number approach to promote
594batching, so that a single grace-period operation can serve numerous
595requests.
596A funnel lock is used to efficiently identify the one task out of
597a concurrent group that will request the grace period.
598All members of the group will block on waitqueues provided in
599the <tt>rcu_node</tt> structure.
600The actual grace-period processing is carried out by a workqueue.
601
602<p>
603CPU-hotplug operations are noted lazily in order to prevent the need
604for tight synchronization between expedited grace periods and
605CPU-hotplug operations.
606The dyntick-idle counters are used to avoid sending IPIs to idle CPUs,
607at least in the common case.
608RCU-preempt and RCU-sched use different IPI handlers and different
609code to respond to the state changes carried out by those handlers,
610but otherwise use common code.
611
612<p>
613Quiescent states are tracked using the <tt>rcu_node</tt> tree,
614and once all necessary quiescent states have been reported,
615all tasks waiting on this expedited grace period are awakened.
616A pair of mutexes are used to allow one grace period's wakeups
617to proceed concurrently with the next grace period's processing.
618
619<p>
620This combination of mechanisms allows expedited grace periods to
621run reasonably efficiently.
622However, for non-time-critical tasks, normal grace periods should be
623used instead because their longer duration permits much higher
624degrees of batching, and thus much lower per-request overheads.
625
626</body></html>
diff --git a/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel0.svg b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel0.svg
new file mode 100644
index 000000000000..98af66557908
--- /dev/null
+++ b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel0.svg
@@ -0,0 +1,275 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
4<svg
5 xmlns:dc="http://purl.org/dc/elements/1.1/"
6 xmlns:cc="http://creativecommons.org/ns#"
7 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8 xmlns:svg="http://www.w3.org/2000/svg"
9 xmlns="http://www.w3.org/2000/svg"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="490.05093"
13 height="125.78741"
14 id="svg2"
15 version="1.1"
16 inkscape:version="0.48.4 r9939"
17 sodipodi:docname="Funnel0.svg">
18 <defs
19 id="defs4">
20 <marker
21 inkscape:stockid="Arrow2Lend"
22 orient="auto"
23 refY="0"
24 refX="0"
25 id="Arrow2Lend"
26 style="overflow:visible">
27 <path
28 id="path3792"
29 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
30 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
31 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
32 inkscape:connector-curvature="0" />
33 </marker>
34 <marker
35 inkscape:stockid="Arrow2Lstart"
36 orient="auto"
37 refY="0"
38 refX="0"
39 id="Arrow2Lstart"
40 style="overflow:visible">
41 <path
42 id="path3789"
43 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
44 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
45 transform="matrix(1.1,0,0,1.1,1.1,0)"
46 inkscape:connector-curvature="0" />
47 </marker>
48 <marker
49 inkscape:stockid="Arrow2Lstart"
50 orient="auto"
51 refY="0"
52 refX="0"
53 id="Arrow2Lstart-4"
54 style="overflow:visible">
55 <path
56 id="path3789-9"
57 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
58 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
59 transform="matrix(1.1,0,0,1.1,1.1,0)"
60 inkscape:connector-curvature="0" />
61 </marker>
62 <marker
63 inkscape:stockid="Arrow2Lend"
64 orient="auto"
65 refY="0"
66 refX="0"
67 id="Arrow2Lend-4"
68 style="overflow:visible">
69 <path
70 id="path3792-4"
71 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
72 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
73 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
74 inkscape:connector-curvature="0" />
75 </marker>
76 </defs>
77 <sodipodi:namedview
78 id="base"
79 pagecolor="#ffffff"
80 bordercolor="#666666"
81 borderopacity="1.0"
82 inkscape:pageopacity="0.0"
83 inkscape:pageshadow="2"
84 inkscape:zoom="1.3670394"
85 inkscape:cx="201.06495"
86 inkscape:cy="-86.548414"
87 inkscape:document-units="px"
88 inkscape:current-layer="layer1"
89 showgrid="false"
90 inkscape:window-width="1351"
91 inkscape:window-height="836"
92 inkscape:window-x="171"
93 inkscape:window-y="279"
94 inkscape:window-maximized="0"
95 fit-margin-top="5"
96 fit-margin-left="5"
97 fit-margin-right="5"
98 fit-margin-bottom="5" />
99 <metadata
100 id="metadata7">
101 <rdf:RDF>
102 <cc:Work
103 rdf:about="">
104 <dc:format>image/svg+xml</dc:format>
105 <dc:type
106 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
107 <dc:title />
108 </cc:Work>
109 </rdf:RDF>
110 </metadata>
111 <g
112 inkscape:label="Layer 1"
113 inkscape:groupmode="layer"
114 id="layer1"
115 transform="translate(-117.08462,-249.92053)">
116 <flowRoot
117 xml:space="preserve"
118 id="flowRoot2985"
119 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"><flowRegion
120 id="flowRegion2987"><rect
121 id="rect2989"
122 width="82.85714"
123 height="11.428572"
124 x="240"
125 y="492.36218" /></flowRegion><flowPara
126 id="flowPara2991" /></flowRoot> <text
127 xml:space="preserve"
128 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"
129 x="362.371"
130 y="262.51819"
131 id="text4441"
132 sodipodi:linespacing="125%"><tspan
133 sodipodi:role="line"
134 id="tspan4443"
135 x="362.371"
136 y="262.51819">-&gt;expedited_sequence: 0</tspan></text>
137 <rect
138 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
139 id="rect3101"
140 width="43.158947"
141 height="26.33428"
142 x="253.55223"
143 y="275.07489" />
144 <rect
145 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
146 id="rect3101-3"
147 width="43.158947"
148 height="26.33428"
149 x="297.04141"
150 y="275.07489" />
151 <rect
152 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
153 id="rect3101-3-6"
154 width="43.158947"
155 height="26.33428"
156 x="427.509"
157 y="275.07489" />
158 <rect
159 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
160 id="rect3101-3-6-7"
161 width="43.158947"
162 height="26.33428"
163 x="384.01981"
164 y="275.07489" />
165 <rect
166 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
167 id="rect3101-3-6-7-5"
168 width="43.158947"
169 height="26.33428"
170 x="340.53061"
171 y="275.07489" />
172 <g
173 id="g3997"
174 transform="translate(-0.87295532,0)">
175 <rect
176 y="343.37366"
177 x="123.95757"
178 height="26.33428"
179 width="43.158947"
180 id="rect3101-35"
181 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
182 <rect
183 y="343.37366"
184 x="167.44673"
185 height="26.33428"
186 width="43.158947"
187 id="rect3101-3-62"
188 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
189 <rect
190 y="343.37366"
191 x="297.91437"
192 height="26.33428"
193 width="43.158947"
194 id="rect3101-3-6-9"
195 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
196 <rect
197 y="343.37366"
198 x="254.42516"
199 height="26.33428"
200 width="43.158947"
201 id="rect3101-3-6-7-1"
202 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
203 <rect
204 y="343.37366"
205 x="210.93593"
206 height="26.33428"
207 width="43.158947"
208 id="rect3101-3-6-7-5-2"
209 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
210 <text
211 xml:space="preserve"
212 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
213 x="145.45404"
214 y="360.25174"
215 id="text3013"
216 sodipodi:linespacing="125%"><tspan
217 sodipodi:role="line"
218 id="tspan3015"
219 x="145.45404"
220 y="360.25174"
221 style="font-size:10px">:0</tspan></text>
222 </g>
223 <g
224 id="g3997-7"
225 transform="translate(260.06223,0)">
226 <rect
227 y="343.37366"
228 x="123.95757"
229 height="26.33428"
230 width="43.158947"
231 id="rect3101-35-0"
232 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
233 <rect
234 y="343.37366"
235 x="167.44673"
236 height="26.33428"
237 width="43.158947"
238 id="rect3101-3-62-9"
239 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
240 <rect
241 y="343.37366"
242 x="297.91437"
243 height="26.33428"
244 width="43.158947"
245 id="rect3101-3-6-9-3"
246 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
247 <rect
248 y="343.37366"
249 x="254.42516"
250 height="26.33428"
251 width="43.158947"
252 id="rect3101-3-6-7-1-6"
253 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
254 <rect
255 y="343.37366"
256 x="210.93593"
257 height="26.33428"
258 width="43.158947"
259 id="rect3101-3-6-7-5-2-0"
260 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
261 <text
262 xml:space="preserve"
263 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
264 x="145.45404"
265 y="360.25174"
266 id="text3013-3"
267 sodipodi:linespacing="125%"><tspan
268 sodipodi:role="line"
269 id="tspan3015-6"
270 x="145.45404"
271 y="360.25174"
272 style="font-size:10px">:0</tspan></text>
273 </g>
274 </g>
275</svg>
diff --git a/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel1.svg b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel1.svg
new file mode 100644
index 000000000000..e0184a37aec7
--- /dev/null
+++ b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel1.svg
@@ -0,0 +1,275 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
4<svg
5 xmlns:dc="http://purl.org/dc/elements/1.1/"
6 xmlns:cc="http://creativecommons.org/ns#"
7 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8 xmlns:svg="http://www.w3.org/2000/svg"
9 xmlns="http://www.w3.org/2000/svg"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="490.05093"
13 height="125.78741"
14 id="svg2"
15 version="1.1"
16 inkscape:version="0.48.4 r9939"
17 sodipodi:docname="Funnel1.svg">
18 <defs
19 id="defs4">
20 <marker
21 inkscape:stockid="Arrow2Lend"
22 orient="auto"
23 refY="0"
24 refX="0"
25 id="Arrow2Lend"
26 style="overflow:visible">
27 <path
28 id="path3792"
29 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
30 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
31 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
32 inkscape:connector-curvature="0" />
33 </marker>
34 <marker
35 inkscape:stockid="Arrow2Lstart"
36 orient="auto"
37 refY="0"
38 refX="0"
39 id="Arrow2Lstart"
40 style="overflow:visible">
41 <path
42 id="path3789"
43 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
44 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
45 transform="matrix(1.1,0,0,1.1,1.1,0)"
46 inkscape:connector-curvature="0" />
47 </marker>
48 <marker
49 inkscape:stockid="Arrow2Lstart"
50 orient="auto"
51 refY="0"
52 refX="0"
53 id="Arrow2Lstart-4"
54 style="overflow:visible">
55 <path
56 id="path3789-9"
57 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
58 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
59 transform="matrix(1.1,0,0,1.1,1.1,0)"
60 inkscape:connector-curvature="0" />
61 </marker>
62 <marker
63 inkscape:stockid="Arrow2Lend"
64 orient="auto"
65 refY="0"
66 refX="0"
67 id="Arrow2Lend-4"
68 style="overflow:visible">
69 <path
70 id="path3792-4"
71 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
72 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
73 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
74 inkscape:connector-curvature="0" />
75 </marker>
76 </defs>
77 <sodipodi:namedview
78 id="base"
79 pagecolor="#ffffff"
80 bordercolor="#666666"
81 borderopacity="1.0"
82 inkscape:pageopacity="0.0"
83 inkscape:pageshadow="2"
84 inkscape:zoom="1.3670394"
85 inkscape:cx="201.06495"
86 inkscape:cy="-86.548414"
87 inkscape:document-units="px"
88 inkscape:current-layer="g3997-7"
89 showgrid="false"
90 inkscape:window-width="1351"
91 inkscape:window-height="836"
92 inkscape:window-x="363"
93 inkscape:window-y="336"
94 inkscape:window-maximized="0"
95 fit-margin-top="5"
96 fit-margin-left="5"
97 fit-margin-right="5"
98 fit-margin-bottom="5" />
99 <metadata
100 id="metadata7">
101 <rdf:RDF>
102 <cc:Work
103 rdf:about="">
104 <dc:format>image/svg+xml</dc:format>
105 <dc:type
106 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
107 <dc:title />
108 </cc:Work>
109 </rdf:RDF>
110 </metadata>
111 <g
112 inkscape:label="Layer 1"
113 inkscape:groupmode="layer"
114 id="layer1"
115 transform="translate(-117.08462,-249.92053)">
116 <flowRoot
117 xml:space="preserve"
118 id="flowRoot2985"
119 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"><flowRegion
120 id="flowRegion2987"><rect
121 id="rect2989"
122 width="82.85714"
123 height="11.428572"
124 x="240"
125 y="492.36218" /></flowRegion><flowPara
126 id="flowPara2991" /></flowRoot> <text
127 xml:space="preserve"
128 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"
129 x="362.371"
130 y="262.51819"
131 id="text4441"
132 sodipodi:linespacing="125%"><tspan
133 sodipodi:role="line"
134 id="tspan4443"
135 x="362.371"
136 y="262.51819">-&gt;expedited_sequence: 0</tspan></text>
137 <rect
138 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
139 id="rect3101"
140 width="43.158947"
141 height="26.33428"
142 x="253.55223"
143 y="275.07489" />
144 <rect
145 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
146 id="rect3101-3"
147 width="43.158947"
148 height="26.33428"
149 x="297.04141"
150 y="275.07489" />
151 <rect
152 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
153 id="rect3101-3-6"
154 width="43.158947"
155 height="26.33428"
156 x="427.509"
157 y="275.07489" />
158 <rect
159 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
160 id="rect3101-3-6-7"
161 width="43.158947"
162 height="26.33428"
163 x="384.01981"
164 y="275.07489" />
165 <rect
166 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
167 id="rect3101-3-6-7-5"
168 width="43.158947"
169 height="26.33428"
170 x="340.53061"
171 y="275.07489" />
172 <g
173 id="g3997"
174 transform="translate(-0.87295532,0)">
175 <rect
176 y="343.37366"
177 x="123.95757"
178 height="26.33428"
179 width="43.158947"
180 id="rect3101-35"
181 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
182 <rect
183 y="343.37366"
184 x="167.44673"
185 height="26.33428"
186 width="43.158947"
187 id="rect3101-3-62"
188 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
189 <rect
190 y="343.37366"
191 x="297.91437"
192 height="26.33428"
193 width="43.158947"
194 id="rect3101-3-6-9"
195 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
196 <rect
197 y="343.37366"
198 x="254.42516"
199 height="26.33428"
200 width="43.158947"
201 id="rect3101-3-6-7-1"
202 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
203 <rect
204 y="343.37366"
205 x="210.93593"
206 height="26.33428"
207 width="43.158947"
208 id="rect3101-3-6-7-5-2"
209 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
210 <text
211 xml:space="preserve"
212 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
213 x="146.00092"
214 y="360.25174"
215 id="text3013"
216 sodipodi:linespacing="125%"><tspan
217 sodipodi:role="line"
218 id="tspan3015"
219 x="146.00092"
220 y="360.25174"
221 style="font-size:10px">A:2</tspan></text>
222 </g>
223 <g
224 id="g3997-7"
225 transform="translate(260.06223,0)">
226 <rect
227 y="343.37366"
228 x="123.95757"
229 height="26.33428"
230 width="43.158947"
231 id="rect3101-35-0"
232 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
233 <rect
234 y="343.37366"
235 x="167.44673"
236 height="26.33428"
237 width="43.158947"
238 id="rect3101-3-62-9"
239 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
240 <rect
241 y="343.37366"
242 x="297.91437"
243 height="26.33428"
244 width="43.158947"
245 id="rect3101-3-6-9-3"
246 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
247 <rect
248 y="343.37366"
249 x="254.42516"
250 height="26.33428"
251 width="43.158947"
252 id="rect3101-3-6-7-1-6"
253 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
254 <rect
255 y="343.37366"
256 x="210.93593"
257 height="26.33428"
258 width="43.158947"
259 id="rect3101-3-6-7-5-2-0"
260 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
261 <text
262 xml:space="preserve"
263 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
264 x="145.54926"
265 y="360.25174"
266 id="text3013-3"
267 sodipodi:linespacing="125%"><tspan
268 sodipodi:role="line"
269 id="tspan3015-6"
270 x="145.54926"
271 y="360.25174"
272 style="font-size:10px">B:2</tspan></text>
273 </g>
274 </g>
275</svg>
diff --git a/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel2.svg b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel2.svg
new file mode 100644
index 000000000000..1bc3fed54d58
--- /dev/null
+++ b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel2.svg
@@ -0,0 +1,287 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
4<svg
5 xmlns:dc="http://purl.org/dc/elements/1.1/"
6 xmlns:cc="http://creativecommons.org/ns#"
7 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8 xmlns:svg="http://www.w3.org/2000/svg"
9 xmlns="http://www.w3.org/2000/svg"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="490.05093"
13 height="125.78741"
14 id="svg2"
15 version="1.1"
16 inkscape:version="0.48.4 r9939"
17 sodipodi:docname="Funnel2.svg">
18 <defs
19 id="defs4">
20 <marker
21 inkscape:stockid="Arrow2Lend"
22 orient="auto"
23 refY="0"
24 refX="0"
25 id="Arrow2Lend"
26 style="overflow:visible">
27 <path
28 id="path3792"
29 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
30 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
31 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
32 inkscape:connector-curvature="0" />
33 </marker>
34 <marker
35 inkscape:stockid="Arrow2Lstart"
36 orient="auto"
37 refY="0"
38 refX="0"
39 id="Arrow2Lstart"
40 style="overflow:visible">
41 <path
42 id="path3789"
43 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
44 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
45 transform="matrix(1.1,0,0,1.1,1.1,0)"
46 inkscape:connector-curvature="0" />
47 </marker>
48 <marker
49 inkscape:stockid="Arrow2Lstart"
50 orient="auto"
51 refY="0"
52 refX="0"
53 id="Arrow2Lstart-4"
54 style="overflow:visible">
55 <path
56 id="path3789-9"
57 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
58 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
59 transform="matrix(1.1,0,0,1.1,1.1,0)"
60 inkscape:connector-curvature="0" />
61 </marker>
62 <marker
63 inkscape:stockid="Arrow2Lend"
64 orient="auto"
65 refY="0"
66 refX="0"
67 id="Arrow2Lend-4"
68 style="overflow:visible">
69 <path
70 id="path3792-4"
71 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
72 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
73 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
74 inkscape:connector-curvature="0" />
75 </marker>
76 </defs>
77 <sodipodi:namedview
78 id="base"
79 pagecolor="#ffffff"
80 bordercolor="#666666"
81 borderopacity="1.0"
82 inkscape:pageopacity="0.0"
83 inkscape:pageshadow="2"
84 inkscape:zoom="1.3670394"
85 inkscape:cx="114.01552"
86 inkscape:cy="-86.548414"
87 inkscape:document-units="px"
88 inkscape:current-layer="g3997-7"
89 showgrid="false"
90 inkscape:window-width="1351"
91 inkscape:window-height="836"
92 inkscape:window-x="363"
93 inkscape:window-y="336"
94 inkscape:window-maximized="0"
95 fit-margin-top="5"
96 fit-margin-left="5"
97 fit-margin-right="5"
98 fit-margin-bottom="5" />
99 <metadata
100 id="metadata7">
101 <rdf:RDF>
102 <cc:Work
103 rdf:about="">
104 <dc:format>image/svg+xml</dc:format>
105 <dc:type
106 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
107 <dc:title />
108 </cc:Work>
109 </rdf:RDF>
110 </metadata>
111 <g
112 inkscape:label="Layer 1"
113 inkscape:groupmode="layer"
114 id="layer1"
115 transform="translate(-117.08462,-249.92053)">
116 <flowRoot
117 xml:space="preserve"
118 id="flowRoot2985"
119 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"><flowRegion
120 id="flowRegion2987"><rect
121 id="rect2989"
122 width="82.85714"
123 height="11.428572"
124 x="240"
125 y="492.36218" /></flowRegion><flowPara
126 id="flowPara2991" /></flowRoot> <text
127 xml:space="preserve"
128 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"
129 x="362.371"
130 y="262.51819"
131 id="text4441"
132 sodipodi:linespacing="125%"><tspan
133 sodipodi:role="line"
134 id="tspan4443"
135 x="362.371"
136 y="262.51819">-&gt;expedited_sequence: 0</tspan></text>
137 <rect
138 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
139 id="rect3101"
140 width="43.158947"
141 height="26.33428"
142 x="253.55223"
143 y="275.07489" />
144 <rect
145 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
146 id="rect3101-3"
147 width="43.158947"
148 height="26.33428"
149 x="297.04141"
150 y="275.07489" />
151 <rect
152 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
153 id="rect3101-3-6"
154 width="43.158947"
155 height="26.33428"
156 x="427.509"
157 y="275.07489" />
158 <rect
159 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
160 id="rect3101-3-6-7"
161 width="43.158947"
162 height="26.33428"
163 x="384.01981"
164 y="275.07489" />
165 <rect
166 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
167 id="rect3101-3-6-7-5"
168 width="43.158947"
169 height="26.33428"
170 x="340.53061"
171 y="275.07489" />
172 <g
173 id="g3997"
174 transform="translate(-0.87295532,0)">
175 <rect
176 y="343.37366"
177 x="123.95757"
178 height="26.33428"
179 width="43.158947"
180 id="rect3101-35"
181 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
182 <rect
183 y="343.37366"
184 x="167.44673"
185 height="26.33428"
186 width="43.158947"
187 id="rect3101-3-62"
188 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
189 <rect
190 y="343.37366"
191 x="297.91437"
192 height="26.33428"
193 width="43.158947"
194 id="rect3101-3-6-9"
195 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
196 <rect
197 y="343.37366"
198 x="254.42516"
199 height="26.33428"
200 width="43.158947"
201 id="rect3101-3-6-7-1"
202 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
203 <rect
204 y="343.37366"
205 x="210.93593"
206 height="26.33428"
207 width="43.158947"
208 id="rect3101-3-6-7-5-2"
209 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
210 <text
211 xml:space="preserve"
212 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
213 x="146.00092"
214 y="360.25174"
215 id="text3013"
216 sodipodi:linespacing="125%"><tspan
217 sodipodi:role="line"
218 id="tspan3015"
219 x="146.00092"
220 y="360.25174"
221 style="font-size:10px">:2</tspan></text>
222 </g>
223 <g
224 id="g3997-7"
225 transform="translate(260.06223,0)">
226 <rect
227 y="343.37366"
228 x="123.95757"
229 height="26.33428"
230 width="43.158947"
231 id="rect3101-35-0"
232 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
233 <rect
234 y="343.37366"
235 x="167.44673"
236 height="26.33428"
237 width="43.158947"
238 id="rect3101-3-62-9"
239 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
240 <rect
241 y="343.37366"
242 x="297.91437"
243 height="26.33428"
244 width="43.158947"
245 id="rect3101-3-6-9-3"
246 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
247 <rect
248 y="343.37366"
249 x="254.42516"
250 height="26.33428"
251 width="43.158947"
252 id="rect3101-3-6-7-1-6"
253 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
254 <rect
255 y="343.37366"
256 x="210.93593"
257 height="26.33428"
258 width="43.158947"
259 id="rect3101-3-6-7-5-2-0"
260 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
261 <text
262 xml:space="preserve"
263 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
264 x="145.54926"
265 y="360.25174"
266 id="text3013-3"
267 sodipodi:linespacing="125%"><tspan
268 sodipodi:role="line"
269 id="tspan3015-6"
270 x="145.54926"
271 y="360.25174"
272 style="font-size:10px">B:2</tspan></text>
273 </g>
274 <text
275 xml:space="preserve"
276 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
277 x="275.59558"
278 y="291.95297"
279 id="text3013-36"
280 sodipodi:linespacing="125%"><tspan
281 sodipodi:role="line"
282 id="tspan3015-7"
283 x="275.59558"
284 y="291.95297"
285 style="font-size:10px">A:2</tspan></text>
286 </g>
287</svg>
diff --git a/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel3.svg b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel3.svg
new file mode 100644
index 000000000000..6d8a1bffb3e4
--- /dev/null
+++ b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel3.svg
@@ -0,0 +1,323 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
4<svg
5 xmlns:dc="http://purl.org/dc/elements/1.1/"
6 xmlns:cc="http://creativecommons.org/ns#"
7 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8 xmlns:svg="http://www.w3.org/2000/svg"
9 xmlns="http://www.w3.org/2000/svg"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="490.05093"
13 height="125.78741"
14 id="svg2"
15 version="1.1"
16 inkscape:version="0.48.4 r9939"
17 sodipodi:docname="Funnel3.svg">
18 <defs
19 id="defs4">
20 <marker
21 inkscape:stockid="Arrow2Lend"
22 orient="auto"
23 refY="0"
24 refX="0"
25 id="Arrow2Lend"
26 style="overflow:visible">
27 <path
28 id="path3792"
29 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
30 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
31 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
32 inkscape:connector-curvature="0" />
33 </marker>
34 <marker
35 inkscape:stockid="Arrow2Lstart"
36 orient="auto"
37 refY="0"
38 refX="0"
39 id="Arrow2Lstart"
40 style="overflow:visible">
41 <path
42 id="path3789"
43 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
44 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
45 transform="matrix(1.1,0,0,1.1,1.1,0)"
46 inkscape:connector-curvature="0" />
47 </marker>
48 <marker
49 inkscape:stockid="Arrow2Lstart"
50 orient="auto"
51 refY="0"
52 refX="0"
53 id="Arrow2Lstart-4"
54 style="overflow:visible">
55 <path
56 id="path3789-9"
57 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
58 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
59 transform="matrix(1.1,0,0,1.1,1.1,0)"
60 inkscape:connector-curvature="0" />
61 </marker>
62 <marker
63 inkscape:stockid="Arrow2Lend"
64 orient="auto"
65 refY="0"
66 refX="0"
67 id="Arrow2Lend-4"
68 style="overflow:visible">
69 <path
70 id="path3792-4"
71 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
72 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
73 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
74 inkscape:connector-curvature="0" />
75 </marker>
76 </defs>
77 <sodipodi:namedview
78 id="base"
79 pagecolor="#ffffff"
80 bordercolor="#666666"
81 borderopacity="1.0"
82 inkscape:pageopacity="0.0"
83 inkscape:pageshadow="2"
84 inkscape:zoom="1.3670394"
85 inkscape:cx="114.01552"
86 inkscape:cy="-86.548414"
87 inkscape:document-units="px"
88 inkscape:current-layer="layer1"
89 showgrid="false"
90 inkscape:window-width="1351"
91 inkscape:window-height="836"
92 inkscape:window-x="68"
93 inkscape:window-y="180"
94 inkscape:window-maximized="0"
95 fit-margin-top="5"
96 fit-margin-left="5"
97 fit-margin-right="5"
98 fit-margin-bottom="5" />
99 <metadata
100 id="metadata7">
101 <rdf:RDF>
102 <cc:Work
103 rdf:about="">
104 <dc:format>image/svg+xml</dc:format>
105 <dc:type
106 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
107 <dc:title />
108 </cc:Work>
109 </rdf:RDF>
110 </metadata>
111 <g
112 inkscape:label="Layer 1"
113 inkscape:groupmode="layer"
114 id="layer1"
115 transform="translate(-117.08462,-249.92053)">
116 <flowRoot
117 xml:space="preserve"
118 id="flowRoot2985"
119 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"><flowRegion
120 id="flowRegion2987"><rect
121 id="rect2989"
122 width="82.85714"
123 height="11.428572"
124 x="240"
125 y="492.36218" /></flowRegion><flowPara
126 id="flowPara2991" /></flowRoot> <text
127 xml:space="preserve"
128 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"
129 x="362.371"
130 y="262.51819"
131 id="text4441"
132 sodipodi:linespacing="125%"><tspan
133 sodipodi:role="line"
134 id="tspan4443"
135 x="362.371"
136 y="262.51819">-&gt;expedited_sequence: 0 GP: A</tspan></text>
137 <rect
138 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
139 id="rect3101"
140 width="43.158947"
141 height="26.33428"
142 x="253.55223"
143 y="275.07489" />
144 <rect
145 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
146 id="rect3101-3"
147 width="43.158947"
148 height="26.33428"
149 x="297.04141"
150 y="275.07489" />
151 <rect
152 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
153 id="rect3101-3-6"
154 width="43.158947"
155 height="26.33428"
156 x="427.509"
157 y="275.07489" />
158 <rect
159 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
160 id="rect3101-3-6-7"
161 width="43.158947"
162 height="26.33428"
163 x="384.01981"
164 y="275.07489" />
165 <rect
166 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
167 id="rect3101-3-6-7-5"
168 width="43.158947"
169 height="26.33428"
170 x="340.53061"
171 y="275.07489" />
172 <g
173 id="g3997"
174 transform="translate(-0.87295532,0)">
175 <rect
176 y="343.37366"
177 x="123.95757"
178 height="26.33428"
179 width="43.158947"
180 id="rect3101-35"
181 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
182 <rect
183 y="343.37366"
184 x="167.44673"
185 height="26.33428"
186 width="43.158947"
187 id="rect3101-3-62"
188 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
189 <rect
190 y="343.37366"
191 x="297.91437"
192 height="26.33428"
193 width="43.158947"
194 id="rect3101-3-6-9"
195 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
196 <rect
197 y="343.37366"
198 x="254.42516"
199 height="26.33428"
200 width="43.158947"
201 id="rect3101-3-6-7-1"
202 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
203 <rect
204 y="343.37366"
205 x="210.93593"
206 height="26.33428"
207 width="43.158947"
208 id="rect3101-3-6-7-5-2"
209 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
210 <text
211 xml:space="preserve"
212 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
213 x="146.00092"
214 y="360.25174"
215 id="text3013"
216 sodipodi:linespacing="125%"><tspan
217 sodipodi:role="line"
218 id="tspan3015"
219 x="146.00092"
220 y="360.25174"
221 style="font-size:10px">:2</tspan></text>
222 <text
223 xml:space="preserve"
224 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
225 x="232.51051"
226 y="360.18094"
227 id="text3013-3-3"
228 sodipodi:linespacing="125%"><tspan
229 sodipodi:role="line"
230 id="tspan3015-6-6"
231 x="232.51051"
232 y="360.18094"
233 style="font-size:10px">C</tspan></text>
234 </g>
235 <g
236 id="g3019"
237 transform="translate(260.06223,0)">
238 <rect
239 y="343.37366"
240 x="123.95757"
241 height="26.33428"
242 width="43.158947"
243 id="rect3101-35-0"
244 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
245 <rect
246 y="343.37366"
247 x="167.44673"
248 height="26.33428"
249 width="43.158947"
250 id="rect3101-3-62-9"
251 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
252 <rect
253 y="343.37366"
254 x="297.91437"
255 height="26.33428"
256 width="43.158947"
257 id="rect3101-3-6-9-3"
258 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
259 <rect
260 y="343.37366"
261 x="254.42516"
262 height="26.33428"
263 width="43.158947"
264 id="rect3101-3-6-7-1-6"
265 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
266 <rect
267 y="343.37366"
268 x="210.93593"
269 height="26.33428"
270 width="43.158947"
271 id="rect3101-3-6-7-5-2-0"
272 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
273 <text
274 xml:space="preserve"
275 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
276 x="145.54926"
277 y="360.25174"
278 id="text3013-3"
279 sodipodi:linespacing="125%"><tspan
280 sodipodi:role="line"
281 id="tspan3015-6"
282 x="145.54926"
283 y="360.25174"
284 style="font-size:10px">:2</tspan></text>
285 <text
286 xml:space="preserve"
287 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
288 x="232.31764"
289 y="360.18582"
290 id="text3013-3-3-7"
291 sodipodi:linespacing="125%"><tspan
292 sodipodi:role="line"
293 id="tspan3015-6-6-5"
294 x="232.31764"
295 y="360.18582"
296 style="font-size:10px">D</tspan></text>
297 </g>
298 <text
299 xml:space="preserve"
300 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
301 x="275.59558"
302 y="291.95297"
303 id="text3013-36"
304 sodipodi:linespacing="125%"><tspan
305 sodipodi:role="line"
306 id="tspan3015-7"
307 x="275.59558"
308 y="291.95297"
309 style="font-size:10px">:2</tspan></text>
310 <text
311 xml:space="preserve"
312 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
313 x="361.97092"
314 y="291.88705"
315 id="text3013-3-36"
316 sodipodi:linespacing="125%"><tspan
317 sodipodi:role="line"
318 id="tspan3015-6-7"
319 x="361.97092"
320 y="291.88705"
321 style="font-size:10px">B</tspan></text>
322 </g>
323</svg>
diff --git a/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel4.svg b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel4.svg
new file mode 100644
index 000000000000..44018fd6342b
--- /dev/null
+++ b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel4.svg
@@ -0,0 +1,323 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
4<svg
5 xmlns:dc="http://purl.org/dc/elements/1.1/"
6 xmlns:cc="http://creativecommons.org/ns#"
7 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8 xmlns:svg="http://www.w3.org/2000/svg"
9 xmlns="http://www.w3.org/2000/svg"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="490.05093"
13 height="125.78741"
14 id="svg2"
15 version="1.1"
16 inkscape:version="0.48.4 r9939"
17 sodipodi:docname="Funnel4.svg">
18 <defs
19 id="defs4">
20 <marker
21 inkscape:stockid="Arrow2Lend"
22 orient="auto"
23 refY="0"
24 refX="0"
25 id="Arrow2Lend"
26 style="overflow:visible">
27 <path
28 id="path3792"
29 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
30 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
31 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
32 inkscape:connector-curvature="0" />
33 </marker>
34 <marker
35 inkscape:stockid="Arrow2Lstart"
36 orient="auto"
37 refY="0"
38 refX="0"
39 id="Arrow2Lstart"
40 style="overflow:visible">
41 <path
42 id="path3789"
43 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
44 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
45 transform="matrix(1.1,0,0,1.1,1.1,0)"
46 inkscape:connector-curvature="0" />
47 </marker>
48 <marker
49 inkscape:stockid="Arrow2Lstart"
50 orient="auto"
51 refY="0"
52 refX="0"
53 id="Arrow2Lstart-4"
54 style="overflow:visible">
55 <path
56 id="path3789-9"
57 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
58 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
59 transform="matrix(1.1,0,0,1.1,1.1,0)"
60 inkscape:connector-curvature="0" />
61 </marker>
62 <marker
63 inkscape:stockid="Arrow2Lend"
64 orient="auto"
65 refY="0"
66 refX="0"
67 id="Arrow2Lend-4"
68 style="overflow:visible">
69 <path
70 id="path3792-4"
71 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
72 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
73 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
74 inkscape:connector-curvature="0" />
75 </marker>
76 </defs>
77 <sodipodi:namedview
78 id="base"
79 pagecolor="#ffffff"
80 bordercolor="#666666"
81 borderopacity="1.0"
82 inkscape:pageopacity="0.0"
83 inkscape:pageshadow="2"
84 inkscape:zoom="1.3670394"
85 inkscape:cx="114.01552"
86 inkscape:cy="-86.548414"
87 inkscape:document-units="px"
88 inkscape:current-layer="layer1"
89 showgrid="false"
90 inkscape:window-width="1351"
91 inkscape:window-height="836"
92 inkscape:window-x="68"
93 inkscape:window-y="180"
94 inkscape:window-maximized="0"
95 fit-margin-top="5"
96 fit-margin-left="5"
97 fit-margin-right="5"
98 fit-margin-bottom="5" />
99 <metadata
100 id="metadata7">
101 <rdf:RDF>
102 <cc:Work
103 rdf:about="">
104 <dc:format>image/svg+xml</dc:format>
105 <dc:type
106 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
107 <dc:title />
108 </cc:Work>
109 </rdf:RDF>
110 </metadata>
111 <g
112 inkscape:label="Layer 1"
113 inkscape:groupmode="layer"
114 id="layer1"
115 transform="translate(-117.08462,-249.92053)">
116 <flowRoot
117 xml:space="preserve"
118 id="flowRoot2985"
119 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"><flowRegion
120 id="flowRegion2987"><rect
121 id="rect2989"
122 width="82.85714"
123 height="11.428572"
124 x="240"
125 y="492.36218" /></flowRegion><flowPara
126 id="flowPara2991" /></flowRoot> <text
127 xml:space="preserve"
128 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"
129 x="362.371"
130 y="262.51819"
131 id="text4441"
132 sodipodi:linespacing="125%"><tspan
133 sodipodi:role="line"
134 id="tspan4443"
135 x="362.371"
136 y="262.51819">-&gt;expedited_sequence: 1 GP: A</tspan></text>
137 <rect
138 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
139 id="rect3101"
140 width="43.158947"
141 height="26.33428"
142 x="253.55223"
143 y="275.07489" />
144 <rect
145 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
146 id="rect3101-3"
147 width="43.158947"
148 height="26.33428"
149 x="297.04141"
150 y="275.07489" />
151 <rect
152 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
153 id="rect3101-3-6"
154 width="43.158947"
155 height="26.33428"
156 x="427.509"
157 y="275.07489" />
158 <rect
159 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
160 id="rect3101-3-6-7"
161 width="43.158947"
162 height="26.33428"
163 x="384.01981"
164 y="275.07489" />
165 <rect
166 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
167 id="rect3101-3-6-7-5"
168 width="43.158947"
169 height="26.33428"
170 x="340.53061"
171 y="275.07489" />
172 <g
173 id="g3997"
174 transform="translate(-0.87295532,0)">
175 <rect
176 y="343.37366"
177 x="123.95757"
178 height="26.33428"
179 width="43.158947"
180 id="rect3101-35"
181 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
182 <rect
183 y="343.37366"
184 x="167.44673"
185 height="26.33428"
186 width="43.158947"
187 id="rect3101-3-62"
188 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
189 <rect
190 y="343.37366"
191 x="297.91437"
192 height="26.33428"
193 width="43.158947"
194 id="rect3101-3-6-9"
195 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
196 <rect
197 y="343.37366"
198 x="254.42516"
199 height="26.33428"
200 width="43.158947"
201 id="rect3101-3-6-7-1"
202 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
203 <rect
204 y="343.37366"
205 x="210.93593"
206 height="26.33428"
207 width="43.158947"
208 id="rect3101-3-6-7-5-2"
209 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
210 <text
211 xml:space="preserve"
212 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
213 x="146.00092"
214 y="360.25174"
215 id="text3013"
216 sodipodi:linespacing="125%"><tspan
217 sodipodi:role="line"
218 id="tspan3015"
219 x="146.00092"
220 y="360.25174"
221 style="font-size:10px">E:4</tspan></text>
222 <text
223 xml:space="preserve"
224 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
225 x="232.51051"
226 y="360.18094"
227 id="text3013-3-3"
228 sodipodi:linespacing="125%"><tspan
229 sodipodi:role="line"
230 id="tspan3015-6-6"
231 x="232.51051"
232 y="360.18094"
233 style="font-size:10px">C</tspan></text>
234 </g>
235 <g
236 id="g3019"
237 transform="translate(260.06223,0)">
238 <rect
239 y="343.37366"
240 x="123.95757"
241 height="26.33428"
242 width="43.158947"
243 id="rect3101-35-0"
244 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
245 <rect
246 y="343.37366"
247 x="167.44673"
248 height="26.33428"
249 width="43.158947"
250 id="rect3101-3-62-9"
251 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
252 <rect
253 y="343.37366"
254 x="297.91437"
255 height="26.33428"
256 width="43.158947"
257 id="rect3101-3-6-9-3"
258 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
259 <rect
260 y="343.37366"
261 x="254.42516"
262 height="26.33428"
263 width="43.158947"
264 id="rect3101-3-6-7-1-6"
265 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
266 <rect
267 y="343.37366"
268 x="210.93593"
269 height="26.33428"
270 width="43.158947"
271 id="rect3101-3-6-7-5-2-0"
272 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
273 <text
274 xml:space="preserve"
275 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
276 x="145.54926"
277 y="360.25174"
278 id="text3013-3"
279 sodipodi:linespacing="125%"><tspan
280 sodipodi:role="line"
281 id="tspan3015-6"
282 x="145.54926"
283 y="360.25174"
284 style="font-size:10px">F:4</tspan></text>
285 <text
286 xml:space="preserve"
287 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
288 x="232.31764"
289 y="360.18582"
290 id="text3013-3-3-7"
291 sodipodi:linespacing="125%"><tspan
292 sodipodi:role="line"
293 id="tspan3015-6-6-5"
294 x="232.31764"
295 y="360.18582"
296 style="font-size:10px">D</tspan></text>
297 </g>
298 <text
299 xml:space="preserve"
300 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
301 x="275.59558"
302 y="291.95297"
303 id="text3013-36"
304 sodipodi:linespacing="125%"><tspan
305 sodipodi:role="line"
306 id="tspan3015-7"
307 x="275.59558"
308 y="291.95297"
309 style="font-size:10px">:2</tspan></text>
310 <text
311 xml:space="preserve"
312 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
313 x="361.97092"
314 y="291.88705"
315 id="text3013-3-36"
316 sodipodi:linespacing="125%"><tspan
317 sodipodi:role="line"
318 id="tspan3015-6-7"
319 x="361.97092"
320 y="291.88705"
321 style="font-size:10px">B</tspan></text>
322 </g>
323</svg>
diff --git a/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel5.svg b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel5.svg
new file mode 100644
index 000000000000..e5eef50454fb
--- /dev/null
+++ b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel5.svg
@@ -0,0 +1,335 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
4<svg
5 xmlns:dc="http://purl.org/dc/elements/1.1/"
6 xmlns:cc="http://creativecommons.org/ns#"
7 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8 xmlns:svg="http://www.w3.org/2000/svg"
9 xmlns="http://www.w3.org/2000/svg"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="490.05093"
13 height="125.78741"
14 id="svg2"
15 version="1.1"
16 inkscape:version="0.48.4 r9939"
17 sodipodi:docname="Funnel5.svg">
18 <defs
19 id="defs4">
20 <marker
21 inkscape:stockid="Arrow2Lend"
22 orient="auto"
23 refY="0"
24 refX="0"
25 id="Arrow2Lend"
26 style="overflow:visible">
27 <path
28 id="path3792"
29 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
30 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
31 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
32 inkscape:connector-curvature="0" />
33 </marker>
34 <marker
35 inkscape:stockid="Arrow2Lstart"
36 orient="auto"
37 refY="0"
38 refX="0"
39 id="Arrow2Lstart"
40 style="overflow:visible">
41 <path
42 id="path3789"
43 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
44 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
45 transform="matrix(1.1,0,0,1.1,1.1,0)"
46 inkscape:connector-curvature="0" />
47 </marker>
48 <marker
49 inkscape:stockid="Arrow2Lstart"
50 orient="auto"
51 refY="0"
52 refX="0"
53 id="Arrow2Lstart-4"
54 style="overflow:visible">
55 <path
56 id="path3789-9"
57 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
58 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
59 transform="matrix(1.1,0,0,1.1,1.1,0)"
60 inkscape:connector-curvature="0" />
61 </marker>
62 <marker
63 inkscape:stockid="Arrow2Lend"
64 orient="auto"
65 refY="0"
66 refX="0"
67 id="Arrow2Lend-4"
68 style="overflow:visible">
69 <path
70 id="path3792-4"
71 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
72 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
73 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
74 inkscape:connector-curvature="0" />
75 </marker>
76 </defs>
77 <sodipodi:namedview
78 id="base"
79 pagecolor="#ffffff"
80 bordercolor="#666666"
81 borderopacity="1.0"
82 inkscape:pageopacity="0.0"
83 inkscape:pageshadow="2"
84 inkscape:zoom="1.3670394"
85 inkscape:cx="114.01552"
86 inkscape:cy="-86.548414"
87 inkscape:document-units="px"
88 inkscape:current-layer="layer1"
89 showgrid="false"
90 inkscape:window-width="1351"
91 inkscape:window-height="836"
92 inkscape:window-x="68"
93 inkscape:window-y="180"
94 inkscape:window-maximized="0"
95 fit-margin-top="5"
96 fit-margin-left="5"
97 fit-margin-right="5"
98 fit-margin-bottom="5" />
99 <metadata
100 id="metadata7">
101 <rdf:RDF>
102 <cc:Work
103 rdf:about="">
104 <dc:format>image/svg+xml</dc:format>
105 <dc:type
106 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
107 <dc:title />
108 </cc:Work>
109 </rdf:RDF>
110 </metadata>
111 <g
112 inkscape:label="Layer 1"
113 inkscape:groupmode="layer"
114 id="layer1"
115 transform="translate(-117.08462,-249.92053)">
116 <flowRoot
117 xml:space="preserve"
118 id="flowRoot2985"
119 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"><flowRegion
120 id="flowRegion2987"><rect
121 id="rect2989"
122 width="82.85714"
123 height="11.428572"
124 x="240"
125 y="492.36218" /></flowRegion><flowPara
126 id="flowPara2991" /></flowRoot> <text
127 xml:space="preserve"
128 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"
129 x="362.371"
130 y="262.51819"
131 id="text4441"
132 sodipodi:linespacing="125%"><tspan
133 sodipodi:role="line"
134 id="tspan4443"
135 x="362.371"
136 y="262.51819">-&gt;expedited_sequence: 1 GP: A,E</tspan></text>
137 <rect
138 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
139 id="rect3101"
140 width="43.158947"
141 height="26.33428"
142 x="253.55223"
143 y="275.07489" />
144 <rect
145 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
146 id="rect3101-3"
147 width="43.158947"
148 height="26.33428"
149 x="297.04141"
150 y="275.07489" />
151 <rect
152 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
153 id="rect3101-3-6"
154 width="43.158947"
155 height="26.33428"
156 x="427.509"
157 y="275.07489" />
158 <rect
159 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
160 id="rect3101-3-6-7"
161 width="43.158947"
162 height="26.33428"
163 x="384.01981"
164 y="275.07489" />
165 <rect
166 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
167 id="rect3101-3-6-7-5"
168 width="43.158947"
169 height="26.33428"
170 x="340.53061"
171 y="275.07489" />
172 <g
173 id="g3997"
174 transform="translate(-0.87295532,0)">
175 <rect
176 y="343.37366"
177 x="123.95757"
178 height="26.33428"
179 width="43.158947"
180 id="rect3101-35"
181 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
182 <rect
183 y="343.37366"
184 x="167.44673"
185 height="26.33428"
186 width="43.158947"
187 id="rect3101-3-62"
188 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
189 <rect
190 y="343.37366"
191 x="297.91437"
192 height="26.33428"
193 width="43.158947"
194 id="rect3101-3-6-9"
195 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
196 <rect
197 y="343.37366"
198 x="254.42516"
199 height="26.33428"
200 width="43.158947"
201 id="rect3101-3-6-7-1"
202 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
203 <rect
204 y="343.37366"
205 x="210.93593"
206 height="26.33428"
207 width="43.158947"
208 id="rect3101-3-6-7-5-2"
209 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
210 <text
211 xml:space="preserve"
212 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
213 x="146.00092"
214 y="360.25174"
215 id="text3013"
216 sodipodi:linespacing="125%"><tspan
217 sodipodi:role="line"
218 id="tspan3015"
219 x="146.00092"
220 y="360.25174"
221 style="font-size:10px">:4</tspan></text>
222 <text
223 xml:space="preserve"
224 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
225 x="232.51051"
226 y="360.18094"
227 id="text3013-3-3"
228 sodipodi:linespacing="125%"><tspan
229 sodipodi:role="line"
230 id="tspan3015-6-6"
231 x="232.51051"
232 y="360.18094"
233 style="font-size:10px">C</tspan></text>
234 </g>
235 <g
236 id="g3019"
237 transform="translate(260.06223,0)">
238 <rect
239 y="343.37366"
240 x="123.95757"
241 height="26.33428"
242 width="43.158947"
243 id="rect3101-35-0"
244 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
245 <rect
246 y="343.37366"
247 x="167.44673"
248 height="26.33428"
249 width="43.158947"
250 id="rect3101-3-62-9"
251 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
252 <rect
253 y="343.37366"
254 x="297.91437"
255 height="26.33428"
256 width="43.158947"
257 id="rect3101-3-6-9-3"
258 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
259 <rect
260 y="343.37366"
261 x="254.42516"
262 height="26.33428"
263 width="43.158947"
264 id="rect3101-3-6-7-1-6"
265 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
266 <rect
267 y="343.37366"
268 x="210.93593"
269 height="26.33428"
270 width="43.158947"
271 id="rect3101-3-6-7-5-2-0"
272 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
273 <text
274 xml:space="preserve"
275 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
276 x="145.54926"
277 y="360.25174"
278 id="text3013-3"
279 sodipodi:linespacing="125%"><tspan
280 sodipodi:role="line"
281 id="tspan3015-6"
282 x="145.54926"
283 y="360.25174"
284 style="font-size:10px">:4</tspan></text>
285 <text
286 xml:space="preserve"
287 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
288 x="232.31764"
289 y="360.18582"
290 id="text3013-3-3-7"
291 sodipodi:linespacing="125%"><tspan
292 sodipodi:role="line"
293 id="tspan3015-6-6-5"
294 x="232.31764"
295 y="360.18582"
296 style="font-size:10px">D</tspan></text>
297 </g>
298 <text
299 xml:space="preserve"
300 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
301 x="275.59558"
302 y="291.95297"
303 id="text3013-36"
304 sodipodi:linespacing="125%"><tspan
305 sodipodi:role="line"
306 id="tspan3015-7"
307 x="275.59558"
308 y="291.95297"
309 style="font-size:10px">:4</tspan></text>
310 <text
311 xml:space="preserve"
312 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
313 x="361.97092"
314 y="291.88705"
315 id="text3013-3-36"
316 sodipodi:linespacing="125%"><tspan
317 sodipodi:role="line"
318 id="tspan3015-6-7"
319 x="361.97092"
320 y="291.88705"
321 style="font-size:10px">B</tspan></text>
322 <text
323 xml:space="preserve"
324 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
325 x="405.40396"
326 y="291.88705"
327 id="text3013-3-36-3"
328 sodipodi:linespacing="125%"><tspan
329 sodipodi:role="line"
330 id="tspan3015-6-7-6"
331 x="405.40396"
332 y="291.88705"
333 style="font-size:10px">F</tspan></text>
334 </g>
335</svg>
diff --git a/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel6.svg b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel6.svg
new file mode 100644
index 000000000000..fbd2c1892886
--- /dev/null
+++ b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel6.svg
@@ -0,0 +1,335 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
4<svg
5 xmlns:dc="http://purl.org/dc/elements/1.1/"
6 xmlns:cc="http://creativecommons.org/ns#"
7 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8 xmlns:svg="http://www.w3.org/2000/svg"
9 xmlns="http://www.w3.org/2000/svg"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="490.05093"
13 height="125.78741"
14 id="svg2"
15 version="1.1"
16 inkscape:version="0.48.4 r9939"
17 sodipodi:docname="Funnel6.svg">
18 <defs
19 id="defs4">
20 <marker
21 inkscape:stockid="Arrow2Lend"
22 orient="auto"
23 refY="0"
24 refX="0"
25 id="Arrow2Lend"
26 style="overflow:visible">
27 <path
28 id="path3792"
29 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
30 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
31 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
32 inkscape:connector-curvature="0" />
33 </marker>
34 <marker
35 inkscape:stockid="Arrow2Lstart"
36 orient="auto"
37 refY="0"
38 refX="0"
39 id="Arrow2Lstart"
40 style="overflow:visible">
41 <path
42 id="path3789"
43 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
44 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
45 transform="matrix(1.1,0,0,1.1,1.1,0)"
46 inkscape:connector-curvature="0" />
47 </marker>
48 <marker
49 inkscape:stockid="Arrow2Lstart"
50 orient="auto"
51 refY="0"
52 refX="0"
53 id="Arrow2Lstart-4"
54 style="overflow:visible">
55 <path
56 id="path3789-9"
57 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
58 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
59 transform="matrix(1.1,0,0,1.1,1.1,0)"
60 inkscape:connector-curvature="0" />
61 </marker>
62 <marker
63 inkscape:stockid="Arrow2Lend"
64 orient="auto"
65 refY="0"
66 refX="0"
67 id="Arrow2Lend-4"
68 style="overflow:visible">
69 <path
70 id="path3792-4"
71 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
72 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
73 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
74 inkscape:connector-curvature="0" />
75 </marker>
76 </defs>
77 <sodipodi:namedview
78 id="base"
79 pagecolor="#ffffff"
80 bordercolor="#666666"
81 borderopacity="1.0"
82 inkscape:pageopacity="0.0"
83 inkscape:pageshadow="2"
84 inkscape:zoom="1.3670394"
85 inkscape:cx="114.01552"
86 inkscape:cy="-86.548414"
87 inkscape:document-units="px"
88 inkscape:current-layer="layer1"
89 showgrid="false"
90 inkscape:window-width="1351"
91 inkscape:window-height="836"
92 inkscape:window-x="68"
93 inkscape:window-y="180"
94 inkscape:window-maximized="0"
95 fit-margin-top="5"
96 fit-margin-left="5"
97 fit-margin-right="5"
98 fit-margin-bottom="5" />
99 <metadata
100 id="metadata7">
101 <rdf:RDF>
102 <cc:Work
103 rdf:about="">
104 <dc:format>image/svg+xml</dc:format>
105 <dc:type
106 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
107 <dc:title />
108 </cc:Work>
109 </rdf:RDF>
110 </metadata>
111 <g
112 inkscape:label="Layer 1"
113 inkscape:groupmode="layer"
114 id="layer1"
115 transform="translate(-117.08462,-249.92053)">
116 <flowRoot
117 xml:space="preserve"
118 id="flowRoot2985"
119 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"><flowRegion
120 id="flowRegion2987"><rect
121 id="rect2989"
122 width="82.85714"
123 height="11.428572"
124 x="240"
125 y="492.36218" /></flowRegion><flowPara
126 id="flowPara2991" /></flowRoot> <text
127 xml:space="preserve"
128 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"
129 x="362.371"
130 y="262.51819"
131 id="text4441"
132 sodipodi:linespacing="125%"><tspan
133 sodipodi:role="line"
134 id="tspan4443"
135 x="362.371"
136 y="262.51819">-&gt;expedited_sequence: 2 GP: E Wakeup: A</tspan></text>
137 <rect
138 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
139 id="rect3101"
140 width="43.158947"
141 height="26.33428"
142 x="253.55223"
143 y="275.07489" />
144 <rect
145 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
146 id="rect3101-3"
147 width="43.158947"
148 height="26.33428"
149 x="297.04141"
150 y="275.07489" />
151 <rect
152 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
153 id="rect3101-3-6"
154 width="43.158947"
155 height="26.33428"
156 x="427.509"
157 y="275.07489" />
158 <rect
159 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
160 id="rect3101-3-6-7"
161 width="43.158947"
162 height="26.33428"
163 x="384.01981"
164 y="275.07489" />
165 <rect
166 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
167 id="rect3101-3-6-7-5"
168 width="43.158947"
169 height="26.33428"
170 x="340.53061"
171 y="275.07489" />
172 <g
173 id="g3997"
174 transform="translate(-0.87295532,0)">
175 <rect
176 y="343.37366"
177 x="123.95757"
178 height="26.33428"
179 width="43.158947"
180 id="rect3101-35"
181 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
182 <rect
183 y="343.37366"
184 x="167.44673"
185 height="26.33428"
186 width="43.158947"
187 id="rect3101-3-62"
188 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
189 <rect
190 y="343.37366"
191 x="297.91437"
192 height="26.33428"
193 width="43.158947"
194 id="rect3101-3-6-9"
195 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
196 <rect
197 y="343.37366"
198 x="254.42516"
199 height="26.33428"
200 width="43.158947"
201 id="rect3101-3-6-7-1"
202 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
203 <rect
204 y="343.37366"
205 x="210.93593"
206 height="26.33428"
207 width="43.158947"
208 id="rect3101-3-6-7-5-2"
209 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
210 <text
211 xml:space="preserve"
212 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
213 x="146.00092"
214 y="360.25174"
215 id="text3013"
216 sodipodi:linespacing="125%"><tspan
217 sodipodi:role="line"
218 id="tspan3015"
219 x="146.00092"
220 y="360.25174"
221 style="font-size:10px">:4</tspan></text>
222 <text
223 xml:space="preserve"
224 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
225 x="232.51051"
226 y="360.18094"
227 id="text3013-3-3"
228 sodipodi:linespacing="125%"><tspan
229 sodipodi:role="line"
230 id="tspan3015-6-6"
231 x="232.51051"
232 y="360.18094"
233 style="font-size:10px">C</tspan></text>
234 </g>
235 <g
236 id="g3019"
237 transform="translate(260.06223,0)">
238 <rect
239 y="343.37366"
240 x="123.95757"
241 height="26.33428"
242 width="43.158947"
243 id="rect3101-35-0"
244 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
245 <rect
246 y="343.37366"
247 x="167.44673"
248 height="26.33428"
249 width="43.158947"
250 id="rect3101-3-62-9"
251 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
252 <rect
253 y="343.37366"
254 x="297.91437"
255 height="26.33428"
256 width="43.158947"
257 id="rect3101-3-6-9-3"
258 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
259 <rect
260 y="343.37366"
261 x="254.42516"
262 height="26.33428"
263 width="43.158947"
264 id="rect3101-3-6-7-1-6"
265 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
266 <rect
267 y="343.37366"
268 x="210.93593"
269 height="26.33428"
270 width="43.158947"
271 id="rect3101-3-6-7-5-2-0"
272 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
273 <text
274 xml:space="preserve"
275 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
276 x="145.54926"
277 y="360.25174"
278 id="text3013-3"
279 sodipodi:linespacing="125%"><tspan
280 sodipodi:role="line"
281 id="tspan3015-6"
282 x="145.54926"
283 y="360.25174"
284 style="font-size:10px">:4</tspan></text>
285 <text
286 xml:space="preserve"
287 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
288 x="232.31764"
289 y="360.18582"
290 id="text3013-3-3-7"
291 sodipodi:linespacing="125%"><tspan
292 sodipodi:role="line"
293 id="tspan3015-6-6-5"
294 x="232.31764"
295 y="360.18582"
296 style="font-size:10px">D</tspan></text>
297 </g>
298 <text
299 xml:space="preserve"
300 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
301 x="275.59558"
302 y="291.95297"
303 id="text3013-36"
304 sodipodi:linespacing="125%"><tspan
305 sodipodi:role="line"
306 id="tspan3015-7"
307 x="275.59558"
308 y="291.95297"
309 style="font-size:10px">:4</tspan></text>
310 <text
311 xml:space="preserve"
312 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
313 x="361.97092"
314 y="291.88705"
315 id="text3013-3-36"
316 sodipodi:linespacing="125%"><tspan
317 sodipodi:role="line"
318 id="tspan3015-6-7"
319 x="361.97092"
320 y="291.88705"
321 style="font-size:10px">B</tspan></text>
322 <text
323 xml:space="preserve"
324 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
325 x="405.40396"
326 y="291.88705"
327 id="text3013-3-36-3"
328 sodipodi:linespacing="125%"><tspan
329 sodipodi:role="line"
330 id="tspan3015-6-7-6"
331 x="405.40396"
332 y="291.88705"
333 style="font-size:10px">F</tspan></text>
334 </g>
335</svg>
diff --git a/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel7.svg b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel7.svg
new file mode 100644
index 000000000000..502e159ed278
--- /dev/null
+++ b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel7.svg
@@ -0,0 +1,347 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
4<svg
5 xmlns:dc="http://purl.org/dc/elements/1.1/"
6 xmlns:cc="http://creativecommons.org/ns#"
7 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8 xmlns:svg="http://www.w3.org/2000/svg"
9 xmlns="http://www.w3.org/2000/svg"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="490.05093"
13 height="125.78741"
14 id="svg2"
15 version="1.1"
16 inkscape:version="0.48.4 r9939"
17 sodipodi:docname="Funnel7.svg">
18 <defs
19 id="defs4">
20 <marker
21 inkscape:stockid="Arrow2Lend"
22 orient="auto"
23 refY="0"
24 refX="0"
25 id="Arrow2Lend"
26 style="overflow:visible">
27 <path
28 id="path3792"
29 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
30 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
31 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
32 inkscape:connector-curvature="0" />
33 </marker>
34 <marker
35 inkscape:stockid="Arrow2Lstart"
36 orient="auto"
37 refY="0"
38 refX="0"
39 id="Arrow2Lstart"
40 style="overflow:visible">
41 <path
42 id="path3789"
43 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
44 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
45 transform="matrix(1.1,0,0,1.1,1.1,0)"
46 inkscape:connector-curvature="0" />
47 </marker>
48 <marker
49 inkscape:stockid="Arrow2Lstart"
50 orient="auto"
51 refY="0"
52 refX="0"
53 id="Arrow2Lstart-4"
54 style="overflow:visible">
55 <path
56 id="path3789-9"
57 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
58 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
59 transform="matrix(1.1,0,0,1.1,1.1,0)"
60 inkscape:connector-curvature="0" />
61 </marker>
62 <marker
63 inkscape:stockid="Arrow2Lend"
64 orient="auto"
65 refY="0"
66 refX="0"
67 id="Arrow2Lend-4"
68 style="overflow:visible">
69 <path
70 id="path3792-4"
71 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
72 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
73 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
74 inkscape:connector-curvature="0" />
75 </marker>
76 </defs>
77 <sodipodi:namedview
78 id="base"
79 pagecolor="#ffffff"
80 bordercolor="#666666"
81 borderopacity="1.0"
82 inkscape:pageopacity="0.0"
83 inkscape:pageshadow="2"
84 inkscape:zoom="1.3670394"
85 inkscape:cx="114.01552"
86 inkscape:cy="-86.548414"
87 inkscape:document-units="px"
88 inkscape:current-layer="layer1"
89 showgrid="false"
90 inkscape:window-width="1351"
91 inkscape:window-height="836"
92 inkscape:window-x="68"
93 inkscape:window-y="180"
94 inkscape:window-maximized="0"
95 fit-margin-top="5"
96 fit-margin-left="5"
97 fit-margin-right="5"
98 fit-margin-bottom="5" />
99 <metadata
100 id="metadata7">
101 <rdf:RDF>
102 <cc:Work
103 rdf:about="">
104 <dc:format>image/svg+xml</dc:format>
105 <dc:type
106 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
107 <dc:title />
108 </cc:Work>
109 </rdf:RDF>
110 </metadata>
111 <g
112 inkscape:label="Layer 1"
113 inkscape:groupmode="layer"
114 id="layer1"
115 transform="translate(-117.08462,-249.92053)">
116 <flowRoot
117 xml:space="preserve"
118 id="flowRoot2985"
119 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"><flowRegion
120 id="flowRegion2987"><rect
121 id="rect2989"
122 width="82.85714"
123 height="11.428572"
124 x="240"
125 y="492.36218" /></flowRegion><flowPara
126 id="flowPara2991" /></flowRoot> <text
127 xml:space="preserve"
128 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"
129 x="362.371"
130 y="262.51819"
131 id="text4441"
132 sodipodi:linespacing="125%"><tspan
133 sodipodi:role="line"
134 id="tspan4443"
135 x="362.371"
136 y="262.51819">-&gt;expedited_sequence: 3 GP: E,H Wakeup: A</tspan></text>
137 <rect
138 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
139 id="rect3101"
140 width="43.158947"
141 height="26.33428"
142 x="253.55223"
143 y="275.07489" />
144 <rect
145 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
146 id="rect3101-3"
147 width="43.158947"
148 height="26.33428"
149 x="297.04141"
150 y="275.07489" />
151 <rect
152 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
153 id="rect3101-3-6"
154 width="43.158947"
155 height="26.33428"
156 x="427.509"
157 y="275.07489" />
158 <rect
159 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
160 id="rect3101-3-6-7"
161 width="43.158947"
162 height="26.33428"
163 x="384.01981"
164 y="275.07489" />
165 <rect
166 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
167 id="rect3101-3-6-7-5"
168 width="43.158947"
169 height="26.33428"
170 x="340.53061"
171 y="275.07489" />
172 <g
173 id="g3997"
174 transform="translate(-0.87295532,0)">
175 <rect
176 y="343.37366"
177 x="123.95757"
178 height="26.33428"
179 width="43.158947"
180 id="rect3101-35"
181 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
182 <rect
183 y="343.37366"
184 x="167.44673"
185 height="26.33428"
186 width="43.158947"
187 id="rect3101-3-62"
188 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
189 <rect
190 y="343.37366"
191 x="297.91437"
192 height="26.33428"
193 width="43.158947"
194 id="rect3101-3-6-9"
195 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
196 <rect
197 y="343.37366"
198 x="254.42516"
199 height="26.33428"
200 width="43.158947"
201 id="rect3101-3-6-7-1"
202 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
203 <rect
204 y="343.37366"
205 x="210.93593"
206 height="26.33428"
207 width="43.158947"
208 id="rect3101-3-6-7-5-2"
209 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
210 <text
211 xml:space="preserve"
212 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
213 x="146.00092"
214 y="360.25174"
215 id="text3013"
216 sodipodi:linespacing="125%"><tspan
217 sodipodi:role="line"
218 id="tspan3015"
219 x="146.00092"
220 y="360.25174"
221 style="font-size:10px">:4</tspan></text>
222 <text
223 xml:space="preserve"
224 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
225 x="232.51051"
226 y="360.18094"
227 id="text3013-3-3"
228 sodipodi:linespacing="125%"><tspan
229 sodipodi:role="line"
230 id="tspan3015-6-6"
231 x="232.51051"
232 y="360.18094"
233 style="font-size:10px">C</tspan></text>
234 </g>
235 <g
236 id="g3019"
237 transform="translate(260.06223,0)">
238 <rect
239 y="343.37366"
240 x="123.95757"
241 height="26.33428"
242 width="43.158947"
243 id="rect3101-35-0"
244 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
245 <rect
246 y="343.37366"
247 x="167.44673"
248 height="26.33428"
249 width="43.158947"
250 id="rect3101-3-62-9"
251 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
252 <rect
253 y="343.37366"
254 x="297.91437"
255 height="26.33428"
256 width="43.158947"
257 id="rect3101-3-6-9-3"
258 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
259 <rect
260 y="343.37366"
261 x="254.42516"
262 height="26.33428"
263 width="43.158947"
264 id="rect3101-3-6-7-1-6"
265 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
266 <rect
267 y="343.37366"
268 x="210.93593"
269 height="26.33428"
270 width="43.158947"
271 id="rect3101-3-6-7-5-2-0"
272 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
273 <text
274 xml:space="preserve"
275 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
276 x="145.54926"
277 y="360.25174"
278 id="text3013-3"
279 sodipodi:linespacing="125%"><tspan
280 sodipodi:role="line"
281 id="tspan3015-6"
282 x="145.54926"
283 y="360.25174"
284 style="font-size:10px">:6</tspan></text>
285 <text
286 xml:space="preserve"
287 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
288 x="232.31764"
289 y="360.18582"
290 id="text3013-3-3-7"
291 sodipodi:linespacing="125%"><tspan
292 sodipodi:role="line"
293 id="tspan3015-6-6-5"
294 x="232.31764"
295 y="360.18582"
296 style="font-size:10px">D</tspan></text>
297 </g>
298 <text
299 xml:space="preserve"
300 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
301 x="275.59558"
302 y="291.95297"
303 id="text3013-36"
304 sodipodi:linespacing="125%"><tspan
305 sodipodi:role="line"
306 id="tspan3015-7"
307 x="275.59558"
308 y="291.95297"
309 style="font-size:10px">:6</tspan></text>
310 <text
311 xml:space="preserve"
312 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
313 x="361.97092"
314 y="291.88705"
315 id="text3013-3-36"
316 sodipodi:linespacing="125%"><tspan
317 sodipodi:role="line"
318 id="tspan3015-6-7"
319 x="361.97092"
320 y="291.88705"
321 style="font-size:10px">B</tspan></text>
322 <text
323 xml:space="preserve"
324 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
325 x="405.40396"
326 y="291.88705"
327 id="text3013-3-36-3"
328 sodipodi:linespacing="125%"><tspan
329 sodipodi:role="line"
330 id="tspan3015-6-7-6"
331 x="405.40396"
332 y="291.88705"
333 style="font-size:10px">F</tspan></text>
334 <text
335 xml:space="preserve"
336 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
337 x="449.22031"
338 y="291.88217"
339 id="text3013-3-36-3-3"
340 sodipodi:linespacing="125%"><tspan
341 sodipodi:role="line"
342 id="tspan3015-6-7-6-6"
343 x="449.22031"
344 y="291.88217"
345 style="font-size:10px">G</tspan></text>
346 </g>
347</svg>
diff --git a/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel8.svg b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel8.svg
new file mode 100644
index 000000000000..677401551c7d
--- /dev/null
+++ b/Documentation/RCU/Design/Expedited-Grace-Periods/Funnel8.svg
@@ -0,0 +1,311 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
4<svg
5 xmlns:dc="http://purl.org/dc/elements/1.1/"
6 xmlns:cc="http://creativecommons.org/ns#"
7 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8 xmlns:svg="http://www.w3.org/2000/svg"
9 xmlns="http://www.w3.org/2000/svg"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="490.05093"
13 height="125.78741"
14 id="svg2"
15 version="1.1"
16 inkscape:version="0.48.4 r9939"
17 sodipodi:docname="Funnel8.svg">
18 <defs
19 id="defs4">
20 <marker
21 inkscape:stockid="Arrow2Lend"
22 orient="auto"
23 refY="0"
24 refX="0"
25 id="Arrow2Lend"
26 style="overflow:visible">
27 <path
28 id="path3792"
29 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
30 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
31 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
32 inkscape:connector-curvature="0" />
33 </marker>
34 <marker
35 inkscape:stockid="Arrow2Lstart"
36 orient="auto"
37 refY="0"
38 refX="0"
39 id="Arrow2Lstart"
40 style="overflow:visible">
41 <path
42 id="path3789"
43 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
44 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
45 transform="matrix(1.1,0,0,1.1,1.1,0)"
46 inkscape:connector-curvature="0" />
47 </marker>
48 <marker
49 inkscape:stockid="Arrow2Lstart"
50 orient="auto"
51 refY="0"
52 refX="0"
53 id="Arrow2Lstart-4"
54 style="overflow:visible">
55 <path
56 id="path3789-9"
57 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
58 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
59 transform="matrix(1.1,0,0,1.1,1.1,0)"
60 inkscape:connector-curvature="0" />
61 </marker>
62 <marker
63 inkscape:stockid="Arrow2Lend"
64 orient="auto"
65 refY="0"
66 refX="0"
67 id="Arrow2Lend-4"
68 style="overflow:visible">
69 <path
70 id="path3792-4"
71 style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
72 d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
73 transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
74 inkscape:connector-curvature="0" />
75 </marker>
76 </defs>
77 <sodipodi:namedview
78 id="base"
79 pagecolor="#ffffff"
80 bordercolor="#666666"
81 borderopacity="1.0"
82 inkscape:pageopacity="0.0"
83 inkscape:pageshadow="2"
84 inkscape:zoom="1.3670394"
85 inkscape:cx="114.01552"
86 inkscape:cy="-86.548414"
87 inkscape:document-units="px"
88 inkscape:current-layer="layer1"
89 showgrid="false"
90 inkscape:window-width="1351"
91 inkscape:window-height="836"
92 inkscape:window-x="68"
93 inkscape:window-y="180"
94 inkscape:window-maximized="0"
95 fit-margin-top="5"
96 fit-margin-left="5"
97 fit-margin-right="5"
98 fit-margin-bottom="5" />
99 <metadata
100 id="metadata7">
101 <rdf:RDF>
102 <cc:Work
103 rdf:about="">
104 <dc:format>image/svg+xml</dc:format>
105 <dc:type
106 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
107 <dc:title />
108 </cc:Work>
109 </rdf:RDF>
110 </metadata>
111 <g
112 inkscape:label="Layer 1"
113 inkscape:groupmode="layer"
114 id="layer1"
115 transform="translate(-117.08462,-249.92053)">
116 <flowRoot
117 xml:space="preserve"
118 id="flowRoot2985"
119 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"><flowRegion
120 id="flowRegion2987"><rect
121 id="rect2989"
122 width="82.85714"
123 height="11.428572"
124 x="240"
125 y="492.36218" /></flowRegion><flowPara
126 id="flowPara2991" /></flowRoot> <text
127 xml:space="preserve"
128 style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Symbol;-inkscape-font-specification:Symbol"
129 x="362.371"
130 y="262.51819"
131 id="text4441"
132 sodipodi:linespacing="125%"><tspan
133 sodipodi:role="line"
134 id="tspan4443"
135 x="362.371"
136 y="262.51819">-&gt;expedited_sequence: 3 GP: E,H</tspan></text>
137 <rect
138 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
139 id="rect3101"
140 width="43.158947"
141 height="26.33428"
142 x="253.55223"
143 y="275.07489" />
144 <rect
145 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
146 id="rect3101-3"
147 width="43.158947"
148 height="26.33428"
149 x="297.04141"
150 y="275.07489" />
151 <rect
152 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
153 id="rect3101-3-6"
154 width="43.158947"
155 height="26.33428"
156 x="427.509"
157 y="275.07489" />
158 <rect
159 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
160 id="rect3101-3-6-7"
161 width="43.158947"
162 height="26.33428"
163 x="384.01981"
164 y="275.07489" />
165 <rect
166 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
167 id="rect3101-3-6-7-5"
168 width="43.158947"
169 height="26.33428"
170 x="340.53061"
171 y="275.07489" />
172 <g
173 id="g3997"
174 transform="translate(-0.87295532,0)">
175 <rect
176 y="343.37366"
177 x="123.95757"
178 height="26.33428"
179 width="43.158947"
180 id="rect3101-35"
181 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
182 <rect
183 y="343.37366"
184 x="167.44673"
185 height="26.33428"
186 width="43.158947"
187 id="rect3101-3-62"
188 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
189 <rect
190 y="343.37366"
191 x="297.91437"
192 height="26.33428"
193 width="43.158947"
194 id="rect3101-3-6-9"
195 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
196 <rect
197 y="343.37366"
198 x="254.42516"
199 height="26.33428"
200 width="43.158947"
201 id="rect3101-3-6-7-1"
202 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
203 <rect
204 y="343.37366"
205 x="210.93593"
206 height="26.33428"
207 width="43.158947"
208 id="rect3101-3-6-7-5-2"
209 style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
210 <text
211 xml:space="preserve"
212 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
213 x="146.00092"
214 y="360.25174"
215 id="text3013"
216 sodipodi:linespacing="125%"><tspan
217 sodipodi:role="line"
218 id="tspan3015"
219 x="146.00092"
220 y="360.25174"
221 style="font-size:10px">:4</tspan></text>
222 </g>
223 <g
224 id="g3019"
225 transform="translate(260.06223,0)">
226 <rect
227 y="343.37366"
228 x="123.95757"
229 height="26.33428"
230 width="43.158947"
231 id="rect3101-35-0"
232 style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
233 <rect
234 y="343.37366"
235 x="167.44673"
236 height="26.33428"
237 width="43.158947"
238 id="rect3101-3-62-9"
239 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
240 <rect
241 y="343.37366"
242 x="297.91437"
243 height="26.33428"
244 width="43.158947"
245 id="rect3101-3-6-9-3"
246 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
247 <rect
248 y="343.37366"
249 x="254.42516"
250 height="26.33428"
251 width="43.158947"
252 id="rect3101-3-6-7-1-6"
253 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
254 <rect
255 y="343.37366"
256 x="210.93593"
257 height="26.33428"
258 width="43.158947"
259 id="rect3101-3-6-7-5-2-0"
260 style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
261 <text
262 xml:space="preserve"
263 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
264 x="145.54926"
265 y="360.25174"
266 id="text3013-3"
267 sodipodi:linespacing="125%"><tspan
268 sodipodi:role="line"
269 id="tspan3015-6"
270 x="145.54926"
271 y="360.25174"
272 style="font-size:10px">:6</tspan></text>
273 </g>
274 <text
275 xml:space="preserve"
276 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
277 x="275.59558"
278 y="291.95297"
279 id="text3013-36"
280 sodipodi:linespacing="125%"><tspan
281 sodipodi:role="line"
282 id="tspan3015-7"
283 x="275.59558"
284 y="291.95297"
285 style="font-size:10px">:6</tspan></text>
286 <text
287 xml:space="preserve"
288 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
289 x="405.40396"
290 y="291.88705"
291 id="text3013-3-36-3"
292 sodipodi:linespacing="125%"><tspan
293 sodipodi:role="line"
294 id="tspan3015-6-7-6"
295 x="405.40396"
296 y="291.88705"
297 style="font-size:10px">F</tspan></text>
298 <text
299 xml:space="preserve"
300 style="font-size:20px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
301 x="449.22031"
302 y="291.88217"
303 id="text3013-3-36-3-3"
304 sodipodi:linespacing="125%"><tspan
305 sodipodi:role="line"
306 id="tspan3015-6-7-6-6"
307 x="449.22031"
308 y="291.88217"
309 style="font-size:10px">G</tspan></text>
310 </g>
311</svg>
diff --git a/Documentation/RCU/Design/Requirements/Requirements.html b/Documentation/RCU/Design/Requirements/Requirements.html
index 39bcb74ea733..21593496aca6 100644
--- a/Documentation/RCU/Design/Requirements/Requirements.html
+++ b/Documentation/RCU/Design/Requirements/Requirements.html
@@ -1480,7 +1480,7 @@ speed-of-light delays if nothing else.
1480 1480
1481<p> 1481<p>
1482Furthermore, uncertainty about external state is inherent in many cases. 1482Furthermore, uncertainty about external state is inherent in many cases.
1483For example, a pair of veternarians might use heartbeat to determine 1483For example, a pair of veterinarians might use heartbeat to determine
1484whether or not a given cat was alive. 1484whether or not a given cat was alive.
1485But how long should they wait after the last heartbeat to decide that 1485But how long should they wait after the last heartbeat to decide that
1486the cat is in fact dead? 1486the cat is in fact dead?
@@ -1489,9 +1489,9 @@ mean that a relaxed cat would be considered to cycle between death
1489and life more than 100 times per minute. 1489and life more than 100 times per minute.
1490Moreover, just as with human beings, a cat's heart might stop for 1490Moreover, just as with human beings, a cat's heart might stop for
1491some period of time, so the exact wait period is a judgment call. 1491some period of time, so the exact wait period is a judgment call.
1492One of our pair of veternarians might wait 30 seconds before pronouncing 1492One of our pair of veterinarians might wait 30 seconds before pronouncing
1493the cat dead, while the other might insist on waiting a full minute. 1493the cat dead, while the other might insist on waiting a full minute.
1494The two veternarians would then disagree on the state of the cat during 1494The two veterinarians would then disagree on the state of the cat during
1495the final 30 seconds of the minute following the last heartbeat. 1495the final 30 seconds of the minute following the last heartbeat.
1496 1496
1497<p> 1497<p>
@@ -1945,7 +1945,7 @@ guard against mishaps and misuse:
1945<ol> 1945<ol>
1946<li> It is all too easy to forget to use <tt>rcu_read_lock()</tt> 1946<li> It is all too easy to forget to use <tt>rcu_read_lock()</tt>
1947 everywhere that it is needed, so kernels built with 1947 everywhere that it is needed, so kernels built with
1948 <tt>CONFIG_PROVE_RCU=y</tt> will spat if 1948 <tt>CONFIG_PROVE_RCU=y</tt> will splat if
1949 <tt>rcu_dereference()</tt> is used outside of an 1949 <tt>rcu_dereference()</tt> is used outside of an
1950 RCU read-side critical section. 1950 RCU read-side critical section.
1951 Update-side code can use <tt>rcu_dereference_protected()</tt>, 1951 Update-side code can use <tt>rcu_dereference_protected()</tt>,
@@ -2421,7 +2421,7 @@ However, there are some restrictions on the code placed within
2421<li> Blocking is prohibited. 2421<li> Blocking is prohibited.
2422 In practice, this is not a serious restriction given that idle 2422 In practice, this is not a serious restriction given that idle
2423 tasks are prohibited from blocking to begin with. 2423 tasks are prohibited from blocking to begin with.
2424<li> Although nesting <tt>RCU_NONIDLE()</tt> is permited, they cannot 2424<li> Although nesting <tt>RCU_NONIDLE()</tt> is permitted, they cannot
2425 nest indefinitely deeply. 2425 nest indefinitely deeply.
2426 However, given that they can be nested on the order of a million 2426 However, given that they can be nested on the order of a million
2427 deep, even on 32-bit systems, this should not be a serious 2427 deep, even on 32-bit systems, this should not be a serious
@@ -2885,7 +2885,7 @@ APIs for defining and initializing <tt>srcu_struct</tt> structures.
2885<h3><a name="Tasks RCU">Tasks RCU</a></h3> 2885<h3><a name="Tasks RCU">Tasks RCU</a></h3>
2886 2886
2887<p> 2887<p>
2888Some forms of tracing use &ldquo;tramopolines&rdquo; to handle the 2888Some forms of tracing use &ldquo;trampolines&rdquo; to handle the
2889binary rewriting required to install different types of probes. 2889binary rewriting required to install different types of probes.
2890It would be good to be able to free old trampolines, which sounds 2890It would be good to be able to free old trampolines, which sounds
2891like a job for some form of RCU. 2891like a job for some form of RCU.
diff --git a/Documentation/RCU/trace.txt b/Documentation/RCU/trace.txt
index 00a3a38b375a..6549012033f9 100644
--- a/Documentation/RCU/trace.txt
+++ b/Documentation/RCU/trace.txt
@@ -237,7 +237,7 @@ o "ktl" is the low-order 16 bits (in hexadecimal) of the count of
237 237
238The output of "cat rcu/rcu_preempt/rcuexp" looks as follows: 238The output of "cat rcu/rcu_preempt/rcuexp" looks as follows:
239 239
240s=21872 wd1=0 wd2=0 wd3=5 n=0 enq=0 sc=21872 240s=21872 wd1=0 wd2=0 wd3=5 enq=0 sc=21872
241 241
242These fields are as follows: 242These fields are as follows:
243 243
@@ -249,9 +249,6 @@ o "wd1", "wd2", and "wd3" are the number of times that an attempt
249 completed an expedited grace period that satisfies the attempted 249 completed an expedited grace period that satisfies the attempted
250 request. "Our work is done." 250 request. "Our work is done."
251 251
252o "n" is number of times that a concurrent CPU-hotplug operation
253 forced a fallback to a normal grace period.
254
255o "enq" is the number of quiescent states still outstanding. 252o "enq" is the number of quiescent states still outstanding.
256 253
257o "sc" is the number of times that the attempt to start a 254o "sc" is the number of times that the attempt to start a
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index be7c0d9506b1..110745e7d61f 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3278,6 +3278,13 @@
3278 Lazy RCU callbacks are those which RCU can 3278 Lazy RCU callbacks are those which RCU can
3279 prove do nothing more than free memory. 3279 prove do nothing more than free memory.
3280 3280
3281 rcutree.rcu_kick_kthreads= [KNL]
3282 Cause the grace-period kthread to get an extra
3283 wake_up() if it sleeps three times longer than
3284 it should at force-quiescent-state time.
3285 This wake_up() will be accompanied by a
3286 WARN_ONCE() splat and an ftrace_dump().
3287
3281 rcuperf.gp_exp= [KNL] 3288 rcuperf.gp_exp= [KNL]
3282 Measure performance of expedited synchronous 3289 Measure performance of expedited synchronous
3283 grace-period primitives. 3290 grace-period primitives.
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
index ba818ecce6f9..d2b0a8d81258 100644
--- a/Documentation/memory-barriers.txt
+++ b/Documentation/memory-barriers.txt
@@ -640,6 +640,10 @@ See also the subsection on "Cache Coherency" for a more thorough example.
640CONTROL DEPENDENCIES 640CONTROL DEPENDENCIES
641-------------------- 641--------------------
642 642
643Control dependencies can be a bit tricky because current compilers do
644not understand them. The purpose of this section is to help you prevent
645the compiler's ignorance from breaking your code.
646
643A load-load control dependency requires a full read memory barrier, not 647A load-load control dependency requires a full read memory barrier, not
644simply a data dependency barrier to make it work correctly. Consider the 648simply a data dependency barrier to make it work correctly. Consider the
645following bit of code: 649following bit of code:
@@ -667,14 +671,15 @@ for load-store control dependencies, as in the following example:
667 671
668 q = READ_ONCE(a); 672 q = READ_ONCE(a);
669 if (q) { 673 if (q) {
670 WRITE_ONCE(b, p); 674 WRITE_ONCE(b, 1);
671 } 675 }
672 676
673Control dependencies pair normally with other types of barriers. That 677Control dependencies pair normally with other types of barriers.
674said, please note that READ_ONCE() is not optional! Without the 678That said, please note that neither READ_ONCE() nor WRITE_ONCE()
675READ_ONCE(), the compiler might combine the load from 'a' with other 679are optional! Without the READ_ONCE(), the compiler might combine the
676loads from 'a', and the store to 'b' with other stores to 'b', with 680load from 'a' with other loads from 'a'. Without the WRITE_ONCE(),
677possible highly counterintuitive effects on ordering. 681the compiler might combine the store to 'b' with other stores to 'b'.
682Either can result in highly counterintuitive effects on ordering.
678 683
679Worse yet, if the compiler is able to prove (say) that the value of 684Worse yet, if the compiler is able to prove (say) that the value of
680variable 'a' is always non-zero, it would be well within its rights 685variable 'a' is always non-zero, it would be well within its rights
@@ -682,7 +687,7 @@ to optimize the original example by eliminating the "if" statement
682as follows: 687as follows:
683 688
684 q = a; 689 q = a;
685 b = p; /* BUG: Compiler and CPU can both reorder!!! */ 690 b = 1; /* BUG: Compiler and CPU can both reorder!!! */
686 691
687So don't leave out the READ_ONCE(). 692So don't leave out the READ_ONCE().
688 693
@@ -692,11 +697,11 @@ branches of the "if" statement as follows:
692 q = READ_ONCE(a); 697 q = READ_ONCE(a);
693 if (q) { 698 if (q) {
694 barrier(); 699 barrier();
695 WRITE_ONCE(b, p); 700 WRITE_ONCE(b, 1);
696 do_something(); 701 do_something();
697 } else { 702 } else {
698 barrier(); 703 barrier();
699 WRITE_ONCE(b, p); 704 WRITE_ONCE(b, 1);
700 do_something_else(); 705 do_something_else();
701 } 706 }
702 707
@@ -705,12 +710,12 @@ optimization levels:
705 710
706 q = READ_ONCE(a); 711 q = READ_ONCE(a);
707 barrier(); 712 barrier();
708 WRITE_ONCE(b, p); /* BUG: No ordering vs. load from a!!! */ 713 WRITE_ONCE(b, 1); /* BUG: No ordering vs. load from a!!! */
709 if (q) { 714 if (q) {
710 /* WRITE_ONCE(b, p); -- moved up, BUG!!! */ 715 /* WRITE_ONCE(b, 1); -- moved up, BUG!!! */
711 do_something(); 716 do_something();
712 } else { 717 } else {
713 /* WRITE_ONCE(b, p); -- moved up, BUG!!! */ 718 /* WRITE_ONCE(b, 1); -- moved up, BUG!!! */
714 do_something_else(); 719 do_something_else();
715 } 720 }
716 721
@@ -723,10 +728,10 @@ memory barriers, for example, smp_store_release():
723 728
724 q = READ_ONCE(a); 729 q = READ_ONCE(a);
725 if (q) { 730 if (q) {
726 smp_store_release(&b, p); 731 smp_store_release(&b, 1);
727 do_something(); 732 do_something();
728 } else { 733 } else {
729 smp_store_release(&b, p); 734 smp_store_release(&b, 1);
730 do_something_else(); 735 do_something_else();
731 } 736 }
732 737
@@ -735,10 +740,10 @@ ordering is guaranteed only when the stores differ, for example:
735 740
736 q = READ_ONCE(a); 741 q = READ_ONCE(a);
737 if (q) { 742 if (q) {
738 WRITE_ONCE(b, p); 743 WRITE_ONCE(b, 1);
739 do_something(); 744 do_something();
740 } else { 745 } else {
741 WRITE_ONCE(b, r); 746 WRITE_ONCE(b, 2);
742 do_something_else(); 747 do_something_else();
743 } 748 }
744 749
@@ -751,10 +756,10 @@ the needed conditional. For example:
751 756
752 q = READ_ONCE(a); 757 q = READ_ONCE(a);
753 if (q % MAX) { 758 if (q % MAX) {
754 WRITE_ONCE(b, p); 759 WRITE_ONCE(b, 1);
755 do_something(); 760 do_something();
756 } else { 761 } else {
757 WRITE_ONCE(b, r); 762 WRITE_ONCE(b, 2);
758 do_something_else(); 763 do_something_else();
759 } 764 }
760 765
@@ -763,7 +768,7 @@ equal to zero, in which case the compiler is within its rights to
763transform the above code into the following: 768transform the above code into the following:
764 769
765 q = READ_ONCE(a); 770 q = READ_ONCE(a);
766 WRITE_ONCE(b, p); 771 WRITE_ONCE(b, 1);
767 do_something_else(); 772 do_something_else();
768 773
769Given this transformation, the CPU is not required to respect the ordering 774Given this transformation, the CPU is not required to respect the ordering
@@ -776,10 +781,10 @@ one, perhaps as follows:
776 q = READ_ONCE(a); 781 q = READ_ONCE(a);
777 BUILD_BUG_ON(MAX <= 1); /* Order load from a with store to b. */ 782 BUILD_BUG_ON(MAX <= 1); /* Order load from a with store to b. */
778 if (q % MAX) { 783 if (q % MAX) {
779 WRITE_ONCE(b, p); 784 WRITE_ONCE(b, 1);
780 do_something(); 785 do_something();
781 } else { 786 } else {
782 WRITE_ONCE(b, r); 787 WRITE_ONCE(b, 2);
783 do_something_else(); 788 do_something_else();
784 } 789 }
785 790
@@ -812,30 +817,28 @@ not necessarily apply to code following the if-statement:
812 817
813 q = READ_ONCE(a); 818 q = READ_ONCE(a);
814 if (q) { 819 if (q) {
815 WRITE_ONCE(b, p); 820 WRITE_ONCE(b, 1);
816 } else { 821 } else {
817 WRITE_ONCE(b, r); 822 WRITE_ONCE(b, 2);
818 } 823 }
819 WRITE_ONCE(c, 1); /* BUG: No ordering against the read from "a". */ 824 WRITE_ONCE(c, 1); /* BUG: No ordering against the read from 'a'. */
820 825
821It is tempting to argue that there in fact is ordering because the 826It is tempting to argue that there in fact is ordering because the
822compiler cannot reorder volatile accesses and also cannot reorder 827compiler cannot reorder volatile accesses and also cannot reorder
823the writes to "b" with the condition. Unfortunately for this line 828the writes to 'b' with the condition. Unfortunately for this line
824of reasoning, the compiler might compile the two writes to "b" as 829of reasoning, the compiler might compile the two writes to 'b' as
825conditional-move instructions, as in this fanciful pseudo-assembly 830conditional-move instructions, as in this fanciful pseudo-assembly
826language: 831language:
827 832
828 ld r1,a 833 ld r1,a
829 ld r2,p
830 ld r3,r
831 cmp r1,$0 834 cmp r1,$0
832 cmov,ne r4,r2 835 cmov,ne r4,$1
833 cmov,eq r4,r3 836 cmov,eq r4,$2
834 st r4,b 837 st r4,b
835 st $1,c 838 st $1,c
836 839
837A weakly ordered CPU would have no dependency of any sort between the load 840A weakly ordered CPU would have no dependency of any sort between the load
838from "a" and the store to "c". The control dependencies would extend 841from 'a' and the store to 'c'. The control dependencies would extend
839only to the pair of cmov instructions and the store depending on them. 842only to the pair of cmov instructions and the store depending on them.
840In short, control dependencies apply only to the stores in the then-clause 843In short, control dependencies apply only to the stores in the then-clause
841and else-clause of the if-statement in question (including functions 844and else-clause of the if-statement in question (including functions
@@ -843,7 +846,7 @@ invoked by those two clauses), not to code following that if-statement.
843 846
844Finally, control dependencies do -not- provide transitivity. This is 847Finally, control dependencies do -not- provide transitivity. This is
845demonstrated by two related examples, with the initial values of 848demonstrated by two related examples, with the initial values of
846x and y both being zero: 849'x' and 'y' both being zero:
847 850
848 CPU 0 CPU 1 851 CPU 0 CPU 1
849 ======================= ======================= 852 ======================= =======================
@@ -915,6 +918,9 @@ In summary:
915 (*) Control dependencies do -not- provide transitivity. If you 918 (*) Control dependencies do -not- provide transitivity. If you
916 need transitivity, use smp_mb(). 919 need transitivity, use smp_mb().
917 920
921 (*) Compilers do not understand control dependencies. It is therefore
922 your job to ensure that they do not break your code.
923
918 924
919SMP BARRIER PAIRING 925SMP BARRIER PAIRING
920------------------- 926-------------------
diff --git a/include/linux/llist.h b/include/linux/llist.h
index fd4ca0b4fe0f..171baa90f6f6 100644
--- a/include/linux/llist.h
+++ b/include/linux/llist.h
@@ -3,28 +3,33 @@
3/* 3/*
4 * Lock-less NULL terminated single linked list 4 * Lock-less NULL terminated single linked list
5 * 5 *
6 * If there are multiple producers and multiple consumers, llist_add 6 * Cases where locking is not needed:
7 * can be used in producers and llist_del_all can be used in 7 * If there are multiple producers and multiple consumers, llist_add can be
8 * consumers. They can work simultaneously without lock. But 8 * used in producers and llist_del_all can be used in consumers simultaneously
9 * llist_del_first can not be used here. Because llist_del_first 9 * without locking. Also a single consumer can use llist_del_first while
10 * depends on list->first->next does not changed if list->first is not 10 * multiple producers simultaneously use llist_add, without any locking.
11 * changed during its operation, but llist_del_first, llist_add, 11 *
12 * llist_add (or llist_del_all, llist_add, llist_add) sequence in 12 * Cases where locking is needed:
13 * another consumer may violate that. 13 * If we have multiple consumers with llist_del_first used in one consumer, and
14 * 14 * llist_del_first or llist_del_all used in other consumers, then a lock is
15 * If there are multiple producers and one consumer, llist_add can be 15 * needed. This is because llist_del_first depends on list->first->next not
16 * used in producers and llist_del_all or llist_del_first can be used 16 * changing, but without lock protection, there's no way to be sure about that
17 * in the consumer. 17 * if a preemption happens in the middle of the delete operation and on being
18 * 18 * preempted back, the list->first is the same as before causing the cmpxchg in
19 * This can be summarized as follow: 19 * llist_del_first to succeed. For example, while a llist_del_first operation
20 * is in progress in one consumer, then a llist_del_first, llist_add,
21 * llist_add (or llist_del_all, llist_add, llist_add) sequence in another
22 * consumer may cause violations.
23 *
24 * This can be summarized as follows:
20 * 25 *
21 * | add | del_first | del_all 26 * | add | del_first | del_all
22 * add | - | - | - 27 * add | - | - | -
23 * del_first | | L | L 28 * del_first | | L | L
24 * del_all | | | - 29 * del_all | | | -
25 * 30 *
26 * Where "-" stands for no lock is needed, while "L" stands for lock 31 * Where, a particular row's operation can happen concurrently with a column's
27 * is needed. 32 * operation, with "-" being no lock needed, while "L" being lock is needed.
28 * 33 *
29 * The list entries deleted via llist_del_all can be traversed with 34 * The list entries deleted via llist_del_all can be traversed with
30 * traversing function such as llist_for_each etc. But the list 35 * traversing function such as llist_for_each etc. But the list
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 01f71e1d2e94..6ade6a52d9d4 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -1161,5 +1161,17 @@ do { \
1161 ftrace_dump(oops_dump_mode); \ 1161 ftrace_dump(oops_dump_mode); \
1162} while (0) 1162} while (0)
1163 1163
1164/*
1165 * Place this after a lock-acquisition primitive to guarantee that
1166 * an UNLOCK+LOCK pair acts as a full barrier. This guarantee applies
1167 * if the UNLOCK and LOCK are executed by the same CPU or if the
1168 * UNLOCK and LOCK operate on the same lock variable.
1169 */
1170#ifdef CONFIG_PPC
1171#define smp_mb__after_unlock_lock() smp_mb() /* Full ordering for lock. */
1172#else /* #ifdef CONFIG_PPC */
1173#define smp_mb__after_unlock_lock() do { } while (0)
1174#endif /* #else #ifdef CONFIG_PPC */
1175
1164 1176
1165#endif /* __LINUX_RCUPDATE_H */ 1177#endif /* __LINUX_RCUPDATE_H */
diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h
index ac81e4063b40..4f9b2fa2173d 100644
--- a/include/linux/rcutiny.h
+++ b/include/linux/rcutiny.h
@@ -27,6 +27,12 @@
27 27
28#include <linux/cache.h> 28#include <linux/cache.h>
29 29
30struct rcu_dynticks;
31static inline int rcu_dynticks_snap(struct rcu_dynticks *rdtp)
32{
33 return 0;
34}
35
30static inline unsigned long get_state_synchronize_rcu(void) 36static inline unsigned long get_state_synchronize_rcu(void)
31{ 37{
32 return 0; 38 return 0;
diff --git a/include/linux/srcu.h b/include/linux/srcu.h
index dc8eb63c6568..a598cf3ac70c 100644
--- a/include/linux/srcu.h
+++ b/include/linux/srcu.h
@@ -33,9 +33,9 @@
33#include <linux/rcupdate.h> 33#include <linux/rcupdate.h>
34#include <linux/workqueue.h> 34#include <linux/workqueue.h>
35 35
36struct srcu_struct_array { 36struct srcu_array {
37 unsigned long c[2]; 37 unsigned long lock_count[2];
38 unsigned long seq[2]; 38 unsigned long unlock_count[2];
39}; 39};
40 40
41struct rcu_batch { 41struct rcu_batch {
@@ -46,7 +46,7 @@ struct rcu_batch {
46 46
47struct srcu_struct { 47struct srcu_struct {
48 unsigned long completed; 48 unsigned long completed;
49 struct srcu_struct_array __percpu *per_cpu_ref; 49 struct srcu_array __percpu *per_cpu_ref;
50 spinlock_t queue_lock; /* protect ->batch_queue, ->running */ 50 spinlock_t queue_lock; /* protect ->batch_queue, ->running */
51 bool running; 51 bool running;
52 /* callbacks just queued */ 52 /* callbacks just queued */
@@ -118,7 +118,7 @@ void process_srcu(struct work_struct *work);
118 * See include/linux/percpu-defs.h for the rules on per-CPU variables. 118 * See include/linux/percpu-defs.h for the rules on per-CPU variables.
119 */ 119 */
120#define __DEFINE_SRCU(name, is_static) \ 120#define __DEFINE_SRCU(name, is_static) \
121 static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\ 121 static DEFINE_PER_CPU(struct srcu_array, name##_srcu_array);\
122 is_static struct srcu_struct name = __SRCU_STRUCT_INIT(name) 122 is_static struct srcu_struct name = __SRCU_STRUCT_INIT(name)
123#define DEFINE_SRCU(name) __DEFINE_SRCU(name, /* not static */) 123#define DEFINE_SRCU(name) __DEFINE_SRCU(name, /* not static */)
124#define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static) 124#define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static)
diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h
index 9d4f9b3a2b7b..e3facb356838 100644
--- a/include/trace/events/rcu.h
+++ b/include/trace/events/rcu.h
@@ -385,11 +385,11 @@ TRACE_EVENT(rcu_quiescent_state_report,
385 385
386/* 386/*
387 * Tracepoint for quiescent states detected by force_quiescent_state(). 387 * Tracepoint for quiescent states detected by force_quiescent_state().
388 * These trace events include the type of RCU, the grace-period number 388 * These trace events include the type of RCU, the grace-period number that
389 * that was blocked by the CPU, the CPU itself, and the type of quiescent 389 * was blocked by the CPU, the CPU itself, and the type of quiescent state,
390 * state, which can be "dti" for dyntick-idle mode, "ofl" for CPU offline, 390 * which can be "dti" for dyntick-idle mode, "ofl" for CPU offline, "kick"
391 * or "kick" when kicking a CPU that has been in dyntick-idle mode for 391 * when kicking a CPU that has been in dyntick-idle mode for too long, or
392 * too long. 392 * "rqc" if the CPU got a quiescent state via its rcu_qs_ctr.
393 */ 393 */
394TRACE_EVENT(rcu_fqs, 394TRACE_EVENT(rcu_fqs,
395 395
diff --git a/init/Kconfig b/init/Kconfig
index e1a937348a3e..b40774578f29 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -529,7 +529,6 @@ config SRCU
529config TASKS_RCU 529config TASKS_RCU
530 bool 530 bool
531 default n 531 default n
532 depends on !UML
533 select SRCU 532 select SRCU
534 help 533 help
535 This option enables a task-based RCU implementation that uses 534 This option enables a task-based RCU implementation that uses
@@ -781,19 +780,6 @@ config RCU_NOCB_CPU_ALL
781 780
782endchoice 781endchoice
783 782
784config RCU_EXPEDITE_BOOT
785 bool
786 default n
787 help
788 This option enables expedited grace periods at boot time,
789 as if rcu_expedite_gp() had been invoked early in boot.
790 The corresponding rcu_unexpedite_gp() is invoked from
791 rcu_end_inkernel_boot(), which is intended to be invoked
792 at the end of the kernel-only boot sequence, just before
793 init is exec'ed.
794
795 Accept the default if unsure.
796
797endmenu # "RCU Subsystem" 783endmenu # "RCU Subsystem"
798 784
799config BUILD_BIN2C 785config BUILD_BIN2C
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 7c38f8f3d97b..d9a698e8458f 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -4412,13 +4412,13 @@ void lockdep_rcu_suspicious(const char *file, const int line, const char *s)
4412#endif /* #ifdef CONFIG_PROVE_RCU_REPEATEDLY */ 4412#endif /* #ifdef CONFIG_PROVE_RCU_REPEATEDLY */
4413 /* Note: the following can be executed concurrently, so be careful. */ 4413 /* Note: the following can be executed concurrently, so be careful. */
4414 printk("\n"); 4414 printk("\n");
4415 printk("===============================\n"); 4415 pr_err("===============================\n");
4416 printk("[ INFO: suspicious RCU usage. ]\n"); 4416 pr_err("[ ERR: suspicious RCU usage. ]\n");
4417 print_kernel_ident(); 4417 print_kernel_ident();
4418 printk("-------------------------------\n"); 4418 pr_err("-------------------------------\n");
4419 printk("%s:%d %s!\n", file, line, s); 4419 pr_err("%s:%d %s!\n", file, line, s);
4420 printk("\nother info that might help us debug this:\n\n"); 4420 pr_err("\nother info that might help us debug this:\n\n");
4421 printk("\n%srcu_scheduler_active = %d, debug_locks = %d\n", 4421 pr_err("\n%srcu_scheduler_active = %d, debug_locks = %d\n",
4422 !rcu_lockdep_current_cpu_online() 4422 !rcu_lockdep_current_cpu_online()
4423 ? "RCU used illegally from offline CPU!\n" 4423 ? "RCU used illegally from offline CPU!\n"
4424 : !rcu_is_watching() 4424 : !rcu_is_watching()
diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c
index f8c5af52a131..d3de04b12f8c 100644
--- a/kernel/locking/locktorture.c
+++ b/kernel/locking/locktorture.c
@@ -780,6 +780,10 @@ static void lock_torture_cleanup(void)
780 else 780 else
781 lock_torture_print_module_parms(cxt.cur_ops, 781 lock_torture_print_module_parms(cxt.cur_ops,
782 "End of test: SUCCESS"); 782 "End of test: SUCCESS");
783
784 kfree(cxt.lwsa);
785 kfree(cxt.lrsa);
786
783end: 787end:
784 torture_cleanup_end(); 788 torture_cleanup_end();
785} 789}
@@ -924,6 +928,8 @@ static int __init lock_torture_init(void)
924 GFP_KERNEL); 928 GFP_KERNEL);
925 if (reader_tasks == NULL) { 929 if (reader_tasks == NULL) {
926 VERBOSE_TOROUT_ERRSTRING("reader_tasks: Out of memory"); 930 VERBOSE_TOROUT_ERRSTRING("reader_tasks: Out of memory");
931 kfree(writer_tasks);
932 writer_tasks = NULL;
927 firsterr = -ENOMEM; 933 firsterr = -ENOMEM;
928 goto unwind; 934 goto unwind;
929 } 935 }
diff --git a/kernel/membarrier.c b/kernel/membarrier.c
index 536c727a56e9..9f9284f37f8d 100644
--- a/kernel/membarrier.c
+++ b/kernel/membarrier.c
@@ -16,6 +16,7 @@
16 16
17#include <linux/syscalls.h> 17#include <linux/syscalls.h>
18#include <linux/membarrier.h> 18#include <linux/membarrier.h>
19#include <linux/tick.h>
19 20
20/* 21/*
21 * Bitmask made from a "or" of all commands within enum membarrier_cmd, 22 * Bitmask made from a "or" of all commands within enum membarrier_cmd,
@@ -51,6 +52,9 @@
51 */ 52 */
52SYSCALL_DEFINE2(membarrier, int, cmd, int, flags) 53SYSCALL_DEFINE2(membarrier, int, cmd, int, flags)
53{ 54{
55 /* MEMBARRIER_CMD_SHARED is not compatible with nohz_full. */
56 if (tick_nohz_full_enabled())
57 return -ENOSYS;
54 if (unlikely(flags)) 58 if (unlikely(flags))
55 return -EINVAL; 59 return -EINVAL;
56 switch (cmd) { 60 switch (cmd) {
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index 87c51225ceec..d81345be730e 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -564,10 +564,25 @@ static void srcu_torture_stats(void)
564 pr_alert("%s%s per-CPU(idx=%d):", 564 pr_alert("%s%s per-CPU(idx=%d):",
565 torture_type, TORTURE_FLAG, idx); 565 torture_type, TORTURE_FLAG, idx);
566 for_each_possible_cpu(cpu) { 566 for_each_possible_cpu(cpu) {
567 unsigned long l0, l1;
568 unsigned long u0, u1;
567 long c0, c1; 569 long c0, c1;
570 struct srcu_array *counts = per_cpu_ptr(srcu_ctlp->per_cpu_ref, cpu);
568 571
569 c0 = (long)per_cpu_ptr(srcu_ctlp->per_cpu_ref, cpu)->c[!idx]; 572 u0 = counts->unlock_count[!idx];
570 c1 = (long)per_cpu_ptr(srcu_ctlp->per_cpu_ref, cpu)->c[idx]; 573 u1 = counts->unlock_count[idx];
574
575 /*
576 * Make sure that a lock is always counted if the corresponding
577 * unlock is counted.
578 */
579 smp_rmb();
580
581 l0 = counts->lock_count[!idx];
582 l1 = counts->lock_count[idx];
583
584 c0 = l0 - u0;
585 c1 = l1 - u1;
571 pr_cont(" %d(%ld,%ld)", cpu, c0, c1); 586 pr_cont(" %d(%ld,%ld)", cpu, c0, c1);
572 } 587 }
573 pr_cont("\n"); 588 pr_cont("\n");
diff --git a/kernel/rcu/srcu.c b/kernel/rcu/srcu.c
index 9b9cdd549caa..e773129c8b08 100644
--- a/kernel/rcu/srcu.c
+++ b/kernel/rcu/srcu.c
@@ -106,7 +106,7 @@ static int init_srcu_struct_fields(struct srcu_struct *sp)
106 rcu_batch_init(&sp->batch_check1); 106 rcu_batch_init(&sp->batch_check1);
107 rcu_batch_init(&sp->batch_done); 107 rcu_batch_init(&sp->batch_done);
108 INIT_DELAYED_WORK(&sp->work, process_srcu); 108 INIT_DELAYED_WORK(&sp->work, process_srcu);
109 sp->per_cpu_ref = alloc_percpu(struct srcu_struct_array); 109 sp->per_cpu_ref = alloc_percpu(struct srcu_array);
110 return sp->per_cpu_ref ? 0 : -ENOMEM; 110 return sp->per_cpu_ref ? 0 : -ENOMEM;
111} 111}
112 112
@@ -141,114 +141,77 @@ EXPORT_SYMBOL_GPL(init_srcu_struct);
141#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ 141#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
142 142
143/* 143/*
144 * Returns approximate total of the readers' ->seq[] values for the 144 * Returns approximate total of the readers' ->lock_count[] values for the
145 * rank of per-CPU counters specified by idx. 145 * rank of per-CPU counters specified by idx.
146 */ 146 */
147static unsigned long srcu_readers_seq_idx(struct srcu_struct *sp, int idx) 147static unsigned long srcu_readers_lock_idx(struct srcu_struct *sp, int idx)
148{ 148{
149 int cpu; 149 int cpu;
150 unsigned long sum = 0; 150 unsigned long sum = 0;
151 unsigned long t;
152 151
153 for_each_possible_cpu(cpu) { 152 for_each_possible_cpu(cpu) {
154 t = READ_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->seq[idx]); 153 struct srcu_array *cpuc = per_cpu_ptr(sp->per_cpu_ref, cpu);
155 sum += t; 154
155 sum += READ_ONCE(cpuc->lock_count[idx]);
156 } 156 }
157 return sum; 157 return sum;
158} 158}
159 159
160/* 160/*
161 * Returns approximate number of readers active on the specified rank 161 * Returns approximate total of the readers' ->unlock_count[] values for the
162 * of the per-CPU ->c[] counters. 162 * rank of per-CPU counters specified by idx.
163 */ 163 */
164static unsigned long srcu_readers_active_idx(struct srcu_struct *sp, int idx) 164static unsigned long srcu_readers_unlock_idx(struct srcu_struct *sp, int idx)
165{ 165{
166 int cpu; 166 int cpu;
167 unsigned long sum = 0; 167 unsigned long sum = 0;
168 unsigned long t;
169 168
170 for_each_possible_cpu(cpu) { 169 for_each_possible_cpu(cpu) {
171 t = READ_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[idx]); 170 struct srcu_array *cpuc = per_cpu_ptr(sp->per_cpu_ref, cpu);
172 sum += t; 171
172 sum += READ_ONCE(cpuc->unlock_count[idx]);
173 } 173 }
174 return sum; 174 return sum;
175} 175}
176 176
177/* 177/*
178 * Return true if the number of pre-existing readers is determined to 178 * Return true if the number of pre-existing readers is determined to
179 * be stably zero. An example unstable zero can occur if the call 179 * be zero.
180 * to srcu_readers_active_idx() misses an __srcu_read_lock() increment,
181 * but due to task migration, sees the corresponding __srcu_read_unlock()
182 * decrement. This can happen because srcu_readers_active_idx() takes
183 * time to sum the array, and might in fact be interrupted or preempted
184 * partway through the summation.
185 */ 180 */
186static bool srcu_readers_active_idx_check(struct srcu_struct *sp, int idx) 181static bool srcu_readers_active_idx_check(struct srcu_struct *sp, int idx)
187{ 182{
188 unsigned long seq; 183 unsigned long unlocks;
189 184
190 seq = srcu_readers_seq_idx(sp, idx); 185 unlocks = srcu_readers_unlock_idx(sp, idx);
191 186
192 /* 187 /*
193 * The following smp_mb() A pairs with the smp_mb() B located in 188 * Make sure that a lock is always counted if the corresponding unlock
194 * __srcu_read_lock(). This pairing ensures that if an 189 * is counted. Needs to be a smp_mb() as the read side may contain a
195 * __srcu_read_lock() increments its counter after the summation 190 * read from a variable that is written to before the synchronize_srcu()
196 * in srcu_readers_active_idx(), then the corresponding SRCU read-side 191 * in the write side. In this case smp_mb()s A and B act like the store
197 * critical section will see any changes made prior to the start 192 * buffering pattern.
198 * of the current SRCU grace period.
199 * 193 *
200 * Also, if the above call to srcu_readers_seq_idx() saw the 194 * This smp_mb() also pairs with smp_mb() C to prevent accesses after the
201 * increment of ->seq[], then the call to srcu_readers_active_idx() 195 * synchronize_srcu() from being executed before the grace period ends.
202 * must see the increment of ->c[].
203 */ 196 */
204 smp_mb(); /* A */ 197 smp_mb(); /* A */
205 198
206 /* 199 /*
207 * Note that srcu_readers_active_idx() can incorrectly return 200 * If the locks are the same as the unlocks, then there must have
208 * zero even though there is a pre-existing reader throughout. 201 * been no readers on this index at some time in between. This does not
209 * To see this, suppose that task A is in a very long SRCU 202 * mean that there are no more readers, as one could have read the
210 * read-side critical section that started on CPU 0, and that 203 * current index but not have incremented the lock counter yet.
211 * no other reader exists, so that the sum of the counters
212 * is equal to one. Then suppose that task B starts executing
213 * srcu_readers_active_idx(), summing up to CPU 1, and then that
214 * task C starts reading on CPU 0, so that its increment is not
215 * summed, but finishes reading on CPU 2, so that its decrement
216 * -is- summed. Then when task B completes its sum, it will
217 * incorrectly get zero, despite the fact that task A has been
218 * in its SRCU read-side critical section the whole time.
219 *
220 * We therefore do a validation step should srcu_readers_active_idx()
221 * return zero.
222 */
223 if (srcu_readers_active_idx(sp, idx) != 0)
224 return false;
225
226 /*
227 * The remainder of this function is the validation step.
228 * The following smp_mb() D pairs with the smp_mb() C in
229 * __srcu_read_unlock(). If the __srcu_read_unlock() was seen
230 * by srcu_readers_active_idx() above, then any destructive
231 * operation performed after the grace period will happen after
232 * the corresponding SRCU read-side critical section.
233 * 204 *
234 * Note that there can be at most NR_CPUS worth of readers using 205 * Possible bug: There is no guarantee that there haven't been ULONG_MAX
235 * the old index, which is not enough to overflow even a 32-bit 206 * increments of ->lock_count[] since the unlocks were counted, meaning
236 * integer. (Yes, this does mean that systems having more than 207 * that this could return true even if there are still active readers.
237 * a billion or so CPUs need to be 64-bit systems.) Therefore, 208 * Since there are no memory barriers around srcu_flip(), the CPU is not
238 * the sum of the ->seq[] counters cannot possibly overflow. 209 * required to increment ->completed before running
239 * Therefore, the only way that the return values of the two 210 * srcu_readers_unlock_idx(), which means that there could be an
240 * calls to srcu_readers_seq_idx() can be equal is if there were 211 * arbitrarily large number of critical sections that execute after
241 * no increments of the corresponding rank of ->seq[] counts 212 * srcu_readers_unlock_idx() but use the old value of ->completed.
242 * in the interim. But the missed-increment scenario laid out
243 * above includes an increment of the ->seq[] counter by
244 * the corresponding __srcu_read_lock(). Therefore, if this
245 * scenario occurs, the return values from the two calls to
246 * srcu_readers_seq_idx() will differ, and thus the validation
247 * step below suffices.
248 */ 213 */
249 smp_mb(); /* D */ 214 return srcu_readers_lock_idx(sp, idx) == unlocks;
250
251 return srcu_readers_seq_idx(sp, idx) == seq;
252} 215}
253 216
254/** 217/**
@@ -266,8 +229,12 @@ static bool srcu_readers_active(struct srcu_struct *sp)
266 unsigned long sum = 0; 229 unsigned long sum = 0;
267 230
268 for_each_possible_cpu(cpu) { 231 for_each_possible_cpu(cpu) {
269 sum += READ_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[0]); 232 struct srcu_array *cpuc = per_cpu_ptr(sp->per_cpu_ref, cpu);
270 sum += READ_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[1]); 233
234 sum += READ_ONCE(cpuc->lock_count[0]);
235 sum += READ_ONCE(cpuc->lock_count[1]);
236 sum -= READ_ONCE(cpuc->unlock_count[0]);
237 sum -= READ_ONCE(cpuc->unlock_count[1]);
271 } 238 }
272 return sum; 239 return sum;
273} 240}
@@ -298,9 +265,8 @@ int __srcu_read_lock(struct srcu_struct *sp)
298 int idx; 265 int idx;
299 266
300 idx = READ_ONCE(sp->completed) & 0x1; 267 idx = READ_ONCE(sp->completed) & 0x1;
301 __this_cpu_inc(sp->per_cpu_ref->c[idx]); 268 __this_cpu_inc(sp->per_cpu_ref->lock_count[idx]);
302 smp_mb(); /* B */ /* Avoid leaking the critical section. */ 269 smp_mb(); /* B */ /* Avoid leaking the critical section. */
303 __this_cpu_inc(sp->per_cpu_ref->seq[idx]);
304 return idx; 270 return idx;
305} 271}
306EXPORT_SYMBOL_GPL(__srcu_read_lock); 272EXPORT_SYMBOL_GPL(__srcu_read_lock);
@@ -314,7 +280,7 @@ EXPORT_SYMBOL_GPL(__srcu_read_lock);
314void __srcu_read_unlock(struct srcu_struct *sp, int idx) 280void __srcu_read_unlock(struct srcu_struct *sp, int idx)
315{ 281{
316 smp_mb(); /* C */ /* Avoid leaking the critical section. */ 282 smp_mb(); /* C */ /* Avoid leaking the critical section. */
317 this_cpu_dec(sp->per_cpu_ref->c[idx]); 283 this_cpu_inc(sp->per_cpu_ref->unlock_count[idx]);
318} 284}
319EXPORT_SYMBOL_GPL(__srcu_read_unlock); 285EXPORT_SYMBOL_GPL(__srcu_read_unlock);
320 286
@@ -349,12 +315,21 @@ static bool try_check_zero(struct srcu_struct *sp, int idx, int trycount)
349 315
350/* 316/*
351 * Increment the ->completed counter so that future SRCU readers will 317 * Increment the ->completed counter so that future SRCU readers will
352 * use the other rank of the ->c[] and ->seq[] arrays. This allows 318 * use the other rank of the ->(un)lock_count[] arrays. This allows
353 * us to wait for pre-existing readers in a starvation-free manner. 319 * us to wait for pre-existing readers in a starvation-free manner.
354 */ 320 */
355static void srcu_flip(struct srcu_struct *sp) 321static void srcu_flip(struct srcu_struct *sp)
356{ 322{
357 sp->completed++; 323 WRITE_ONCE(sp->completed, sp->completed + 1);
324
325 /*
326 * Ensure that if the updater misses an __srcu_read_unlock()
327 * increment, that task's next __srcu_read_lock() will see the
328 * above counter update. Note that both this memory barrier
329 * and the one in srcu_readers_active_idx_check() provide the
330 * guarantee for __srcu_read_lock().
331 */
332 smp_mb(); /* D */ /* Pairs with C. */
358} 333}
359 334
360/* 335/*
@@ -392,6 +367,7 @@ void call_srcu(struct srcu_struct *sp, struct rcu_head *head,
392 head->next = NULL; 367 head->next = NULL;
393 head->func = func; 368 head->func = func;
394 spin_lock_irqsave(&sp->queue_lock, flags); 369 spin_lock_irqsave(&sp->queue_lock, flags);
370 smp_mb__after_unlock_lock(); /* Caller's prior accesses before GP. */
395 rcu_batch_queue(&sp->batch_queue, head); 371 rcu_batch_queue(&sp->batch_queue, head);
396 if (!sp->running) { 372 if (!sp->running) {
397 sp->running = true; 373 sp->running = true;
@@ -425,6 +401,7 @@ static void __synchronize_srcu(struct srcu_struct *sp, int trycount)
425 head->next = NULL; 401 head->next = NULL;
426 head->func = wakeme_after_rcu; 402 head->func = wakeme_after_rcu;
427 spin_lock_irq(&sp->queue_lock); 403 spin_lock_irq(&sp->queue_lock);
404 smp_mb__after_unlock_lock(); /* Caller's prior accesses before GP. */
428 if (!sp->running) { 405 if (!sp->running) {
429 /* steal the processing owner */ 406 /* steal the processing owner */
430 sp->running = true; 407 sp->running = true;
@@ -444,8 +421,11 @@ static void __synchronize_srcu(struct srcu_struct *sp, int trycount)
444 spin_unlock_irq(&sp->queue_lock); 421 spin_unlock_irq(&sp->queue_lock);
445 } 422 }
446 423
447 if (!done) 424 if (!done) {
448 wait_for_completion(&rcu.completion); 425 wait_for_completion(&rcu.completion);
426 smp_mb(); /* Caller's later accesses after GP. */
427 }
428
449} 429}
450 430
451/** 431/**
@@ -613,7 +593,8 @@ static void srcu_advance_batches(struct srcu_struct *sp, int trycount)
613/* 593/*
614 * Invoke a limited number of SRCU callbacks that have passed through 594 * Invoke a limited number of SRCU callbacks that have passed through
615 * their grace period. If there are more to do, SRCU will reschedule 595 * their grace period. If there are more to do, SRCU will reschedule
616 * the workqueue. 596 * the workqueue. Note that needed memory barriers have been executed
597 * in this task's context by srcu_readers_active_idx_check().
617 */ 598 */
618static void srcu_invoke_callbacks(struct srcu_struct *sp) 599static void srcu_invoke_callbacks(struct srcu_struct *sp)
619{ 600{
diff --git a/kernel/rcu/tiny.c b/kernel/rcu/tiny.c
index b23a4d076f3d..fa6a48d3917b 100644
--- a/kernel/rcu/tiny.c
+++ b/kernel/rcu/tiny.c
@@ -41,8 +41,6 @@
41 41
42/* Forward declarations for tiny_plugin.h. */ 42/* Forward declarations for tiny_plugin.h. */
43struct rcu_ctrlblk; 43struct rcu_ctrlblk;
44static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp);
45static void rcu_process_callbacks(struct softirq_action *unused);
46static void __call_rcu(struct rcu_head *head, 44static void __call_rcu(struct rcu_head *head,
47 rcu_callback_t func, 45 rcu_callback_t func,
48 struct rcu_ctrlblk *rcp); 46 struct rcu_ctrlblk *rcp);
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index cb4e2056ccf3..d80e0d2f68c6 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -281,6 +281,116 @@ static DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = {
281#endif /* #ifdef CONFIG_NO_HZ_FULL_SYSIDLE */ 281#endif /* #ifdef CONFIG_NO_HZ_FULL_SYSIDLE */
282}; 282};
283 283
284/*
285 * Record entry into an extended quiescent state. This is only to be
286 * called when not already in an extended quiescent state.
287 */
288static void rcu_dynticks_eqs_enter(void)
289{
290 struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
291 int special;
292
293 /*
294 * CPUs seeing atomic_inc_return() must see prior RCU read-side
295 * critical sections, and we also must force ordering with the
296 * next idle sojourn.
297 */
298 special = atomic_inc_return(&rdtp->dynticks);
299 WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && special & 0x1);
300}
301
302/*
303 * Record exit from an extended quiescent state. This is only to be
304 * called from an extended quiescent state.
305 */
306static void rcu_dynticks_eqs_exit(void)
307{
308 struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
309 int special;
310
311 /*
312 * CPUs seeing atomic_inc_return() must see prior idle sojourns,
313 * and we also must force ordering with the next RCU read-side
314 * critical section.
315 */
316 special = atomic_inc_return(&rdtp->dynticks);
317 WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && !(special & 0x1));
318}
319
320/*
321 * Reset the current CPU's ->dynticks counter to indicate that the
322 * newly onlined CPU is no longer in an extended quiescent state.
323 * This will either leave the counter unchanged, or increment it
324 * to the next non-quiescent value.
325 *
326 * The non-atomic test/increment sequence works because the upper bits
327 * of the ->dynticks counter are manipulated only by the corresponding CPU,
328 * or when the corresponding CPU is offline.
329 */
330static void rcu_dynticks_eqs_online(void)
331{
332 struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
333
334 if (atomic_read(&rdtp->dynticks) & 0x1)
335 return;
336 atomic_add(0x1, &rdtp->dynticks);
337}
338
339/*
340 * Is the current CPU in an extended quiescent state?
341 *
342 * No ordering, as we are sampling CPU-local information.
343 */
344bool rcu_dynticks_curr_cpu_in_eqs(void)
345{
346 struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
347
348 return !(atomic_read(&rdtp->dynticks) & 0x1);
349}
350
351/*
352 * Snapshot the ->dynticks counter with full ordering so as to allow
353 * stable comparison of this counter with past and future snapshots.
354 */
355int rcu_dynticks_snap(struct rcu_dynticks *rdtp)
356{
357 int snap = atomic_add_return(0, &rdtp->dynticks);
358
359 return snap;
360}
361
362/*
363 * Return true if the snapshot returned from rcu_dynticks_snap()
364 * indicates that RCU is in an extended quiescent state.
365 */
366static bool rcu_dynticks_in_eqs(int snap)
367{
368 return !(snap & 0x1);
369}
370
371/*
372 * Return true if the CPU corresponding to the specified rcu_dynticks
373 * structure has spent some time in an extended quiescent state since
374 * rcu_dynticks_snap() returned the specified snapshot.
375 */
376static bool rcu_dynticks_in_eqs_since(struct rcu_dynticks *rdtp, int snap)
377{
378 return snap != rcu_dynticks_snap(rdtp);
379}
380
381/*
382 * Do a double-increment of the ->dynticks counter to emulate a
383 * momentary idle-CPU quiescent state.
384 */
385static void rcu_dynticks_momentary_idle(void)
386{
387 struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
388 int special = atomic_add_return(2, &rdtp->dynticks);
389
390 /* It is illegal to call this from idle state. */
391 WARN_ON_ONCE(!(special & 0x1));
392}
393
284DEFINE_PER_CPU_SHARED_ALIGNED(unsigned long, rcu_qs_ctr); 394DEFINE_PER_CPU_SHARED_ALIGNED(unsigned long, rcu_qs_ctr);
285EXPORT_PER_CPU_SYMBOL_GPL(rcu_qs_ctr); 395EXPORT_PER_CPU_SYMBOL_GPL(rcu_qs_ctr);
286 396
@@ -300,7 +410,6 @@ EXPORT_PER_CPU_SYMBOL_GPL(rcu_qs_ctr);
300static void rcu_momentary_dyntick_idle(void) 410static void rcu_momentary_dyntick_idle(void)
301{ 411{
302 struct rcu_data *rdp; 412 struct rcu_data *rdp;
303 struct rcu_dynticks *rdtp;
304 int resched_mask; 413 int resched_mask;
305 struct rcu_state *rsp; 414 struct rcu_state *rsp;
306 415
@@ -327,10 +436,7 @@ static void rcu_momentary_dyntick_idle(void)
327 * quiescent state, with no need for this CPU to do anything 436 * quiescent state, with no need for this CPU to do anything
328 * further. 437 * further.
329 */ 438 */
330 rdtp = this_cpu_ptr(&rcu_dynticks); 439 rcu_dynticks_momentary_idle();
331 smp_mb__before_atomic(); /* Earlier stuff before QS. */
332 atomic_add(2, &rdtp->dynticks); /* QS. */
333 smp_mb__after_atomic(); /* Later stuff after QS. */
334 break; 440 break;
335 } 441 }
336} 442}
@@ -611,7 +717,7 @@ static int
611cpu_has_callbacks_ready_to_invoke(struct rcu_data *rdp) 717cpu_has_callbacks_ready_to_invoke(struct rcu_data *rdp)
612{ 718{
613 return &rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL] && 719 return &rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL] &&
614 rdp->nxttail[RCU_DONE_TAIL] != NULL; 720 rdp->nxttail[RCU_NEXT_TAIL] != NULL;
615} 721}
616 722
617/* 723/*
@@ -673,7 +779,7 @@ static void rcu_eqs_enter_common(long long oldval, bool user)
673{ 779{
674 struct rcu_state *rsp; 780 struct rcu_state *rsp;
675 struct rcu_data *rdp; 781 struct rcu_data *rdp;
676 struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks); 782 RCU_TRACE(struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);)
677 783
678 trace_rcu_dyntick(TPS("Start"), oldval, rdtp->dynticks_nesting); 784 trace_rcu_dyntick(TPS("Start"), oldval, rdtp->dynticks_nesting);
679 if (IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && 785 if (IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
@@ -692,12 +798,7 @@ static void rcu_eqs_enter_common(long long oldval, bool user)
692 do_nocb_deferred_wakeup(rdp); 798 do_nocb_deferred_wakeup(rdp);
693 } 799 }
694 rcu_prepare_for_idle(); 800 rcu_prepare_for_idle();
695 /* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */ 801 rcu_dynticks_eqs_enter();
696 smp_mb__before_atomic(); /* See above. */
697 atomic_inc(&rdtp->dynticks);
698 smp_mb__after_atomic(); /* Force ordering with next sojourn. */
699 WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
700 atomic_read(&rdtp->dynticks) & 0x1);
701 rcu_dynticks_task_enter(); 802 rcu_dynticks_task_enter();
702 803
703 /* 804 /*
@@ -826,15 +927,10 @@ void rcu_irq_exit_irqson(void)
826 */ 927 */
827static void rcu_eqs_exit_common(long long oldval, int user) 928static void rcu_eqs_exit_common(long long oldval, int user)
828{ 929{
829 struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks); 930 RCU_TRACE(struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);)
830 931
831 rcu_dynticks_task_exit(); 932 rcu_dynticks_task_exit();
832 smp_mb__before_atomic(); /* Force ordering w/previous sojourn. */ 933 rcu_dynticks_eqs_exit();
833 atomic_inc(&rdtp->dynticks);
834 /* CPUs seeing atomic_inc() must see later RCU read-side crit sects */
835 smp_mb__after_atomic(); /* See above. */
836 WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
837 !(atomic_read(&rdtp->dynticks) & 0x1));
838 rcu_cleanup_after_idle(); 934 rcu_cleanup_after_idle();
839 trace_rcu_dyntick(TPS("End"), oldval, rdtp->dynticks_nesting); 935 trace_rcu_dyntick(TPS("End"), oldval, rdtp->dynticks_nesting);
840 if (IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && 936 if (IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
@@ -980,12 +1076,8 @@ void rcu_nmi_enter(void)
980 * to be in the outermost NMI handler that interrupted an RCU-idle 1076 * to be in the outermost NMI handler that interrupted an RCU-idle
981 * period (observation due to Andy Lutomirski). 1077 * period (observation due to Andy Lutomirski).
982 */ 1078 */
983 if (!(atomic_read(&rdtp->dynticks) & 0x1)) { 1079 if (rcu_dynticks_curr_cpu_in_eqs()) {
984 smp_mb__before_atomic(); /* Force delay from prior write. */ 1080 rcu_dynticks_eqs_exit();
985 atomic_inc(&rdtp->dynticks);
986 /* atomic_inc() before later RCU read-side crit sects */
987 smp_mb__after_atomic(); /* See above. */
988 WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1));
989 incby = 1; 1081 incby = 1;
990 } 1082 }
991 rdtp->dynticks_nmi_nesting += incby; 1083 rdtp->dynticks_nmi_nesting += incby;
@@ -1010,7 +1102,7 @@ void rcu_nmi_exit(void)
1010 * to us!) 1102 * to us!)
1011 */ 1103 */
1012 WARN_ON_ONCE(rdtp->dynticks_nmi_nesting <= 0); 1104 WARN_ON_ONCE(rdtp->dynticks_nmi_nesting <= 0);
1013 WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1)); 1105 WARN_ON_ONCE(rcu_dynticks_curr_cpu_in_eqs());
1014 1106
1015 /* 1107 /*
1016 * If the nesting level is not 1, the CPU wasn't RCU-idle, so 1108 * If the nesting level is not 1, the CPU wasn't RCU-idle, so
@@ -1023,11 +1115,7 @@ void rcu_nmi_exit(void)
1023 1115
1024 /* This NMI interrupted an RCU-idle CPU, restore RCU-idleness. */ 1116 /* This NMI interrupted an RCU-idle CPU, restore RCU-idleness. */
1025 rdtp->dynticks_nmi_nesting = 0; 1117 rdtp->dynticks_nmi_nesting = 0;
1026 /* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */ 1118 rcu_dynticks_eqs_enter();
1027 smp_mb__before_atomic(); /* See above. */
1028 atomic_inc(&rdtp->dynticks);
1029 smp_mb__after_atomic(); /* Force delay to next write. */
1030 WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1);
1031} 1119}
1032 1120
1033/** 1121/**
@@ -1040,7 +1128,7 @@ void rcu_nmi_exit(void)
1040 */ 1128 */
1041bool notrace __rcu_is_watching(void) 1129bool notrace __rcu_is_watching(void)
1042{ 1130{
1043 return atomic_read(this_cpu_ptr(&rcu_dynticks.dynticks)) & 0x1; 1131 return !rcu_dynticks_curr_cpu_in_eqs();
1044} 1132}
1045 1133
1046/** 1134/**
@@ -1123,9 +1211,9 @@ static int rcu_is_cpu_rrupt_from_idle(void)
1123static int dyntick_save_progress_counter(struct rcu_data *rdp, 1211static int dyntick_save_progress_counter(struct rcu_data *rdp,
1124 bool *isidle, unsigned long *maxj) 1212 bool *isidle, unsigned long *maxj)
1125{ 1213{
1126 rdp->dynticks_snap = atomic_add_return(0, &rdp->dynticks->dynticks); 1214 rdp->dynticks_snap = rcu_dynticks_snap(rdp->dynticks);
1127 rcu_sysidle_check_cpu(rdp, isidle, maxj); 1215 rcu_sysidle_check_cpu(rdp, isidle, maxj);
1128 if ((rdp->dynticks_snap & 0x1) == 0) { 1216 if (rcu_dynticks_in_eqs(rdp->dynticks_snap)) {
1129 trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("dti")); 1217 trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("dti"));
1130 if (ULONG_CMP_LT(READ_ONCE(rdp->gpnum) + ULONG_MAX / 4, 1218 if (ULONG_CMP_LT(READ_ONCE(rdp->gpnum) + ULONG_MAX / 4,
1131 rdp->mynode->gpnum)) 1219 rdp->mynode->gpnum))
@@ -1144,12 +1232,10 @@ static int dyntick_save_progress_counter(struct rcu_data *rdp,
1144static int rcu_implicit_dynticks_qs(struct rcu_data *rdp, 1232static int rcu_implicit_dynticks_qs(struct rcu_data *rdp,
1145 bool *isidle, unsigned long *maxj) 1233 bool *isidle, unsigned long *maxj)
1146{ 1234{
1147 unsigned int curr; 1235 unsigned long jtsq;
1148 int *rcrmp; 1236 int *rcrmp;
1149 unsigned int snap; 1237 unsigned long rjtsc;
1150 1238 struct rcu_node *rnp;
1151 curr = (unsigned int)atomic_add_return(0, &rdp->dynticks->dynticks);
1152 snap = (unsigned int)rdp->dynticks_snap;
1153 1239
1154 /* 1240 /*
1155 * If the CPU passed through or entered a dynticks idle phase with 1241 * If the CPU passed through or entered a dynticks idle phase with
@@ -1159,27 +1245,39 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp,
1159 * read-side critical section that started before the beginning 1245 * read-side critical section that started before the beginning
1160 * of the current RCU grace period. 1246 * of the current RCU grace period.
1161 */ 1247 */
1162 if ((curr & 0x1) == 0 || UINT_CMP_GE(curr, snap + 2)) { 1248 if (rcu_dynticks_in_eqs_since(rdp->dynticks, rdp->dynticks_snap)) {
1163 trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("dti")); 1249 trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("dti"));
1164 rdp->dynticks_fqs++; 1250 rdp->dynticks_fqs++;
1165 return 1; 1251 return 1;
1166 } 1252 }
1167 1253
1254 /* Compute and saturate jiffies_till_sched_qs. */
1255 jtsq = jiffies_till_sched_qs;
1256 rjtsc = rcu_jiffies_till_stall_check();
1257 if (jtsq > rjtsc / 2) {
1258 WRITE_ONCE(jiffies_till_sched_qs, rjtsc);
1259 jtsq = rjtsc / 2;
1260 } else if (jtsq < 1) {
1261 WRITE_ONCE(jiffies_till_sched_qs, 1);
1262 jtsq = 1;
1263 }
1264
1168 /* 1265 /*
1169 * Check for the CPU being offline, but only if the grace period 1266 * Has this CPU encountered a cond_resched_rcu_qs() since the
1170 * is old enough. We don't need to worry about the CPU changing 1267 * beginning of the grace period? For this to be the case,
1171 * state: If we see it offline even once, it has been through a 1268 * the CPU has to have noticed the current grace period. This
1172 * quiescent state. 1269 * might not be the case for nohz_full CPUs looping in the kernel.
1173 *
1174 * The reason for insisting that the grace period be at least
1175 * one jiffy old is that CPUs that are not quite online and that
1176 * have just gone offline can still execute RCU read-side critical
1177 * sections.
1178 */ 1270 */
1179 if (ULONG_CMP_GE(rdp->rsp->gp_start + 2, jiffies)) 1271 rnp = rdp->mynode;
1180 return 0; /* Grace period is not old enough. */ 1272 if (time_after(jiffies, rdp->rsp->gp_start + jtsq) &&
1181 barrier(); 1273 READ_ONCE(rdp->rcu_qs_ctr_snap) != per_cpu(rcu_qs_ctr, rdp->cpu) &&
1182 if (cpu_is_offline(rdp->cpu)) { 1274 READ_ONCE(rdp->gpnum) == rnp->gpnum && !rdp->gpwrap) {
1275 trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("rqc"));
1276 return 1;
1277 }
1278
1279 /* Check for the CPU being offline. */
1280 if (!(rdp->grpmask & rcu_rnp_online_cpus(rnp))) {
1183 trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("ofl")); 1281 trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("ofl"));
1184 rdp->offline_fqs++; 1282 rdp->offline_fqs++;
1185 return 1; 1283 return 1;
@@ -1207,9 +1305,8 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp,
1207 * warning delay. 1305 * warning delay.
1208 */ 1306 */
1209 rcrmp = &per_cpu(rcu_sched_qs_mask, rdp->cpu); 1307 rcrmp = &per_cpu(rcu_sched_qs_mask, rdp->cpu);
1210 if (ULONG_CMP_GE(jiffies, 1308 if (time_after(jiffies, rdp->rsp->gp_start + jtsq) ||
1211 rdp->rsp->gp_start + jiffies_till_sched_qs) || 1309 time_after(jiffies, rdp->rsp->jiffies_resched)) {
1212 ULONG_CMP_GE(jiffies, rdp->rsp->jiffies_resched)) {
1213 if (!(READ_ONCE(*rcrmp) & rdp->rsp->flavor_mask)) { 1310 if (!(READ_ONCE(*rcrmp) & rdp->rsp->flavor_mask)) {
1214 WRITE_ONCE(rdp->cond_resched_completed, 1311 WRITE_ONCE(rdp->cond_resched_completed,
1215 READ_ONCE(rdp->mynode->completed)); 1312 READ_ONCE(rdp->mynode->completed));
@@ -1220,11 +1317,12 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp,
1220 rdp->rsp->jiffies_resched += 5; /* Re-enable beating. */ 1317 rdp->rsp->jiffies_resched += 5; /* Re-enable beating. */
1221 } 1318 }
1222 1319
1223 /* And if it has been a really long time, kick the CPU as well. */ 1320 /*
1224 if (ULONG_CMP_GE(jiffies, 1321 * If more than halfway to RCU CPU stall-warning time, do
1225 rdp->rsp->gp_start + 2 * jiffies_till_sched_qs) || 1322 * a resched_cpu() to try to loosen things up a bit.
1226 ULONG_CMP_GE(jiffies, rdp->rsp->gp_start + jiffies_till_sched_qs)) 1323 */
1227 resched_cpu(rdp->cpu); /* Force CPU into scheduler. */ 1324 if (jiffies - rdp->rsp->gp_start > rcu_jiffies_till_stall_check() / 2)
1325 resched_cpu(rdp->cpu);
1228 1326
1229 return 0; 1327 return 0;
1230} 1328}
@@ -1277,7 +1375,10 @@ static void rcu_check_gp_kthread_starvation(struct rcu_state *rsp)
1277} 1375}
1278 1376
1279/* 1377/*
1280 * Dump stacks of all tasks running on stalled CPUs. 1378 * Dump stacks of all tasks running on stalled CPUs. First try using
1379 * NMIs, but fall back to manual remote stack tracing on architectures
1380 * that don't support NMI-based stack dumps. The NMI-triggered stack
1381 * traces are more accurate because they are printed by the target CPU.
1281 */ 1382 */
1282static void rcu_dump_cpu_stacks(struct rcu_state *rsp) 1383static void rcu_dump_cpu_stacks(struct rcu_state *rsp)
1283{ 1384{
@@ -1287,11 +1388,10 @@ static void rcu_dump_cpu_stacks(struct rcu_state *rsp)
1287 1388
1288 rcu_for_each_leaf_node(rsp, rnp) { 1389 rcu_for_each_leaf_node(rsp, rnp) {
1289 raw_spin_lock_irqsave_rcu_node(rnp, flags); 1390 raw_spin_lock_irqsave_rcu_node(rnp, flags);
1290 if (rnp->qsmask != 0) { 1391 for_each_leaf_node_possible_cpu(rnp, cpu)
1291 for_each_leaf_node_possible_cpu(rnp, cpu) 1392 if (rnp->qsmask & leaf_node_cpu_bit(rnp, cpu))
1292 if (rnp->qsmask & leaf_node_cpu_bit(rnp, cpu)) 1393 if (!trigger_single_cpu_backtrace(cpu))
1293 dump_cpu_task(cpu); 1394 dump_cpu_task(cpu);
1294 }
1295 raw_spin_unlock_irqrestore_rcu_node(rnp, flags); 1395 raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
1296 } 1396 }
1297} 1397}
@@ -1379,6 +1479,9 @@ static void print_other_cpu_stall(struct rcu_state *rsp, unsigned long gpnum)
1379 (long)rsp->gpnum, (long)rsp->completed, totqlen); 1479 (long)rsp->gpnum, (long)rsp->completed, totqlen);
1380 if (ndetected) { 1480 if (ndetected) {
1381 rcu_dump_cpu_stacks(rsp); 1481 rcu_dump_cpu_stacks(rsp);
1482
1483 /* Complain about tasks blocking the grace period. */
1484 rcu_print_detail_task_stall(rsp);
1382 } else { 1485 } else {
1383 if (READ_ONCE(rsp->gpnum) != gpnum || 1486 if (READ_ONCE(rsp->gpnum) != gpnum ||
1384 READ_ONCE(rsp->completed) == gpnum) { 1487 READ_ONCE(rsp->completed) == gpnum) {
@@ -1395,9 +1498,6 @@ static void print_other_cpu_stall(struct rcu_state *rsp, unsigned long gpnum)
1395 } 1498 }
1396 } 1499 }
1397 1500
1398 /* Complain about tasks blocking the grace period. */
1399 rcu_print_detail_task_stall(rsp);
1400
1401 rcu_check_gp_kthread_starvation(rsp); 1501 rcu_check_gp_kthread_starvation(rsp);
1402 1502
1403 panic_on_rcu_stall(); 1503 panic_on_rcu_stall();
@@ -2467,10 +2567,8 @@ rcu_report_qs_rdp(int cpu, struct rcu_state *rsp, struct rcu_data *rdp)
2467 2567
2468 rnp = rdp->mynode; 2568 rnp = rdp->mynode;
2469 raw_spin_lock_irqsave_rcu_node(rnp, flags); 2569 raw_spin_lock_irqsave_rcu_node(rnp, flags);
2470 if ((rdp->cpu_no_qs.b.norm && 2570 if (rdp->cpu_no_qs.b.norm || rdp->gpnum != rnp->gpnum ||
2471 rdp->rcu_qs_ctr_snap == __this_cpu_read(rcu_qs_ctr)) || 2571 rnp->completed == rnp->gpnum || rdp->gpwrap) {
2472 rdp->gpnum != rnp->gpnum || rnp->completed == rnp->gpnum ||
2473 rdp->gpwrap) {
2474 2572
2475 /* 2573 /*
2476 * The grace period in which this quiescent state was 2574 * The grace period in which this quiescent state was
@@ -2525,8 +2623,7 @@ rcu_check_quiescent_state(struct rcu_state *rsp, struct rcu_data *rdp)
2525 * Was there a quiescent state since the beginning of the grace 2623 * Was there a quiescent state since the beginning of the grace
2526 * period? If no, then exit and wait for the next call. 2624 * period? If no, then exit and wait for the next call.
2527 */ 2625 */
2528 if (rdp->cpu_no_qs.b.norm && 2626 if (rdp->cpu_no_qs.b.norm)
2529 rdp->rcu_qs_ctr_snap == __this_cpu_read(rcu_qs_ctr))
2530 return; 2627 return;
2531 2628
2532 /* 2629 /*
@@ -3480,9 +3577,7 @@ static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp)
3480 rdp->core_needs_qs && rdp->cpu_no_qs.b.norm && 3577 rdp->core_needs_qs && rdp->cpu_no_qs.b.norm &&
3481 rdp->rcu_qs_ctr_snap == __this_cpu_read(rcu_qs_ctr)) { 3578 rdp->rcu_qs_ctr_snap == __this_cpu_read(rcu_qs_ctr)) {
3482 rdp->n_rp_core_needs_qs++; 3579 rdp->n_rp_core_needs_qs++;
3483 } else if (rdp->core_needs_qs && 3580 } else if (rdp->core_needs_qs && !rdp->cpu_no_qs.b.norm) {
3484 (!rdp->cpu_no_qs.b.norm ||
3485 rdp->rcu_qs_ctr_snap != __this_cpu_read(rcu_qs_ctr))) {
3486 rdp->n_rp_report_qs++; 3581 rdp->n_rp_report_qs++;
3487 return 1; 3582 return 1;
3488 } 3583 }
@@ -3748,7 +3843,7 @@ rcu_boot_init_percpu_data(int cpu, struct rcu_state *rsp)
3748 rdp->grpmask = leaf_node_cpu_bit(rdp->mynode, cpu); 3843 rdp->grpmask = leaf_node_cpu_bit(rdp->mynode, cpu);
3749 rdp->dynticks = &per_cpu(rcu_dynticks, cpu); 3844 rdp->dynticks = &per_cpu(rcu_dynticks, cpu);
3750 WARN_ON_ONCE(rdp->dynticks->dynticks_nesting != DYNTICK_TASK_EXIT_IDLE); 3845 WARN_ON_ONCE(rdp->dynticks->dynticks_nesting != DYNTICK_TASK_EXIT_IDLE);
3751 WARN_ON_ONCE(atomic_read(&rdp->dynticks->dynticks) != 1); 3846 WARN_ON_ONCE(rcu_dynticks_in_eqs(rcu_dynticks_snap(rdp->dynticks)));
3752 rdp->cpu = cpu; 3847 rdp->cpu = cpu;
3753 rdp->rsp = rsp; 3848 rdp->rsp = rsp;
3754 rcu_boot_init_nocb_percpu_data(rdp); 3849 rcu_boot_init_nocb_percpu_data(rdp);
@@ -3765,7 +3860,6 @@ static void
3765rcu_init_percpu_data(int cpu, struct rcu_state *rsp) 3860rcu_init_percpu_data(int cpu, struct rcu_state *rsp)
3766{ 3861{
3767 unsigned long flags; 3862 unsigned long flags;
3768 unsigned long mask;
3769 struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu); 3863 struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
3770 struct rcu_node *rnp = rcu_get_root(rsp); 3864 struct rcu_node *rnp = rcu_get_root(rsp);
3771 3865
@@ -3778,8 +3872,7 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp)
3778 init_callback_list(rdp); /* Re-enable callbacks on this CPU. */ 3872 init_callback_list(rdp); /* Re-enable callbacks on this CPU. */
3779 rdp->dynticks->dynticks_nesting = DYNTICK_TASK_EXIT_IDLE; 3873 rdp->dynticks->dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
3780 rcu_sysidle_init_percpu_data(rdp->dynticks); 3874 rcu_sysidle_init_percpu_data(rdp->dynticks);
3781 atomic_set(&rdp->dynticks->dynticks, 3875 rcu_dynticks_eqs_online();
3782 (atomic_read(&rdp->dynticks->dynticks) & ~0x1) + 1);
3783 raw_spin_unlock_rcu_node(rnp); /* irqs remain disabled. */ 3876 raw_spin_unlock_rcu_node(rnp); /* irqs remain disabled. */
3784 3877
3785 /* 3878 /*
@@ -3788,7 +3881,6 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp)
3788 * of the next grace period. 3881 * of the next grace period.
3789 */ 3882 */
3790 rnp = rdp->mynode; 3883 rnp = rdp->mynode;
3791 mask = rdp->grpmask;
3792 raw_spin_lock_rcu_node(rnp); /* irqs already disabled. */ 3884 raw_spin_lock_rcu_node(rnp); /* irqs already disabled. */
3793 if (!rdp->beenonline) 3885 if (!rdp->beenonline)
3794 WRITE_ONCE(rsp->ncpus, READ_ONCE(rsp->ncpus) + 1); 3886 WRITE_ONCE(rsp->ncpus, READ_ONCE(rsp->ncpus) + 1);
@@ -3872,7 +3964,7 @@ void rcu_cpu_starting(unsigned int cpu)
3872 struct rcu_state *rsp; 3964 struct rcu_state *rsp;
3873 3965
3874 for_each_rcu_flavor(rsp) { 3966 for_each_rcu_flavor(rsp) {
3875 rdp = this_cpu_ptr(rsp->rda); 3967 rdp = per_cpu_ptr(rsp->rda, cpu);
3876 rnp = rdp->mynode; 3968 rnp = rdp->mynode;
3877 mask = rdp->grpmask; 3969 mask = rdp->grpmask;
3878 raw_spin_lock_irqsave_rcu_node(rnp, flags); 3970 raw_spin_lock_irqsave_rcu_node(rnp, flags);
diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
index fe98dd24adf8..b60f2b6caa14 100644
--- a/kernel/rcu/tree.h
+++ b/kernel/rcu/tree.h
@@ -521,7 +521,6 @@ struct rcu_state {
521 struct mutex exp_mutex; /* Serialize expedited GP. */ 521 struct mutex exp_mutex; /* Serialize expedited GP. */
522 struct mutex exp_wake_mutex; /* Serialize wakeup. */ 522 struct mutex exp_wake_mutex; /* Serialize wakeup. */
523 unsigned long expedited_sequence; /* Take a ticket. */ 523 unsigned long expedited_sequence; /* Take a ticket. */
524 atomic_long_t expedited_normal; /* # fallbacks to normal. */
525 atomic_t expedited_need_qs; /* # CPUs left to check in. */ 524 atomic_t expedited_need_qs; /* # CPUs left to check in. */
526 struct swait_queue_head expedited_wq; /* Wait for check-ins. */ 525 struct swait_queue_head expedited_wq; /* Wait for check-ins. */
527 int ncpus_snap; /* # CPUs seen last time. */ 526 int ncpus_snap; /* # CPUs seen last time. */
@@ -595,6 +594,8 @@ extern struct rcu_state rcu_bh_state;
595extern struct rcu_state rcu_preempt_state; 594extern struct rcu_state rcu_preempt_state;
596#endif /* #ifdef CONFIG_PREEMPT_RCU */ 595#endif /* #ifdef CONFIG_PREEMPT_RCU */
597 596
597int rcu_dynticks_snap(struct rcu_dynticks *rdtp);
598
598#ifdef CONFIG_RCU_BOOST 599#ifdef CONFIG_RCU_BOOST
599DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status); 600DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status);
600DECLARE_PER_CPU(int, rcu_cpu_kthread_cpu); 601DECLARE_PER_CPU(int, rcu_cpu_kthread_cpu);
@@ -688,18 +689,6 @@ static inline void rcu_nocb_q_lengths(struct rcu_data *rdp, long *ql, long *qll)
688#endif /* #ifdef CONFIG_RCU_TRACE */ 689#endif /* #ifdef CONFIG_RCU_TRACE */
689 690
690/* 691/*
691 * Place this after a lock-acquisition primitive to guarantee that
692 * an UNLOCK+LOCK pair act as a full barrier. This guarantee applies
693 * if the UNLOCK and LOCK are executed by the same CPU or if the
694 * UNLOCK and LOCK operate on the same lock variable.
695 */
696#ifdef CONFIG_PPC
697#define smp_mb__after_unlock_lock() smp_mb() /* Full ordering for lock. */
698#else /* #ifdef CONFIG_PPC */
699#define smp_mb__after_unlock_lock() do { } while (0)
700#endif /* #else #ifdef CONFIG_PPC */
701
702/*
703 * Wrappers for the rcu_node::lock acquire and release. 692 * Wrappers for the rcu_node::lock acquire and release.
704 * 693 *
705 * Because the rcu_nodes form a tree, the tree traversal locking will observe 694 * Because the rcu_nodes form a tree, the tree traversal locking will observe
diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h
index e59e1849b89a..a7b639ccd46e 100644
--- a/kernel/rcu/tree_exp.h
+++ b/kernel/rcu/tree_exp.h
@@ -20,16 +20,26 @@
20 * Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> 20 * Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
21 */ 21 */
22 22
23/* Wrapper functions for expedited grace periods. */ 23/*
24 * Record the start of an expedited grace period.
25 */
24static void rcu_exp_gp_seq_start(struct rcu_state *rsp) 26static void rcu_exp_gp_seq_start(struct rcu_state *rsp)
25{ 27{
26 rcu_seq_start(&rsp->expedited_sequence); 28 rcu_seq_start(&rsp->expedited_sequence);
27} 29}
30
31/*
32 * Record the end of an expedited grace period.
33 */
28static void rcu_exp_gp_seq_end(struct rcu_state *rsp) 34static void rcu_exp_gp_seq_end(struct rcu_state *rsp)
29{ 35{
30 rcu_seq_end(&rsp->expedited_sequence); 36 rcu_seq_end(&rsp->expedited_sequence);
31 smp_mb(); /* Ensure that consecutive grace periods serialize. */ 37 smp_mb(); /* Ensure that consecutive grace periods serialize. */
32} 38}
39
40/*
41 * Take a snapshot of the expedited-grace-period counter.
42 */
33static unsigned long rcu_exp_gp_seq_snap(struct rcu_state *rsp) 43static unsigned long rcu_exp_gp_seq_snap(struct rcu_state *rsp)
34{ 44{
35 unsigned long s; 45 unsigned long s;
@@ -39,6 +49,12 @@ static unsigned long rcu_exp_gp_seq_snap(struct rcu_state *rsp)
39 trace_rcu_exp_grace_period(rsp->name, s, TPS("snap")); 49 trace_rcu_exp_grace_period(rsp->name, s, TPS("snap"));
40 return s; 50 return s;
41} 51}
52
53/*
54 * Given a counter snapshot from rcu_exp_gp_seq_snap(), return true
55 * if a full expedited grace period has elapsed since that snapshot
56 * was taken.
57 */
42static bool rcu_exp_gp_seq_done(struct rcu_state *rsp, unsigned long s) 58static bool rcu_exp_gp_seq_done(struct rcu_state *rsp, unsigned long s)
43{ 59{
44 return rcu_seq_done(&rsp->expedited_sequence, s); 60 return rcu_seq_done(&rsp->expedited_sequence, s);
@@ -356,12 +372,11 @@ static void sync_rcu_exp_select_cpus(struct rcu_state *rsp,
356 mask_ofl_test = 0; 372 mask_ofl_test = 0;
357 for_each_leaf_node_possible_cpu(rnp, cpu) { 373 for_each_leaf_node_possible_cpu(rnp, cpu) {
358 struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu); 374 struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
359 struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu);
360 375
361 rdp->exp_dynticks_snap = 376 rdp->exp_dynticks_snap =
362 atomic_add_return(0, &rdtp->dynticks); 377 rcu_dynticks_snap(rdp->dynticks);
363 if (raw_smp_processor_id() == cpu || 378 if (raw_smp_processor_id() == cpu ||
364 !(rdp->exp_dynticks_snap & 0x1) || 379 rcu_dynticks_in_eqs(rdp->exp_dynticks_snap) ||
365 !(rnp->qsmaskinitnext & rdp->grpmask)) 380 !(rnp->qsmaskinitnext & rdp->grpmask))
366 mask_ofl_test |= rdp->grpmask; 381 mask_ofl_test |= rdp->grpmask;
367 } 382 }
@@ -380,13 +395,12 @@ static void sync_rcu_exp_select_cpus(struct rcu_state *rsp,
380 for_each_leaf_node_possible_cpu(rnp, cpu) { 395 for_each_leaf_node_possible_cpu(rnp, cpu) {
381 unsigned long mask = leaf_node_cpu_bit(rnp, cpu); 396 unsigned long mask = leaf_node_cpu_bit(rnp, cpu);
382 struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu); 397 struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
383 struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu);
384 398
385 if (!(mask_ofl_ipi & mask)) 399 if (!(mask_ofl_ipi & mask))
386 continue; 400 continue;
387retry_ipi: 401retry_ipi:
388 if (atomic_add_return(0, &rdtp->dynticks) != 402 if (rcu_dynticks_in_eqs_since(rdp->dynticks,
389 rdp->exp_dynticks_snap) { 403 rdp->exp_dynticks_snap)) {
390 mask_ofl_test |= mask; 404 mask_ofl_test |= mask;
391 continue; 405 continue;
392 } 406 }
@@ -623,6 +637,11 @@ void synchronize_sched_expedited(void)
623{ 637{
624 struct rcu_state *rsp = &rcu_sched_state; 638 struct rcu_state *rsp = &rcu_sched_state;
625 639
640 RCU_LOCKDEP_WARN(lock_is_held(&rcu_bh_lock_map) ||
641 lock_is_held(&rcu_lock_map) ||
642 lock_is_held(&rcu_sched_lock_map),
643 "Illegal synchronize_sched_expedited() in RCU read-side critical section");
644
626 /* If only one CPU, this is automatically a grace period. */ 645 /* If only one CPU, this is automatically a grace period. */
627 if (rcu_blocking_is_gp()) 646 if (rcu_blocking_is_gp())
628 return; 647 return;
@@ -692,6 +711,11 @@ void synchronize_rcu_expedited(void)
692{ 711{
693 struct rcu_state *rsp = rcu_state_p; 712 struct rcu_state *rsp = rcu_state_p;
694 713
714 RCU_LOCKDEP_WARN(lock_is_held(&rcu_bh_lock_map) ||
715 lock_is_held(&rcu_lock_map) ||
716 lock_is_held(&rcu_sched_lock_map),
717 "Illegal synchronize_rcu_expedited() in RCU read-side critical section");
718
695 if (rcu_scheduler_active == RCU_SCHEDULER_INACTIVE) 719 if (rcu_scheduler_active == RCU_SCHEDULER_INACTIVE)
696 return; 720 return;
697 _synchronize_rcu_expedited(rsp, sync_rcu_exp_handler); 721 _synchronize_rcu_expedited(rsp, sync_rcu_exp_handler);
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 56583e764ebf..a240f3308be6 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -1643,7 +1643,7 @@ static void print_cpu_stall_info(struct rcu_state *rsp, int cpu)
1643 "o."[!!(rdp->grpmask & rdp->mynode->qsmaskinit)], 1643 "o."[!!(rdp->grpmask & rdp->mynode->qsmaskinit)],
1644 "N."[!!(rdp->grpmask & rdp->mynode->qsmaskinitnext)], 1644 "N."[!!(rdp->grpmask & rdp->mynode->qsmaskinitnext)],
1645 ticks_value, ticks_title, 1645 ticks_value, ticks_title,
1646 atomic_read(&rdtp->dynticks) & 0xfff, 1646 rcu_dynticks_snap(rdtp) & 0xfff,
1647 rdtp->dynticks_nesting, rdtp->dynticks_nmi_nesting, 1647 rdtp->dynticks_nesting, rdtp->dynticks_nmi_nesting,
1648 rdp->softirq_snap, kstat_softirqs_cpu(RCU_SOFTIRQ, cpu), 1648 rdp->softirq_snap, kstat_softirqs_cpu(RCU_SOFTIRQ, cpu),
1649 READ_ONCE(rsp->n_force_qs) - rsp->n_force_qs_gpstart, 1649 READ_ONCE(rsp->n_force_qs) - rsp->n_force_qs_gpstart,
@@ -2366,8 +2366,9 @@ static void __init rcu_organize_nocb_kthreads(struct rcu_state *rsp)
2366 } 2366 }
2367 2367
2368 /* 2368 /*
2369 * Each pass through this loop sets up one rcu_data structure and 2369 * Each pass through this loop sets up one rcu_data structure.
2370 * spawns one rcu_nocb_kthread(). 2370 * Should the corresponding CPU come online in the future, then
2371 * we will spawn the needed set of rcu_nocb_kthread() kthreads.
2371 */ 2372 */
2372 for_each_cpu(cpu, rcu_nocb_mask) { 2373 for_each_cpu(cpu, rcu_nocb_mask) {
2373 rdp = per_cpu_ptr(rsp->rda, cpu); 2374 rdp = per_cpu_ptr(rsp->rda, cpu);
diff --git a/kernel/rcu/tree_trace.c b/kernel/rcu/tree_trace.c
index b1f28972872c..8751a748499a 100644
--- a/kernel/rcu/tree_trace.c
+++ b/kernel/rcu/tree_trace.c
@@ -124,7 +124,7 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp)
124 rdp->rcu_qs_ctr_snap == per_cpu(rcu_qs_ctr, rdp->cpu), 124 rdp->rcu_qs_ctr_snap == per_cpu(rcu_qs_ctr, rdp->cpu),
125 rdp->core_needs_qs); 125 rdp->core_needs_qs);
126 seq_printf(m, " dt=%d/%llx/%d df=%lu", 126 seq_printf(m, " dt=%d/%llx/%d df=%lu",
127 atomic_read(&rdp->dynticks->dynticks), 127 rcu_dynticks_snap(rdp->dynticks),
128 rdp->dynticks->dynticks_nesting, 128 rdp->dynticks->dynticks_nesting,
129 rdp->dynticks->dynticks_nmi_nesting, 129 rdp->dynticks->dynticks_nmi_nesting,
130 rdp->dynticks_fqs); 130 rdp->dynticks_fqs);
@@ -194,9 +194,8 @@ static int show_rcuexp(struct seq_file *m, void *v)
194 s2 += atomic_long_read(&rdp->exp_workdone2); 194 s2 += atomic_long_read(&rdp->exp_workdone2);
195 s3 += atomic_long_read(&rdp->exp_workdone3); 195 s3 += atomic_long_read(&rdp->exp_workdone3);
196 } 196 }
197 seq_printf(m, "s=%lu wd0=%lu wd1=%lu wd2=%lu wd3=%lu n=%lu enq=%d sc=%lu\n", 197 seq_printf(m, "s=%lu wd0=%lu wd1=%lu wd2=%lu wd3=%lu enq=%d sc=%lu\n",
198 rsp->expedited_sequence, s0, s1, s2, s3, 198 rsp->expedited_sequence, s0, s1, s2, s3,
199 atomic_long_read(&rsp->expedited_normal),
200 atomic_read(&rsp->expedited_need_qs), 199 atomic_read(&rsp->expedited_need_qs),
201 rsp->expedited_sequence / 2); 200 rsp->expedited_sequence / 2);
202 return 0; 201 return 0;
diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c
index 4f6db7e6a117..9e03db9ea9c0 100644
--- a/kernel/rcu/update.c
+++ b/kernel/rcu/update.c
@@ -132,8 +132,7 @@ bool rcu_gp_is_normal(void)
132} 132}
133EXPORT_SYMBOL_GPL(rcu_gp_is_normal); 133EXPORT_SYMBOL_GPL(rcu_gp_is_normal);
134 134
135static atomic_t rcu_expedited_nesting = 135static atomic_t rcu_expedited_nesting = ATOMIC_INIT(1);
136 ATOMIC_INIT(IS_ENABLED(CONFIG_RCU_EXPEDITE_BOOT) ? 1 : 0);
137 136
138/* 137/*
139 * Should normal grace-period primitives be expedited? Intended for 138 * Should normal grace-period primitives be expedited? Intended for
@@ -182,8 +181,7 @@ EXPORT_SYMBOL_GPL(rcu_unexpedite_gp);
182 */ 181 */
183void rcu_end_inkernel_boot(void) 182void rcu_end_inkernel_boot(void)
184{ 183{
185 if (IS_ENABLED(CONFIG_RCU_EXPEDITE_BOOT)) 184 rcu_unexpedite_gp();
186 rcu_unexpedite_gp();
187 if (rcu_normal_after_boot) 185 if (rcu_normal_after_boot)
188 WRITE_ONCE(rcu_normal, 1); 186 WRITE_ONCE(rcu_normal, 1);
189} 187}
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index eb9e9a7870fa..9db831439aa2 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1450,6 +1450,7 @@ config RCU_CPU_STALL_TIMEOUT
1450config RCU_TRACE 1450config RCU_TRACE
1451 bool "Enable tracing for RCU" 1451 bool "Enable tracing for RCU"
1452 depends on DEBUG_KERNEL 1452 depends on DEBUG_KERNEL
1453 default y if TREE_RCU
1453 select TRACE_CLOCK 1454 select TRACE_CLOCK
1454 help 1455 help
1455 This option provides tracing in RCU which presents stats 1456 This option provides tracing in RCU which presents stats
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/CFcommon b/tools/testing/selftests/rcutorture/configs/rcu/CFcommon
index f824b4c9d9d9..d2d2a86139db 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/CFcommon
+++ b/tools/testing/selftests/rcutorture/configs/rcu/CFcommon
@@ -1,5 +1,2 @@
1CONFIG_RCU_TORTURE_TEST=y 1CONFIG_RCU_TORTURE_TEST=y
2CONFIG_PRINTK_TIME=y 2CONFIG_PRINTK_TIME=y
3CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y
4CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y
5CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TINY01 b/tools/testing/selftests/rcutorture/configs/rcu/TINY01
index 0a63e073a00c..6db705e55487 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TINY01
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TINY01
@@ -7,6 +7,7 @@ CONFIG_HZ_PERIODIC=n
7CONFIG_NO_HZ_IDLE=y 7CONFIG_NO_HZ_IDLE=y
8CONFIG_NO_HZ_FULL=n 8CONFIG_NO_HZ_FULL=n
9CONFIG_RCU_TRACE=n 9CONFIG_RCU_TRACE=n
10#CHECK#CONFIG_RCU_STALL_COMMON=n
10CONFIG_DEBUG_LOCK_ALLOC=n 11CONFIG_DEBUG_LOCK_ALLOC=n
11CONFIG_DEBUG_OBJECTS_RCU_HEAD=n 12CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
12CONFIG_PREEMPT_COUNT=n 13CONFIG_PREEMPT_COUNT=n
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TINY02 b/tools/testing/selftests/rcutorture/configs/rcu/TINY02
index f1892e0371c9..a59f7686e219 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TINY02
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TINY02
@@ -8,7 +8,8 @@ CONFIG_NO_HZ_IDLE=n
8CONFIG_NO_HZ_FULL=n 8CONFIG_NO_HZ_FULL=n
9CONFIG_RCU_TRACE=y 9CONFIG_RCU_TRACE=y
10CONFIG_PROVE_LOCKING=y 10CONFIG_PROVE_LOCKING=y
11CONFIG_PROVE_RCU_REPEATEDLY=y
11#CHECK#CONFIG_PROVE_RCU=y 12#CHECK#CONFIG_PROVE_RCU=y
12CONFIG_DEBUG_LOCK_ALLOC=y 13CONFIG_DEBUG_LOCK_ALLOC=y
13CONFIG_DEBUG_OBJECTS_RCU_HEAD=n 14CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
14CONFIG_PREEMPT_COUNT=y 15CONFIG_PREEMPT_COUNT=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE01 b/tools/testing/selftests/rcutorture/configs/rcu/TREE01
index f572b873c620..359cb258f639 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TREE01
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE01
@@ -16,3 +16,6 @@ CONFIG_DEBUG_LOCK_ALLOC=n
16CONFIG_RCU_BOOST=n 16CONFIG_RCU_BOOST=n
17CONFIG_DEBUG_OBJECTS_RCU_HEAD=n 17CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
18CONFIG_RCU_EXPERT=y 18CONFIG_RCU_EXPERT=y
19CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y
20CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y
21CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE02 b/tools/testing/selftests/rcutorture/configs/rcu/TREE02
index ef6a22c44dea..c1ab5926568b 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TREE02
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE02
@@ -20,3 +20,7 @@ CONFIG_PROVE_LOCKING=n
20CONFIG_RCU_BOOST=n 20CONFIG_RCU_BOOST=n
21CONFIG_DEBUG_OBJECTS_RCU_HEAD=n 21CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
22CONFIG_RCU_EXPERT=y 22CONFIG_RCU_EXPERT=y
23CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y
24CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y
25CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y
26CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE03 b/tools/testing/selftests/rcutorture/configs/rcu/TREE03
index 7a17c503b382..3b93ee544e70 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TREE03
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE03
@@ -17,3 +17,6 @@ CONFIG_RCU_BOOST=y
17CONFIG_RCU_KTHREAD_PRIO=2 17CONFIG_RCU_KTHREAD_PRIO=2
18CONFIG_DEBUG_OBJECTS_RCU_HEAD=n 18CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
19CONFIG_RCU_EXPERT=y 19CONFIG_RCU_EXPERT=y
20CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y
21CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y
22CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE04 b/tools/testing/selftests/rcutorture/configs/rcu/TREE04
index 17cbe098b115..5af758e783c7 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TREE04
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE04
@@ -19,3 +19,7 @@ CONFIG_RCU_NOCB_CPU=n
19CONFIG_DEBUG_LOCK_ALLOC=n 19CONFIG_DEBUG_LOCK_ALLOC=n
20CONFIG_DEBUG_OBJECTS_RCU_HEAD=n 20CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
21CONFIG_RCU_EXPERT=y 21CONFIG_RCU_EXPERT=y
22CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y
23CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y
24CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y
25CONFIG_RCU_EQS_DEBUG=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE05 b/tools/testing/selftests/rcutorture/configs/rcu/TREE05
index 1257d3227b1e..d4cdc0d74e16 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TREE05
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE05
@@ -19,3 +19,6 @@ CONFIG_PROVE_LOCKING=y
19#CHECK#CONFIG_PROVE_RCU=y 19#CHECK#CONFIG_PROVE_RCU=y
20CONFIG_DEBUG_OBJECTS_RCU_HEAD=n 20CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
21CONFIG_RCU_EXPERT=y 21CONFIG_RCU_EXPERT=y
22CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y
23CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y
24CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE06 b/tools/testing/selftests/rcutorture/configs/rcu/TREE06
index d3e456b74cbe..4cb02bd28f08 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TREE06
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE06
@@ -20,3 +20,6 @@ CONFIG_PROVE_LOCKING=y
20#CHECK#CONFIG_PROVE_RCU=y 20#CHECK#CONFIG_PROVE_RCU=y
21CONFIG_DEBUG_OBJECTS_RCU_HEAD=y 21CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
22CONFIG_RCU_EXPERT=y 22CONFIG_RCU_EXPERT=y
23CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y
24CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y
25CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE07 b/tools/testing/selftests/rcutorture/configs/rcu/TREE07
index 3956b4131f72..b12a3ea1867e 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TREE07
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE07
@@ -19,3 +19,6 @@ CONFIG_RCU_NOCB_CPU=n
19CONFIG_DEBUG_LOCK_ALLOC=n 19CONFIG_DEBUG_LOCK_ALLOC=n
20CONFIG_DEBUG_OBJECTS_RCU_HEAD=n 20CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
21CONFIG_RCU_EXPERT=y 21CONFIG_RCU_EXPERT=y
22CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y
23CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y
24CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE08 b/tools/testing/selftests/rcutorture/configs/rcu/TREE08
index bb9b0c1a23c2..099cc63c6a3b 100644
--- a/tools/testing/selftests/rcutorture/configs/rcu/TREE08
+++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE08
@@ -17,8 +17,8 @@ CONFIG_RCU_FANOUT_LEAF=2
17CONFIG_RCU_NOCB_CPU=y 17CONFIG_RCU_NOCB_CPU=y
18CONFIG_RCU_NOCB_CPU_ALL=y 18CONFIG_RCU_NOCB_CPU_ALL=y
19CONFIG_DEBUG_LOCK_ALLOC=n 19CONFIG_DEBUG_LOCK_ALLOC=n
20CONFIG_PROVE_LOCKING=y 20CONFIG_PROVE_LOCKING=n
21#CHECK#CONFIG_PROVE_RCU=y
22CONFIG_RCU_BOOST=n 21CONFIG_RCU_BOOST=n
23CONFIG_DEBUG_OBJECTS_RCU_HEAD=n 22CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
24CONFIG_RCU_EXPERT=y 23CONFIG_RCU_EXPERT=y
24CONFIG_RCU_EQS_DEBUG=y
diff --git a/tools/testing/selftests/rcutorture/doc/TREE_RCU-kconfig.txt b/tools/testing/selftests/rcutorture/doc/TREE_RCU-kconfig.txt
index 4e2b1893d40d..364801b1a230 100644
--- a/tools/testing/selftests/rcutorture/doc/TREE_RCU-kconfig.txt
+++ b/tools/testing/selftests/rcutorture/doc/TREE_RCU-kconfig.txt
@@ -14,6 +14,7 @@ CONFIG_NO_HZ_FULL_SYSIDLE -- Do one.
14CONFIG_PREEMPT -- Do half. (First three and #8.) 14CONFIG_PREEMPT -- Do half. (First three and #8.)
15CONFIG_PROVE_LOCKING -- Do several, covering CONFIG_DEBUG_LOCK_ALLOC=y and not. 15CONFIG_PROVE_LOCKING -- Do several, covering CONFIG_DEBUG_LOCK_ALLOC=y and not.
16CONFIG_PROVE_RCU -- Hardwired to CONFIG_PROVE_LOCKING. 16CONFIG_PROVE_RCU -- Hardwired to CONFIG_PROVE_LOCKING.
17CONFIG_PROVE_RCU_REPEATEDLY -- Do one.
17CONFIG_RCU_BOOST -- one of PREEMPT_RCU. 18CONFIG_RCU_BOOST -- one of PREEMPT_RCU.
18CONFIG_RCU_KTHREAD_PRIO -- set to 2 for _BOOST testing. 19CONFIG_RCU_KTHREAD_PRIO -- set to 2 for _BOOST testing.
19CONFIG_RCU_FANOUT -- Cover hierarchy, but overlap with others. 20CONFIG_RCU_FANOUT -- Cover hierarchy, but overlap with others.
@@ -25,7 +26,12 @@ CONFIG_RCU_NOCB_CPU_NONE -- Do one.
25CONFIG_RCU_NOCB_CPU_ZERO -- Do one. 26CONFIG_RCU_NOCB_CPU_ZERO -- Do one.
26CONFIG_RCU_TRACE -- Do half. 27CONFIG_RCU_TRACE -- Do half.
27CONFIG_SMP -- Need one !SMP for PREEMPT_RCU. 28CONFIG_SMP -- Need one !SMP for PREEMPT_RCU.
28!RCU_EXPERT -- Do a few, but these have to be vanilla configurations. 29CONFIG_RCU_EXPERT=n -- Do a few, but these have to be vanilla configurations.
30CONFIG_RCU_EQS_DEBUG -- Do at least one for CONFIG_NO_HZ_FULL and not.
31CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP -- Do for all but a couple TREE scenarios.
32CONFIG_RCU_TORTURE_TEST_SLOW_INIT -- Do for all but a couple TREE scenarios.
33CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT -- Do for all but a couple TREE scenarios.
34
29RCU-bh: Do one with PREEMPT and one with !PREEMPT. 35RCU-bh: Do one with PREEMPT and one with !PREEMPT.
30RCU-sched: Do one with PREEMPT but not BOOST. 36RCU-sched: Do one with PREEMPT but not BOOST.
31 37
@@ -72,7 +78,30 @@ CONFIG_RCU_TORTURE_TEST_RUNNABLE
72 78
73 Always used in KVM testing. 79 Always used in KVM testing.
74 80
81CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT_DELAY
82CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY
83CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP_DELAY
84
85 Inspection suffices, ignore.
86
75CONFIG_PREEMPT_RCU 87CONFIG_PREEMPT_RCU
76CONFIG_TREE_RCU 88CONFIG_TREE_RCU
89CONFIG_TINY_RCU
90
91 These are controlled by CONFIG_PREEMPT and/or CONFIG_SMP.
92
93CONFIG_SPARSE_RCU_POINTER
94
95 Makes sense only for sparse runs, not for kernel builds.
96
97CONFIG_SRCU
98CONFIG_TASKS_RCU
99
100 Selected by CONFIG_RCU_TORTURE_TEST, so cannot disable.
101
102CONFIG_RCU_TRACE
103
104 Implied by CONFIG_RCU_TRACE for Tree RCU.
105
77 106
78 These are controlled by CONFIG_PREEMPT. 107boot parameters ignored: TBD
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/.gitignore b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/.gitignore
new file mode 100644
index 000000000000..712a3d41a325
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/.gitignore
@@ -0,0 +1 @@
srcu.c
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/Makefile b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/Makefile
new file mode 100644
index 000000000000..16b01559fa55
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/Makefile
@@ -0,0 +1,16 @@
1all: srcu.c store_buffering
2
3LINUX_SOURCE = ../../../../../..
4
5modified_srcu_input = $(LINUX_SOURCE)/include/linux/srcu.h \
6 $(LINUX_SOURCE)/kernel/rcu/srcu.c
7
8modified_srcu_output = include/linux/srcu.h srcu.c
9
10include/linux/srcu.h: srcu.c
11
12srcu.c: modify_srcu.awk Makefile $(modified_srcu_input)
13 awk -f modify_srcu.awk $(modified_srcu_input) $(modified_srcu_output)
14
15store_buffering:
16 @cd tests/store_buffering; make
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/delay.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/delay.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/delay.h
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/export.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/export.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/export.h
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/mutex.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/mutex.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/mutex.h
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/percpu.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/percpu.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/percpu.h
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/preempt.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/preempt.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/preempt.h
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/rcupdate.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/rcupdate.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/rcupdate.h
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/sched.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/sched.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/sched.h
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/smp.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/smp.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/smp.h
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/workqueue.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/workqueue.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux/workqueue.h
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/uapi/linux/types.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/uapi/linux/types.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/uapi/linux/types.h
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/include/linux/.gitignore b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/include/linux/.gitignore
new file mode 100644
index 000000000000..1d016e66980a
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/include/linux/.gitignore
@@ -0,0 +1 @@
srcu.h
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/include/linux/kconfig.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/include/linux/kconfig.h
new file mode 100644
index 000000000000..f2860dd1b407
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/include/linux/kconfig.h
@@ -0,0 +1 @@
#include <LINUX_SOURCE/linux/kconfig.h>
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/include/linux/types.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/include/linux/types.h
new file mode 100644
index 000000000000..4a3d538fef12
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/include/linux/types.h
@@ -0,0 +1,155 @@
1/*
2 * This header has been modifies to remove definitions of types that
3 * are defined in standard userspace headers or are problematic for some
4 * other reason.
5 */
6
7#ifndef _LINUX_TYPES_H
8#define _LINUX_TYPES_H
9
10#define __EXPORTED_HEADERS__
11#include <uapi/linux/types.h>
12
13#ifndef __ASSEMBLY__
14
15#define DECLARE_BITMAP(name, bits) \
16 unsigned long name[BITS_TO_LONGS(bits)]
17
18typedef __u32 __kernel_dev_t;
19
20/* bsd */
21typedef unsigned char u_char;
22typedef unsigned short u_short;
23typedef unsigned int u_int;
24typedef unsigned long u_long;
25
26/* sysv */
27typedef unsigned char unchar;
28typedef unsigned short ushort;
29typedef unsigned int uint;
30typedef unsigned long ulong;
31
32#ifndef __BIT_TYPES_DEFINED__
33#define __BIT_TYPES_DEFINED__
34
35typedef __u8 u_int8_t;
36typedef __s8 int8_t;
37typedef __u16 u_int16_t;
38typedef __s16 int16_t;
39typedef __u32 u_int32_t;
40typedef __s32 int32_t;
41
42#endif /* !(__BIT_TYPES_DEFINED__) */
43
44typedef __u8 uint8_t;
45typedef __u16 uint16_t;
46typedef __u32 uint32_t;
47
48/* this is a special 64bit data type that is 8-byte aligned */
49#define aligned_u64 __u64 __attribute__((aligned(8)))
50#define aligned_be64 __be64 __attribute__((aligned(8)))
51#define aligned_le64 __le64 __attribute__((aligned(8)))
52
53/**
54 * The type used for indexing onto a disc or disc partition.
55 *
56 * Linux always considers sectors to be 512 bytes long independently
57 * of the devices real block size.
58 *
59 * blkcnt_t is the type of the inode's block count.
60 */
61#ifdef CONFIG_LBDAF
62typedef u64 sector_t;
63#else
64typedef unsigned long sector_t;
65#endif
66
67/*
68 * The type of an index into the pagecache.
69 */
70#define pgoff_t unsigned long
71
72/*
73 * A dma_addr_t can hold any valid DMA address, i.e., any address returned
74 * by the DMA API.
75 *
76 * If the DMA API only uses 32-bit addresses, dma_addr_t need only be 32
77 * bits wide. Bus addresses, e.g., PCI BARs, may be wider than 32 bits,
78 * but drivers do memory-mapped I/O to ioremapped kernel virtual addresses,
79 * so they don't care about the size of the actual bus addresses.
80 */
81#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
82typedef u64 dma_addr_t;
83#else
84typedef u32 dma_addr_t;
85#endif
86
87#ifdef CONFIG_PHYS_ADDR_T_64BIT
88typedef u64 phys_addr_t;
89#else
90typedef u32 phys_addr_t;
91#endif
92
93typedef phys_addr_t resource_size_t;
94
95/*
96 * This type is the placeholder for a hardware interrupt number. It has to be
97 * big enough to enclose whatever representation is used by a given platform.
98 */
99typedef unsigned long irq_hw_number_t;
100
101typedef struct {
102 int counter;
103} atomic_t;
104
105#ifdef CONFIG_64BIT
106typedef struct {
107 long counter;
108} atomic64_t;
109#endif
110
111struct list_head {
112 struct list_head *next, *prev;
113};
114
115struct hlist_head {
116 struct hlist_node *first;
117};
118
119struct hlist_node {
120 struct hlist_node *next, **pprev;
121};
122
123/**
124 * struct callback_head - callback structure for use with RCU and task_work
125 * @next: next update requests in a list
126 * @func: actual update function to call after the grace period.
127 *
128 * The struct is aligned to size of pointer. On most architectures it happens
129 * naturally due ABI requirements, but some architectures (like CRIS) have
130 * weird ABI and we need to ask it explicitly.
131 *
132 * The alignment is required to guarantee that bits 0 and 1 of @next will be
133 * clear under normal conditions -- as long as we use call_rcu(),
134 * call_rcu_bh(), call_rcu_sched(), or call_srcu() to queue callback.
135 *
136 * This guarantee is important for few reasons:
137 * - future call_rcu_lazy() will make use of lower bits in the pointer;
138 * - the structure shares storage spacer in struct page with @compound_head,
139 * which encode PageTail() in bit 0. The guarantee is needed to avoid
140 * false-positive PageTail().
141 */
142struct callback_head {
143 struct callback_head *next;
144 void (*func)(struct callback_head *head);
145} __attribute__((aligned(sizeof(void *))));
146#define rcu_head callback_head
147
148typedef void (*rcu_callback_t)(struct rcu_head *head);
149typedef void (*call_rcu_func_t)(struct rcu_head *head, rcu_callback_t func);
150
151/* clocksource cycle base type */
152typedef u64 cycle_t;
153
154#endif /* __ASSEMBLY__ */
155#endif /* _LINUX_TYPES_H */
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/modify_srcu.awk b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/modify_srcu.awk
new file mode 100755
index 000000000000..8ff89043d0a9
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/modify_srcu.awk
@@ -0,0 +1,375 @@
1#!/bin/awk -f
2
3# Modify SRCU for formal verification. The first argument should be srcu.h and
4# the second should be srcu.c. Outputs modified srcu.h and srcu.c into the
5# current directory.
6
7BEGIN {
8 if (ARGC != 5) {
9 print "Usange: input.h input.c output.h output.c" > "/dev/stderr";
10 exit 1;
11 }
12 h_output = ARGV[3];
13 c_output = ARGV[4];
14 ARGC = 3;
15
16 # Tokenize using FS and not RS as FS supports regular expressions. Each
17 # record is one line of source, except that backslashed lines are
18 # combined. Comments are treated as field separators, as are quotes.
19 quote_regexp="\"([^\\\\\"]|\\\\.)*\"";
20 comment_regexp="\\/\\*([^*]|\\*+[^*/])*\\*\\/|\\/\\/.*(\n|$)";
21 FS="([ \\\\\t\n\v\f;,.=(){}+*/<>&|^-]|\\[|\\]|" comment_regexp "|" quote_regexp ")+";
22
23 inside_srcu_struct = 0;
24 inside_srcu_init_def = 0;
25 srcu_init_param_name = "";
26 in_macro = 0;
27 brace_nesting = 0;
28 paren_nesting = 0;
29
30 # Allow the manipulation of the last field separator after has been
31 # seen.
32 last_fs = "";
33 # Whether the last field separator was intended to be output.
34 last_fs_print = 0;
35
36 # rcu_batches stores the initialization for each instance of struct
37 # rcu_batch
38
39 in_comment = 0;
40
41 outputfile = "";
42}
43
44{
45 prev_outputfile = outputfile;
46 if (FILENAME ~ /\.h$/) {
47 outputfile = h_output;
48 if (FNR != NR) {
49 print "Incorrect file order" > "/dev/stderr";
50 exit 1;
51 }
52 }
53 else
54 outputfile = c_output;
55
56 if (prev_outputfile && outputfile != prev_outputfile) {
57 new_outputfile = outputfile;
58 outputfile = prev_outputfile;
59 update_fieldsep("", 0);
60 outputfile = new_outputfile;
61 }
62}
63
64# Combine the next line into $0.
65function combine_line() {
66 ret = getline next_line;
67 if (ret == 0) {
68 # Don't allow two consecutive getlines at the end of the file
69 if (eof_found) {
70 print "Error: expected more input." > "/dev/stderr";
71 exit 1;
72 } else {
73 eof_found = 1;
74 }
75 } else if (ret == -1) {
76 print "Error reading next line of file" FILENAME > "/dev/stderr";
77 exit 1;
78 }
79 $0 = $0 "\n" next_line;
80}
81
82# Combine backslashed lines and multiline comments.
83function combine_backslashes() {
84 while (/\\$|\/\*([^*]|\*+[^*\/])*\**$/) {
85 combine_line();
86 }
87}
88
89function read_line() {
90 combine_line();
91 combine_backslashes();
92}
93
94# Print out field separators and update variables that depend on them. Only
95# print if p is true. Call with sep="" and p=0 to print out the last field
96# separator.
97function update_fieldsep(sep, p) {
98 # Count braces
99 sep_tmp = sep;
100 gsub(quote_regexp "|" comment_regexp, "", sep_tmp);
101 while (1)
102 {
103 if (sub("[^{}()]*\\{", "", sep_tmp)) {
104 brace_nesting++;
105 continue;
106 }
107 if (sub("[^{}()]*\\}", "", sep_tmp)) {
108 brace_nesting--;
109 if (brace_nesting < 0) {
110 print "Unbalanced braces!" > "/dev/stderr";
111 exit 1;
112 }
113 continue;
114 }
115 if (sub("[^{}()]*\\(", "", sep_tmp)) {
116 paren_nesting++;
117 continue;
118 }
119 if (sub("[^{}()]*\\)", "", sep_tmp)) {
120 paren_nesting--;
121 if (paren_nesting < 0) {
122 print "Unbalanced parenthesis!" > "/dev/stderr";
123 exit 1;
124 }
125 continue;
126 }
127
128 break;
129 }
130
131 if (last_fs_print)
132 printf("%s", last_fs) > outputfile;
133 last_fs = sep;
134 last_fs_print = p;
135}
136
137# Shifts the fields down by n positions. Calls next if there are no more. If p
138# is true then print out field separators.
139function shift_fields(n, p) {
140 do {
141 if (match($0, FS) > 0) {
142 update_fieldsep(substr($0, RSTART, RLENGTH), p);
143 if (RSTART + RLENGTH <= length())
144 $0 = substr($0, RSTART + RLENGTH);
145 else
146 $0 = "";
147 } else {
148 update_fieldsep("", 0);
149 print "" > outputfile;
150 next;
151 }
152 } while (--n > 0);
153}
154
155# Shifts and prints the first n fields.
156function print_fields(n) {
157 do {
158 update_fieldsep("", 0);
159 printf("%s", $1) > outputfile;
160 shift_fields(1, 1);
161 } while (--n > 0);
162}
163
164{
165 combine_backslashes();
166}
167
168# Print leading FS
169{
170 if (match($0, "^(" FS ")+") > 0) {
171 update_fieldsep(substr($0, RSTART, RLENGTH), 1);
172 if (RSTART + RLENGTH <= length())
173 $0 = substr($0, RSTART + RLENGTH);
174 else
175 $0 = "";
176 }
177}
178
179# Parse the line.
180{
181 while (NF > 0) {
182 if ($1 == "struct" && NF < 3) {
183 read_line();
184 continue;
185 }
186
187 if (FILENAME ~ /\.h$/ && !inside_srcu_struct &&
188 brace_nesting == 0 && paren_nesting == 0 &&
189 $1 == "struct" && $2 == "srcu_struct" &&
190 $0 ~ "^struct(" FS ")+srcu_struct(" FS ")+\\{") {
191 inside_srcu_struct = 1;
192 print_fields(2);
193 continue;
194 }
195 if (inside_srcu_struct && brace_nesting == 0 &&
196 paren_nesting == 0) {
197 inside_srcu_struct = 0;
198 update_fieldsep("", 0);
199 for (name in rcu_batches)
200 print "extern struct rcu_batch " name ";" > outputfile;
201 }
202
203 if (inside_srcu_struct && $1 == "struct" && $2 == "rcu_batch") {
204 # Move rcu_batches outside of the struct.
205 rcu_batches[$3] = "";
206 shift_fields(3, 1);
207 sub(/;[[:space:]]*$/, "", last_fs);
208 continue;
209 }
210
211 if (FILENAME ~ /\.h$/ && !inside_srcu_init_def &&
212 $1 == "#define" && $2 == "__SRCU_STRUCT_INIT") {
213 inside_srcu_init_def = 1;
214 srcu_init_param_name = $3;
215 in_macro = 1;
216 print_fields(3);
217 continue;
218 }
219 if (inside_srcu_init_def && brace_nesting == 0 &&
220 paren_nesting == 0) {
221 inside_srcu_init_def = 0;
222 in_macro = 0;
223 continue;
224 }
225
226 if (inside_srcu_init_def && brace_nesting == 1 &&
227 paren_nesting == 0 && last_fs ~ /\.[[:space:]]*$/ &&
228 $1 ~ /^[[:alnum:]_]+$/) {
229 name = $1;
230 if (name in rcu_batches) {
231 # Remove the dot.
232 sub(/\.[[:space:]]*$/, "", last_fs);
233
234 old_record = $0;
235 do
236 shift_fields(1, 0);
237 while (last_fs !~ /,/ || paren_nesting > 0);
238 end_loc = length(old_record) - length($0);
239 end_loc += index(last_fs, ",") - length(last_fs);
240
241 last_fs = substr(last_fs, index(last_fs, ",") + 1);
242 last_fs_print = 1;
243
244 match(old_record, "^"name"("FS")+=");
245 start_loc = RSTART + RLENGTH;
246
247 len = end_loc - start_loc;
248 initializer = substr(old_record, start_loc, len);
249 gsub(srcu_init_param_name "\\.", "", initializer);
250 rcu_batches[name] = initializer;
251 continue;
252 }
253 }
254
255 # Don't include a nonexistent file
256 if (!in_macro && $1 == "#include" && /^#include[[:space:]]+"rcu\.h"/) {
257 update_fieldsep("", 0);
258 next;
259 }
260
261 # Ignore most preprocessor stuff.
262 if (!in_macro && $1 ~ /#/) {
263 break;
264 }
265
266 if (brace_nesting > 0 && $1 ~ "^[[:alnum:]_]+$" && NF < 2) {
267 read_line();
268 continue;
269 }
270 if (brace_nesting > 0 &&
271 $0 ~ "^[[:alnum:]_]+[[:space:]]*(\\.|->)[[:space:]]*[[:alnum:]_]+" &&
272 $2 in rcu_batches) {
273 # Make uses of rcu_batches global. Somewhat unreliable.
274 shift_fields(1, 0);
275 print_fields(1);
276 continue;
277 }
278
279 if ($1 == "static" && NF < 3) {
280 read_line();
281 continue;
282 }
283 if ($1 == "static" && ($2 == "bool" && $3 == "try_check_zero" ||
284 $2 == "void" && $3 == "srcu_flip")) {
285 shift_fields(1, 1);
286 print_fields(2);
287 continue;
288 }
289
290 # Distinguish between read-side and write-side memory barriers.
291 if ($1 == "smp_mb" && NF < 2) {
292 read_line();
293 continue;
294 }
295 if (match($0, /^smp_mb[[:space:]();\/*]*[[:alnum:]]/)) {
296 barrier_letter = substr($0, RLENGTH, 1);
297 if (barrier_letter ~ /A|D/)
298 new_barrier_name = "sync_smp_mb";
299 else if (barrier_letter ~ /B|C/)
300 new_barrier_name = "rs_smp_mb";
301 else {
302 print "Unrecognized memory barrier." > "/dev/null";
303 exit 1;
304 }
305
306 shift_fields(1, 1);
307 printf("%s", new_barrier_name) > outputfile;
308 continue;
309 }
310
311 # Skip definition of rcu_synchronize, since it is already
312 # defined in misc.h. Only present in old versions of srcu.
313 if (brace_nesting == 0 && paren_nesting == 0 &&
314 $1 == "struct" && $2 == "rcu_synchronize" &&
315 $0 ~ "^struct(" FS ")+rcu_synchronize(" FS ")+\\{") {
316 shift_fields(2, 0);
317 while (brace_nesting) {
318 if (NF < 2)
319 read_line();
320 shift_fields(1, 0);
321 }
322 }
323
324 # Skip definition of wakeme_after_rcu for the same reason
325 if (brace_nesting == 0 && $1 == "static" && $2 == "void" &&
326 $3 == "wakeme_after_rcu") {
327 while (NF < 5)
328 read_line();
329 shift_fields(3, 0);
330 do {
331 while (NF < 3)
332 read_line();
333 shift_fields(1, 0);
334 } while (paren_nesting || brace_nesting);
335 }
336
337 if ($1 ~ /^(unsigned|long)$/ && NF < 3) {
338 read_line();
339 continue;
340 }
341
342 # Give srcu_batches_completed the correct type for old SRCU.
343 if (brace_nesting == 0 && $1 == "long" &&
344 $2 == "srcu_batches_completed") {
345 update_fieldsep("", 0);
346 printf("unsigned ") > outputfile;
347 print_fields(2);
348 continue;
349 }
350 if (brace_nesting == 0 && $1 == "unsigned" && $2 == "long" &&
351 $3 == "srcu_batches_completed") {
352 print_fields(3);
353 continue;
354 }
355
356 # Just print out the input code by default.
357 print_fields(1);
358 }
359 update_fieldsep("", 0);
360 print > outputfile;
361 next;
362}
363
364END {
365 update_fieldsep("", 0);
366
367 if (brace_nesting != 0) {
368 print "Unbalanced braces!" > "/dev/stderr";
369 exit 1;
370 }
371
372 # Define the rcu_batches
373 for (name in rcu_batches)
374 print "struct rcu_batch " name " = " rcu_batches[name] ";" > c_output;
375}
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/assume.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/assume.h
new file mode 100644
index 000000000000..a64955447995
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/assume.h
@@ -0,0 +1,16 @@
1#ifndef ASSUME_H
2#define ASSUME_H
3
4/* Provide an assumption macro that can be disabled for gcc. */
5#ifdef RUN
6#define assume(x) \
7 do { \
8 /* Evaluate x to suppress warnings. */ \
9 (void) (x); \
10 } while (0)
11
12#else
13#define assume(x) __CPROVER_assume(x)
14#endif
15
16#endif
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h
new file mode 100644
index 000000000000..6687acc08e6d
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/barriers.h
@@ -0,0 +1,41 @@
1#ifndef BARRIERS_H
2#define BARRIERS_H
3
4#define barrier() __asm__ __volatile__("" : : : "memory")
5
6#ifdef RUN
7#define smp_mb() __sync_synchronize()
8#define smp_mb__after_unlock_lock() __sync_synchronize()
9#else
10/*
11 * Copied from CBMC's implementation of __sync_synchronize(), which
12 * seems to be disabled by default.
13 */
14#define smp_mb() __CPROVER_fence("WWfence", "RRfence", "RWfence", "WRfence", \
15 "WWcumul", "RRcumul", "RWcumul", "WRcumul")
16#define smp_mb__after_unlock_lock() __CPROVER_fence("WWfence", "RRfence", "RWfence", "WRfence", \
17 "WWcumul", "RRcumul", "RWcumul", "WRcumul")
18#endif
19
20/*
21 * Allow memory barriers to be disabled in either the read or write side
22 * of SRCU individually.
23 */
24
25#ifndef NO_SYNC_SMP_MB
26#define sync_smp_mb() smp_mb()
27#else
28#define sync_smp_mb() do {} while (0)
29#endif
30
31#ifndef NO_READ_SIDE_SMP_MB
32#define rs_smp_mb() smp_mb()
33#else
34#define rs_smp_mb() do {} while (0)
35#endif
36
37#define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x))
38#define READ_ONCE(x) ACCESS_ONCE(x)
39#define WRITE_ONCE(x, val) (ACCESS_ONCE(x) = (val))
40
41#endif
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/bug_on.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/bug_on.h
new file mode 100644
index 000000000000..2a80e91f78e7
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/bug_on.h
@@ -0,0 +1,13 @@
1#ifndef BUG_ON_H
2#define BUG_ON_H
3
4#include <assert.h>
5
6#define BUG() assert(0)
7#define BUG_ON(x) assert(!(x))
8
9/* Does it make sense to treat warnings as errors? */
10#define WARN() BUG()
11#define WARN_ON(x) (BUG_ON(x), false)
12
13#endif
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/combined_source.c b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/combined_source.c
new file mode 100644
index 000000000000..29eb5d2697ed
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/combined_source.c
@@ -0,0 +1,13 @@
1#include <config.h>
2
3/* Include all source files. */
4
5#include "include_srcu.c"
6
7#include "preempt.c"
8#include "misc.c"
9
10/* Used by test.c files */
11#include <pthread.h>
12#include <stdlib.h>
13#include <linux/srcu.h>
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/config.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/config.h
new file mode 100644
index 000000000000..a60038aeea7a
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/config.h
@@ -0,0 +1,27 @@
1/* "Cheater" definitions based on restricted Kconfig choices. */
2
3#undef CONFIG_TINY_RCU
4#undef __CHECKER__
5#undef CONFIG_DEBUG_LOCK_ALLOC
6#undef CONFIG_DEBUG_OBJECTS_RCU_HEAD
7#undef CONFIG_HOTPLUG_CPU
8#undef CONFIG_MODULES
9#undef CONFIG_NO_HZ_FULL_SYSIDLE
10#undef CONFIG_PREEMPT_COUNT
11#undef CONFIG_PREEMPT_RCU
12#undef CONFIG_PROVE_RCU
13#undef CONFIG_RCU_NOCB_CPU
14#undef CONFIG_RCU_NOCB_CPU_ALL
15#undef CONFIG_RCU_STALL_COMMON
16#undef CONFIG_RCU_TRACE
17#undef CONFIG_RCU_USER_QS
18#undef CONFIG_TASKS_RCU
19#define CONFIG_TREE_RCU
20
21#define CONFIG_GENERIC_ATOMIC64
22
23#if NR_CPUS > 1
24#define CONFIG_SMP
25#else
26#undef CONFIG_SMP
27#endif
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/include_srcu.c b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/include_srcu.c
new file mode 100644
index 000000000000..5ec582a53018
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/include_srcu.c
@@ -0,0 +1,31 @@
1#include <config.h>
2
3#include <assert.h>
4#include <errno.h>
5#include <inttypes.h>
6#include <pthread.h>
7#include <stddef.h>
8#include <string.h>
9#include <sys/types.h>
10
11#include "int_typedefs.h"
12
13#include "barriers.h"
14#include "bug_on.h"
15#include "locks.h"
16#include "misc.h"
17#include "preempt.h"
18#include "percpu.h"
19#include "workqueues.h"
20
21#ifdef USE_SIMPLE_SYNC_SRCU
22#define synchronize_srcu(sp) synchronize_srcu_original(sp)
23#endif
24
25#include <srcu.c>
26
27#ifdef USE_SIMPLE_SYNC_SRCU
28#undef synchronize_srcu
29
30#include "simple_sync_srcu.c"
31#endif
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/int_typedefs.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/int_typedefs.h
new file mode 100644
index 000000000000..3aad63917858
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/int_typedefs.h
@@ -0,0 +1,33 @@
1#ifndef INT_TYPEDEFS_H
2#define INT_TYPEDEFS_H
3
4#include <inttypes.h>
5
6typedef int8_t s8;
7typedef uint8_t u8;
8typedef int16_t s16;
9typedef uint16_t u16;
10typedef int32_t s32;
11typedef uint32_t u32;
12typedef int64_t s64;
13typedef uint64_t u64;
14
15typedef int8_t __s8;
16typedef uint8_t __u8;
17typedef int16_t __s16;
18typedef uint16_t __u16;
19typedef int32_t __s32;
20typedef uint32_t __u32;
21typedef int64_t __s64;
22typedef uint64_t __u64;
23
24#define S8_C(x) INT8_C(x)
25#define U8_C(x) UINT8_C(x)
26#define S16_C(x) INT16_C(x)
27#define U16_C(x) UINT16_C(x)
28#define S32_C(x) INT32_C(x)
29#define U32_C(x) UINT32_C(x)
30#define S64_C(x) INT64_C(x)
31#define U64_C(x) UINT64_C(x)
32
33#endif
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/locks.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/locks.h
new file mode 100644
index 000000000000..356004665576
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/locks.h
@@ -0,0 +1,220 @@
1#ifndef LOCKS_H
2#define LOCKS_H
3
4#include <limits.h>
5#include <pthread.h>
6#include <stdbool.h>
7
8#include "assume.h"
9#include "bug_on.h"
10#include "preempt.h"
11
12int nondet_int(void);
13
14#define __acquire(x)
15#define __acquires(x)
16#define __release(x)
17#define __releases(x)
18
19/* Only use one lock mechanism. Select which one. */
20#ifdef PTHREAD_LOCK
21struct lock_impl {
22 pthread_mutex_t mutex;
23};
24
25static inline void lock_impl_lock(struct lock_impl *lock)
26{
27 BUG_ON(pthread_mutex_lock(&lock->mutex));
28}
29
30static inline void lock_impl_unlock(struct lock_impl *lock)
31{
32 BUG_ON(pthread_mutex_unlock(&lock->mutex));
33}
34
35static inline bool lock_impl_trylock(struct lock_impl *lock)
36{
37 int err = pthread_mutex_trylock(&lock->mutex);
38
39 if (!err)
40 return true;
41 else if (err == EBUSY)
42 return false;
43 BUG();
44}
45
46static inline void lock_impl_init(struct lock_impl *lock)
47{
48 pthread_mutex_init(&lock->mutex, NULL);
49}
50
51#define LOCK_IMPL_INITIALIZER {.mutex = PTHREAD_MUTEX_INITIALIZER}
52
53#else /* !defined(PTHREAD_LOCK) */
54/* Spinlock that assumes that it always gets the lock immediately. */
55
56struct lock_impl {
57 bool locked;
58};
59
60static inline bool lock_impl_trylock(struct lock_impl *lock)
61{
62#ifdef RUN
63 /* TODO: Should this be a test and set? */
64 return __sync_bool_compare_and_swap(&lock->locked, false, true);
65#else
66 __CPROVER_atomic_begin();
67 bool old_locked = lock->locked;
68 lock->locked = true;
69 __CPROVER_atomic_end();
70
71 /* Minimal barrier to prevent accesses leaking out of lock. */
72 __CPROVER_fence("RRfence", "RWfence");
73
74 return !old_locked;
75#endif
76}
77
78static inline void lock_impl_lock(struct lock_impl *lock)
79{
80 /*
81 * CBMC doesn't support busy waiting, so just assume that the
82 * lock is available.
83 */
84 assume(lock_impl_trylock(lock));
85
86 /*
87 * If the lock was already held by this thread then the assumption
88 * is unsatisfiable (deadlock).
89 */
90}
91
92static inline void lock_impl_unlock(struct lock_impl *lock)
93{
94#ifdef RUN
95 BUG_ON(!__sync_bool_compare_and_swap(&lock->locked, true, false));
96#else
97 /* Minimal barrier to prevent accesses leaking out of lock. */
98 __CPROVER_fence("RWfence", "WWfence");
99
100 __CPROVER_atomic_begin();
101 bool old_locked = lock->locked;
102 lock->locked = false;
103 __CPROVER_atomic_end();
104
105 BUG_ON(!old_locked);
106#endif
107}
108
109static inline void lock_impl_init(struct lock_impl *lock)
110{
111 lock->locked = false;
112}
113
114#define LOCK_IMPL_INITIALIZER {.locked = false}
115
116#endif /* !defined(PTHREAD_LOCK) */
117
118/*
119 * Implement spinlocks using the lock mechanism. Wrap the lock to prevent mixing
120 * locks of different types.
121 */
122typedef struct {
123 struct lock_impl internal_lock;
124} spinlock_t;
125
126#define SPIN_LOCK_UNLOCKED {.internal_lock = LOCK_IMPL_INITIALIZER}
127#define __SPIN_LOCK_UNLOCKED(x) SPIN_LOCK_UNLOCKED
128#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
129
130static inline void spin_lock_init(spinlock_t *lock)
131{
132 lock_impl_init(&lock->internal_lock);
133}
134
135static inline void spin_lock(spinlock_t *lock)
136{
137 /*
138 * Spin locks also need to be removed in order to eliminate all
139 * memory barriers. They are only used by the write side anyway.
140 */
141#ifndef NO_SYNC_SMP_MB
142 preempt_disable();
143 lock_impl_lock(&lock->internal_lock);
144#endif
145}
146
147static inline void spin_unlock(spinlock_t *lock)
148{
149#ifndef NO_SYNC_SMP_MB
150 lock_impl_unlock(&lock->internal_lock);
151 preempt_enable();
152#endif
153}
154
155/* Don't bother with interrupts */
156#define spin_lock_irq(lock) spin_lock(lock)
157#define spin_unlock_irq(lock) spin_unlock(lock)
158#define spin_lock_irqsave(lock, flags) spin_lock(lock)
159#define spin_unlock_irqrestore(lock, flags) spin_unlock(lock)
160
161/*
162 * This is supposed to return an int, but I think that a bool should work as
163 * well.
164 */
165static inline bool spin_trylock(spinlock_t *lock)
166{
167#ifndef NO_SYNC_SMP_MB
168 preempt_disable();
169 return lock_impl_trylock(&lock->internal_lock);
170#else
171 return true;
172#endif
173}
174
175struct completion {
176 /* Hopefuly this won't overflow. */
177 unsigned int count;
178};
179
180#define COMPLETION_INITIALIZER(x) {.count = 0}
181#define DECLARE_COMPLETION(x) struct completion x = COMPLETION_INITIALIZER(x)
182#define DECLARE_COMPLETION_ONSTACK(x) DECLARE_COMPLETION(x)
183
184static inline void init_completion(struct completion *c)
185{
186 c->count = 0;
187}
188
189static inline void wait_for_completion(struct completion *c)
190{
191 unsigned int prev_count = __sync_fetch_and_sub(&c->count, 1);
192
193 assume(prev_count);
194}
195
196static inline void complete(struct completion *c)
197{
198 unsigned int prev_count = __sync_fetch_and_add(&c->count, 1);
199
200 BUG_ON(prev_count == UINT_MAX);
201}
202
203/* This function probably isn't very useful for CBMC. */
204static inline bool try_wait_for_completion(struct completion *c)
205{
206 BUG();
207}
208
209static inline bool completion_done(struct completion *c)
210{
211 return c->count;
212}
213
214/* TODO: Implement complete_all */
215static inline void complete_all(struct completion *c)
216{
217 BUG();
218}
219
220#endif
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/misc.c b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/misc.c
new file mode 100644
index 000000000000..ca892e3b2351
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/misc.c
@@ -0,0 +1,11 @@
1#include <config.h>
2
3#include "misc.h"
4#include "bug_on.h"
5
6struct rcu_head;
7
8void wakeme_after_rcu(struct rcu_head *head)
9{
10 BUG();
11}
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/misc.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/misc.h
new file mode 100644
index 000000000000..aca50030f954
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/misc.h
@@ -0,0 +1,58 @@
1#ifndef MISC_H
2#define MISC_H
3
4#include "assume.h"
5#include "int_typedefs.h"
6#include "locks.h"
7
8#include <linux/types.h>
9
10/* Probably won't need to deal with bottom halves. */
11static inline void local_bh_disable(void) {}
12static inline void local_bh_enable(void) {}
13
14#define MODULE_ALIAS(X)
15#define module_param(...)
16#define EXPORT_SYMBOL_GPL(x)
17
18#define container_of(ptr, type, member) ({ \
19 const typeof(((type *)0)->member) *__mptr = (ptr); \
20 (type *)((char *)__mptr - offsetof(type, member)); \
21})
22
23#ifndef USE_SIMPLE_SYNC_SRCU
24/* Abuse udelay to make sure that busy loops terminate. */
25#define udelay(x) assume(0)
26
27#else
28
29/* The simple custom synchronize_srcu is ok with try_check_zero failing. */
30#define udelay(x) do { } while (0)
31#endif
32
33#define trace_rcu_torture_read(rcutorturename, rhp, secs, c_old, c) \
34 do { } while (0)
35
36#define notrace
37
38/* Avoid including rcupdate.h */
39struct rcu_synchronize {
40 struct rcu_head head;
41 struct completion completion;
42};
43
44void wakeme_after_rcu(struct rcu_head *head);
45
46#define rcu_lock_acquire(a) do { } while (0)
47#define rcu_lock_release(a) do { } while (0)
48#define rcu_lockdep_assert(c, s) do { } while (0)
49#define RCU_LOCKDEP_WARN(c, s) do { } while (0)
50
51/* Let CBMC non-deterministically choose switch between normal and expedited. */
52bool rcu_gp_is_normal(void);
53bool rcu_gp_is_expedited(void);
54
55/* Do the same for old versions of rcu. */
56#define rcu_expedited (rcu_gp_is_expedited())
57
58#endif
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/percpu.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/percpu.h
new file mode 100644
index 000000000000..3de5a49de49b
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/percpu.h
@@ -0,0 +1,92 @@
1#ifndef PERCPU_H
2#define PERCPU_H
3
4#include <stddef.h>
5#include "bug_on.h"
6#include "preempt.h"
7
8#define __percpu
9
10/* Maximum size of any percpu data. */
11#define PERCPU_OFFSET (4 * sizeof(long))
12
13/* Ignore alignment, as CBMC doesn't care about false sharing. */
14#define alloc_percpu(type) __alloc_percpu(sizeof(type), 1)
15
16static inline void *__alloc_percpu(size_t size, size_t align)
17{
18 BUG();
19 return NULL;
20}
21
22static inline void free_percpu(void *ptr)
23{
24 BUG();
25}
26
27#define per_cpu_ptr(ptr, cpu) \
28 ((typeof(ptr)) ((char *) (ptr) + PERCPU_OFFSET * cpu))
29
30#define __this_cpu_inc(pcp) __this_cpu_add(pcp, 1)
31#define __this_cpu_dec(pcp) __this_cpu_sub(pcp, 1)
32#define __this_cpu_sub(pcp, n) __this_cpu_add(pcp, -(typeof(pcp)) (n))
33
34#define this_cpu_inc(pcp) this_cpu_add(pcp, 1)
35#define this_cpu_dec(pcp) this_cpu_sub(pcp, 1)
36#define this_cpu_sub(pcp, n) this_cpu_add(pcp, -(typeof(pcp)) (n))
37
38/* Make CBMC use atomics to work around bug. */
39#ifdef RUN
40#define THIS_CPU_ADD_HELPER(ptr, x) (*(ptr) += (x))
41#else
42/*
43 * Split the atomic into a read and a write so that it has the least
44 * possible ordering.
45 */
46#define THIS_CPU_ADD_HELPER(ptr, x) \
47 do { \
48 typeof(ptr) this_cpu_add_helper_ptr = (ptr); \
49 typeof(ptr) this_cpu_add_helper_x = (x); \
50 typeof(*ptr) this_cpu_add_helper_temp; \
51 __CPROVER_atomic_begin(); \
52 this_cpu_add_helper_temp = *(this_cpu_add_helper_ptr); \
53 __CPROVER_atomic_end(); \
54 this_cpu_add_helper_temp += this_cpu_add_helper_x; \
55 __CPROVER_atomic_begin(); \
56 *(this_cpu_add_helper_ptr) = this_cpu_add_helper_temp; \
57 __CPROVER_atomic_end(); \
58 } while (0)
59#endif
60
61/*
62 * For some reason CBMC needs an atomic operation even though this is percpu
63 * data.
64 */
65#define __this_cpu_add(pcp, n) \
66 do { \
67 BUG_ON(preemptible()); \
68 THIS_CPU_ADD_HELPER(per_cpu_ptr(&(pcp), thread_cpu_id), \
69 (typeof(pcp)) (n)); \
70 } while (0)
71
72#define this_cpu_add(pcp, n) \
73 do { \
74 int this_cpu_add_impl_cpu = get_cpu(); \
75 THIS_CPU_ADD_HELPER(per_cpu_ptr(&(pcp), this_cpu_add_impl_cpu), \
76 (typeof(pcp)) (n)); \
77 put_cpu(); \
78 } while (0)
79
80/*
81 * This will cause a compiler warning because of the cast from char[][] to
82 * type*. This will cause a compile time error if type is too big.
83 */
84#define DEFINE_PER_CPU(type, name) \
85 char name[NR_CPUS][PERCPU_OFFSET]; \
86 typedef char percpu_too_big_##name \
87 [sizeof(type) > PERCPU_OFFSET ? -1 : 1]
88
89#define for_each_possible_cpu(cpu) \
90 for ((cpu) = 0; (cpu) < NR_CPUS; ++(cpu))
91
92#endif
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/preempt.c b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/preempt.c
new file mode 100644
index 000000000000..4f1b068e9b7a
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/preempt.c
@@ -0,0 +1,78 @@
1#include <config.h>
2
3#include "preempt.h"
4
5#include "assume.h"
6#include "locks.h"
7
8/* Support NR_CPUS of at most 64 */
9#define CPU_PREEMPTION_LOCKS_INIT0 LOCK_IMPL_INITIALIZER
10#define CPU_PREEMPTION_LOCKS_INIT1 \
11 CPU_PREEMPTION_LOCKS_INIT0, CPU_PREEMPTION_LOCKS_INIT0
12#define CPU_PREEMPTION_LOCKS_INIT2 \
13 CPU_PREEMPTION_LOCKS_INIT1, CPU_PREEMPTION_LOCKS_INIT1
14#define CPU_PREEMPTION_LOCKS_INIT3 \
15 CPU_PREEMPTION_LOCKS_INIT2, CPU_PREEMPTION_LOCKS_INIT2
16#define CPU_PREEMPTION_LOCKS_INIT4 \
17 CPU_PREEMPTION_LOCKS_INIT3, CPU_PREEMPTION_LOCKS_INIT3
18#define CPU_PREEMPTION_LOCKS_INIT5 \
19 CPU_PREEMPTION_LOCKS_INIT4, CPU_PREEMPTION_LOCKS_INIT4
20
21/*
22 * Simulate disabling preemption by locking a particular cpu. NR_CPUS
23 * should be the actual number of cpus, not just the maximum.
24 */
25struct lock_impl cpu_preemption_locks[NR_CPUS] = {
26 CPU_PREEMPTION_LOCKS_INIT0
27#if (NR_CPUS - 1) & 1
28 , CPU_PREEMPTION_LOCKS_INIT0
29#endif
30#if (NR_CPUS - 1) & 2
31 , CPU_PREEMPTION_LOCKS_INIT1
32#endif
33#if (NR_CPUS - 1) & 4
34 , CPU_PREEMPTION_LOCKS_INIT2
35#endif
36#if (NR_CPUS - 1) & 8
37 , CPU_PREEMPTION_LOCKS_INIT3
38#endif
39#if (NR_CPUS - 1) & 16
40 , CPU_PREEMPTION_LOCKS_INIT4
41#endif
42#if (NR_CPUS - 1) & 32
43 , CPU_PREEMPTION_LOCKS_INIT5
44#endif
45};
46
47#undef CPU_PREEMPTION_LOCKS_INIT0
48#undef CPU_PREEMPTION_LOCKS_INIT1
49#undef CPU_PREEMPTION_LOCKS_INIT2
50#undef CPU_PREEMPTION_LOCKS_INIT3
51#undef CPU_PREEMPTION_LOCKS_INIT4
52#undef CPU_PREEMPTION_LOCKS_INIT5
53
54__thread int thread_cpu_id;
55__thread int preempt_disable_count;
56
57void preempt_disable(void)
58{
59 BUG_ON(preempt_disable_count < 0 || preempt_disable_count == INT_MAX);
60
61 if (preempt_disable_count++)
62 return;
63
64 thread_cpu_id = nondet_int();
65 assume(thread_cpu_id >= 0);
66 assume(thread_cpu_id < NR_CPUS);
67 lock_impl_lock(&cpu_preemption_locks[thread_cpu_id]);
68}
69
70void preempt_enable(void)
71{
72 BUG_ON(preempt_disable_count < 1);
73
74 if (--preempt_disable_count)
75 return;
76
77 lock_impl_unlock(&cpu_preemption_locks[thread_cpu_id]);
78}
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/preempt.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/preempt.h
new file mode 100644
index 000000000000..2f95ee0e4dd5
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/preempt.h
@@ -0,0 +1,58 @@
1#ifndef PREEMPT_H
2#define PREEMPT_H
3
4#include <stdbool.h>
5
6#include "bug_on.h"
7
8/* This flag contains garbage if preempt_disable_count is 0. */
9extern __thread int thread_cpu_id;
10
11/* Support recursive preemption disabling. */
12extern __thread int preempt_disable_count;
13
14void preempt_disable(void);
15void preempt_enable(void);
16
17static inline void preempt_disable_notrace(void)
18{
19 preempt_disable();
20}
21
22static inline void preempt_enable_no_resched(void)
23{
24 preempt_enable();
25}
26
27static inline void preempt_enable_notrace(void)
28{
29 preempt_enable();
30}
31
32static inline int preempt_count(void)
33{
34 return preempt_disable_count;
35}
36
37static inline bool preemptible(void)
38{
39 return !preempt_count();
40}
41
42static inline int get_cpu(void)
43{
44 preempt_disable();
45 return thread_cpu_id;
46}
47
48static inline void put_cpu(void)
49{
50 preempt_enable();
51}
52
53static inline void might_sleep(void)
54{
55 BUG_ON(preempt_disable_count);
56}
57
58#endif
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/simple_sync_srcu.c b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/simple_sync_srcu.c
new file mode 100644
index 000000000000..ac9cbc62b411
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/simple_sync_srcu.c
@@ -0,0 +1,50 @@
1#include <config.h>
2
3#include <assert.h>
4#include <errno.h>
5#include <inttypes.h>
6#include <pthread.h>
7#include <stddef.h>
8#include <string.h>
9#include <sys/types.h>
10
11#include "int_typedefs.h"
12
13#include "barriers.h"
14#include "bug_on.h"
15#include "locks.h"
16#include "misc.h"
17#include "preempt.h"
18#include "percpu.h"
19#include "workqueues.h"
20
21#include <linux/srcu.h>
22
23/* Functions needed from modify_srcu.c */
24bool try_check_zero(struct srcu_struct *sp, int idx, int trycount);
25void srcu_flip(struct srcu_struct *sp);
26
27/* Simpler implementation of synchronize_srcu that ignores batching. */
28void synchronize_srcu(struct srcu_struct *sp)
29{
30 int idx;
31 /*
32 * This code assumes that try_check_zero will succeed anyway,
33 * so there is no point in multiple tries.
34 */
35 const int trycount = 1;
36
37 might_sleep();
38
39 /* Ignore the lock, as multiple writers aren't working yet anyway. */
40
41 idx = 1 ^ (sp->completed & 1);
42
43 /* For comments see srcu_advance_batches. */
44
45 assume(try_check_zero(sp, idx, trycount));
46
47 srcu_flip(sp);
48
49 assume(try_check_zero(sp, idx^1, trycount));
50}
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/workqueues.h b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/workqueues.h
new file mode 100644
index 000000000000..e58c8dfd3e90
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/src/workqueues.h
@@ -0,0 +1,102 @@
1#ifndef WORKQUEUES_H
2#define WORKQUEUES_H
3
4#include <stdbool.h>
5
6#include "barriers.h"
7#include "bug_on.h"
8#include "int_typedefs.h"
9
10#include <linux/types.h>
11
12/* Stub workqueue implementation. */
13
14struct work_struct;
15typedef void (*work_func_t)(struct work_struct *work);
16void delayed_work_timer_fn(unsigned long __data);
17
18struct work_struct {
19/* atomic_long_t data; */
20 unsigned long data;
21
22 struct list_head entry;
23 work_func_t func;
24#ifdef CONFIG_LOCKDEP
25 struct lockdep_map lockdep_map;
26#endif
27};
28
29struct timer_list {
30 struct hlist_node entry;
31 unsigned long expires;
32 void (*function)(unsigned long);
33 unsigned long data;
34 u32 flags;
35 int slack;
36};
37
38struct delayed_work {
39 struct work_struct work;
40 struct timer_list timer;
41
42 /* target workqueue and CPU ->timer uses to queue ->work */
43 struct workqueue_struct *wq;
44 int cpu;
45};
46
47
48static inline bool schedule_work(struct work_struct *work)
49{
50 BUG();
51 return true;
52}
53
54static inline bool schedule_work_on(int cpu, struct work_struct *work)
55{
56 BUG();
57 return true;
58}
59
60static inline bool queue_work(struct workqueue_struct *wq,
61 struct work_struct *work)
62{
63 BUG();
64 return true;
65}
66
67static inline bool queue_delayed_work(struct workqueue_struct *wq,
68 struct delayed_work *dwork,
69 unsigned long delay)
70{
71 BUG();
72 return true;
73}
74
75#define INIT_WORK(w, f) \
76 do { \
77 (w)->data = 0; \
78 (w)->func = (f); \
79 } while (0)
80
81#define INIT_DELAYED_WORK(w, f) INIT_WORK(&(w)->work, (f))
82
83#define __WORK_INITIALIZER(n, f) { \
84 .data = 0, \
85 .entry = { &(n).entry, &(n).entry }, \
86 .func = f \
87 }
88
89/* Don't bother initializing timer. */
90#define __DELAYED_WORK_INITIALIZER(n, f, tflags) { \
91 .work = __WORK_INITIALIZER((n).work, (f)), \
92 }
93
94#define DECLARE_WORK(n, f) \
95 struct workqueue_struct n = __WORK_INITIALIZER
96
97#define DECLARE_DELAYED_WORK(n, f) \
98 struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f, 0)
99
100#define system_power_efficient_wq ((struct workqueue_struct *) NULL)
101
102#endif
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/.gitignore b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/.gitignore
new file mode 100644
index 000000000000..f47cb2045f13
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/.gitignore
@@ -0,0 +1 @@
*.out
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/Makefile b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/Makefile
new file mode 100644
index 000000000000..3a3aee149225
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/Makefile
@@ -0,0 +1,11 @@
1CBMC_FLAGS = -I../.. -I../../src -I../../include -I../../empty_includes -32 -pointer-check -mm pso
2
3all:
4 for i in ./*.pass; do \
5 echo $$i ; \
6 CBMC_FLAGS="$(CBMC_FLAGS)" sh ../test_script.sh --should-pass $$i > $$i.out 2>&1 ; \
7 done
8 for i in ./*.fail; do \
9 echo $$i ; \
10 CBMC_FLAGS="$(CBMC_FLAGS)" sh ../test_script.sh --should-fail $$i > $$i.out 2>&1 ; \
11 done
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/assert_end.fail b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/assert_end.fail
new file mode 100644
index 000000000000..40c8075919d1
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/assert_end.fail
@@ -0,0 +1 @@
test_cbmc_options="-DASSERT_END"
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/force.fail b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/force.fail
new file mode 100644
index 000000000000..ada5baf0b60d
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/force.fail
@@ -0,0 +1 @@
test_cbmc_options="-DFORCE_FAILURE"
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/force2.fail b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/force2.fail
new file mode 100644
index 000000000000..8fe00c8db466
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/force2.fail
@@ -0,0 +1 @@
test_cbmc_options="-DFORCE_FAILURE_2"
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/force3.fail b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/force3.fail
new file mode 100644
index 000000000000..612ed6772844
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/force3.fail
@@ -0,0 +1 @@
test_cbmc_options="-DFORCE_FAILURE_3"
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/main.pass b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/main.pass
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/main.pass
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/test.c b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/test.c
new file mode 100644
index 000000000000..470b1105a112
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/test.c
@@ -0,0 +1,72 @@
1#include <src/combined_source.c>
2
3int x;
4int y;
5
6int __unbuffered_tpr_x;
7int __unbuffered_tpr_y;
8
9DEFINE_SRCU(ss);
10
11void rcu_reader(void)
12{
13 int idx;
14
15#ifndef FORCE_FAILURE_3
16 idx = srcu_read_lock(&ss);
17#endif
18 might_sleep();
19
20 __unbuffered_tpr_y = READ_ONCE(y);
21#ifdef FORCE_FAILURE
22 srcu_read_unlock(&ss, idx);
23 idx = srcu_read_lock(&ss);
24#endif
25 WRITE_ONCE(x, 1);
26
27#ifndef FORCE_FAILURE_3
28 srcu_read_unlock(&ss, idx);
29#endif
30 might_sleep();
31}
32
33void *thread_update(void *arg)
34{
35 WRITE_ONCE(y, 1);
36#ifndef FORCE_FAILURE_2
37 synchronize_srcu(&ss);
38#endif
39 might_sleep();
40 __unbuffered_tpr_x = READ_ONCE(x);
41
42 return NULL;
43}
44
45void *thread_process_reader(void *arg)
46{
47 rcu_reader();
48
49 return NULL;
50}
51
52int main(int argc, char *argv[])
53{
54 pthread_t tu;
55 pthread_t tpr;
56
57 if (pthread_create(&tu, NULL, thread_update, NULL))
58 abort();
59 if (pthread_create(&tpr, NULL, thread_process_reader, NULL))
60 abort();
61 if (pthread_join(tu, NULL))
62 abort();
63 if (pthread_join(tpr, NULL))
64 abort();
65 assert(__unbuffered_tpr_y != 0 || __unbuffered_tpr_x != 0);
66
67#ifdef ASSERT_END
68 assert(0);
69#endif
70
71 return 0;
72}
diff --git a/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/test_script.sh b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/test_script.sh
new file mode 100755
index 000000000000..d1545972a0fa
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/test_script.sh
@@ -0,0 +1,102 @@
1#!/bin/sh
2
3# This script expects a mode (either --should-pass or --should-fail) followed by
4# an input file. The script uses the following environment variables. The test C
5# source file is expected to be named test.c in the directory containing the
6# input file.
7#
8# CBMC: The command to run CBMC. Default: cbmc
9# CBMC_FLAGS: Additional flags to pass to CBMC
10# NR_CPUS: Number of cpus to run tests with. Default specified by the test
11# SYNC_SRCU_MODE: Choose implementation of synchronize_srcu. Defaults to simple.
12# kernel: Version included in the linux kernel source.
13# simple: Use try_check_zero directly.
14#
15# The input file is a script that is sourced by this file. It can define any of
16# the following variables to configure the test.
17#
18# test_cbmc_options: Extra options to pass to CBMC.
19# min_cpus_fail: Minimum number of CPUs (NR_CPUS) for verification to fail.
20# The test is expected to pass if it is run with fewer. (Only
21# useful for .fail files)
22# default_cpus: Quantity of CPUs to use for the test, if not specified on the
23# command line. Default: Larger of 2 and MIN_CPUS_FAIL.
24
25set -e
26
27if test "$#" -ne 2; then
28 echo "Expected one option followed by an input file" 1>&2
29 exit 99
30fi
31
32if test "x$1" = "x--should-pass"; then
33 should_pass="yes"
34elif test "x$1" = "x--should-fail"; then
35 should_pass="no"
36else
37 echo "Unrecognized argument '$1'" 1>&2
38
39 # Exit code 99 indicates a hard error.
40 exit 99
41fi
42
43CBMC=${CBMC:-cbmc}
44
45SYNC_SRCU_MODE=${SYNC_SRCU_MODE:-simple}
46
47case ${SYNC_SRCU_MODE} in
48kernel) sync_srcu_mode_flags="" ;;
49simple) sync_srcu_mode_flags="-DUSE_SIMPLE_SYNC_SRCU" ;;
50
51*)
52 echo "Unrecognized argument '${SYNC_SRCU_MODE}'" 1>&2
53 exit 99
54 ;;
55esac
56
57min_cpus_fail=1
58
59c_file=`dirname "$2"`/test.c
60
61# Source the input file.
62. $2
63
64if test ${min_cpus_fail} -gt 2; then
65 default_default_cpus=${min_cpus_fail}
66else
67 default_default_cpus=2
68fi
69default_cpus=${default_cpus:-${default_default_cpus}}
70cpus=${NR_CPUS:-${default_cpus}}
71
72# Check if there are two few cpus to make the test fail.
73if test $cpus -lt ${min_cpus_fail:-0}; then
74 should_pass="yes"
75fi
76
77cbmc_opts="-DNR_CPUS=${cpus} ${sync_srcu_mode_flags} ${test_cbmc_options} ${CBMC_FLAGS}"
78
79echo "Running CBMC: ${CBMC} ${cbmc_opts} ${c_file}"
80if ${CBMC} ${cbmc_opts} "${c_file}"; then
81 # Verification successful. Make sure that it was supposed to verify.
82 test "x${should_pass}" = xyes
83else
84 cbmc_exit_status=$?
85
86 # An exit status of 10 indicates a failed verification.
87 # (see cbmc_parse_optionst::do_bmc in the CBMC source code)
88 if test ${cbmc_exit_status} -eq 10 && test "x${should_pass}" = xno; then
89 :
90 else
91 echo "CBMC returned ${cbmc_exit_status} exit status" 1>&2
92
93 # Parse errors have exit status 6. Any other type of error
94 # should be considered a hard error.
95 if test ${cbmc_exit_status} -ne 6 && \
96 test ${cbmc_exit_status} -ne 10; then
97 exit 99
98 else
99 exit 1
100 fi
101 fi
102fi