diff options
author | Ingo Molnar <mingo@kernel.org> | 2017-01-31 01:45:42 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-01-31 01:45:42 -0500 |
commit | a8709fa4a06d4af5f86e3660839531cbe0f2a19b (patch) | |
tree | 4deb2947a93294e4771265a60c508598a98cb494 | |
parent | f9a42e0d58cf0fe3d902e63d4582f2ea4cd2bb8b (diff) | |
parent | 31945aa9f14085c81cb3257e51bb210698b78626 (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>
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. McKenney</p> | 8 | <p>This article was contributed by Paul E. 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 | ||
34 | At 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 | |||
9 | This document describes RCU's expedited grace periods. | ||
10 | Unlike RCU's normal grace periods, which accept long latencies to attain | ||
11 | high efficiency and minimal disturbance, expedited grace periods accept | ||
12 | lower efficiency and significant disturbance to attain shorter latencies. | ||
13 | |||
14 | <p> | ||
15 | There are three flavors of RCU (RCU-bh, RCU-preempt, and RCU-sched), | ||
16 | but only two flavors of expedited grace periods because the RCU-bh | ||
17 | expedited grace period maps onto the RCU-sched expedited grace period. | ||
18 | Each 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"> | ||
34 | Expedited Grace Period Design</a></h2> | ||
35 | |||
36 | <p> | ||
37 | The expedited RCU grace periods cannot be accused of being subtle, | ||
38 | given that they for all intents and purposes hammer every CPU that | ||
39 | has not yet provided a quiescent state for the current expedited | ||
40 | grace period. | ||
41 | The one saving grace is that the hammer has grown a bit smaller | ||
42 | over time: The old call to <tt>try_stop_cpus()</tt> has been | ||
43 | replaced with a set of calls to <tt>smp_call_function_single()</tt>, | ||
44 | each of which results in an IPI to the target CPU. | ||
45 | The corresponding handler function checks the CPU's state, motivating | ||
46 | a faster quiescent state where possible, and triggering a report | ||
47 | of that quiescent state. | ||
48 | As always for RCU, once everything has spent some time in a quiescent | ||
49 | state, the expedited grace period has completed. | ||
50 | |||
51 | <p> | ||
52 | The details of the <tt>smp_call_function_single()</tt> handler's | ||
53 | operation depend on the RCU flavor, as described in the following | ||
54 | sections. | ||
55 | |||
56 | <h2><a name="RCU-preempt Expedited Grace Periods"> | ||
57 | RCU-preempt Expedited Grace Periods</a></h2> | ||
58 | |||
59 | <p> | ||
60 | The overall flow of the handling of a given CPU by an RCU-preempt | ||
61 | expedited grace period is shown in the following diagram: | ||
62 | |||
63 | <p><img src="ExpRCUFlow.svg" alt="ExpRCUFlow.svg" width="55%"> | ||
64 | |||
65 | <p> | ||
66 | The solid arrows denote direct action, for example, a function call. | ||
67 | The dotted arrows denote indirect action, for example, an IPI | ||
68 | or a state that is reached after some time. | ||
69 | |||
70 | <p> | ||
71 | If a given CPU is offline or idle, <tt>synchronize_rcu_expedited()</tt> | ||
72 | will ignore it because idle and offline CPUs are already residing | ||
73 | in quiescent states. | ||
74 | Otherwise, the expedited grace period will use | ||
75 | <tt>smp_call_function_single()</tt> to send the CPU an IPI, which | ||
76 | is handled by <tt>sync_rcu_exp_handler()</tt>. | ||
77 | |||
78 | <p> | ||
79 | However, because this is preemptible RCU, <tt>sync_rcu_exp_handler()</tt> | ||
80 | can check to see if the CPU is currently running in an RCU read-side | ||
81 | critical section. | ||
82 | If not, the handler can immediately report a quiescent state. | ||
83 | Otherwise, it sets flags so that the outermost <tt>rcu_read_unlock()</tt> | ||
84 | invocation will provide the needed quiescent-state report. | ||
85 | This flag-setting avoids the previous forced preemption of all | ||
86 | CPUs that might have RCU read-side critical sections. | ||
87 | In addition, this flag-setting is done so as to avoid increasing | ||
88 | the overhead of the common-case fastpath through the scheduler. | ||
89 | |||
90 | <p> | ||
91 | Again because this is preemptible RCU, an RCU read-side critical section | ||
92 | can be preempted. | ||
93 | When that happens, RCU will enqueue the task, which will the continue to | ||
94 | block the current expedited grace period until it resumes and finds its | ||
95 | outermost <tt>rcu_read_unlock()</tt>. | ||
96 | The CPU will report a quiescent state just after enqueuing the task because | ||
97 | the CPU is no longer blocking the grace period. | ||
98 | It is instead the preempted task doing the blocking. | ||
99 | The list of blocked tasks is managed by <tt>rcu_preempt_ctxt_queue()</tt>, | ||
100 | which is called from <tt>rcu_preempt_note_context_switch()</tt>, which | ||
101 | in turn is called from <tt>rcu_note_context_switch()</tt>, which in | ||
102 | turn is called from the scheduler. | ||
103 | |||
104 | <table> | ||
105 | <tr><th> </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> </td></tr> | ||
132 | </table> | ||
133 | |||
134 | <p> | ||
135 | Please note that this is just the overall flow: | ||
136 | Additional complications can arise due to races with CPUs going idle | ||
137 | or offline, among other things. | ||
138 | |||
139 | <h2><a name="RCU-sched Expedited Grace Periods"> | ||
140 | RCU-sched Expedited Grace Periods</a></h2> | ||
141 | |||
142 | <p> | ||
143 | The overall flow of the handling of a given CPU by an RCU-sched | ||
144 | expedited grace period is shown in the following diagram: | ||
145 | |||
146 | <p><img src="ExpSchedFlow.svg" alt="ExpSchedFlow.svg" width="55%"> | ||
147 | |||
148 | <p> | ||
149 | As with RCU-preempt's <tt>synchronize_rcu_expedited()</tt>, | ||
150 | <tt>synchronize_sched_expedited()</tt> ignores offline and | ||
151 | idle CPUs, again because they are in remotely detectable | ||
152 | quiescent states. | ||
153 | However, the <tt>synchronize_rcu_expedited()</tt> handler | ||
154 | is <tt>sync_sched_exp_handler()</tt>, and because the | ||
155 | <tt>rcu_read_lock_sched()</tt> and <tt>rcu_read_unlock_sched()</tt> | ||
156 | leave no trace of their invocation, in general it is not possible to tell | ||
157 | whether or not the current CPU is in an RCU read-side critical section. | ||
158 | The best that <tt>sync_sched_exp_handler()</tt> can do is to check | ||
159 | for idle, on the off-chance that the CPU went idle while the IPI | ||
160 | was in flight. | ||
161 | If the CPU is idle, then tt>sync_sched_exp_handler()</tt> reports | ||
162 | the quiescent state. | ||
163 | |||
164 | <p> | ||
165 | Otherwise, the handler invokes <tt>resched_cpu()</tt>, which forces | ||
166 | a future context switch. | ||
167 | At the time of the context switch, the CPU reports the quiescent state. | ||
168 | Should the CPU go offline first, it will report the quiescent state | ||
169 | at that time. | ||
170 | |||
171 | <h2><a name="Expedited Grace Period and CPU Hotplug"> | ||
172 | Expedited Grace Period and CPU Hotplug</a></h2> | ||
173 | |||
174 | <p> | ||
175 | The expedited nature of expedited grace periods require a much tighter | ||
176 | interaction with CPU hotplug operations than is required for normal | ||
177 | grace periods. | ||
178 | In addition, attempting to IPI offline CPUs will result in splats, but | ||
179 | failing to IPI online CPUs can result in too-short grace periods. | ||
180 | Neither option is acceptable in production kernels. | ||
181 | |||
182 | <p> | ||
183 | The interaction between expedited grace periods and CPU hotplug operations | ||
184 | is 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>->ncpus</tt> | ||
189 | field. | ||
190 | The <tt>rcu_state</tt> structure's <tt>->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>->expmaskinitnext</tt> field. | ||
198 | The <tt>rcu_node</tt> structure's <tt>->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>->ncpus</tt> and | ||
203 | <tt>->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>->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>->expmaskinit</tt> | ||
209 | field from its <tt>->expmaskinitnext</tt> field. | ||
210 | <li> Each <tt>rcu_node</tt> structure's <tt>->expmaskinit</tt> | ||
211 | field is used to initialize that structure's | ||
212 | <tt>->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>->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> </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> </td></tr> | ||
274 | </table> | ||
275 | |||
276 | <h2><a name="Expedited Grace Period Refinements"> | ||
277 | Expedited 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> | ||
292 | Each expedited grace period checks for idle CPUs when initially forming | ||
293 | the 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>). | ||
295 | If the CPU is idle at any time between those two times, the CPU will | ||
296 | not be IPIed. | ||
297 | Instead, the task pushing the grace period forward will include the | ||
298 | idle CPUs in the mask passed to <tt>rcu_report_exp_cpu_mult()</tt>. | ||
299 | |||
300 | <p> | ||
301 | For RCU-sched, there is an additional check for idle in the IPI | ||
302 | handler, <tt>sync_sched_exp_handler()</tt>. | ||
303 | If the IPI has interrupted the idle loop, then | ||
304 | <tt>sync_sched_exp_handler()</tt> invokes <tt>rcu_report_exp_rdp()</tt> | ||
305 | to report the corresponding quiescent state. | ||
306 | |||
307 | <p> | ||
308 | For RCU-preempt, there is no specific check for idle in the | ||
309 | IPI handler (<tt>sync_rcu_exp_handler()</tt>), but because | ||
310 | RCU read-side critical sections are not permitted within the | ||
311 | idle loop, if <tt>sync_rcu_exp_handler()</tt> sees that the CPU is within | ||
312 | RCU read-side critical section, the CPU cannot possibly be idle. | ||
313 | Otherwise, <tt>sync_rcu_exp_handler()</tt> invokes | ||
314 | <tt>rcu_report_exp_rdp()</tt> to report the corresponding quiescent | ||
315 | state, regardless of whether or not that quiescent state was due to | ||
316 | the CPU being idle. | ||
317 | |||
318 | <p> | ||
319 | In summary, RCU expedited grace periods check for idle when building | ||
320 | the bitmask of CPUs that must be IPIed, just before sending each IPI, | ||
321 | and (either explicitly or implicitly) within the IPI handler. | ||
322 | |||
323 | <h3><a name="Batching via Sequence Counter"> | ||
324 | Batching via Sequence Counter</a></h3> | ||
325 | |||
326 | <p> | ||
327 | If each grace-period request was carried out separately, expedited | ||
328 | grace periods would have abysmal scalability and | ||
329 | problematic high-load characteristics. | ||
330 | Because each grace-period operation can serve an unlimited number of | ||
331 | updates, it is important to <i>batch</i> requests, so that a single | ||
332 | expedited grace-period operation will cover all requests in the | ||
333 | corresponding batch. | ||
334 | |||
335 | <p> | ||
336 | This batching is controlled by a sequence counter named | ||
337 | <tt>->expedited_sequence</tt> in the <tt>rcu_state</tt> structure. | ||
338 | This counter has an odd value when there is an expedited grace period | ||
339 | in progress and an even value otherwise, so that dividing the counter | ||
340 | value by two gives the number of completed grace periods. | ||
341 | During any given update request, the counter must transition from | ||
342 | even to odd and then back to even, thus indicating that a grace | ||
343 | period has elapsed. | ||
344 | Therefore, if the initial value of the counter is <tt>s</tt>, | ||
345 | the updater must wait until the counter reaches at least the | ||
346 | value <tt>(s+3)&~0x1</tt>. | ||
347 | This 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> | ||
362 | Again, only one request in a given batch need actually carry out | ||
363 | a grace-period operation, which means there must be an efficient | ||
364 | way to identify which of many concurrent reqeusts will initiate | ||
365 | the grace period, and that there be an efficient way for the | ||
366 | remaining requests to wait for that grace period to complete. | ||
367 | However, that is the topic of the next section. | ||
368 | |||
369 | <h3><a name="Funnel Locking and Wait/Wakeup"> | ||
370 | Funnel Locking and Wait/Wakeup</a></h3> | ||
371 | |||
372 | <p> | ||
373 | The natural way to sort out which of a batch of updaters will initiate | ||
374 | the expedited grace period is to use the <tt>rcu_node</tt> combining | ||
375 | tree, as implemented by the <tt>exp_funnel_lock()</tt> function. | ||
376 | The first updater corresponding to a given grace period arriving | ||
377 | at a given <tt>rcu_node</tt> structure records its desired grace-period | ||
378 | sequence number in the <tt>->exp_seq_rq</tt> field and moves up | ||
379 | to the next level in the tree. | ||
380 | Otherwise, if the <tt>->exp_seq_rq</tt> field already contains | ||
381 | the sequence number for the desired grace period or some later one, | ||
382 | the updater blocks on one of four wait queues in the | ||
383 | <tt>->exp_wq[]</tt> array, using the second-from-bottom | ||
384 | and third-from bottom bits as an index. | ||
385 | An <tt>->exp_lock</tt> field in the <tt>rcu_node</tt> structure | ||
386 | synchronizes access to these fields. | ||
387 | |||
388 | <p> | ||
389 | An empty <tt>rcu_node</tt> tree is shown in the following diagram, | ||
390 | with the white cells representing the <tt>->exp_seq_rq</tt> field | ||
391 | and the red cells representing the elements of the | ||
392 | <tt>->exp_wq[]</tt> array. | ||
393 | |||
394 | <p><img src="Funnel0.svg" alt="Funnel0.svg" width="75%"> | ||
395 | |||
396 | <p> | ||
397 | The next diagram shows the situation after the arrival of Task A | ||
398 | and Task B at the leftmost and rightmost leaf <tt>rcu_node</tt> | ||
399 | structures, respectively. | ||
400 | The current value of the <tt>rcu_state</tt> structure's | ||
401 | <tt>->expedited_sequence</tt> field is zero, so adding three and | ||
402 | clearing the bottom bit results in the value two, which both tasks | ||
403 | record in the <tt>->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> | ||
409 | Each of Tasks A and B will move up to the root | ||
410 | <tt>rcu_node</tt> structure. | ||
411 | Suppose that Task A wins, recording its desired grace-period sequence | ||
412 | number and resulting in the state shown below: | ||
413 | |||
414 | <p><img src="Funnel2.svg" alt="Funnel2.svg" width="75%"> | ||
415 | |||
416 | <p> | ||
417 | Task A now advances to initiate a new grace period, while Task B | ||
418 | moves up to the root <tt>rcu_node</tt> structure, and, seeing that | ||
419 | its desired sequence number is already recorded, blocks on | ||
420 | <tt>->exp_wq[1]</tt>. | ||
421 | |||
422 | <table> | ||
423 | <tr><th> </th></tr> | ||
424 | <tr><th align="left">Quick Quiz:</th></tr> | ||
425 | <tr><td> | ||
426 | Why <tt>->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>->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>->exp_wq[1]</tt>. | ||
440 | </font></td></tr> | ||
441 | <tr><td> </td></tr> | ||
442 | </table> | ||
443 | |||
444 | <p> | ||
445 | If Tasks C and D also arrive at this point, they will compute the | ||
446 | same desired grace-period sequence number, and see that both leaf | ||
447 | <tt>rcu_node</tt> structures already have that value recorded. | ||
448 | They will therefore block on their respective <tt>rcu_node</tt> | ||
449 | structures' <tt>->exp_wq[1]</tt> fields, as shown below: | ||
450 | |||
451 | <p><img src="Funnel3.svg" alt="Funnel3.svg" width="75%"> | ||
452 | |||
453 | <p> | ||
454 | Task A now acquires the <tt>rcu_state</tt> structure's | ||
455 | <tt>->exp_mutex</tt> and initiates the grace period, which | ||
456 | increments <tt>->expedited_sequence</tt>. | ||
457 | Therefore, if Tasks E and F arrive, they will compute | ||
458 | a desired sequence number of 4 and will record this value as | ||
459 | shown below: | ||
460 | |||
461 | <p><img src="Funnel4.svg" alt="Funnel4.svg" width="75%"> | ||
462 | |||
463 | <p> | ||
464 | Tasks E and F will propagate up the <tt>rcu_node</tt> | ||
465 | combining tree, with Task F blocking on the root <tt>rcu_node</tt> | ||
466 | structure and Task E wait for Task A to finish so that | ||
467 | it can start the next grace period. | ||
468 | The resulting state is as shown below: | ||
469 | |||
470 | <p><img src="Funnel5.svg" alt="Funnel5.svg" width="75%"> | ||
471 | |||
472 | <p> | ||
473 | Once the grace period completes, Task A | ||
474 | starts waking up the tasks waiting for this grace period to complete, | ||
475 | increments the <tt>->expedited_sequence</tt>, | ||
476 | acquires the <tt>->exp_wake_mutex</tt> and then releases the | ||
477 | <tt>->exp_mutex</tt>. | ||
478 | This results in the following state: | ||
479 | |||
480 | <p><img src="Funnel6.svg" alt="Funnel6.svg" width="75%"> | ||
481 | |||
482 | <p> | ||
483 | Task E can then acquire <tt>->exp_mutex</tt> and increment | ||
484 | <tt>->expedited_sequence</tt> to the value three. | ||
485 | If new tasks G and H arrive and moves up the combining tree at the | ||
486 | same time, the state will be as follows: | ||
487 | |||
488 | <p><img src="Funnel7.svg" alt="Funnel7.svg" width="75%"> | ||
489 | |||
490 | <p> | ||
491 | Note that three of the root <tt>rcu_node</tt> structure's | ||
492 | waitqueues are now occupied. | ||
493 | However, at some point, Task A will wake up the | ||
494 | tasks blocked on the <tt>->exp_wq</tt> waitqueues, resulting | ||
495 | in the following state: | ||
496 | |||
497 | <p><img src="Funnel8.svg" alt="Funnel8.svg" width="75%"> | ||
498 | |||
499 | <p> | ||
500 | Execution will continue with Tasks E and H completing | ||
501 | their grace periods and carrying out their wakeups. | ||
502 | |||
503 | <table> | ||
504 | <tr><th> </th></tr> | ||
505 | <tr><th align="left">Quick Quiz:</th></tr> | ||
506 | <tr><td> | ||
507 | What happens if Task A takes so long to do its wakeups | ||
508 | that Task 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 E will block on the <tt>->exp_wake_mutex</tt>, | ||
513 | which will also prevent it from releasing <tt>->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>->exp_wq[]</tt> array. | ||
517 | </font></td></tr> | ||
518 | <tr><td> </td></tr> | ||
519 | </table> | ||
520 | |||
521 | <h3><a name="Use of Workqueues">Use of Workqueues</a></h3> | ||
522 | |||
523 | <p> | ||
524 | In earlier implementations, the task requesting the expedited | ||
525 | grace period also drove it to completion. | ||
526 | This straightforward approach had the disadvantage of needing to | ||
527 | account for signals sent to user tasks, | ||
528 | so more recent implemementations use the Linux kernel's | ||
529 | <a href="https://www.kernel.org/doc/Documentation/workqueue.txt">workqueues</a>. | ||
530 | |||
531 | <p> | ||
532 | The requesting task still does counter snapshotting and funnel-lock | ||
533 | processing, but the task reaching the top of the funnel lock | ||
534 | does a <tt>schedule_work()</tt> (from <tt>_synchronize_rcu_expedited()</tt> | ||
535 | so that a workqueue kthread does the actual grace-period processing. | ||
536 | Because workqueue kthreads do not accept signals, grace-period-wait | ||
537 | processing need not allow for signals. | ||
538 | |||
539 | In addition, this approach allows wakeups for the previous expedited | ||
540 | grace period to be overlapped with processing for the next expedited | ||
541 | grace period. | ||
542 | Because there are only four sets of waitqueues, it is necessary to | ||
543 | ensure that the previous grace period's wakeups complete before the | ||
544 | next grace period's wakeups start. | ||
545 | This is handled by having the <tt>->exp_mutex</tt> | ||
546 | guard expedited grace-period processing and the | ||
547 | <tt>->exp_wake_mutex</tt> guard wakeups. | ||
548 | The key point is that the <tt>->exp_mutex</tt> is not released | ||
549 | until the first wakeup is complete, which means that the | ||
550 | <tt>->exp_wake_mutex</tt> has already been acquired at that point. | ||
551 | This approach ensures that the previous grace period's wakeups can | ||
552 | be carried out while the current grace period is in process, but | ||
553 | that these wakeups will complete before the next grace period starts. | ||
554 | This means that only three waitqueues are required, guaranteeing that | ||
555 | the four that are provided are sufficient. | ||
556 | |||
557 | <h3><a name="Stall Warnings">Stall Warnings</a></h3> | ||
558 | |||
559 | <p> | ||
560 | Expediting grace periods does nothing to speed things up when RCU | ||
561 | readers take too long, and therefore expedited grace periods check | ||
562 | for stalls just as normal grace periods do. | ||
563 | |||
564 | <table> | ||
565 | <tr><th> </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> </td></tr> | ||
579 | </table> | ||
580 | |||
581 | The <tt>synchronize_sched_expedited_wait()</tt> function loops waiting | ||
582 | for the expedited grace period to end, but with a timeout set to the | ||
583 | current RCU CPU stall-warning time. | ||
584 | If this time is exceeded, any CPUs or <tt>rcu_node</tt> structures | ||
585 | blocking the current grace period are printed. | ||
586 | Each stall warning results in another pass through the loop, but the | ||
587 | second and subsequent passes use longer stall times. | ||
588 | |||
589 | <h3><a name="Summary"> | ||
590 | Summary</a></h3> | ||
591 | |||
592 | <p> | ||
593 | Expedited grace periods use a sequence-number approach to promote | ||
594 | batching, so that a single grace-period operation can serve numerous | ||
595 | requests. | ||
596 | A funnel lock is used to efficiently identify the one task out of | ||
597 | a concurrent group that will request the grace period. | ||
598 | All members of the group will block on waitqueues provided in | ||
599 | the <tt>rcu_node</tt> structure. | ||
600 | The actual grace-period processing is carried out by a workqueue. | ||
601 | |||
602 | <p> | ||
603 | CPU-hotplug operations are noted lazily in order to prevent the need | ||
604 | for tight synchronization between expedited grace periods and | ||
605 | CPU-hotplug operations. | ||
606 | The dyntick-idle counters are used to avoid sending IPIs to idle CPUs, | ||
607 | at least in the common case. | ||
608 | RCU-preempt and RCU-sched use different IPI handlers and different | ||
609 | code to respond to the state changes carried out by those handlers, | ||
610 | but otherwise use common code. | ||
611 | |||
612 | <p> | ||
613 | Quiescent states are tracked using the <tt>rcu_node</tt> tree, | ||
614 | and once all necessary quiescent states have been reported, | ||
615 | all tasks waiting on this expedited grace period are awakened. | ||
616 | A pair of mutexes are used to allow one grace period's wakeups | ||
617 | to proceed concurrently with the next grace period's processing. | ||
618 | |||
619 | <p> | ||
620 | This combination of mechanisms allows expedited grace periods to | ||
621 | run reasonably efficiently. | ||
622 | However, for non-time-critical tasks, normal grace periods should be | ||
623 | used instead because their longer duration permits much higher | ||
624 | degrees 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">->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">->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">->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">->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">->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">->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">->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">->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">->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> |
1482 | Furthermore, uncertainty about external state is inherent in many cases. | 1482 | Furthermore, uncertainty about external state is inherent in many cases. |
1483 | For example, a pair of veternarians might use heartbeat to determine | 1483 | For example, a pair of veterinarians might use heartbeat to determine |
1484 | whether or not a given cat was alive. | 1484 | whether or not a given cat was alive. |
1485 | But how long should they wait after the last heartbeat to decide that | 1485 | But how long should they wait after the last heartbeat to decide that |
1486 | the cat is in fact dead? | 1486 | the cat is in fact dead? |
@@ -1489,9 +1489,9 @@ mean that a relaxed cat would be considered to cycle between death | |||
1489 | and life more than 100 times per minute. | 1489 | and life more than 100 times per minute. |
1490 | Moreover, just as with human beings, a cat's heart might stop for | 1490 | Moreover, just as with human beings, a cat's heart might stop for |
1491 | some period of time, so the exact wait period is a judgment call. | 1491 | some period of time, so the exact wait period is a judgment call. |
1492 | One of our pair of veternarians might wait 30 seconds before pronouncing | 1492 | One of our pair of veterinarians might wait 30 seconds before pronouncing |
1493 | the cat dead, while the other might insist on waiting a full minute. | 1493 | the cat dead, while the other might insist on waiting a full minute. |
1494 | The two veternarians would then disagree on the state of the cat during | 1494 | The two veterinarians would then disagree on the state of the cat during |
1495 | the final 30 seconds of the minute following the last heartbeat. | 1495 | the 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> |
2888 | Some forms of tracing use “tramopolines” to handle the | 2888 | Some forms of tracing use “trampolines” to handle the |
2889 | binary rewriting required to install different types of probes. | 2889 | binary rewriting required to install different types of probes. |
2890 | It would be good to be able to free old trampolines, which sounds | 2890 | It would be good to be able to free old trampolines, which sounds |
2891 | like a job for some form of RCU. | 2891 | like 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 | ||
238 | The output of "cat rcu/rcu_preempt/rcuexp" looks as follows: | 238 | The output of "cat rcu/rcu_preempt/rcuexp" looks as follows: |
239 | 239 | ||
240 | s=21872 wd1=0 wd2=0 wd3=5 n=0 enq=0 sc=21872 | 240 | s=21872 wd1=0 wd2=0 wd3=5 enq=0 sc=21872 |
241 | 241 | ||
242 | These fields are as follows: | 242 | These 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 | ||
252 | o "n" is number of times that a concurrent CPU-hotplug operation | ||
253 | forced a fallback to a normal grace period. | ||
254 | |||
255 | o "enq" is the number of quiescent states still outstanding. | 252 | o "enq" is the number of quiescent states still outstanding. |
256 | 253 | ||
257 | o "sc" is the number of times that the attempt to start a | 254 | o "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. | |||
640 | CONTROL DEPENDENCIES | 640 | CONTROL DEPENDENCIES |
641 | -------------------- | 641 | -------------------- |
642 | 642 | ||
643 | Control dependencies can be a bit tricky because current compilers do | ||
644 | not understand them. The purpose of this section is to help you prevent | ||
645 | the compiler's ignorance from breaking your code. | ||
646 | |||
643 | A load-load control dependency requires a full read memory barrier, not | 647 | A load-load control dependency requires a full read memory barrier, not |
644 | simply a data dependency barrier to make it work correctly. Consider the | 648 | simply a data dependency barrier to make it work correctly. Consider the |
645 | following bit of code: | 649 | following 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 | ||
673 | Control dependencies pair normally with other types of barriers. That | 677 | Control dependencies pair normally with other types of barriers. |
674 | said, please note that READ_ONCE() is not optional! Without the | 678 | That said, please note that neither READ_ONCE() nor WRITE_ONCE() |
675 | READ_ONCE(), the compiler might combine the load from 'a' with other | 679 | are optional! Without the READ_ONCE(), the compiler might combine the |
676 | loads from 'a', and the store to 'b' with other stores to 'b', with | 680 | load from 'a' with other loads from 'a'. Without the WRITE_ONCE(), |
677 | possible highly counterintuitive effects on ordering. | 681 | the compiler might combine the store to 'b' with other stores to 'b'. |
682 | Either can result in highly counterintuitive effects on ordering. | ||
678 | 683 | ||
679 | Worse yet, if the compiler is able to prove (say) that the value of | 684 | Worse yet, if the compiler is able to prove (say) that the value of |
680 | variable 'a' is always non-zero, it would be well within its rights | 685 | variable '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 | |||
682 | as follows: | 687 | as 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 | ||
687 | So don't leave out the READ_ONCE(). | 692 | So 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 | |||
763 | transform the above code into the following: | 768 | transform 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 | ||
769 | Given this transformation, the CPU is not required to respect the ordering | 774 | Given 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 | ||
821 | It is tempting to argue that there in fact is ordering because the | 826 | It is tempting to argue that there in fact is ordering because the |
822 | compiler cannot reorder volatile accesses and also cannot reorder | 827 | compiler cannot reorder volatile accesses and also cannot reorder |
823 | the writes to "b" with the condition. Unfortunately for this line | 828 | the writes to 'b' with the condition. Unfortunately for this line |
824 | of reasoning, the compiler might compile the two writes to "b" as | 829 | of reasoning, the compiler might compile the two writes to 'b' as |
825 | conditional-move instructions, as in this fanciful pseudo-assembly | 830 | conditional-move instructions, as in this fanciful pseudo-assembly |
826 | language: | 831 | language: |
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 | ||
837 | A weakly ordered CPU would have no dependency of any sort between the load | 840 | A weakly ordered CPU would have no dependency of any sort between the load |
838 | from "a" and the store to "c". The control dependencies would extend | 841 | from 'a' and the store to 'c'. The control dependencies would extend |
839 | only to the pair of cmov instructions and the store depending on them. | 842 | only to the pair of cmov instructions and the store depending on them. |
840 | In short, control dependencies apply only to the stores in the then-clause | 843 | In short, control dependencies apply only to the stores in the then-clause |
841 | and else-clause of the if-statement in question (including functions | 844 | and 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 | ||
844 | Finally, control dependencies do -not- provide transitivity. This is | 847 | Finally, control dependencies do -not- provide transitivity. This is |
845 | demonstrated by two related examples, with the initial values of | 848 | demonstrated by two related examples, with the initial values of |
846 | x 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 | ||
919 | SMP BARRIER PAIRING | 925 | SMP 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 | ||
30 | struct rcu_dynticks; | ||
31 | static inline int rcu_dynticks_snap(struct rcu_dynticks *rdtp) | ||
32 | { | ||
33 | return 0; | ||
34 | } | ||
35 | |||
30 | static inline unsigned long get_state_synchronize_rcu(void) | 36 | static 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 | ||
36 | struct srcu_struct_array { | 36 | struct 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 | ||
41 | struct rcu_batch { | 41 | struct rcu_batch { |
@@ -46,7 +46,7 @@ struct rcu_batch { | |||
46 | 46 | ||
47 | struct srcu_struct { | 47 | struct 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 | */ |
394 | TRACE_EVENT(rcu_fqs, | 394 | TRACE_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 | |||
529 | config TASKS_RCU | 529 | config 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 | ||
782 | endchoice | 781 | endchoice |
783 | 782 | ||
784 | config 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 | |||
797 | endmenu # "RCU Subsystem" | 783 | endmenu # "RCU Subsystem" |
798 | 784 | ||
799 | config BUILD_BIN2C | 785 | config 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 | |||
783 | end: | 787 | end: |
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 | */ |
52 | SYSCALL_DEFINE2(membarrier, int, cmd, int, flags) | 53 | SYSCALL_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 | */ |
147 | static unsigned long srcu_readers_seq_idx(struct srcu_struct *sp, int idx) | 147 | static 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 | */ |
164 | static unsigned long srcu_readers_active_idx(struct srcu_struct *sp, int idx) | 164 | static 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 | */ |
186 | static bool srcu_readers_active_idx_check(struct srcu_struct *sp, int idx) | 181 | static 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 | } |
306 | EXPORT_SYMBOL_GPL(__srcu_read_lock); | 272 | EXPORT_SYMBOL_GPL(__srcu_read_lock); |
@@ -314,7 +280,7 @@ EXPORT_SYMBOL_GPL(__srcu_read_lock); | |||
314 | void __srcu_read_unlock(struct srcu_struct *sp, int idx) | 280 | void __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 | } |
319 | EXPORT_SYMBOL_GPL(__srcu_read_unlock); | 285 | EXPORT_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 | */ |
355 | static void srcu_flip(struct srcu_struct *sp) | 321 | static 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 | */ |
618 | static void srcu_invoke_callbacks(struct srcu_struct *sp) | 599 | static 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. */ |
43 | struct rcu_ctrlblk; | 43 | struct rcu_ctrlblk; |
44 | static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp); | ||
45 | static void rcu_process_callbacks(struct softirq_action *unused); | ||
46 | static void __call_rcu(struct rcu_head *head, | 44 | static 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 | */ | ||
288 | static 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 | */ | ||
306 | static 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 | */ | ||
330 | static 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 | */ | ||
344 | bool 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 | */ | ||
355 | int 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 | */ | ||
366 | static 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 | */ | ||
376 | static 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 | */ | ||
385 | static 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 | |||
284 | DEFINE_PER_CPU_SHARED_ALIGNED(unsigned long, rcu_qs_ctr); | 394 | DEFINE_PER_CPU_SHARED_ALIGNED(unsigned long, rcu_qs_ctr); |
285 | EXPORT_PER_CPU_SYMBOL_GPL(rcu_qs_ctr); | 395 | EXPORT_PER_CPU_SYMBOL_GPL(rcu_qs_ctr); |
286 | 396 | ||
@@ -300,7 +410,6 @@ EXPORT_PER_CPU_SYMBOL_GPL(rcu_qs_ctr); | |||
300 | static void rcu_momentary_dyntick_idle(void) | 410 | static 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 | |||
611 | cpu_has_callbacks_ready_to_invoke(struct rcu_data *rdp) | 717 | cpu_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 | */ |
827 | static void rcu_eqs_exit_common(long long oldval, int user) | 928 | static 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 | */ |
1041 | bool notrace __rcu_is_watching(void) | 1129 | bool 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) | |||
1123 | static int dyntick_save_progress_counter(struct rcu_data *rdp, | 1211 | static 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, | |||
1144 | static int rcu_implicit_dynticks_qs(struct rcu_data *rdp, | 1232 | static 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 | */ |
1282 | static void rcu_dump_cpu_stacks(struct rcu_state *rsp) | 1383 | static 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 | |||
3765 | rcu_init_percpu_data(int cpu, struct rcu_state *rsp) | 3860 | rcu_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; | |||
595 | extern struct rcu_state rcu_preempt_state; | 594 | extern struct rcu_state rcu_preempt_state; |
596 | #endif /* #ifdef CONFIG_PREEMPT_RCU */ | 595 | #endif /* #ifdef CONFIG_PREEMPT_RCU */ |
597 | 596 | ||
597 | int rcu_dynticks_snap(struct rcu_dynticks *rdtp); | ||
598 | |||
598 | #ifdef CONFIG_RCU_BOOST | 599 | #ifdef CONFIG_RCU_BOOST |
599 | DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status); | 600 | DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status); |
600 | DECLARE_PER_CPU(int, rcu_cpu_kthread_cpu); | 601 | DECLARE_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 | */ | ||
24 | static void rcu_exp_gp_seq_start(struct rcu_state *rsp) | 26 | static 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 | */ | ||
28 | static void rcu_exp_gp_seq_end(struct rcu_state *rsp) | 34 | static 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 | */ | ||
33 | static unsigned long rcu_exp_gp_seq_snap(struct rcu_state *rsp) | 43 | static 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 | */ | ||
42 | static bool rcu_exp_gp_seq_done(struct rcu_state *rsp, unsigned long s) | 58 | static 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; |
387 | retry_ipi: | 401 | retry_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 | } |
133 | EXPORT_SYMBOL_GPL(rcu_gp_is_normal); | 133 | EXPORT_SYMBOL_GPL(rcu_gp_is_normal); |
134 | 134 | ||
135 | static atomic_t rcu_expedited_nesting = | 135 | static 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 | */ |
183 | void rcu_end_inkernel_boot(void) | 182 | void 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 | |||
1450 | config RCU_TRACE | 1450 | config 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 @@ | |||
1 | CONFIG_RCU_TORTURE_TEST=y | 1 | CONFIG_RCU_TORTURE_TEST=y |
2 | CONFIG_PRINTK_TIME=y | 2 | CONFIG_PRINTK_TIME=y |
3 | CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y | ||
4 | CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y | ||
5 | CONFIG_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 | |||
7 | CONFIG_NO_HZ_IDLE=y | 7 | CONFIG_NO_HZ_IDLE=y |
8 | CONFIG_NO_HZ_FULL=n | 8 | CONFIG_NO_HZ_FULL=n |
9 | CONFIG_RCU_TRACE=n | 9 | CONFIG_RCU_TRACE=n |
10 | #CHECK#CONFIG_RCU_STALL_COMMON=n | ||
10 | CONFIG_DEBUG_LOCK_ALLOC=n | 11 | CONFIG_DEBUG_LOCK_ALLOC=n |
11 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 12 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
12 | CONFIG_PREEMPT_COUNT=n | 13 | CONFIG_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 | |||
8 | CONFIG_NO_HZ_FULL=n | 8 | CONFIG_NO_HZ_FULL=n |
9 | CONFIG_RCU_TRACE=y | 9 | CONFIG_RCU_TRACE=y |
10 | CONFIG_PROVE_LOCKING=y | 10 | CONFIG_PROVE_LOCKING=y |
11 | CONFIG_PROVE_RCU_REPEATEDLY=y | ||
11 | #CHECK#CONFIG_PROVE_RCU=y | 12 | #CHECK#CONFIG_PROVE_RCU=y |
12 | CONFIG_DEBUG_LOCK_ALLOC=y | 13 | CONFIG_DEBUG_LOCK_ALLOC=y |
13 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 14 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=y |
14 | CONFIG_PREEMPT_COUNT=y | 15 | CONFIG_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 | |||
16 | CONFIG_RCU_BOOST=n | 16 | CONFIG_RCU_BOOST=n |
17 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 17 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
18 | CONFIG_RCU_EXPERT=y | 18 | CONFIG_RCU_EXPERT=y |
19 | CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y | ||
20 | CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y | ||
21 | CONFIG_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 | |||
20 | CONFIG_RCU_BOOST=n | 20 | CONFIG_RCU_BOOST=n |
21 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 21 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
22 | CONFIG_RCU_EXPERT=y | 22 | CONFIG_RCU_EXPERT=y |
23 | CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y | ||
24 | CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y | ||
25 | CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y | ||
26 | CONFIG_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 | |||
17 | CONFIG_RCU_KTHREAD_PRIO=2 | 17 | CONFIG_RCU_KTHREAD_PRIO=2 |
18 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 18 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
19 | CONFIG_RCU_EXPERT=y | 19 | CONFIG_RCU_EXPERT=y |
20 | CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y | ||
21 | CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y | ||
22 | CONFIG_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 | |||
19 | CONFIG_DEBUG_LOCK_ALLOC=n | 19 | CONFIG_DEBUG_LOCK_ALLOC=n |
20 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 20 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
21 | CONFIG_RCU_EXPERT=y | 21 | CONFIG_RCU_EXPERT=y |
22 | CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y | ||
23 | CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y | ||
24 | CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y | ||
25 | CONFIG_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 |
20 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 20 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
21 | CONFIG_RCU_EXPERT=y | 21 | CONFIG_RCU_EXPERT=y |
22 | CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y | ||
23 | CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y | ||
24 | CONFIG_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 |
21 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=y | 21 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=y |
22 | CONFIG_RCU_EXPERT=y | 22 | CONFIG_RCU_EXPERT=y |
23 | CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y | ||
24 | CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y | ||
25 | CONFIG_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 | |||
19 | CONFIG_DEBUG_LOCK_ALLOC=n | 19 | CONFIG_DEBUG_LOCK_ALLOC=n |
20 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 20 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
21 | CONFIG_RCU_EXPERT=y | 21 | CONFIG_RCU_EXPERT=y |
22 | CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y | ||
23 | CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y | ||
24 | CONFIG_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 | |||
17 | CONFIG_RCU_NOCB_CPU=y | 17 | CONFIG_RCU_NOCB_CPU=y |
18 | CONFIG_RCU_NOCB_CPU_ALL=y | 18 | CONFIG_RCU_NOCB_CPU_ALL=y |
19 | CONFIG_DEBUG_LOCK_ALLOC=n | 19 | CONFIG_DEBUG_LOCK_ALLOC=n |
20 | CONFIG_PROVE_LOCKING=y | 20 | CONFIG_PROVE_LOCKING=n |
21 | #CHECK#CONFIG_PROVE_RCU=y | ||
22 | CONFIG_RCU_BOOST=n | 21 | CONFIG_RCU_BOOST=n |
23 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n | 22 | CONFIG_DEBUG_OBJECTS_RCU_HEAD=n |
24 | CONFIG_RCU_EXPERT=y | 23 | CONFIG_RCU_EXPERT=y |
24 | CONFIG_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. | |||
14 | CONFIG_PREEMPT -- Do half. (First three and #8.) | 14 | CONFIG_PREEMPT -- Do half. (First three and #8.) |
15 | CONFIG_PROVE_LOCKING -- Do several, covering CONFIG_DEBUG_LOCK_ALLOC=y and not. | 15 | CONFIG_PROVE_LOCKING -- Do several, covering CONFIG_DEBUG_LOCK_ALLOC=y and not. |
16 | CONFIG_PROVE_RCU -- Hardwired to CONFIG_PROVE_LOCKING. | 16 | CONFIG_PROVE_RCU -- Hardwired to CONFIG_PROVE_LOCKING. |
17 | CONFIG_PROVE_RCU_REPEATEDLY -- Do one. | ||
17 | CONFIG_RCU_BOOST -- one of PREEMPT_RCU. | 18 | CONFIG_RCU_BOOST -- one of PREEMPT_RCU. |
18 | CONFIG_RCU_KTHREAD_PRIO -- set to 2 for _BOOST testing. | 19 | CONFIG_RCU_KTHREAD_PRIO -- set to 2 for _BOOST testing. |
19 | CONFIG_RCU_FANOUT -- Cover hierarchy, but overlap with others. | 20 | CONFIG_RCU_FANOUT -- Cover hierarchy, but overlap with others. |
@@ -25,7 +26,12 @@ CONFIG_RCU_NOCB_CPU_NONE -- Do one. | |||
25 | CONFIG_RCU_NOCB_CPU_ZERO -- Do one. | 26 | CONFIG_RCU_NOCB_CPU_ZERO -- Do one. |
26 | CONFIG_RCU_TRACE -- Do half. | 27 | CONFIG_RCU_TRACE -- Do half. |
27 | CONFIG_SMP -- Need one !SMP for PREEMPT_RCU. | 28 | CONFIG_SMP -- Need one !SMP for PREEMPT_RCU. |
28 | !RCU_EXPERT -- Do a few, but these have to be vanilla configurations. | 29 | CONFIG_RCU_EXPERT=n -- Do a few, but these have to be vanilla configurations. |
30 | CONFIG_RCU_EQS_DEBUG -- Do at least one for CONFIG_NO_HZ_FULL and not. | ||
31 | CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP -- Do for all but a couple TREE scenarios. | ||
32 | CONFIG_RCU_TORTURE_TEST_SLOW_INIT -- Do for all but a couple TREE scenarios. | ||
33 | CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT -- Do for all but a couple TREE scenarios. | ||
34 | |||
29 | RCU-bh: Do one with PREEMPT and one with !PREEMPT. | 35 | RCU-bh: Do one with PREEMPT and one with !PREEMPT. |
30 | RCU-sched: Do one with PREEMPT but not BOOST. | 36 | RCU-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 | ||
81 | CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT_DELAY | ||
82 | CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY | ||
83 | CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP_DELAY | ||
84 | |||
85 | Inspection suffices, ignore. | ||
86 | |||
75 | CONFIG_PREEMPT_RCU | 87 | CONFIG_PREEMPT_RCU |
76 | CONFIG_TREE_RCU | 88 | CONFIG_TREE_RCU |
89 | CONFIG_TINY_RCU | ||
90 | |||
91 | These are controlled by CONFIG_PREEMPT and/or CONFIG_SMP. | ||
92 | |||
93 | CONFIG_SPARSE_RCU_POINTER | ||
94 | |||
95 | Makes sense only for sparse runs, not for kernel builds. | ||
96 | |||
97 | CONFIG_SRCU | ||
98 | CONFIG_TASKS_RCU | ||
99 | |||
100 | Selected by CONFIG_RCU_TORTURE_TEST, so cannot disable. | ||
101 | |||
102 | CONFIG_RCU_TRACE | ||
103 | |||
104 | Implied by CONFIG_RCU_TRACE for Tree RCU. | ||
105 | |||
77 | 106 | ||
78 | These are controlled by CONFIG_PREEMPT. | 107 | boot 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 @@ | |||
1 | all: srcu.c store_buffering | ||
2 | |||
3 | LINUX_SOURCE = ../../../../../.. | ||
4 | |||
5 | modified_srcu_input = $(LINUX_SOURCE)/include/linux/srcu.h \ | ||
6 | $(LINUX_SOURCE)/kernel/rcu/srcu.c | ||
7 | |||
8 | modified_srcu_output = include/linux/srcu.h srcu.c | ||
9 | |||
10 | include/linux/srcu.h: srcu.c | ||
11 | |||
12 | srcu.c: modify_srcu.awk Makefile $(modified_srcu_input) | ||
13 | awk -f modify_srcu.awk $(modified_srcu_input) $(modified_srcu_output) | ||
14 | |||
15 | store_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 | |||
18 | typedef __u32 __kernel_dev_t; | ||
19 | |||
20 | /* bsd */ | ||
21 | typedef unsigned char u_char; | ||
22 | typedef unsigned short u_short; | ||
23 | typedef unsigned int u_int; | ||
24 | typedef unsigned long u_long; | ||
25 | |||
26 | /* sysv */ | ||
27 | typedef unsigned char unchar; | ||
28 | typedef unsigned short ushort; | ||
29 | typedef unsigned int uint; | ||
30 | typedef unsigned long ulong; | ||
31 | |||
32 | #ifndef __BIT_TYPES_DEFINED__ | ||
33 | #define __BIT_TYPES_DEFINED__ | ||
34 | |||
35 | typedef __u8 u_int8_t; | ||
36 | typedef __s8 int8_t; | ||
37 | typedef __u16 u_int16_t; | ||
38 | typedef __s16 int16_t; | ||
39 | typedef __u32 u_int32_t; | ||
40 | typedef __s32 int32_t; | ||
41 | |||
42 | #endif /* !(__BIT_TYPES_DEFINED__) */ | ||
43 | |||
44 | typedef __u8 uint8_t; | ||
45 | typedef __u16 uint16_t; | ||
46 | typedef __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 | ||
62 | typedef u64 sector_t; | ||
63 | #else | ||
64 | typedef 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 | ||
82 | typedef u64 dma_addr_t; | ||
83 | #else | ||
84 | typedef u32 dma_addr_t; | ||
85 | #endif | ||
86 | |||
87 | #ifdef CONFIG_PHYS_ADDR_T_64BIT | ||
88 | typedef u64 phys_addr_t; | ||
89 | #else | ||
90 | typedef u32 phys_addr_t; | ||
91 | #endif | ||
92 | |||
93 | typedef 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 | */ | ||
99 | typedef unsigned long irq_hw_number_t; | ||
100 | |||
101 | typedef struct { | ||
102 | int counter; | ||
103 | } atomic_t; | ||
104 | |||
105 | #ifdef CONFIG_64BIT | ||
106 | typedef struct { | ||
107 | long counter; | ||
108 | } atomic64_t; | ||
109 | #endif | ||
110 | |||
111 | struct list_head { | ||
112 | struct list_head *next, *prev; | ||
113 | }; | ||
114 | |||
115 | struct hlist_head { | ||
116 | struct hlist_node *first; | ||
117 | }; | ||
118 | |||
119 | struct 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 | */ | ||
142 | struct 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 | |||
148 | typedef void (*rcu_callback_t)(struct rcu_head *head); | ||
149 | typedef void (*call_rcu_func_t)(struct rcu_head *head, rcu_callback_t func); | ||
150 | |||
151 | /* clocksource cycle base type */ | ||
152 | typedef 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 | |||
7 | BEGIN { | ||
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. | ||
65 | function 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. | ||
83 | function combine_backslashes() { | ||
84 | while (/\\$|\/\*([^*]|\*+[^*\/])*\**$/) { | ||
85 | combine_line(); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | function 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. | ||
97 | function 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. | ||
139 | function 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. | ||
156 | function 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 | |||
364 | END { | ||
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 | |||
6 | typedef int8_t s8; | ||
7 | typedef uint8_t u8; | ||
8 | typedef int16_t s16; | ||
9 | typedef uint16_t u16; | ||
10 | typedef int32_t s32; | ||
11 | typedef uint32_t u32; | ||
12 | typedef int64_t s64; | ||
13 | typedef uint64_t u64; | ||
14 | |||
15 | typedef int8_t __s8; | ||
16 | typedef uint8_t __u8; | ||
17 | typedef int16_t __s16; | ||
18 | typedef uint16_t __u16; | ||
19 | typedef int32_t __s32; | ||
20 | typedef uint32_t __u32; | ||
21 | typedef int64_t __s64; | ||
22 | typedef 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 | |||
12 | int 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 | ||
21 | struct lock_impl { | ||
22 | pthread_mutex_t mutex; | ||
23 | }; | ||
24 | |||
25 | static inline void lock_impl_lock(struct lock_impl *lock) | ||
26 | { | ||
27 | BUG_ON(pthread_mutex_lock(&lock->mutex)); | ||
28 | } | ||
29 | |||
30 | static inline void lock_impl_unlock(struct lock_impl *lock) | ||
31 | { | ||
32 | BUG_ON(pthread_mutex_unlock(&lock->mutex)); | ||
33 | } | ||
34 | |||
35 | static 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 | |||
46 | static 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 | |||
56 | struct lock_impl { | ||
57 | bool locked; | ||
58 | }; | ||
59 | |||
60 | static 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 | |||
78 | static 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 | |||
92 | static 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 | |||
109 | static 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 | */ | ||
122 | typedef 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 | |||
130 | static inline void spin_lock_init(spinlock_t *lock) | ||
131 | { | ||
132 | lock_impl_init(&lock->internal_lock); | ||
133 | } | ||
134 | |||
135 | static 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 | |||
147 | static 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 | */ | ||
165 | static 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 | |||
175 | struct 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 | |||
184 | static inline void init_completion(struct completion *c) | ||
185 | { | ||
186 | c->count = 0; | ||
187 | } | ||
188 | |||
189 | static 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 | |||
196 | static 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. */ | ||
204 | static inline bool try_wait_for_completion(struct completion *c) | ||
205 | { | ||
206 | BUG(); | ||
207 | } | ||
208 | |||
209 | static inline bool completion_done(struct completion *c) | ||
210 | { | ||
211 | return c->count; | ||
212 | } | ||
213 | |||
214 | /* TODO: Implement complete_all */ | ||
215 | static 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 | |||
6 | struct rcu_head; | ||
7 | |||
8 | void 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. */ | ||
11 | static inline void local_bh_disable(void) {} | ||
12 | static 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 */ | ||
39 | struct rcu_synchronize { | ||
40 | struct rcu_head head; | ||
41 | struct completion completion; | ||
42 | }; | ||
43 | |||
44 | void 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. */ | ||
52 | bool rcu_gp_is_normal(void); | ||
53 | bool 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 | |||
16 | static inline void *__alloc_percpu(size_t size, size_t align) | ||
17 | { | ||
18 | BUG(); | ||
19 | return NULL; | ||
20 | } | ||
21 | |||
22 | static 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 | */ | ||
25 | struct 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 | |||
57 | void 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 | |||
70 | void 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. */ | ||
9 | extern __thread int thread_cpu_id; | ||
10 | |||
11 | /* Support recursive preemption disabling. */ | ||
12 | extern __thread int preempt_disable_count; | ||
13 | |||
14 | void preempt_disable(void); | ||
15 | void preempt_enable(void); | ||
16 | |||
17 | static inline void preempt_disable_notrace(void) | ||
18 | { | ||
19 | preempt_disable(); | ||
20 | } | ||
21 | |||
22 | static inline void preempt_enable_no_resched(void) | ||
23 | { | ||
24 | preempt_enable(); | ||
25 | } | ||
26 | |||
27 | static inline void preempt_enable_notrace(void) | ||
28 | { | ||
29 | preempt_enable(); | ||
30 | } | ||
31 | |||
32 | static inline int preempt_count(void) | ||
33 | { | ||
34 | return preempt_disable_count; | ||
35 | } | ||
36 | |||
37 | static inline bool preemptible(void) | ||
38 | { | ||
39 | return !preempt_count(); | ||
40 | } | ||
41 | |||
42 | static inline int get_cpu(void) | ||
43 | { | ||
44 | preempt_disable(); | ||
45 | return thread_cpu_id; | ||
46 | } | ||
47 | |||
48 | static inline void put_cpu(void) | ||
49 | { | ||
50 | preempt_enable(); | ||
51 | } | ||
52 | |||
53 | static 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 */ | ||
24 | bool try_check_zero(struct srcu_struct *sp, int idx, int trycount); | ||
25 | void srcu_flip(struct srcu_struct *sp); | ||
26 | |||
27 | /* Simpler implementation of synchronize_srcu that ignores batching. */ | ||
28 | void 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 | |||
14 | struct work_struct; | ||
15 | typedef void (*work_func_t)(struct work_struct *work); | ||
16 | void delayed_work_timer_fn(unsigned long __data); | ||
17 | |||
18 | struct 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 | |||
29 | struct 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 | |||
38 | struct 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 | |||
48 | static inline bool schedule_work(struct work_struct *work) | ||
49 | { | ||
50 | BUG(); | ||
51 | return true; | ||
52 | } | ||
53 | |||
54 | static inline bool schedule_work_on(int cpu, struct work_struct *work) | ||
55 | { | ||
56 | BUG(); | ||
57 | return true; | ||
58 | } | ||
59 | |||
60 | static inline bool queue_work(struct workqueue_struct *wq, | ||
61 | struct work_struct *work) | ||
62 | { | ||
63 | BUG(); | ||
64 | return true; | ||
65 | } | ||
66 | |||
67 | static 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 @@ | |||
1 | CBMC_FLAGS = -I../.. -I../../src -I../../include -I../../empty_includes -32 -pointer-check -mm pso | ||
2 | |||
3 | all: | ||
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 | |||
3 | int x; | ||
4 | int y; | ||
5 | |||
6 | int __unbuffered_tpr_x; | ||
7 | int __unbuffered_tpr_y; | ||
8 | |||
9 | DEFINE_SRCU(ss); | ||
10 | |||
11 | void 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 | |||
33 | void *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 | |||
45 | void *thread_process_reader(void *arg) | ||
46 | { | ||
47 | rcu_reader(); | ||
48 | |||
49 | return NULL; | ||
50 | } | ||
51 | |||
52 | int 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 | |||
25 | set -e | ||
26 | |||
27 | if test "$#" -ne 2; then | ||
28 | echo "Expected one option followed by an input file" 1>&2 | ||
29 | exit 99 | ||
30 | fi | ||
31 | |||
32 | if test "x$1" = "x--should-pass"; then | ||
33 | should_pass="yes" | ||
34 | elif test "x$1" = "x--should-fail"; then | ||
35 | should_pass="no" | ||
36 | else | ||
37 | echo "Unrecognized argument '$1'" 1>&2 | ||
38 | |||
39 | # Exit code 99 indicates a hard error. | ||
40 | exit 99 | ||
41 | fi | ||
42 | |||
43 | CBMC=${CBMC:-cbmc} | ||
44 | |||
45 | SYNC_SRCU_MODE=${SYNC_SRCU_MODE:-simple} | ||
46 | |||
47 | case ${SYNC_SRCU_MODE} in | ||
48 | kernel) sync_srcu_mode_flags="" ;; | ||
49 | simple) sync_srcu_mode_flags="-DUSE_SIMPLE_SYNC_SRCU" ;; | ||
50 | |||
51 | *) | ||
52 | echo "Unrecognized argument '${SYNC_SRCU_MODE}'" 1>&2 | ||
53 | exit 99 | ||
54 | ;; | ||
55 | esac | ||
56 | |||
57 | min_cpus_fail=1 | ||
58 | |||
59 | c_file=`dirname "$2"`/test.c | ||
60 | |||
61 | # Source the input file. | ||
62 | . $2 | ||
63 | |||
64 | if test ${min_cpus_fail} -gt 2; then | ||
65 | default_default_cpus=${min_cpus_fail} | ||
66 | else | ||
67 | default_default_cpus=2 | ||
68 | fi | ||
69 | default_cpus=${default_cpus:-${default_default_cpus}} | ||
70 | cpus=${NR_CPUS:-${default_cpus}} | ||
71 | |||
72 | # Check if there are two few cpus to make the test fail. | ||
73 | if test $cpus -lt ${min_cpus_fail:-0}; then | ||
74 | should_pass="yes" | ||
75 | fi | ||
76 | |||
77 | cbmc_opts="-DNR_CPUS=${cpus} ${sync_srcu_mode_flags} ${test_cbmc_options} ${CBMC_FLAGS}" | ||
78 | |||
79 | echo "Running CBMC: ${CBMC} ${cbmc_opts} ${c_file}" | ||
80 | if ${CBMC} ${cbmc_opts} "${c_file}"; then | ||
81 | # Verification successful. Make sure that it was supposed to verify. | ||
82 | test "x${should_pass}" = xyes | ||
83 | else | ||
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 | ||
102 | fi | ||