Merge branch 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull RCU updates from Ingo Molnar: "The RCU changes in this cycle are: - 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 Most of the diffstat comes from the relatively large documentation update" * 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (42 commits) srcu: Reduce probability of SRCU ->unlock_count[] counter overflow rcutorture: Add CBMC-based formal verification for SRCU srcu: Force full grace-period ordering srcu: Implement more-efficient reader counts rcu: Adjust FQS offline checks for exact online-CPU detection rcu: Check cond_resched_rcu_qs() state less often to reduce GP overhead rcu: Abstract extended quiescent state determination rcu: Abstract dynticks extended quiescent state enter/exit operations rcu: Add lockdep checks to synchronous expedited primitives rcu: Eliminate unused expedited_normal counter llist: Clarify comments about when locking is needed rcu: Fix comment in rcu_organize_nocb_kthreads() rcu: Enable RCU tracepoints by default to aid in debugging rcu: Make rcu_cpu_starting() use its "cpu" argument rcu: Add comment headers to expedited-grace-period counter functions rcu: Don't wake rcuc/X kthreads on NOCB CPUs rcu: Re-enable TASKS_RCU for User Mode Linux rcu: Once again use NMI-based stack traces in stall warnings rcu: Remove short-term CPU kicking rcu: Add long-term CPU kicking ...
|
@ -4,7 +4,7 @@
|
||||||
<head><title>A Tour Through TREE_RCU's Data Structures [LWN.net]</title>
|
<head><title>A Tour Through TREE_RCU's Data Structures [LWN.net]</title>
|
||||||
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
|
||||||
<p>January 27, 2016</p>
|
<p>December 18, 2016</p>
|
||||||
<p>This article was contributed by Paul E. McKenney</p>
|
<p>This article was contributed by Paul E. McKenney</p>
|
||||||
|
|
||||||
<h3>Introduction</h3>
|
<h3>Introduction</h3>
|
||||||
|
@ -31,9 +31,6 @@ to each other.
|
||||||
Accessor Functions</a>
|
Accessor Functions</a>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
At the end we have the
|
|
||||||
<a href="#Answers to Quick Quizzes">answers to the quick quizzes</a>.
|
|
||||||
|
|
||||||
<h3><a name="Data-Structure Relationships">Data-Structure Relationships</a></h3>
|
<h3><a name="Data-Structure Relationships">Data-Structure Relationships</a></h3>
|
||||||
|
|
||||||
<p>RCU is for all intents and purposes a large state machine, and its
|
<p>RCU is for all intents and purposes a large state machine, and its
|
||||||
|
|
|
@ -0,0 +1,830 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Creator: fig2dev Version 3.2 Patchlevel 5e -->
|
||||||
|
|
||||||
|
<!-- CreationDate: Wed Dec 9 17:39:46 2015 -->
|
||||||
|
|
||||||
|
<!-- Magnification: 3.000 -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="952.6817"
|
||||||
|
height="1219.6219"
|
||||||
|
viewBox="-66 -66 12729.905 16296.808"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="ExpRCUFlow.svg">
|
||||||
|
<metadata
|
||||||
|
id="metadata94">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs92">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4146"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Mend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3852"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Mend-9"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3852-7"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-7"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-6"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-1"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-4"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-16"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-8"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-160"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-5"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-78"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-66"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-8"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-56"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-19"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-89"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-85"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-3"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-73"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-55"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-5"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-88"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-198"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-2"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-22"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="marker5072"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path5074"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-87"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-63"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-6"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-26"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-0"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-51"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1090"
|
||||||
|
inkscape:window-height="1148"
|
||||||
|
id="namedview90"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:zoom="0.80021373"
|
||||||
|
inkscape:cx="462.49289"
|
||||||
|
inkscape:cy="623.19585"
|
||||||
|
inkscape:window-x="557"
|
||||||
|
inkscape:window-y="24"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="g4"
|
||||||
|
inkscape:snap-grids="false"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-bottom="5"
|
||||||
|
fit-margin-left="5" />
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4"
|
||||||
|
transform="translate(23.312813,523.41305)">
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 11475 2250 - 11475 3465-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 11475 5625 - 11475 6840-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 7875 225 - 10665 225-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 9675 675 - 7785 675-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 9675 4725 - 10665 4725-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 9225 5175 - 10665 5175-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 8775 11475 - 10665 11475-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 11475 9000 - 11475 10215-->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<g
|
||||||
|
id="g4104"
|
||||||
|
transform="translate(-1068.9745,0)">
|
||||||
|
<rect
|
||||||
|
transform="matrix(-0.70710678,0.70710678,-0.70710678,-0.70710678,0,0)"
|
||||||
|
y="-7383.8755"
|
||||||
|
x="-6124.8989"
|
||||||
|
height="1966.2251"
|
||||||
|
width="1953.6969"
|
||||||
|
id="rect3032-1-0"
|
||||||
|
style="fill:#96ff96;fill-opacity:1;stroke:#000000;stroke-width:45.00382233;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4098"
|
||||||
|
y="818.40338"
|
||||||
|
x="8168.2671"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="818.40338"
|
||||||
|
x="8168.2671"
|
||||||
|
id="tspan4100"
|
||||||
|
sodipodi:role="line">Idle or</tspan><tspan
|
||||||
|
id="tspan4102"
|
||||||
|
y="1152.4579"
|
||||||
|
x="8168.2671"
|
||||||
|
sodipodi:role="line">offline?</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g4114"
|
||||||
|
transform="translate(0,147.96969)">
|
||||||
|
<rect
|
||||||
|
id="rect6"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1475.6636"
|
||||||
|
width="4401.7612"
|
||||||
|
y="0"
|
||||||
|
x="0" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110"
|
||||||
|
y="835.11212"
|
||||||
|
x="2206.4917"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="835.11212"
|
||||||
|
x="2206.4917"
|
||||||
|
id="tspan4112"
|
||||||
|
sodipodi:role="line">CPU N Start</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="M 4432.5052,897.4924 5684.8749,880.79414"
|
||||||
|
id="path4119"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="M 8503.0006,874.12161 9755.3703,857.42334"
|
||||||
|
id="path4119-8"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="8617.0977"
|
||||||
|
y="705.50983"
|
||||||
|
id="text4593"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4595"
|
||||||
|
x="8617.0977"
|
||||||
|
y="705.50983">Y</tspan></text>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-9"
|
||||||
|
transform="translate(9722.4732,131.27105)">
|
||||||
|
<rect
|
||||||
|
id="rect6-0"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1425.5687"
|
||||||
|
width="2748.6331"
|
||||||
|
y="0"
|
||||||
|
x="80.17308" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-5"
|
||||||
|
y="835.11212"
|
||||||
|
x="1460.1007"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="835.11212"
|
||||||
|
x="1460.1007"
|
||||||
|
id="tspan4112-9"
|
||||||
|
sodipodi:role="line">Done</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-5"
|
||||||
|
transform="translate(0,3705.3456)">
|
||||||
|
<rect
|
||||||
|
id="rect6-1"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1475.6636"
|
||||||
|
width="4401.7612"
|
||||||
|
y="0"
|
||||||
|
x="0" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-9"
|
||||||
|
y="835.11212"
|
||||||
|
x="2206.4917"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="835.11212"
|
||||||
|
x="2206.4917"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4776">Send IPI to CPU N</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="M 7102.5627,2263.5171 4430.8404,3682.8694"
|
||||||
|
id="path4119-3"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4104-1"
|
||||||
|
transform="translate(-1065.3349,6403.5782)">
|
||||||
|
<rect
|
||||||
|
transform="matrix(-0.70710678,0.70710678,-0.70710678,-0.70710678,0,0)"
|
||||||
|
y="-7383.8755"
|
||||||
|
x="-6124.8989"
|
||||||
|
height="1966.2251"
|
||||||
|
width="1953.6969"
|
||||||
|
id="rect3032-1-0-6"
|
||||||
|
style="fill:#96ff96;fill-opacity:1;stroke:#000000;stroke-width:45.00382233;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4098-3"
|
||||||
|
y="482.00006"
|
||||||
|
x="8168.2671"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
id="tspan4102-8"
|
||||||
|
y="482.00006"
|
||||||
|
x="8168.2671"
|
||||||
|
sodipodi:role="line">In RCU</tspan><tspan
|
||||||
|
y="816.05457"
|
||||||
|
x="8168.2671"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4833">read-side</tspan><tspan
|
||||||
|
y="1150.109"
|
||||||
|
x="8168.2671"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4835">critical</tspan><tspan
|
||||||
|
y="1484.1636"
|
||||||
|
x="8168.2671"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4837">section?</tspan></text>
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="6463.0864"
|
||||||
|
y="2285.6765"
|
||||||
|
id="text4593-0"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4595-6"
|
||||||
|
x="6463.0864"
|
||||||
|
y="2285.6765">N</tspan></text>
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="m 2189.1897,5219.361 16.6983,1252.3697"
|
||||||
|
id="path4119-0"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-5-2"
|
||||||
|
transform="translate(0,6551.5479)">
|
||||||
|
<rect
|
||||||
|
id="rect6-1-7"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1475.6636"
|
||||||
|
width="4401.7612"
|
||||||
|
y="0"
|
||||||
|
x="0" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-9-5"
|
||||||
|
y="835.11212"
|
||||||
|
x="2206.4917"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="835.11212"
|
||||||
|
x="2206.4917"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4776-5">IPI Handler</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="m 4432.5052,7297.9678 1252.3697,-16.6982"
|
||||||
|
id="path4119-2"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="m 8503.0013,7278.6595 1252.369,-16.6982"
|
||||||
|
id="path4119-8-7"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="8617.0977"
|
||||||
|
y="7110.0186"
|
||||||
|
id="text4593-4"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4595-0"
|
||||||
|
x="8617.0977"
|
||||||
|
y="7110.0186">N</tspan></text>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-9-3"
|
||||||
|
transform="translate(9722.4732,6535.809)">
|
||||||
|
<rect
|
||||||
|
id="rect6-0-7"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1425.5687"
|
||||||
|
width="2748.6331"
|
||||||
|
y="29.467337"
|
||||||
|
x="80.17308" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-5-7"
|
||||||
|
y="503.71591"
|
||||||
|
x="1460.1007"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="503.71591"
|
||||||
|
x="1460.1007"
|
||||||
|
id="tspan4112-9-0"
|
||||||
|
sodipodi:role="line">Report CPU</tspan><tspan
|
||||||
|
y="837.77039"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4923">Quiescent</tspan><tspan
|
||||||
|
y="1171.825"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4925">State</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="m 7102.5627,8725.7454 16.6983,1252.3697"
|
||||||
|
id="path4119-0-0"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="6797.0522"
|
||||||
|
y="9018.6807"
|
||||||
|
id="text4593-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4595-2"
|
||||||
|
x="6797.0522"
|
||||||
|
y="9018.6807">Y</tspan></text>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-9-3-8"
|
||||||
|
transform="translate(-80.17308,11381.108)">
|
||||||
|
<rect
|
||||||
|
id="rect6-0-7-5"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1425.5687"
|
||||||
|
width="2748.6331"
|
||||||
|
y="29.467337"
|
||||||
|
x="80.17308" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-5-7-6"
|
||||||
|
y="841.88086"
|
||||||
|
x="1460.1007"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="841.88086"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4925-1">rcu_read_unlock()</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="m 1362.6256,10071.26 16.6983,1252.369"
|
||||||
|
id="path4119-0-0-7"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="m 1362.6256,12883.919 16.6983,1252.369"
|
||||||
|
id="path4119-0-0-7-7"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-9-3-8-1"
|
||||||
|
transform="translate(9722.4732,11389.458)">
|
||||||
|
<rect
|
||||||
|
id="rect6-0-7-5-1"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1425.5687"
|
||||||
|
width="2748.6331"
|
||||||
|
y="29.467337"
|
||||||
|
x="80.17308" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-5-7-6-2"
|
||||||
|
y="841.88086"
|
||||||
|
x="1460.1007"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="841.88086"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4925-1-2">Context Switch</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="m 11165.272,10071.26 16.698,1252.369"
|
||||||
|
id="path4119-0-0-7-8"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-9-3-9"
|
||||||
|
transform="translate(-80.17308,14163.046)">
|
||||||
|
<rect
|
||||||
|
id="rect6-0-7-1"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1425.5687"
|
||||||
|
width="2748.6331"
|
||||||
|
y="29.467337"
|
||||||
|
x="80.17308" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-5-7-3"
|
||||||
|
y="503.71591"
|
||||||
|
x="1460.1007"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="503.71591"
|
||||||
|
x="1460.1007"
|
||||||
|
id="tspan4112-9-0-4"
|
||||||
|
sodipodi:role="line">Report CPU</tspan><tspan
|
||||||
|
y="837.77039"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4923-3">and Task</tspan><tspan
|
||||||
|
y="1171.825"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4925-9">Quiescent States</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-9-3-8-1-8"
|
||||||
|
transform="translate(5663.2978,11389.458)">
|
||||||
|
<rect
|
||||||
|
id="rect6-0-7-5-1-1"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1425.5687"
|
||||||
|
width="2748.6331"
|
||||||
|
y="29.467337"
|
||||||
|
x="80.17308" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-5-7-6-2-4"
|
||||||
|
y="841.88086"
|
||||||
|
x="1460.1007"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="841.88086"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4925-1-2-4">Enqueue Task</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="M 9827.612,12141.988 8575.243,12125.29"
|
||||||
|
id="path4119-8-7-5"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="m 7106.0965,12818.962 16.6983,1252.369"
|
||||||
|
id="path4119-0-0-7-7-5"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-9-3-9-2"
|
||||||
|
transform="translate(5663.2978,14098.088)">
|
||||||
|
<rect
|
||||||
|
id="rect6-0-7-1-8"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1425.5687"
|
||||||
|
width="2748.6331"
|
||||||
|
y="29.467337"
|
||||||
|
x="80.17308" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-5-7-3-4"
|
||||||
|
y="503.71591"
|
||||||
|
x="1460.1007"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="503.71591"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4923-3-2">Report CPU</tspan><tspan
|
||||||
|
y="837.77039"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4925-9-9">Quiescent</tspan><tspan
|
||||||
|
y="1171.825"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan5239">State</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="M 5733.305,14095.542 2761.014,12809.774"
|
||||||
|
id="path4119-0-0-2"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
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"
|
||||||
|
d="m 1353.3524,10079.499 9701.6916,0 100.189,-16.698"
|
||||||
|
id="path5265"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccc" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 32 KiB |
|
@ -0,0 +1,826 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Creator: fig2dev Version 3.2 Patchlevel 5e -->
|
||||||
|
|
||||||
|
<!-- CreationDate: Wed Dec 9 17:39:46 2015 -->
|
||||||
|
|
||||||
|
<!-- Magnification: 3.000 -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="952.6817"
|
||||||
|
height="1425.6191"
|
||||||
|
viewBox="-66 -66 12729.905 19049.38"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="ExpSchedFlow.svg">
|
||||||
|
<metadata
|
||||||
|
id="metadata94">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs92">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4146"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Mend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3852"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Mend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow1Mend-9"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3852-7"
|
||||||
|
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||||
|
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-7"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-6"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-1"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-4"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-16"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-8"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-160"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-5"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-78"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-66"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-8"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-56"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-19"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-89"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-85"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-3"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-73"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-55"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-5"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-88"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-198"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-2"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-22"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="marker5072"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path5074"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-87"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-63"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-6"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-26"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-0"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4146-51"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-58"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path4146-61"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1090"
|
||||||
|
inkscape:window-height="1148"
|
||||||
|
id="namedview90"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:zoom="0.80021373"
|
||||||
|
inkscape:cx="462.49289"
|
||||||
|
inkscape:cy="473.6718"
|
||||||
|
inkscape:window-x="770"
|
||||||
|
inkscape:window-y="24"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="g4114-9-3-9"
|
||||||
|
inkscape:snap-grids="false"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-bottom="5"
|
||||||
|
fit-margin-left="5" />
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4"
|
||||||
|
transform="translate(23.312814,523.41265)">
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 11475 2250 - 11475 3465-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 11475 5625 - 11475 6840-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 7875 225 - 10665 225-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 9675 675 - 7785 675-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 9675 4725 - 10665 4725-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 9225 5175 - 10665 5175-->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 8775 11475 - 10665 11475-->
|
||||||
|
<!-- Line: box -->
|
||||||
|
<!-- Line -->
|
||||||
|
<!-- Arrowhead on XXXpoint 11475 9000 - 11475 10215-->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<!-- Text -->
|
||||||
|
<g
|
||||||
|
id="g4104"
|
||||||
|
transform="translate(-1068.9745,0)">
|
||||||
|
<rect
|
||||||
|
transform="matrix(-0.70710678,0.70710678,-0.70710678,-0.70710678,0,0)"
|
||||||
|
y="-7383.8755"
|
||||||
|
x="-6124.8989"
|
||||||
|
height="1966.2251"
|
||||||
|
width="1953.6969"
|
||||||
|
id="rect3032-1-0"
|
||||||
|
style="fill:#96ff96;fill-opacity:1;stroke:#000000;stroke-width:45.00382233;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4098"
|
||||||
|
y="818.40338"
|
||||||
|
x="8168.2671"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="818.40338"
|
||||||
|
x="8168.2671"
|
||||||
|
id="tspan4100"
|
||||||
|
sodipodi:role="line">Idle or</tspan><tspan
|
||||||
|
id="tspan4102"
|
||||||
|
y="1152.4579"
|
||||||
|
x="8168.2671"
|
||||||
|
sodipodi:role="line">offline?</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g4114"
|
||||||
|
transform="translate(0,147.96969)">
|
||||||
|
<rect
|
||||||
|
id="rect6"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1475.6636"
|
||||||
|
width="4401.7612"
|
||||||
|
y="0"
|
||||||
|
x="0" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110"
|
||||||
|
y="835.11212"
|
||||||
|
x="2206.4917"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="835.11212"
|
||||||
|
x="2206.4917"
|
||||||
|
id="tspan4112"
|
||||||
|
sodipodi:role="line">CPU N Start</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="M 4432.5052,897.4924 5684.8749,880.79414"
|
||||||
|
id="path4119"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="M 8503.0006,874.12161 9755.3703,857.42334"
|
||||||
|
id="path4119-8"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="8617.0977"
|
||||||
|
y="705.50983"
|
||||||
|
id="text4593"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4595"
|
||||||
|
x="8617.0977"
|
||||||
|
y="705.50983">Y</tspan></text>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-9"
|
||||||
|
transform="translate(9722.4732,131.27105)">
|
||||||
|
<rect
|
||||||
|
id="rect6-0"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1425.5687"
|
||||||
|
width="2748.6331"
|
||||||
|
y="0"
|
||||||
|
x="80.17308" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-5"
|
||||||
|
y="835.11212"
|
||||||
|
x="1460.1007"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="835.11212"
|
||||||
|
x="1460.1007"
|
||||||
|
id="tspan4112-9"
|
||||||
|
sodipodi:role="line">Done</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-5"
|
||||||
|
transform="translate(0,3705.3456)">
|
||||||
|
<rect
|
||||||
|
id="rect6-1"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1475.6636"
|
||||||
|
width="4401.7612"
|
||||||
|
y="0"
|
||||||
|
x="0" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-9"
|
||||||
|
y="835.11212"
|
||||||
|
x="2206.4917"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="835.11212"
|
||||||
|
x="2206.4917"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4776">Send IPI to CPU N</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="M 7102.5627,2263.5171 4430.8404,3682.8694"
|
||||||
|
id="path4119-3"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4104-1"
|
||||||
|
transform="translate(-1065.3349,6403.5782)">
|
||||||
|
<rect
|
||||||
|
transform="matrix(-0.70710678,0.70710678,-0.70710678,-0.70710678,0,0)"
|
||||||
|
y="-7383.8755"
|
||||||
|
x="-6124.8989"
|
||||||
|
height="1966.2251"
|
||||||
|
width="1953.6969"
|
||||||
|
id="rect3032-1-0-6"
|
||||||
|
style="fill:#96ff96;fill-opacity:1;stroke:#000000;stroke-width:45.00382233;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4098-3"
|
||||||
|
y="985.4306"
|
||||||
|
x="8168.2671"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="985.4306"
|
||||||
|
x="8168.2671"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3109">CPU idle?</tspan></text>
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="6463.0864"
|
||||||
|
y="2285.6765"
|
||||||
|
id="text4593-0"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4595-6"
|
||||||
|
x="6463.0864"
|
||||||
|
y="2285.6765">N</tspan></text>
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="m 2189.1897,5219.361 16.6983,1252.3697"
|
||||||
|
id="path4119-0"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-5-2"
|
||||||
|
transform="translate(0,6551.5479)">
|
||||||
|
<rect
|
||||||
|
id="rect6-1-7"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1475.6636"
|
||||||
|
width="4401.7612"
|
||||||
|
y="0"
|
||||||
|
x="0" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-9-5"
|
||||||
|
y="835.11212"
|
||||||
|
x="2206.4917"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="835.11212"
|
||||||
|
x="2206.4917"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4776-5">IPI Handler</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="m 4432.5052,7297.9678 1252.3697,-16.6982"
|
||||||
|
id="path4119-2"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="m 8503.0013,7278.6595 1252.369,-16.6982"
|
||||||
|
id="path4119-8-7"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="8617.0977"
|
||||||
|
y="7110.0186"
|
||||||
|
id="text4593-4"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4595-0"
|
||||||
|
x="8617.0977"
|
||||||
|
y="7110.0186">Y</tspan></text>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-9-3"
|
||||||
|
transform="translate(9722.4732,6535.809)">
|
||||||
|
<rect
|
||||||
|
id="rect6-0-7"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1425.5687"
|
||||||
|
width="2748.6331"
|
||||||
|
y="29.467337"
|
||||||
|
x="80.17308" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-5-7"
|
||||||
|
y="503.71591"
|
||||||
|
x="1460.1007"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="503.71591"
|
||||||
|
x="1460.1007"
|
||||||
|
id="tspan4112-9-0"
|
||||||
|
sodipodi:role="line">Report CPU</tspan><tspan
|
||||||
|
y="837.77039"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4923">Quiescent</tspan><tspan
|
||||||
|
y="1171.825"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4925">State</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="m 7102.5627,11478.337 16.6983,1252.35"
|
||||||
|
id="path4119-0-0"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="6797.0522"
|
||||||
|
y="9018.6807"
|
||||||
|
id="text4593-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4595-2"
|
||||||
|
x="6797.0522"
|
||||||
|
y="9018.6807">N</tspan></text>
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-9-3-8"
|
||||||
|
transform="translate(-80.17308,14133.68)">
|
||||||
|
<rect
|
||||||
|
id="rect6-0-7-5"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1425.5687"
|
||||||
|
width="2748.6331"
|
||||||
|
y="29.467337"
|
||||||
|
x="80.17308" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-5-7-6"
|
||||||
|
y="841.88086"
|
||||||
|
x="1460.1007"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="841.88086"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4925-1">Context Switch</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="m 1362.6256,12823.832 16.6983,1252.369"
|
||||||
|
id="path4119-0-0-7"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="m 1362.6256,15636.491 16.6983,1252.369"
|
||||||
|
id="path4119-0-0-7-7"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-9-3-8-1"
|
||||||
|
transform="translate(9722.4732,14142.03)">
|
||||||
|
<rect
|
||||||
|
id="rect6-0-7-5-1"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1425.5687"
|
||||||
|
width="2748.6331"
|
||||||
|
y="29.467337"
|
||||||
|
x="80.17308" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-5-7-6-2"
|
||||||
|
y="841.88086"
|
||||||
|
x="1460.1007"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="841.88086"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4925-1-2">CPU Offline</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="m 11165.272,12823.832 16.698,1252.369"
|
||||||
|
id="path4119-0-0-7-8"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-9-3-9"
|
||||||
|
transform="translate(-80.17308,16915.618)">
|
||||||
|
<rect
|
||||||
|
id="rect6-0-7-1"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1425.5687"
|
||||||
|
width="2748.6331"
|
||||||
|
y="29.467337"
|
||||||
|
x="80.17308" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-5-7-3"
|
||||||
|
y="505.47754"
|
||||||
|
x="1460.1007"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="505.47754"
|
||||||
|
x="1460.1007"
|
||||||
|
id="tspan4112-9-0-4"
|
||||||
|
sodipodi:role="line">Report CPU</tspan><tspan
|
||||||
|
y="839.53204"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4925-9">Quiescent</tspan><tspan
|
||||||
|
y="1173.5865"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3168">State</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="m 11165.272,15571.534 16.698,1252.369"
|
||||||
|
id="path4119-0-0-7-7-5"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-9-3-9-2"
|
||||||
|
transform="translate(9722.4732,16850.66)">
|
||||||
|
<rect
|
||||||
|
id="rect6-0-7-1-8"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1425.5687"
|
||||||
|
width="2748.6331"
|
||||||
|
y="29.467337"
|
||||||
|
x="80.17308" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-5-7-3-4"
|
||||||
|
y="503.71591"
|
||||||
|
x="1460.1007"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="503.71591"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4923-3-2">Report CPU</tspan><tspan
|
||||||
|
y="837.77039"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4925-9-9">Quiescent</tspan><tspan
|
||||||
|
y="1171.825"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan5239">State</tspan></text>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
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"
|
||||||
|
d="m 1353.3524,12832.071 9701.6916,0 100.189,-16.698"
|
||||||
|
id="path5265"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccc" />
|
||||||
|
<path
|
||||||
|
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)"
|
||||||
|
d="m 7112.6465,8669.1867 16.6983,1252.369"
|
||||||
|
id="path4119-0-0-7-7-5-7"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<g
|
||||||
|
style="fill:none;stroke-width:0.025in"
|
||||||
|
id="g4114-9-3-8-1-8-3"
|
||||||
|
transform="translate(5663.1399,9972.3627)">
|
||||||
|
<rect
|
||||||
|
id="rect6-0-7-5-1-1-9"
|
||||||
|
style="fill:#87cfff;stroke:#000000;stroke-width:45.00382233;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
rx="0"
|
||||||
|
height="1425.5687"
|
||||||
|
width="2748.6331"
|
||||||
|
y="29.467337"
|
||||||
|
x="80.17308" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text4110-5-7-6-2-4-0"
|
||||||
|
y="841.88086"
|
||||||
|
x="1460.1007"
|
||||||
|
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"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
y="841.88086"
|
||||||
|
x="1460.1007"
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4925-1-2-4-5">reched_cpu()</tspan></text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 32 KiB |
|
@ -0,0 +1,626 @@
|
||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html>
|
||||||
|
<head><title>A Tour Through TREE_RCU's Expedited Grace Periods</title>
|
||||||
|
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
|
||||||
|
<h2>Introduction</h2>
|
||||||
|
|
||||||
|
This document describes RCU's expedited grace periods.
|
||||||
|
Unlike RCU's normal grace periods, which accept long latencies to attain
|
||||||
|
high efficiency and minimal disturbance, expedited grace periods accept
|
||||||
|
lower efficiency and significant disturbance to attain shorter latencies.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
There are three flavors of RCU (RCU-bh, RCU-preempt, and RCU-sched),
|
||||||
|
but only two flavors of expedited grace periods because the RCU-bh
|
||||||
|
expedited grace period maps onto the RCU-sched expedited grace period.
|
||||||
|
Each of the remaining two implementations is covered in its own section.
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li> <a href="#Expedited Grace Period Design">
|
||||||
|
Expedited Grace Period Design</a>
|
||||||
|
<li> <a href="#RCU-preempt Expedited Grace Periods">
|
||||||
|
RCU-preempt Expedited Grace Periods</a>
|
||||||
|
<li> <a href="#RCU-sched Expedited Grace Periods">
|
||||||
|
RCU-sched Expedited Grace Periods</a>
|
||||||
|
<li> <a href="#Expedited Grace Period and CPU Hotplug">
|
||||||
|
Expedited Grace Period and CPU Hotplug</a>
|
||||||
|
<li> <a href="#Expedited Grace Period Refinements">
|
||||||
|
Expedited Grace Period Refinements</a>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<h2><a name="Expedited Grace Period Design">
|
||||||
|
Expedited Grace Period Design</a></h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The expedited RCU grace periods cannot be accused of being subtle,
|
||||||
|
given that they for all intents and purposes hammer every CPU that
|
||||||
|
has not yet provided a quiescent state for the current expedited
|
||||||
|
grace period.
|
||||||
|
The one saving grace is that the hammer has grown a bit smaller
|
||||||
|
over time: The old call to <tt>try_stop_cpus()</tt> has been
|
||||||
|
replaced with a set of calls to <tt>smp_call_function_single()</tt>,
|
||||||
|
each of which results in an IPI to the target CPU.
|
||||||
|
The corresponding handler function checks the CPU's state, motivating
|
||||||
|
a faster quiescent state where possible, and triggering a report
|
||||||
|
of that quiescent state.
|
||||||
|
As always for RCU, once everything has spent some time in a quiescent
|
||||||
|
state, the expedited grace period has completed.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The details of the <tt>smp_call_function_single()</tt> handler's
|
||||||
|
operation depend on the RCU flavor, as described in the following
|
||||||
|
sections.
|
||||||
|
|
||||||
|
<h2><a name="RCU-preempt Expedited Grace Periods">
|
||||||
|
RCU-preempt Expedited Grace Periods</a></h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The overall flow of the handling of a given CPU by an RCU-preempt
|
||||||
|
expedited grace period is shown in the following diagram:
|
||||||
|
|
||||||
|
<p><img src="ExpRCUFlow.svg" alt="ExpRCUFlow.svg" width="55%">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The solid arrows denote direct action, for example, a function call.
|
||||||
|
The dotted arrows denote indirect action, for example, an IPI
|
||||||
|
or a state that is reached after some time.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If a given CPU is offline or idle, <tt>synchronize_rcu_expedited()</tt>
|
||||||
|
will ignore it because idle and offline CPUs are already residing
|
||||||
|
in quiescent states.
|
||||||
|
Otherwise, the expedited grace period will use
|
||||||
|
<tt>smp_call_function_single()</tt> to send the CPU an IPI, which
|
||||||
|
is handled by <tt>sync_rcu_exp_handler()</tt>.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
However, because this is preemptible RCU, <tt>sync_rcu_exp_handler()</tt>
|
||||||
|
can check to see if the CPU is currently running in an RCU read-side
|
||||||
|
critical section.
|
||||||
|
If not, the handler can immediately report a quiescent state.
|
||||||
|
Otherwise, it sets flags so that the outermost <tt>rcu_read_unlock()</tt>
|
||||||
|
invocation will provide the needed quiescent-state report.
|
||||||
|
This flag-setting avoids the previous forced preemption of all
|
||||||
|
CPUs that might have RCU read-side critical sections.
|
||||||
|
In addition, this flag-setting is done so as to avoid increasing
|
||||||
|
the overhead of the common-case fastpath through the scheduler.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Again because this is preemptible RCU, an RCU read-side critical section
|
||||||
|
can be preempted.
|
||||||
|
When that happens, RCU will enqueue the task, which will the continue to
|
||||||
|
block the current expedited grace period until it resumes and finds its
|
||||||
|
outermost <tt>rcu_read_unlock()</tt>.
|
||||||
|
The CPU will report a quiescent state just after enqueuing the task because
|
||||||
|
the CPU is no longer blocking the grace period.
|
||||||
|
It is instead the preempted task doing the blocking.
|
||||||
|
The list of blocked tasks is managed by <tt>rcu_preempt_ctxt_queue()</tt>,
|
||||||
|
which is called from <tt>rcu_preempt_note_context_switch()</tt>, which
|
||||||
|
in turn is called from <tt>rcu_note_context_switch()</tt>, which in
|
||||||
|
turn is called from the scheduler.
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th> </th></tr>
|
||||||
|
<tr><th align="left">Quick Quiz:</th></tr>
|
||||||
|
<tr><td>
|
||||||
|
Why not just have the expedited grace period check the
|
||||||
|
state of all the CPUs?
|
||||||
|
After all, that would avoid all those real-time-unfriendly IPIs.
|
||||||
|
</td></tr>
|
||||||
|
<tr><th align="left">Answer:</th></tr>
|
||||||
|
<tr><td bgcolor="#ffffff"><font color="ffffff">
|
||||||
|
Because we want the RCU read-side critical sections to run fast,
|
||||||
|
which means no memory barriers.
|
||||||
|
Therefore, it is not possible to safely check the state from some
|
||||||
|
other CPU.
|
||||||
|
And even if it was possible to safely check the state, it would
|
||||||
|
still be necessary to IPI the CPU to safely interact with the
|
||||||
|
upcoming <tt>rcu_read_unlock()</tt> invocation, which means that
|
||||||
|
the remote state testing would not help the worst-case
|
||||||
|
latency that real-time applications care about.
|
||||||
|
|
||||||
|
<p><font color="ffffff">One way to prevent your real-time
|
||||||
|
application from getting hit with these IPIs is to
|
||||||
|
build your kernel with <tt>CONFIG_NO_HZ_FULL=y</tt>.
|
||||||
|
RCU would then perceive the CPU running your application
|
||||||
|
as being idle, and it would be able to safely detect that
|
||||||
|
state without needing to IPI the CPU.
|
||||||
|
</font></td></tr>
|
||||||
|
<tr><td> </td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Please note that this is just the overall flow:
|
||||||
|
Additional complications can arise due to races with CPUs going idle
|
||||||
|
or offline, among other things.
|
||||||
|
|
||||||
|
<h2><a name="RCU-sched Expedited Grace Periods">
|
||||||
|
RCU-sched Expedited Grace Periods</a></h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The overall flow of the handling of a given CPU by an RCU-sched
|
||||||
|
expedited grace period is shown in the following diagram:
|
||||||
|
|
||||||
|
<p><img src="ExpSchedFlow.svg" alt="ExpSchedFlow.svg" width="55%">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
As with RCU-preempt's <tt>synchronize_rcu_expedited()</tt>,
|
||||||
|
<tt>synchronize_sched_expedited()</tt> ignores offline and
|
||||||
|
idle CPUs, again because they are in remotely detectable
|
||||||
|
quiescent states.
|
||||||
|
However, the <tt>synchronize_rcu_expedited()</tt> handler
|
||||||
|
is <tt>sync_sched_exp_handler()</tt>, and because the
|
||||||
|
<tt>rcu_read_lock_sched()</tt> and <tt>rcu_read_unlock_sched()</tt>
|
||||||
|
leave no trace of their invocation, in general it is not possible to tell
|
||||||
|
whether or not the current CPU is in an RCU read-side critical section.
|
||||||
|
The best that <tt>sync_sched_exp_handler()</tt> can do is to check
|
||||||
|
for idle, on the off-chance that the CPU went idle while the IPI
|
||||||
|
was in flight.
|
||||||
|
If the CPU is idle, then tt>sync_sched_exp_handler()</tt> reports
|
||||||
|
the quiescent state.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Otherwise, the handler invokes <tt>resched_cpu()</tt>, which forces
|
||||||
|
a future context switch.
|
||||||
|
At the time of the context switch, the CPU reports the quiescent state.
|
||||||
|
Should the CPU go offline first, it will report the quiescent state
|
||||||
|
at that time.
|
||||||
|
|
||||||
|
<h2><a name="Expedited Grace Period and CPU Hotplug">
|
||||||
|
Expedited Grace Period and CPU Hotplug</a></h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The expedited nature of expedited grace periods require a much tighter
|
||||||
|
interaction with CPU hotplug operations than is required for normal
|
||||||
|
grace periods.
|
||||||
|
In addition, attempting to IPI offline CPUs will result in splats, but
|
||||||
|
failing to IPI online CPUs can result in too-short grace periods.
|
||||||
|
Neither option is acceptable in production kernels.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The interaction between expedited grace periods and CPU hotplug operations
|
||||||
|
is carried out at several levels:
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li> The number of CPUs that have ever been online is tracked
|
||||||
|
by the <tt>rcu_state</tt> structure's <tt>->ncpus</tt>
|
||||||
|
field.
|
||||||
|
The <tt>rcu_state</tt> structure's <tt>->ncpus_snap</tt>
|
||||||
|
field tracks the number of CPUs that have ever been online
|
||||||
|
at the beginning of an RCU expedited grace period.
|
||||||
|
Note that this number never decreases, at least in the absence
|
||||||
|
of a time machine.
|
||||||
|
<li> The identities of the CPUs that have ever been online is
|
||||||
|
tracked by the <tt>rcu_node</tt> structure's
|
||||||
|
<tt>->expmaskinitnext</tt> field.
|
||||||
|
The <tt>rcu_node</tt> structure's <tt>->expmaskinit</tt>
|
||||||
|
field tracks the identities of the CPUs that were online
|
||||||
|
at least once at the beginning of the most recent RCU
|
||||||
|
expedited grace period.
|
||||||
|
The <tt>rcu_state</tt> structure's <tt>->ncpus</tt> and
|
||||||
|
<tt>->ncpus_snap</tt> fields are used to detect when
|
||||||
|
new CPUs have come online for the first time, that is,
|
||||||
|
when the <tt>rcu_node</tt> structure's <tt>->expmaskinitnext</tt>
|
||||||
|
field has changed since the beginning of the last RCU
|
||||||
|
expedited grace period, which triggers an update of each
|
||||||
|
<tt>rcu_node</tt> structure's <tt>->expmaskinit</tt>
|
||||||
|
field from its <tt>->expmaskinitnext</tt> field.
|
||||||
|
<li> Each <tt>rcu_node</tt> structure's <tt>->expmaskinit</tt>
|
||||||
|
field is used to initialize that structure's
|
||||||
|
<tt>->expmask</tt> at the beginning of each RCU
|
||||||
|
expedited grace period.
|
||||||
|
This means that only those CPUs that have been online at least
|
||||||
|
once will be considered for a given grace period.
|
||||||
|
<li> Any CPU that goes offline will clear its bit in its leaf
|
||||||
|
<tt>rcu_node</tt> structure's <tt>->qsmaskinitnext</tt>
|
||||||
|
field, so any CPU with that bit clear can safely be ignored.
|
||||||
|
However, it is possible for a CPU coming online or going offline
|
||||||
|
to have this bit set for some time while <tt>cpu_online</tt>
|
||||||
|
returns <tt>false</tt>.
|
||||||
|
<li> For each non-idle CPU that RCU believes is currently online, the grace
|
||||||
|
period invokes <tt>smp_call_function_single()</tt>.
|
||||||
|
If this succeeds, the CPU was fully online.
|
||||||
|
Failure indicates that the CPU is in the process of coming online
|
||||||
|
or going offline, in which case it is necessary to wait for a
|
||||||
|
short time period and try again.
|
||||||
|
The purpose of this wait (or series of waits, as the case may be)
|
||||||
|
is to permit a concurrent CPU-hotplug operation to complete.
|
||||||
|
<li> In the case of RCU-sched, one of the last acts of an outgoing CPU
|
||||||
|
is to invoke <tt>rcu_report_dead()</tt>, which
|
||||||
|
reports a quiescent state for that CPU.
|
||||||
|
However, this is likely paranoia-induced redundancy. <!-- @@@ -->
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th> </th></tr>
|
||||||
|
<tr><th align="left">Quick Quiz:</th></tr>
|
||||||
|
<tr><td>
|
||||||
|
Why all the dancing around with multiple counters and masks
|
||||||
|
tracking CPUs that were once online?
|
||||||
|
Why not just have a single set of masks tracking the currently
|
||||||
|
online CPUs and be done with it?
|
||||||
|
</td></tr>
|
||||||
|
<tr><th align="left">Answer:</th></tr>
|
||||||
|
<tr><td bgcolor="#ffffff"><font color="ffffff">
|
||||||
|
Maintaining single set of masks tracking the online CPUs <i>sounds</i>
|
||||||
|
easier, at least until you try working out all the race conditions
|
||||||
|
between grace-period initialization and CPU-hotplug operations.
|
||||||
|
For example, suppose initialization is progressing down the
|
||||||
|
tree while a CPU-offline operation is progressing up the tree.
|
||||||
|
This situation can result in bits set at the top of the tree
|
||||||
|
that have no counterparts at the bottom of the tree.
|
||||||
|
Those bits will never be cleared, which will result in
|
||||||
|
grace-period hangs.
|
||||||
|
In short, that way lies madness, to say nothing of a great many
|
||||||
|
bugs, hangs, and deadlocks.
|
||||||
|
|
||||||
|
<p><font color="ffffff">
|
||||||
|
In contrast, the current multi-mask multi-counter scheme ensures
|
||||||
|
that grace-period initialization will always see consistent masks
|
||||||
|
up and down the tree, which brings significant simplifications
|
||||||
|
over the single-mask method.
|
||||||
|
|
||||||
|
<p><font color="ffffff">
|
||||||
|
This is an instance of
|
||||||
|
<a href="http://www.cs.columbia.edu/~library/TR-repository/reports/reports-1992/cucs-039-92.ps.gz"><font color="ffffff">
|
||||||
|
deferring work in order to avoid synchronization</a>.
|
||||||
|
Lazily recording CPU-hotplug events at the beginning of the next
|
||||||
|
grace period greatly simplifies maintenance of the CPU-tracking
|
||||||
|
bitmasks in the <tt>rcu_node</tt> tree.
|
||||||
|
</font></td></tr>
|
||||||
|
<tr><td> </td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2><a name="Expedited Grace Period Refinements">
|
||||||
|
Expedited Grace Period Refinements</a></h2>
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li> <a href="#Idle-CPU Checks">Idle-CPU checks</a>.
|
||||||
|
<li> <a href="#Batching via Sequence Counter">
|
||||||
|
Batching via sequence counter</a>.
|
||||||
|
<li> <a href="#Funnel Locking and Wait/Wakeup">
|
||||||
|
Funnel locking and wait/wakeup</a>.
|
||||||
|
<li> <a href="#Use of Workqueues">Use of Workqueues</a>.
|
||||||
|
<li> <a href="#Stall Warnings">Stall warnings</a>.
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<h3><a name="Idle-CPU Checks">Idle-CPU Checks</a></h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Each expedited grace period checks for idle CPUs when initially forming
|
||||||
|
the mask of CPUs to be IPIed and again just before IPIing a CPU
|
||||||
|
(both checks are carried out by <tt>sync_rcu_exp_select_cpus()</tt>).
|
||||||
|
If the CPU is idle at any time between those two times, the CPU will
|
||||||
|
not be IPIed.
|
||||||
|
Instead, the task pushing the grace period forward will include the
|
||||||
|
idle CPUs in the mask passed to <tt>rcu_report_exp_cpu_mult()</tt>.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
For RCU-sched, there is an additional check for idle in the IPI
|
||||||
|
handler, <tt>sync_sched_exp_handler()</tt>.
|
||||||
|
If the IPI has interrupted the idle loop, then
|
||||||
|
<tt>sync_sched_exp_handler()</tt> invokes <tt>rcu_report_exp_rdp()</tt>
|
||||||
|
to report the corresponding quiescent state.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
For RCU-preempt, there is no specific check for idle in the
|
||||||
|
IPI handler (<tt>sync_rcu_exp_handler()</tt>), but because
|
||||||
|
RCU read-side critical sections are not permitted within the
|
||||||
|
idle loop, if <tt>sync_rcu_exp_handler()</tt> sees that the CPU is within
|
||||||
|
RCU read-side critical section, the CPU cannot possibly be idle.
|
||||||
|
Otherwise, <tt>sync_rcu_exp_handler()</tt> invokes
|
||||||
|
<tt>rcu_report_exp_rdp()</tt> to report the corresponding quiescent
|
||||||
|
state, regardless of whether or not that quiescent state was due to
|
||||||
|
the CPU being idle.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In summary, RCU expedited grace periods check for idle when building
|
||||||
|
the bitmask of CPUs that must be IPIed, just before sending each IPI,
|
||||||
|
and (either explicitly or implicitly) within the IPI handler.
|
||||||
|
|
||||||
|
<h3><a name="Batching via Sequence Counter">
|
||||||
|
Batching via Sequence Counter</a></h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If each grace-period request was carried out separately, expedited
|
||||||
|
grace periods would have abysmal scalability and
|
||||||
|
problematic high-load characteristics.
|
||||||
|
Because each grace-period operation can serve an unlimited number of
|
||||||
|
updates, it is important to <i>batch</i> requests, so that a single
|
||||||
|
expedited grace-period operation will cover all requests in the
|
||||||
|
corresponding batch.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This batching is controlled by a sequence counter named
|
||||||
|
<tt>->expedited_sequence</tt> in the <tt>rcu_state</tt> structure.
|
||||||
|
This counter has an odd value when there is an expedited grace period
|
||||||
|
in progress and an even value otherwise, so that dividing the counter
|
||||||
|
value by two gives the number of completed grace periods.
|
||||||
|
During any given update request, the counter must transition from
|
||||||
|
even to odd and then back to even, thus indicating that a grace
|
||||||
|
period has elapsed.
|
||||||
|
Therefore, if the initial value of the counter is <tt>s</tt>,
|
||||||
|
the updater must wait until the counter reaches at least the
|
||||||
|
value <tt>(s+3)&~0x1</tt>.
|
||||||
|
This counter is managed by the following access functions:
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li> <tt>rcu_exp_gp_seq_start()</tt>, which marks the start of
|
||||||
|
an expedited grace period.
|
||||||
|
<li> <tt>rcu_exp_gp_seq_end()</tt>, which marks the end of an
|
||||||
|
expedited grace period.
|
||||||
|
<li> <tt>rcu_exp_gp_seq_snap()</tt>, which obtains a snapshot of
|
||||||
|
the counter.
|
||||||
|
<li> <tt>rcu_exp_gp_seq_done()</tt>, which returns <tt>true</tt>
|
||||||
|
if a full expedited grace period has elapsed since the
|
||||||
|
corresponding call to <tt>rcu_exp_gp_seq_snap()</tt>.
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Again, only one request in a given batch need actually carry out
|
||||||
|
a grace-period operation, which means there must be an efficient
|
||||||
|
way to identify which of many concurrent reqeusts will initiate
|
||||||
|
the grace period, and that there be an efficient way for the
|
||||||
|
remaining requests to wait for that grace period to complete.
|
||||||
|
However, that is the topic of the next section.
|
||||||
|
|
||||||
|
<h3><a name="Funnel Locking and Wait/Wakeup">
|
||||||
|
Funnel Locking and Wait/Wakeup</a></h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The natural way to sort out which of a batch of updaters will initiate
|
||||||
|
the expedited grace period is to use the <tt>rcu_node</tt> combining
|
||||||
|
tree, as implemented by the <tt>exp_funnel_lock()</tt> function.
|
||||||
|
The first updater corresponding to a given grace period arriving
|
||||||
|
at a given <tt>rcu_node</tt> structure records its desired grace-period
|
||||||
|
sequence number in the <tt>->exp_seq_rq</tt> field and moves up
|
||||||
|
to the next level in the tree.
|
||||||
|
Otherwise, if the <tt>->exp_seq_rq</tt> field already contains
|
||||||
|
the sequence number for the desired grace period or some later one,
|
||||||
|
the updater blocks on one of four wait queues in the
|
||||||
|
<tt>->exp_wq[]</tt> array, using the second-from-bottom
|
||||||
|
and third-from bottom bits as an index.
|
||||||
|
An <tt>->exp_lock</tt> field in the <tt>rcu_node</tt> structure
|
||||||
|
synchronizes access to these fields.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
An empty <tt>rcu_node</tt> tree is shown in the following diagram,
|
||||||
|
with the white cells representing the <tt>->exp_seq_rq</tt> field
|
||||||
|
and the red cells representing the elements of the
|
||||||
|
<tt>->exp_wq[]</tt> array.
|
||||||
|
|
||||||
|
<p><img src="Funnel0.svg" alt="Funnel0.svg" width="75%">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The next diagram shows the situation after the arrival of Task A
|
||||||
|
and Task B at the leftmost and rightmost leaf <tt>rcu_node</tt>
|
||||||
|
structures, respectively.
|
||||||
|
The current value of the <tt>rcu_state</tt> structure's
|
||||||
|
<tt>->expedited_sequence</tt> field is zero, so adding three and
|
||||||
|
clearing the bottom bit results in the value two, which both tasks
|
||||||
|
record in the <tt>->exp_seq_rq</tt> field of their respective
|
||||||
|
<tt>rcu_node</tt> structures:
|
||||||
|
|
||||||
|
<p><img src="Funnel1.svg" alt="Funnel1.svg" width="75%">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Each of Tasks A and B will move up to the root
|
||||||
|
<tt>rcu_node</tt> structure.
|
||||||
|
Suppose that Task A wins, recording its desired grace-period sequence
|
||||||
|
number and resulting in the state shown below:
|
||||||
|
|
||||||
|
<p><img src="Funnel2.svg" alt="Funnel2.svg" width="75%">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Task A now advances to initiate a new grace period, while Task B
|
||||||
|
moves up to the root <tt>rcu_node</tt> structure, and, seeing that
|
||||||
|
its desired sequence number is already recorded, blocks on
|
||||||
|
<tt>->exp_wq[1]</tt>.
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th> </th></tr>
|
||||||
|
<tr><th align="left">Quick Quiz:</th></tr>
|
||||||
|
<tr><td>
|
||||||
|
Why <tt>->exp_wq[1]</tt>?
|
||||||
|
Given that the value of these tasks' desired sequence number is
|
||||||
|
two, so shouldn't they instead block on <tt>->exp_wq[2]</tt>?
|
||||||
|
</td></tr>
|
||||||
|
<tr><th align="left">Answer:</th></tr>
|
||||||
|
<tr><td bgcolor="#ffffff"><font color="ffffff">
|
||||||
|
No.
|
||||||
|
|
||||||
|
<p><font color="ffffff">
|
||||||
|
Recall that the bottom bit of the desired sequence number indicates
|
||||||
|
whether or not a grace period is currently in progress.
|
||||||
|
It is therefore necessary to shift the sequence number right one
|
||||||
|
bit position to obtain the number of the grace period.
|
||||||
|
This results in <tt>->exp_wq[1]</tt>.
|
||||||
|
</font></td></tr>
|
||||||
|
<tr><td> </td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If Tasks C and D also arrive at this point, they will compute the
|
||||||
|
same desired grace-period sequence number, and see that both leaf
|
||||||
|
<tt>rcu_node</tt> structures already have that value recorded.
|
||||||
|
They will therefore block on their respective <tt>rcu_node</tt>
|
||||||
|
structures' <tt>->exp_wq[1]</tt> fields, as shown below:
|
||||||
|
|
||||||
|
<p><img src="Funnel3.svg" alt="Funnel3.svg" width="75%">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Task A now acquires the <tt>rcu_state</tt> structure's
|
||||||
|
<tt>->exp_mutex</tt> and initiates the grace period, which
|
||||||
|
increments <tt>->expedited_sequence</tt>.
|
||||||
|
Therefore, if Tasks E and F arrive, they will compute
|
||||||
|
a desired sequence number of 4 and will record this value as
|
||||||
|
shown below:
|
||||||
|
|
||||||
|
<p><img src="Funnel4.svg" alt="Funnel4.svg" width="75%">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Tasks E and F will propagate up the <tt>rcu_node</tt>
|
||||||
|
combining tree, with Task F blocking on the root <tt>rcu_node</tt>
|
||||||
|
structure and Task E wait for Task A to finish so that
|
||||||
|
it can start the next grace period.
|
||||||
|
The resulting state is as shown below:
|
||||||
|
|
||||||
|
<p><img src="Funnel5.svg" alt="Funnel5.svg" width="75%">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Once the grace period completes, Task A
|
||||||
|
starts waking up the tasks waiting for this grace period to complete,
|
||||||
|
increments the <tt>->expedited_sequence</tt>,
|
||||||
|
acquires the <tt>->exp_wake_mutex</tt> and then releases the
|
||||||
|
<tt>->exp_mutex</tt>.
|
||||||
|
This results in the following state:
|
||||||
|
|
||||||
|
<p><img src="Funnel6.svg" alt="Funnel6.svg" width="75%">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Task E can then acquire <tt>->exp_mutex</tt> and increment
|
||||||
|
<tt>->expedited_sequence</tt> to the value three.
|
||||||
|
If new tasks G and H arrive and moves up the combining tree at the
|
||||||
|
same time, the state will be as follows:
|
||||||
|
|
||||||
|
<p><img src="Funnel7.svg" alt="Funnel7.svg" width="75%">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Note that three of the root <tt>rcu_node</tt> structure's
|
||||||
|
waitqueues are now occupied.
|
||||||
|
However, at some point, Task A will wake up the
|
||||||
|
tasks blocked on the <tt>->exp_wq</tt> waitqueues, resulting
|
||||||
|
in the following state:
|
||||||
|
|
||||||
|
<p><img src="Funnel8.svg" alt="Funnel8.svg" width="75%">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Execution will continue with Tasks E and H completing
|
||||||
|
their grace periods and carrying out their wakeups.
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th> </th></tr>
|
||||||
|
<tr><th align="left">Quick Quiz:</th></tr>
|
||||||
|
<tr><td>
|
||||||
|
What happens if Task A takes so long to do its wakeups
|
||||||
|
that Task E's grace period completes?
|
||||||
|
</td></tr>
|
||||||
|
<tr><th align="left">Answer:</th></tr>
|
||||||
|
<tr><td bgcolor="#ffffff"><font color="ffffff">
|
||||||
|
Then Task E will block on the <tt>->exp_wake_mutex</tt>,
|
||||||
|
which will also prevent it from releasing <tt>->exp_mutex</tt>,
|
||||||
|
which in turn will prevent the next grace period from starting.
|
||||||
|
This last is important in preventing overflow of the
|
||||||
|
<tt>->exp_wq[]</tt> array.
|
||||||
|
</font></td></tr>
|
||||||
|
<tr><td> </td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h3><a name="Use of Workqueues">Use of Workqueues</a></h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In earlier implementations, the task requesting the expedited
|
||||||
|
grace period also drove it to completion.
|
||||||
|
This straightforward approach had the disadvantage of needing to
|
||||||
|
account for signals sent to user tasks,
|
||||||
|
so more recent implemementations use the Linux kernel's
|
||||||
|
<a href="https://www.kernel.org/doc/Documentation/workqueue.txt">workqueues</a>.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The requesting task still does counter snapshotting and funnel-lock
|
||||||
|
processing, but the task reaching the top of the funnel lock
|
||||||
|
does a <tt>schedule_work()</tt> (from <tt>_synchronize_rcu_expedited()</tt>
|
||||||
|
so that a workqueue kthread does the actual grace-period processing.
|
||||||
|
Because workqueue kthreads do not accept signals, grace-period-wait
|
||||||
|
processing need not allow for signals.
|
||||||
|
|
||||||
|
In addition, this approach allows wakeups for the previous expedited
|
||||||
|
grace period to be overlapped with processing for the next expedited
|
||||||
|
grace period.
|
||||||
|
Because there are only four sets of waitqueues, it is necessary to
|
||||||
|
ensure that the previous grace period's wakeups complete before the
|
||||||
|
next grace period's wakeups start.
|
||||||
|
This is handled by having the <tt>->exp_mutex</tt>
|
||||||
|
guard expedited grace-period processing and the
|
||||||
|
<tt>->exp_wake_mutex</tt> guard wakeups.
|
||||||
|
The key point is that the <tt>->exp_mutex</tt> is not released
|
||||||
|
until the first wakeup is complete, which means that the
|
||||||
|
<tt>->exp_wake_mutex</tt> has already been acquired at that point.
|
||||||
|
This approach ensures that the previous grace period's wakeups can
|
||||||
|
be carried out while the current grace period is in process, but
|
||||||
|
that these wakeups will complete before the next grace period starts.
|
||||||
|
This means that only three waitqueues are required, guaranteeing that
|
||||||
|
the four that are provided are sufficient.
|
||||||
|
|
||||||
|
<h3><a name="Stall Warnings">Stall Warnings</a></h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Expediting grace periods does nothing to speed things up when RCU
|
||||||
|
readers take too long, and therefore expedited grace periods check
|
||||||
|
for stalls just as normal grace periods do.
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr><th> </th></tr>
|
||||||
|
<tr><th align="left">Quick Quiz:</th></tr>
|
||||||
|
<tr><td>
|
||||||
|
But why not just let the normal grace-period machinery
|
||||||
|
detect the stalls, given that a given reader must block
|
||||||
|
both normal and expedited grace periods?
|
||||||
|
</td></tr>
|
||||||
|
<tr><th align="left">Answer:</th></tr>
|
||||||
|
<tr><td bgcolor="#ffffff"><font color="ffffff">
|
||||||
|
Because it is quite possible that at a given time there
|
||||||
|
is no normal grace period in progress, in which case the
|
||||||
|
normal grace period cannot emit a stall warning.
|
||||||
|
</font></td></tr>
|
||||||
|
<tr><td> </td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
The <tt>synchronize_sched_expedited_wait()</tt> function loops waiting
|
||||||
|
for the expedited grace period to end, but with a timeout set to the
|
||||||
|
current RCU CPU stall-warning time.
|
||||||
|
If this time is exceeded, any CPUs or <tt>rcu_node</tt> structures
|
||||||
|
blocking the current grace period are printed.
|
||||||
|
Each stall warning results in another pass through the loop, but the
|
||||||
|
second and subsequent passes use longer stall times.
|
||||||
|
|
||||||
|
<h3><a name="Summary">
|
||||||
|
Summary</a></h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Expedited grace periods use a sequence-number approach to promote
|
||||||
|
batching, so that a single grace-period operation can serve numerous
|
||||||
|
requests.
|
||||||
|
A funnel lock is used to efficiently identify the one task out of
|
||||||
|
a concurrent group that will request the grace period.
|
||||||
|
All members of the group will block on waitqueues provided in
|
||||||
|
the <tt>rcu_node</tt> structure.
|
||||||
|
The actual grace-period processing is carried out by a workqueue.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
CPU-hotplug operations are noted lazily in order to prevent the need
|
||||||
|
for tight synchronization between expedited grace periods and
|
||||||
|
CPU-hotplug operations.
|
||||||
|
The dyntick-idle counters are used to avoid sending IPIs to idle CPUs,
|
||||||
|
at least in the common case.
|
||||||
|
RCU-preempt and RCU-sched use different IPI handlers and different
|
||||||
|
code to respond to the state changes carried out by those handlers,
|
||||||
|
but otherwise use common code.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Quiescent states are tracked using the <tt>rcu_node</tt> tree,
|
||||||
|
and once all necessary quiescent states have been reported,
|
||||||
|
all tasks waiting on this expedited grace period are awakened.
|
||||||
|
A pair of mutexes are used to allow one grace period's wakeups
|
||||||
|
to proceed concurrently with the next grace period's processing.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This combination of mechanisms allows expedited grace periods to
|
||||||
|
run reasonably efficiently.
|
||||||
|
However, for non-time-critical tasks, normal grace periods should be
|
||||||
|
used instead because their longer duration permits much higher
|
||||||
|
degrees of batching, and thus much lower per-request overheads.
|
||||||
|
|
||||||
|
</body></html>
|
|
@ -0,0 +1,275 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="490.05093"
|
||||||
|
height="125.78741"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="Funnel0.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789-9"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792-4"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.3670394"
|
||||||
|
inkscape:cx="201.06495"
|
||||||
|
inkscape:cy="-86.548414"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1351"
|
||||||
|
inkscape:window-height="836"
|
||||||
|
inkscape:window-x="171"
|
||||||
|
inkscape:window-y="279"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-left="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-bottom="5" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-117.08462,-249.92053)">
|
||||||
|
<flowRoot
|
||||||
|
xml:space="preserve"
|
||||||
|
id="flowRoot2985"
|
||||||
|
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
|
||||||
|
id="flowRegion2987"><rect
|
||||||
|
id="rect2989"
|
||||||
|
width="82.85714"
|
||||||
|
height="11.428572"
|
||||||
|
x="240"
|
||||||
|
y="492.36218" /></flowRegion><flowPara
|
||||||
|
id="flowPara2991" /></flowRoot> <text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819"
|
||||||
|
id="text4441"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4443"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819">->expedited_sequence: 0</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||||
|
id="rect3101"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="253.55223"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="297.04141"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="427.509"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="384.01981"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7-5"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="340.53061"
|
||||||
|
y="275.07489" />
|
||||||
|
<g
|
||||||
|
id="g3997"
|
||||||
|
transform="translate(-0.87295532,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="145.45404"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015"
|
||||||
|
x="145.45404"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">:0</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g3997-7"
|
||||||
|
transform="translate(260.06223,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35-0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62-9"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9-3"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1-6"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2-0"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="145.45404"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6"
|
||||||
|
x="145.45404"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">:0</tspan></text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 10 KiB |
|
@ -0,0 +1,275 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="490.05093"
|
||||||
|
height="125.78741"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="Funnel1.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789-9"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792-4"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.3670394"
|
||||||
|
inkscape:cx="201.06495"
|
||||||
|
inkscape:cy="-86.548414"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="g3997-7"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1351"
|
||||||
|
inkscape:window-height="836"
|
||||||
|
inkscape:window-x="363"
|
||||||
|
inkscape:window-y="336"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-left="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-bottom="5" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-117.08462,-249.92053)">
|
||||||
|
<flowRoot
|
||||||
|
xml:space="preserve"
|
||||||
|
id="flowRoot2985"
|
||||||
|
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
|
||||||
|
id="flowRegion2987"><rect
|
||||||
|
id="rect2989"
|
||||||
|
width="82.85714"
|
||||||
|
height="11.428572"
|
||||||
|
x="240"
|
||||||
|
y="492.36218" /></flowRegion><flowPara
|
||||||
|
id="flowPara2991" /></flowRoot> <text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819"
|
||||||
|
id="text4441"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4443"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819">->expedited_sequence: 0</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||||
|
id="rect3101"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="253.55223"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="297.04141"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="427.509"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="384.01981"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7-5"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="340.53061"
|
||||||
|
y="275.07489" />
|
||||||
|
<g
|
||||||
|
id="g3997"
|
||||||
|
transform="translate(-0.87295532,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="146.00092"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015"
|
||||||
|
x="146.00092"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">A:2</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g3997-7"
|
||||||
|
transform="translate(260.06223,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35-0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62-9"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9-3"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1-6"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2-0"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="145.54926"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6"
|
||||||
|
x="145.54926"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">B:2</tspan></text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 10 KiB |
|
@ -0,0 +1,287 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="490.05093"
|
||||||
|
height="125.78741"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="Funnel2.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789-9"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792-4"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.3670394"
|
||||||
|
inkscape:cx="114.01552"
|
||||||
|
inkscape:cy="-86.548414"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="g3997-7"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1351"
|
||||||
|
inkscape:window-height="836"
|
||||||
|
inkscape:window-x="363"
|
||||||
|
inkscape:window-y="336"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-left="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-bottom="5" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-117.08462,-249.92053)">
|
||||||
|
<flowRoot
|
||||||
|
xml:space="preserve"
|
||||||
|
id="flowRoot2985"
|
||||||
|
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
|
||||||
|
id="flowRegion2987"><rect
|
||||||
|
id="rect2989"
|
||||||
|
width="82.85714"
|
||||||
|
height="11.428572"
|
||||||
|
x="240"
|
||||||
|
y="492.36218" /></flowRegion><flowPara
|
||||||
|
id="flowPara2991" /></flowRoot> <text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819"
|
||||||
|
id="text4441"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4443"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819">->expedited_sequence: 0</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||||
|
id="rect3101"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="253.55223"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="297.04141"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="427.509"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="384.01981"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7-5"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="340.53061"
|
||||||
|
y="275.07489" />
|
||||||
|
<g
|
||||||
|
id="g3997"
|
||||||
|
transform="translate(-0.87295532,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="146.00092"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015"
|
||||||
|
x="146.00092"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">:2</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g3997-7"
|
||||||
|
transform="translate(260.06223,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35-0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62-9"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9-3"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1-6"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2-0"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="145.54926"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6"
|
||||||
|
x="145.54926"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">B:2</tspan></text>
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="275.59558"
|
||||||
|
y="291.95297"
|
||||||
|
id="text3013-36"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-7"
|
||||||
|
x="275.59558"
|
||||||
|
y="291.95297"
|
||||||
|
style="font-size:10px">A:2</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 11 KiB |
|
@ -0,0 +1,323 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="490.05093"
|
||||||
|
height="125.78741"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="Funnel3.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789-9"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792-4"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.3670394"
|
||||||
|
inkscape:cx="114.01552"
|
||||||
|
inkscape:cy="-86.548414"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1351"
|
||||||
|
inkscape:window-height="836"
|
||||||
|
inkscape:window-x="68"
|
||||||
|
inkscape:window-y="180"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-left="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-bottom="5" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-117.08462,-249.92053)">
|
||||||
|
<flowRoot
|
||||||
|
xml:space="preserve"
|
||||||
|
id="flowRoot2985"
|
||||||
|
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
|
||||||
|
id="flowRegion2987"><rect
|
||||||
|
id="rect2989"
|
||||||
|
width="82.85714"
|
||||||
|
height="11.428572"
|
||||||
|
x="240"
|
||||||
|
y="492.36218" /></flowRegion><flowPara
|
||||||
|
id="flowPara2991" /></flowRoot> <text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819"
|
||||||
|
id="text4441"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4443"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819">->expedited_sequence: 0 GP: A</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||||
|
id="rect3101"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="253.55223"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="297.04141"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="427.509"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="384.01981"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7-5"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="340.53061"
|
||||||
|
y="275.07489" />
|
||||||
|
<g
|
||||||
|
id="g3997"
|
||||||
|
transform="translate(-0.87295532,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="146.00092"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015"
|
||||||
|
x="146.00092"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">:2</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="232.51051"
|
||||||
|
y="360.18094"
|
||||||
|
id="text3013-3-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-6"
|
||||||
|
x="232.51051"
|
||||||
|
y="360.18094"
|
||||||
|
style="font-size:10px">C</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g3019"
|
||||||
|
transform="translate(260.06223,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35-0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62-9"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9-3"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1-6"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2-0"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="145.54926"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6"
|
||||||
|
x="145.54926"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">:2</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="232.31764"
|
||||||
|
y="360.18582"
|
||||||
|
id="text3013-3-3-7"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-6-5"
|
||||||
|
x="232.31764"
|
||||||
|
y="360.18582"
|
||||||
|
style="font-size:10px">D</tspan></text>
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="275.59558"
|
||||||
|
y="291.95297"
|
||||||
|
id="text3013-36"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-7"
|
||||||
|
x="275.59558"
|
||||||
|
y="291.95297"
|
||||||
|
style="font-size:10px">:2</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="361.97092"
|
||||||
|
y="291.88705"
|
||||||
|
id="text3013-3-36"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-7"
|
||||||
|
x="361.97092"
|
||||||
|
y="291.88705"
|
||||||
|
style="font-size:10px">B</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 12 KiB |
|
@ -0,0 +1,323 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="490.05093"
|
||||||
|
height="125.78741"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="Funnel4.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789-9"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792-4"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.3670394"
|
||||||
|
inkscape:cx="114.01552"
|
||||||
|
inkscape:cy="-86.548414"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1351"
|
||||||
|
inkscape:window-height="836"
|
||||||
|
inkscape:window-x="68"
|
||||||
|
inkscape:window-y="180"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-left="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-bottom="5" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-117.08462,-249.92053)">
|
||||||
|
<flowRoot
|
||||||
|
xml:space="preserve"
|
||||||
|
id="flowRoot2985"
|
||||||
|
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
|
||||||
|
id="flowRegion2987"><rect
|
||||||
|
id="rect2989"
|
||||||
|
width="82.85714"
|
||||||
|
height="11.428572"
|
||||||
|
x="240"
|
||||||
|
y="492.36218" /></flowRegion><flowPara
|
||||||
|
id="flowPara2991" /></flowRoot> <text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819"
|
||||||
|
id="text4441"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4443"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819">->expedited_sequence: 1 GP: A</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||||
|
id="rect3101"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="253.55223"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="297.04141"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="427.509"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="384.01981"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7-5"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="340.53061"
|
||||||
|
y="275.07489" />
|
||||||
|
<g
|
||||||
|
id="g3997"
|
||||||
|
transform="translate(-0.87295532,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="146.00092"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015"
|
||||||
|
x="146.00092"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">E:4</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="232.51051"
|
||||||
|
y="360.18094"
|
||||||
|
id="text3013-3-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-6"
|
||||||
|
x="232.51051"
|
||||||
|
y="360.18094"
|
||||||
|
style="font-size:10px">C</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g3019"
|
||||||
|
transform="translate(260.06223,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35-0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62-9"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9-3"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1-6"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2-0"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="145.54926"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6"
|
||||||
|
x="145.54926"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">F:4</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="232.31764"
|
||||||
|
y="360.18582"
|
||||||
|
id="text3013-3-3-7"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-6-5"
|
||||||
|
x="232.31764"
|
||||||
|
y="360.18582"
|
||||||
|
style="font-size:10px">D</tspan></text>
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="275.59558"
|
||||||
|
y="291.95297"
|
||||||
|
id="text3013-36"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-7"
|
||||||
|
x="275.59558"
|
||||||
|
y="291.95297"
|
||||||
|
style="font-size:10px">:2</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="361.97092"
|
||||||
|
y="291.88705"
|
||||||
|
id="text3013-3-36"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-7"
|
||||||
|
x="361.97092"
|
||||||
|
y="291.88705"
|
||||||
|
style="font-size:10px">B</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 12 KiB |
|
@ -0,0 +1,335 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="490.05093"
|
||||||
|
height="125.78741"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="Funnel5.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789-9"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792-4"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.3670394"
|
||||||
|
inkscape:cx="114.01552"
|
||||||
|
inkscape:cy="-86.548414"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1351"
|
||||||
|
inkscape:window-height="836"
|
||||||
|
inkscape:window-x="68"
|
||||||
|
inkscape:window-y="180"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-left="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-bottom="5" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-117.08462,-249.92053)">
|
||||||
|
<flowRoot
|
||||||
|
xml:space="preserve"
|
||||||
|
id="flowRoot2985"
|
||||||
|
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
|
||||||
|
id="flowRegion2987"><rect
|
||||||
|
id="rect2989"
|
||||||
|
width="82.85714"
|
||||||
|
height="11.428572"
|
||||||
|
x="240"
|
||||||
|
y="492.36218" /></flowRegion><flowPara
|
||||||
|
id="flowPara2991" /></flowRoot> <text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819"
|
||||||
|
id="text4441"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4443"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819">->expedited_sequence: 1 GP: A,E</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||||
|
id="rect3101"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="253.55223"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="297.04141"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="427.509"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="384.01981"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7-5"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="340.53061"
|
||||||
|
y="275.07489" />
|
||||||
|
<g
|
||||||
|
id="g3997"
|
||||||
|
transform="translate(-0.87295532,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="146.00092"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015"
|
||||||
|
x="146.00092"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">:4</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="232.51051"
|
||||||
|
y="360.18094"
|
||||||
|
id="text3013-3-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-6"
|
||||||
|
x="232.51051"
|
||||||
|
y="360.18094"
|
||||||
|
style="font-size:10px">C</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g3019"
|
||||||
|
transform="translate(260.06223,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35-0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62-9"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9-3"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1-6"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2-0"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="145.54926"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6"
|
||||||
|
x="145.54926"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">:4</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="232.31764"
|
||||||
|
y="360.18582"
|
||||||
|
id="text3013-3-3-7"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-6-5"
|
||||||
|
x="232.31764"
|
||||||
|
y="360.18582"
|
||||||
|
style="font-size:10px">D</tspan></text>
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="275.59558"
|
||||||
|
y="291.95297"
|
||||||
|
id="text3013-36"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-7"
|
||||||
|
x="275.59558"
|
||||||
|
y="291.95297"
|
||||||
|
style="font-size:10px">:4</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="361.97092"
|
||||||
|
y="291.88705"
|
||||||
|
id="text3013-3-36"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-7"
|
||||||
|
x="361.97092"
|
||||||
|
y="291.88705"
|
||||||
|
style="font-size:10px">B</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="405.40396"
|
||||||
|
y="291.88705"
|
||||||
|
id="text3013-3-36-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-7-6"
|
||||||
|
x="405.40396"
|
||||||
|
y="291.88705"
|
||||||
|
style="font-size:10px">F</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 13 KiB |
|
@ -0,0 +1,335 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="490.05093"
|
||||||
|
height="125.78741"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="Funnel6.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789-9"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792-4"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.3670394"
|
||||||
|
inkscape:cx="114.01552"
|
||||||
|
inkscape:cy="-86.548414"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1351"
|
||||||
|
inkscape:window-height="836"
|
||||||
|
inkscape:window-x="68"
|
||||||
|
inkscape:window-y="180"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-left="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-bottom="5" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-117.08462,-249.92053)">
|
||||||
|
<flowRoot
|
||||||
|
xml:space="preserve"
|
||||||
|
id="flowRoot2985"
|
||||||
|
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
|
||||||
|
id="flowRegion2987"><rect
|
||||||
|
id="rect2989"
|
||||||
|
width="82.85714"
|
||||||
|
height="11.428572"
|
||||||
|
x="240"
|
||||||
|
y="492.36218" /></flowRegion><flowPara
|
||||||
|
id="flowPara2991" /></flowRoot> <text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819"
|
||||||
|
id="text4441"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4443"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819">->expedited_sequence: 2 GP: E Wakeup: A</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||||
|
id="rect3101"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="253.55223"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="297.04141"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="427.509"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="384.01981"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7-5"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="340.53061"
|
||||||
|
y="275.07489" />
|
||||||
|
<g
|
||||||
|
id="g3997"
|
||||||
|
transform="translate(-0.87295532,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="146.00092"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015"
|
||||||
|
x="146.00092"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">:4</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="232.51051"
|
||||||
|
y="360.18094"
|
||||||
|
id="text3013-3-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-6"
|
||||||
|
x="232.51051"
|
||||||
|
y="360.18094"
|
||||||
|
style="font-size:10px">C</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g3019"
|
||||||
|
transform="translate(260.06223,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35-0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62-9"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9-3"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1-6"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2-0"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="145.54926"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6"
|
||||||
|
x="145.54926"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">:4</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="232.31764"
|
||||||
|
y="360.18582"
|
||||||
|
id="text3013-3-3-7"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-6-5"
|
||||||
|
x="232.31764"
|
||||||
|
y="360.18582"
|
||||||
|
style="font-size:10px">D</tspan></text>
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="275.59558"
|
||||||
|
y="291.95297"
|
||||||
|
id="text3013-36"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-7"
|
||||||
|
x="275.59558"
|
||||||
|
y="291.95297"
|
||||||
|
style="font-size:10px">:4</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="361.97092"
|
||||||
|
y="291.88705"
|
||||||
|
id="text3013-3-36"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-7"
|
||||||
|
x="361.97092"
|
||||||
|
y="291.88705"
|
||||||
|
style="font-size:10px">B</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="405.40396"
|
||||||
|
y="291.88705"
|
||||||
|
id="text3013-3-36-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-7-6"
|
||||||
|
x="405.40396"
|
||||||
|
y="291.88705"
|
||||||
|
style="font-size:10px">F</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 13 KiB |
|
@ -0,0 +1,347 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="490.05093"
|
||||||
|
height="125.78741"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="Funnel7.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789-9"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792-4"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.3670394"
|
||||||
|
inkscape:cx="114.01552"
|
||||||
|
inkscape:cy="-86.548414"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1351"
|
||||||
|
inkscape:window-height="836"
|
||||||
|
inkscape:window-x="68"
|
||||||
|
inkscape:window-y="180"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-left="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-bottom="5" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-117.08462,-249.92053)">
|
||||||
|
<flowRoot
|
||||||
|
xml:space="preserve"
|
||||||
|
id="flowRoot2985"
|
||||||
|
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
|
||||||
|
id="flowRegion2987"><rect
|
||||||
|
id="rect2989"
|
||||||
|
width="82.85714"
|
||||||
|
height="11.428572"
|
||||||
|
x="240"
|
||||||
|
y="492.36218" /></flowRegion><flowPara
|
||||||
|
id="flowPara2991" /></flowRoot> <text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819"
|
||||||
|
id="text4441"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4443"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819">->expedited_sequence: 3 GP: E,H Wakeup: A</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||||
|
id="rect3101"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="253.55223"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="297.04141"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||||
|
id="rect3101-3-6"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="427.509"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="384.01981"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7-5"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="340.53061"
|
||||||
|
y="275.07489" />
|
||||||
|
<g
|
||||||
|
id="g3997"
|
||||||
|
transform="translate(-0.87295532,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="146.00092"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015"
|
||||||
|
x="146.00092"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">:4</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="232.51051"
|
||||||
|
y="360.18094"
|
||||||
|
id="text3013-3-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-6"
|
||||||
|
x="232.51051"
|
||||||
|
y="360.18094"
|
||||||
|
style="font-size:10px">C</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g3019"
|
||||||
|
transform="translate(260.06223,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35-0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62-9"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9-3"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1-6"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2-0"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="145.54926"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6"
|
||||||
|
x="145.54926"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">:6</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="232.31764"
|
||||||
|
y="360.18582"
|
||||||
|
id="text3013-3-3-7"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-6-5"
|
||||||
|
x="232.31764"
|
||||||
|
y="360.18582"
|
||||||
|
style="font-size:10px">D</tspan></text>
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="275.59558"
|
||||||
|
y="291.95297"
|
||||||
|
id="text3013-36"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-7"
|
||||||
|
x="275.59558"
|
||||||
|
y="291.95297"
|
||||||
|
style="font-size:10px">:6</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="361.97092"
|
||||||
|
y="291.88705"
|
||||||
|
id="text3013-3-36"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-7"
|
||||||
|
x="361.97092"
|
||||||
|
y="291.88705"
|
||||||
|
style="font-size:10px">B</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="405.40396"
|
||||||
|
y="291.88705"
|
||||||
|
id="text3013-3-36-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-7-6"
|
||||||
|
x="405.40396"
|
||||||
|
y="291.88705"
|
||||||
|
style="font-size:10px">F</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="449.22031"
|
||||||
|
y="291.88217"
|
||||||
|
id="text3013-3-36-3-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-7-6-6"
|
||||||
|
x="449.22031"
|
||||||
|
y="291.88217"
|
||||||
|
style="font-size:10px">G</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 13 KiB |
|
@ -0,0 +1,311 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="490.05093"
|
||||||
|
height="125.78741"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="Funnel8.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lstart-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3789-9"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Lend"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Lend-4"
|
||||||
|
style="overflow:visible">
|
||||||
|
<path
|
||||||
|
id="path3792-4"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||||
|
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"
|
||||||
|
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.3670394"
|
||||||
|
inkscape:cx="114.01552"
|
||||||
|
inkscape:cy="-86.548414"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1351"
|
||||||
|
inkscape:window-height="836"
|
||||||
|
inkscape:window-x="68"
|
||||||
|
inkscape:window-y="180"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
fit-margin-top="5"
|
||||||
|
fit-margin-left="5"
|
||||||
|
fit-margin-right="5"
|
||||||
|
fit-margin-bottom="5" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-117.08462,-249.92053)">
|
||||||
|
<flowRoot
|
||||||
|
xml:space="preserve"
|
||||||
|
id="flowRoot2985"
|
||||||
|
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
|
||||||
|
id="flowRegion2987"><rect
|
||||||
|
id="rect2989"
|
||||||
|
width="82.85714"
|
||||||
|
height="11.428572"
|
||||||
|
x="240"
|
||||||
|
y="492.36218" /></flowRegion><flowPara
|
||||||
|
id="flowPara2991" /></flowRoot> <text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819"
|
||||||
|
id="text4441"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4443"
|
||||||
|
x="362.371"
|
||||||
|
y="262.51819">->expedited_sequence: 3 GP: E,H</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||||
|
id="rect3101"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="253.55223"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="297.04141"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||||
|
id="rect3101-3-6"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="427.509"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="384.01981"
|
||||||
|
y="275.07489" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1"
|
||||||
|
id="rect3101-3-6-7-5"
|
||||||
|
width="43.158947"
|
||||||
|
height="26.33428"
|
||||||
|
x="340.53061"
|
||||||
|
y="275.07489" />
|
||||||
|
<g
|
||||||
|
id="g3997"
|
||||||
|
transform="translate(-0.87295532,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2"
|
||||||
|
style="fill:#ff8282;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;fill-opacity:1" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="146.00092"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015"
|
||||||
|
x="146.00092"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">:4</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g3019"
|
||||||
|
transform="translate(260.06223,0)">
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="123.95757"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-35-0"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="167.44673"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-62-9"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="297.91437"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-9-3"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="254.42516"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-1-6"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<rect
|
||||||
|
y="343.37366"
|
||||||
|
x="210.93593"
|
||||||
|
height="26.33428"
|
||||||
|
width="43.158947"
|
||||||
|
id="rect3101-3-6-7-5-2-0"
|
||||||
|
style="fill:#ff8282;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="145.54926"
|
||||||
|
y="360.25174"
|
||||||
|
id="text3013-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6"
|
||||||
|
x="145.54926"
|
||||||
|
y="360.25174"
|
||||||
|
style="font-size:10px">:6</tspan></text>
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="275.59558"
|
||||||
|
y="291.95297"
|
||||||
|
id="text3013-36"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-7"
|
||||||
|
x="275.59558"
|
||||||
|
y="291.95297"
|
||||||
|
style="font-size:10px">:6</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="405.40396"
|
||||||
|
y="291.88705"
|
||||||
|
id="text3013-3-36-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-7-6"
|
||||||
|
x="405.40396"
|
||||||
|
y="291.88705"
|
||||||
|
style="font-size:10px">F</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
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"
|
||||||
|
x="449.22031"
|
||||||
|
y="291.88217"
|
||||||
|
id="text3013-3-36-3-3"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3015-6-7-6-6"
|
||||||
|
x="449.22031"
|
||||||
|
y="291.88217"
|
||||||
|
style="font-size:10px">G</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 12 KiB |
|
@ -1480,7 +1480,7 @@ speed-of-light delays if nothing else.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Furthermore, uncertainty about external state is inherent in many cases.
|
Furthermore, uncertainty about external state is inherent in many cases.
|
||||||
For example, a pair of veternarians might use heartbeat to determine
|
For example, a pair of veterinarians might use heartbeat to determine
|
||||||
whether or not a given cat was alive.
|
whether or not a given cat was alive.
|
||||||
But how long should they wait after the last heartbeat to decide that
|
But how long should they wait after the last heartbeat to decide that
|
||||||
the cat is in fact dead?
|
the cat is in fact dead?
|
||||||
|
@ -1489,9 +1489,9 @@ mean that a relaxed cat would be considered to cycle between death
|
||||||
and life more than 100 times per minute.
|
and life more than 100 times per minute.
|
||||||
Moreover, just as with human beings, a cat's heart might stop for
|
Moreover, just as with human beings, a cat's heart might stop for
|
||||||
some period of time, so the exact wait period is a judgment call.
|
some period of time, so the exact wait period is a judgment call.
|
||||||
One of our pair of veternarians might wait 30 seconds before pronouncing
|
One of our pair of veterinarians might wait 30 seconds before pronouncing
|
||||||
the cat dead, while the other might insist on waiting a full minute.
|
the cat dead, while the other might insist on waiting a full minute.
|
||||||
The two veternarians would then disagree on the state of the cat during
|
The two veterinarians would then disagree on the state of the cat during
|
||||||
the final 30 seconds of the minute following the last heartbeat.
|
the final 30 seconds of the minute following the last heartbeat.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -1945,7 +1945,7 @@ guard against mishaps and misuse:
|
||||||
<ol>
|
<ol>
|
||||||
<li> It is all too easy to forget to use <tt>rcu_read_lock()</tt>
|
<li> It is all too easy to forget to use <tt>rcu_read_lock()</tt>
|
||||||
everywhere that it is needed, so kernels built with
|
everywhere that it is needed, so kernels built with
|
||||||
<tt>CONFIG_PROVE_RCU=y</tt> will spat if
|
<tt>CONFIG_PROVE_RCU=y</tt> will splat if
|
||||||
<tt>rcu_dereference()</tt> is used outside of an
|
<tt>rcu_dereference()</tt> is used outside of an
|
||||||
RCU read-side critical section.
|
RCU read-side critical section.
|
||||||
Update-side code can use <tt>rcu_dereference_protected()</tt>,
|
Update-side code can use <tt>rcu_dereference_protected()</tt>,
|
||||||
|
@ -2421,7 +2421,7 @@ However, there are some restrictions on the code placed within
|
||||||
<li> Blocking is prohibited.
|
<li> Blocking is prohibited.
|
||||||
In practice, this is not a serious restriction given that idle
|
In practice, this is not a serious restriction given that idle
|
||||||
tasks are prohibited from blocking to begin with.
|
tasks are prohibited from blocking to begin with.
|
||||||
<li> Although nesting <tt>RCU_NONIDLE()</tt> is permited, they cannot
|
<li> Although nesting <tt>RCU_NONIDLE()</tt> is permitted, they cannot
|
||||||
nest indefinitely deeply.
|
nest indefinitely deeply.
|
||||||
However, given that they can be nested on the order of a million
|
However, given that they can be nested on the order of a million
|
||||||
deep, even on 32-bit systems, this should not be a serious
|
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.
|
||||||
<h3><a name="Tasks RCU">Tasks RCU</a></h3>
|
<h3><a name="Tasks RCU">Tasks RCU</a></h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Some forms of tracing use “tramopolines” to handle the
|
Some forms of tracing use “trampolines” to handle the
|
||||||
binary rewriting required to install different types of probes.
|
binary rewriting required to install different types of probes.
|
||||||
It would be good to be able to free old trampolines, which sounds
|
It would be good to be able to free old trampolines, which sounds
|
||||||
like a job for some form of RCU.
|
like a job for some form of RCU.
|
||||||
|
|
|
@ -237,7 +237,7 @@ o "ktl" is the low-order 16 bits (in hexadecimal) of the count of
|
||||||
|
|
||||||
The output of "cat rcu/rcu_preempt/rcuexp" looks as follows:
|
The output of "cat rcu/rcu_preempt/rcuexp" looks as follows:
|
||||||
|
|
||||||
s=21872 wd1=0 wd2=0 wd3=5 n=0 enq=0 sc=21872
|
s=21872 wd1=0 wd2=0 wd3=5 enq=0 sc=21872
|
||||||
|
|
||||||
These fields are as follows:
|
These fields are as follows:
|
||||||
|
|
||||||
|
@ -249,9 +249,6 @@ o "wd1", "wd2", and "wd3" are the number of times that an attempt
|
||||||
completed an expedited grace period that satisfies the attempted
|
completed an expedited grace period that satisfies the attempted
|
||||||
request. "Our work is done."
|
request. "Our work is done."
|
||||||
|
|
||||||
o "n" is number of times that a concurrent CPU-hotplug operation
|
|
||||||
forced a fallback to a normal grace period.
|
|
||||||
|
|
||||||
o "enq" is the number of quiescent states still outstanding.
|
o "enq" is the number of quiescent states still outstanding.
|
||||||
|
|
||||||
o "sc" is the number of times that the attempt to start a
|
o "sc" is the number of times that the attempt to start a
|
||||||
|
|
|
@ -3269,6 +3269,13 @@
|
||||||
Lazy RCU callbacks are those which RCU can
|
Lazy RCU callbacks are those which RCU can
|
||||||
prove do nothing more than free memory.
|
prove do nothing more than free memory.
|
||||||
|
|
||||||
|
rcutree.rcu_kick_kthreads= [KNL]
|
||||||
|
Cause the grace-period kthread to get an extra
|
||||||
|
wake_up() if it sleeps three times longer than
|
||||||
|
it should at force-quiescent-state time.
|
||||||
|
This wake_up() will be accompanied by a
|
||||||
|
WARN_ONCE() splat and an ftrace_dump().
|
||||||
|
|
||||||
rcuperf.gp_exp= [KNL]
|
rcuperf.gp_exp= [KNL]
|
||||||
Measure performance of expedited synchronous
|
Measure performance of expedited synchronous
|
||||||
grace-period primitives.
|
grace-period primitives.
|
||||||
|
|
|
@ -640,6 +640,10 @@ See also the subsection on "Cache Coherency" for a more thorough example.
|
||||||
CONTROL DEPENDENCIES
|
CONTROL DEPENDENCIES
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
Control dependencies can be a bit tricky because current compilers do
|
||||||
|
not understand them. The purpose of this section is to help you prevent
|
||||||
|
the compiler's ignorance from breaking your code.
|
||||||
|
|
||||||
A load-load control dependency requires a full read memory barrier, not
|
A load-load control dependency requires a full read memory barrier, not
|
||||||
simply a data dependency barrier to make it work correctly. Consider the
|
simply a data dependency barrier to make it work correctly. Consider the
|
||||||
following bit of code:
|
following bit of code:
|
||||||
|
@ -667,14 +671,15 @@ for load-store control dependencies, as in the following example:
|
||||||
|
|
||||||
q = READ_ONCE(a);
|
q = READ_ONCE(a);
|
||||||
if (q) {
|
if (q) {
|
||||||
WRITE_ONCE(b, p);
|
WRITE_ONCE(b, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Control dependencies pair normally with other types of barriers. That
|
Control dependencies pair normally with other types of barriers.
|
||||||
said, please note that READ_ONCE() is not optional! Without the
|
That said, please note that neither READ_ONCE() nor WRITE_ONCE()
|
||||||
READ_ONCE(), the compiler might combine the load from 'a' with other
|
are optional! Without the READ_ONCE(), the compiler might combine the
|
||||||
loads from 'a', and the store to 'b' with other stores to 'b', with
|
load from 'a' with other loads from 'a'. Without the WRITE_ONCE(),
|
||||||
possible highly counterintuitive effects on ordering.
|
the compiler might combine the store to 'b' with other stores to 'b'.
|
||||||
|
Either can result in highly counterintuitive effects on ordering.
|
||||||
|
|
||||||
Worse yet, if the compiler is able to prove (say) that the value of
|
Worse yet, if the compiler is able to prove (say) that the value of
|
||||||
variable 'a' is always non-zero, it would be well within its rights
|
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
|
||||||
as follows:
|
as follows:
|
||||||
|
|
||||||
q = a;
|
q = a;
|
||||||
b = p; /* BUG: Compiler and CPU can both reorder!!! */
|
b = 1; /* BUG: Compiler and CPU can both reorder!!! */
|
||||||
|
|
||||||
So don't leave out the READ_ONCE().
|
So don't leave out the READ_ONCE().
|
||||||
|
|
||||||
|
@ -692,11 +697,11 @@ branches of the "if" statement as follows:
|
||||||
q = READ_ONCE(a);
|
q = READ_ONCE(a);
|
||||||
if (q) {
|
if (q) {
|
||||||
barrier();
|
barrier();
|
||||||
WRITE_ONCE(b, p);
|
WRITE_ONCE(b, 1);
|
||||||
do_something();
|
do_something();
|
||||||
} else {
|
} else {
|
||||||
barrier();
|
barrier();
|
||||||
WRITE_ONCE(b, p);
|
WRITE_ONCE(b, 1);
|
||||||
do_something_else();
|
do_something_else();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -705,12 +710,12 @@ optimization levels:
|
||||||
|
|
||||||
q = READ_ONCE(a);
|
q = READ_ONCE(a);
|
||||||
barrier();
|
barrier();
|
||||||
WRITE_ONCE(b, p); /* BUG: No ordering vs. load from a!!! */
|
WRITE_ONCE(b, 1); /* BUG: No ordering vs. load from a!!! */
|
||||||
if (q) {
|
if (q) {
|
||||||
/* WRITE_ONCE(b, p); -- moved up, BUG!!! */
|
/* WRITE_ONCE(b, 1); -- moved up, BUG!!! */
|
||||||
do_something();
|
do_something();
|
||||||
} else {
|
} else {
|
||||||
/* WRITE_ONCE(b, p); -- moved up, BUG!!! */
|
/* WRITE_ONCE(b, 1); -- moved up, BUG!!! */
|
||||||
do_something_else();
|
do_something_else();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -723,10 +728,10 @@ memory barriers, for example, smp_store_release():
|
||||||
|
|
||||||
q = READ_ONCE(a);
|
q = READ_ONCE(a);
|
||||||
if (q) {
|
if (q) {
|
||||||
smp_store_release(&b, p);
|
smp_store_release(&b, 1);
|
||||||
do_something();
|
do_something();
|
||||||
} else {
|
} else {
|
||||||
smp_store_release(&b, p);
|
smp_store_release(&b, 1);
|
||||||
do_something_else();
|
do_something_else();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -735,10 +740,10 @@ ordering is guaranteed only when the stores differ, for example:
|
||||||
|
|
||||||
q = READ_ONCE(a);
|
q = READ_ONCE(a);
|
||||||
if (q) {
|
if (q) {
|
||||||
WRITE_ONCE(b, p);
|
WRITE_ONCE(b, 1);
|
||||||
do_something();
|
do_something();
|
||||||
} else {
|
} else {
|
||||||
WRITE_ONCE(b, r);
|
WRITE_ONCE(b, 2);
|
||||||
do_something_else();
|
do_something_else();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,10 +756,10 @@ the needed conditional. For example:
|
||||||
|
|
||||||
q = READ_ONCE(a);
|
q = READ_ONCE(a);
|
||||||
if (q % MAX) {
|
if (q % MAX) {
|
||||||
WRITE_ONCE(b, p);
|
WRITE_ONCE(b, 1);
|
||||||
do_something();
|
do_something();
|
||||||
} else {
|
} else {
|
||||||
WRITE_ONCE(b, r);
|
WRITE_ONCE(b, 2);
|
||||||
do_something_else();
|
do_something_else();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,7 +768,7 @@ equal to zero, in which case the compiler is within its rights to
|
||||||
transform the above code into the following:
|
transform the above code into the following:
|
||||||
|
|
||||||
q = READ_ONCE(a);
|
q = READ_ONCE(a);
|
||||||
WRITE_ONCE(b, p);
|
WRITE_ONCE(b, 1);
|
||||||
do_something_else();
|
do_something_else();
|
||||||
|
|
||||||
Given this transformation, the CPU is not required to respect the ordering
|
Given this transformation, the CPU is not required to respect the ordering
|
||||||
|
@ -776,10 +781,10 @@ one, perhaps as follows:
|
||||||
q = READ_ONCE(a);
|
q = READ_ONCE(a);
|
||||||
BUILD_BUG_ON(MAX <= 1); /* Order load from a with store to b. */
|
BUILD_BUG_ON(MAX <= 1); /* Order load from a with store to b. */
|
||||||
if (q % MAX) {
|
if (q % MAX) {
|
||||||
WRITE_ONCE(b, p);
|
WRITE_ONCE(b, 1);
|
||||||
do_something();
|
do_something();
|
||||||
} else {
|
} else {
|
||||||
WRITE_ONCE(b, r);
|
WRITE_ONCE(b, 2);
|
||||||
do_something_else();
|
do_something_else();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -812,30 +817,28 @@ not necessarily apply to code following the if-statement:
|
||||||
|
|
||||||
q = READ_ONCE(a);
|
q = READ_ONCE(a);
|
||||||
if (q) {
|
if (q) {
|
||||||
WRITE_ONCE(b, p);
|
WRITE_ONCE(b, 1);
|
||||||
} else {
|
} else {
|
||||||
WRITE_ONCE(b, r);
|
WRITE_ONCE(b, 2);
|
||||||
}
|
}
|
||||||
WRITE_ONCE(c, 1); /* BUG: No ordering against the read from "a". */
|
WRITE_ONCE(c, 1); /* BUG: No ordering against the read from 'a'. */
|
||||||
|
|
||||||
It is tempting to argue that there in fact is ordering because the
|
It is tempting to argue that there in fact is ordering because the
|
||||||
compiler cannot reorder volatile accesses and also cannot reorder
|
compiler cannot reorder volatile accesses and also cannot reorder
|
||||||
the writes to "b" with the condition. Unfortunately for this line
|
the writes to 'b' with the condition. Unfortunately for this line
|
||||||
of reasoning, the compiler might compile the two writes to "b" as
|
of reasoning, the compiler might compile the two writes to 'b' as
|
||||||
conditional-move instructions, as in this fanciful pseudo-assembly
|
conditional-move instructions, as in this fanciful pseudo-assembly
|
||||||
language:
|
language:
|
||||||
|
|
||||||
ld r1,a
|
ld r1,a
|
||||||
ld r2,p
|
|
||||||
ld r3,r
|
|
||||||
cmp r1,$0
|
cmp r1,$0
|
||||||
cmov,ne r4,r2
|
cmov,ne r4,$1
|
||||||
cmov,eq r4,r3
|
cmov,eq r4,$2
|
||||||
st r4,b
|
st r4,b
|
||||||
st $1,c
|
st $1,c
|
||||||
|
|
||||||
A weakly ordered CPU would have no dependency of any sort between the load
|
A weakly ordered CPU would have no dependency of any sort between the load
|
||||||
from "a" and the store to "c". The control dependencies would extend
|
from 'a' and the store to 'c'. The control dependencies would extend
|
||||||
only to the pair of cmov instructions and the store depending on them.
|
only to the pair of cmov instructions and the store depending on them.
|
||||||
In short, control dependencies apply only to the stores in the then-clause
|
In short, control dependencies apply only to the stores in the then-clause
|
||||||
and else-clause of the if-statement in question (including functions
|
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.
|
||||||
|
|
||||||
Finally, control dependencies do -not- provide transitivity. This is
|
Finally, control dependencies do -not- provide transitivity. This is
|
||||||
demonstrated by two related examples, with the initial values of
|
demonstrated by two related examples, with the initial values of
|
||||||
x and y both being zero:
|
'x' and 'y' both being zero:
|
||||||
|
|
||||||
CPU 0 CPU 1
|
CPU 0 CPU 1
|
||||||
======================= =======================
|
======================= =======================
|
||||||
|
@ -915,6 +918,9 @@ In summary:
|
||||||
(*) Control dependencies do -not- provide transitivity. If you
|
(*) Control dependencies do -not- provide transitivity. If you
|
||||||
need transitivity, use smp_mb().
|
need transitivity, use smp_mb().
|
||||||
|
|
||||||
|
(*) Compilers do not understand control dependencies. It is therefore
|
||||||
|
your job to ensure that they do not break your code.
|
||||||
|
|
||||||
|
|
||||||
SMP BARRIER PAIRING
|
SMP BARRIER PAIRING
|
||||||
-------------------
|
-------------------
|
||||||
|
|
|
@ -3,28 +3,33 @@
|
||||||
/*
|
/*
|
||||||
* Lock-less NULL terminated single linked list
|
* Lock-less NULL terminated single linked list
|
||||||
*
|
*
|
||||||
* If there are multiple producers and multiple consumers, llist_add
|
* Cases where locking is not needed:
|
||||||
* can be used in producers and llist_del_all can be used in
|
* If there are multiple producers and multiple consumers, llist_add can be
|
||||||
* consumers. They can work simultaneously without lock. But
|
* used in producers and llist_del_all can be used in consumers simultaneously
|
||||||
* llist_del_first can not be used here. Because llist_del_first
|
* without locking. Also a single consumer can use llist_del_first while
|
||||||
* depends on list->first->next does not changed if list->first is not
|
* multiple producers simultaneously use llist_add, without any locking.
|
||||||
* changed during its operation, but llist_del_first, llist_add,
|
|
||||||
* llist_add (or llist_del_all, llist_add, llist_add) sequence in
|
|
||||||
* another consumer may violate that.
|
|
||||||
*
|
*
|
||||||
* If there are multiple producers and one consumer, llist_add can be
|
* Cases where locking is needed:
|
||||||
* used in producers and llist_del_all or llist_del_first can be used
|
* If we have multiple consumers with llist_del_first used in one consumer, and
|
||||||
* in the consumer.
|
* llist_del_first or llist_del_all used in other consumers, then a lock is
|
||||||
|
* needed. This is because llist_del_first depends on list->first->next not
|
||||||
|
* changing, but without lock protection, there's no way to be sure about that
|
||||||
|
* if a preemption happens in the middle of the delete operation and on being
|
||||||
|
* preempted back, the list->first is the same as before causing the cmpxchg in
|
||||||
|
* llist_del_first to succeed. For example, while a llist_del_first operation
|
||||||
|
* is in progress in one consumer, then a llist_del_first, llist_add,
|
||||||
|
* llist_add (or llist_del_all, llist_add, llist_add) sequence in another
|
||||||
|
* consumer may cause violations.
|
||||||
*
|
*
|
||||||
* This can be summarized as follow:
|
* This can be summarized as follows:
|
||||||
*
|
*
|
||||||
* | add | del_first | del_all
|
* | add | del_first | del_all
|
||||||
* add | - | - | -
|
* add | - | - | -
|
||||||
* del_first | | L | L
|
* del_first | | L | L
|
||||||
* del_all | | | -
|
* del_all | | | -
|
||||||
*
|
*
|
||||||
* Where "-" stands for no lock is needed, while "L" stands for lock
|
* Where, a particular row's operation can happen concurrently with a column's
|
||||||
* is needed.
|
* operation, with "-" being no lock needed, while "L" being lock is needed.
|
||||||
*
|
*
|
||||||
* The list entries deleted via llist_del_all can be traversed with
|
* The list entries deleted via llist_del_all can be traversed with
|
||||||
* traversing function such as llist_for_each etc. But the list
|
* traversing function such as llist_for_each etc. But the list
|
||||||
|
|
|
@ -1161,5 +1161,17 @@ do { \
|
||||||
ftrace_dump(oops_dump_mode); \
|
ftrace_dump(oops_dump_mode); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Place this after a lock-acquisition primitive to guarantee that
|
||||||
|
* an UNLOCK+LOCK pair acts as a full barrier. This guarantee applies
|
||||||
|
* if the UNLOCK and LOCK are executed by the same CPU or if the
|
||||||
|
* UNLOCK and LOCK operate on the same lock variable.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_PPC
|
||||||
|
#define smp_mb__after_unlock_lock() smp_mb() /* Full ordering for lock. */
|
||||||
|
#else /* #ifdef CONFIG_PPC */
|
||||||
|
#define smp_mb__after_unlock_lock() do { } while (0)
|
||||||
|
#endif /* #else #ifdef CONFIG_PPC */
|
||||||
|
|
||||||
|
|
||||||
#endif /* __LINUX_RCUPDATE_H */
|
#endif /* __LINUX_RCUPDATE_H */
|
||||||
|
|
|
@ -27,6 +27,12 @@
|
||||||
|
|
||||||
#include <linux/cache.h>
|
#include <linux/cache.h>
|
||||||
|
|
||||||
|
struct rcu_dynticks;
|
||||||
|
static inline int rcu_dynticks_snap(struct rcu_dynticks *rdtp)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline unsigned long get_state_synchronize_rcu(void)
|
static inline unsigned long get_state_synchronize_rcu(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -33,9 +33,9 @@
|
||||||
#include <linux/rcupdate.h>
|
#include <linux/rcupdate.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
|
||||||
struct srcu_struct_array {
|
struct srcu_array {
|
||||||
unsigned long c[2];
|
unsigned long lock_count[2];
|
||||||
unsigned long seq[2];
|
unsigned long unlock_count[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rcu_batch {
|
struct rcu_batch {
|
||||||
|
@ -46,7 +46,7 @@ struct rcu_batch {
|
||||||
|
|
||||||
struct srcu_struct {
|
struct srcu_struct {
|
||||||
unsigned long completed;
|
unsigned long completed;
|
||||||
struct srcu_struct_array __percpu *per_cpu_ref;
|
struct srcu_array __percpu *per_cpu_ref;
|
||||||
spinlock_t queue_lock; /* protect ->batch_queue, ->running */
|
spinlock_t queue_lock; /* protect ->batch_queue, ->running */
|
||||||
bool running;
|
bool running;
|
||||||
/* callbacks just queued */
|
/* callbacks just queued */
|
||||||
|
@ -118,7 +118,7 @@ void process_srcu(struct work_struct *work);
|
||||||
* See include/linux/percpu-defs.h for the rules on per-CPU variables.
|
* See include/linux/percpu-defs.h for the rules on per-CPU variables.
|
||||||
*/
|
*/
|
||||||
#define __DEFINE_SRCU(name, is_static) \
|
#define __DEFINE_SRCU(name, is_static) \
|
||||||
static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\
|
static DEFINE_PER_CPU(struct srcu_array, name##_srcu_array);\
|
||||||
is_static struct srcu_struct name = __SRCU_STRUCT_INIT(name)
|
is_static struct srcu_struct name = __SRCU_STRUCT_INIT(name)
|
||||||
#define DEFINE_SRCU(name) __DEFINE_SRCU(name, /* not static */)
|
#define DEFINE_SRCU(name) __DEFINE_SRCU(name, /* not static */)
|
||||||
#define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static)
|
#define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static)
|
||||||
|
|
|
@ -385,11 +385,11 @@ TRACE_EVENT(rcu_quiescent_state_report,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tracepoint for quiescent states detected by force_quiescent_state().
|
* Tracepoint for quiescent states detected by force_quiescent_state().
|
||||||
* These trace events include the type of RCU, the grace-period number
|
* These trace events include the type of RCU, the grace-period number that
|
||||||
* that was blocked by the CPU, the CPU itself, and the type of quiescent
|
* was blocked by the CPU, the CPU itself, and the type of quiescent state,
|
||||||
* state, which can be "dti" for dyntick-idle mode, "ofl" for CPU offline,
|
* which can be "dti" for dyntick-idle mode, "ofl" for CPU offline, "kick"
|
||||||
* or "kick" when kicking a CPU that has been in dyntick-idle mode for
|
* when kicking a CPU that has been in dyntick-idle mode for too long, or
|
||||||
* too long.
|
* "rqc" if the CPU got a quiescent state via its rcu_qs_ctr.
|
||||||
*/
|
*/
|
||||||
TRACE_EVENT(rcu_fqs,
|
TRACE_EVENT(rcu_fqs,
|
||||||
|
|
||||||
|
|
14
init/Kconfig
|
@ -529,7 +529,6 @@ config SRCU
|
||||||
config TASKS_RCU
|
config TASKS_RCU
|
||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
depends on !UML
|
|
||||||
select SRCU
|
select SRCU
|
||||||
help
|
help
|
||||||
This option enables a task-based RCU implementation that uses
|
This option enables a task-based RCU implementation that uses
|
||||||
|
@ -781,19 +780,6 @@ config RCU_NOCB_CPU_ALL
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
config RCU_EXPEDITE_BOOT
|
|
||||||
bool
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
This option enables expedited grace periods at boot time,
|
|
||||||
as if rcu_expedite_gp() had been invoked early in boot.
|
|
||||||
The corresponding rcu_unexpedite_gp() is invoked from
|
|
||||||
rcu_end_inkernel_boot(), which is intended to be invoked
|
|
||||||
at the end of the kernel-only boot sequence, just before
|
|
||||||
init is exec'ed.
|
|
||||||
|
|
||||||
Accept the default if unsure.
|
|
||||||
|
|
||||||
endmenu # "RCU Subsystem"
|
endmenu # "RCU Subsystem"
|
||||||
|
|
||||||
config BUILD_BIN2C
|
config BUILD_BIN2C
|
||||||
|
|
|
@ -4412,13 +4412,13 @@ void lockdep_rcu_suspicious(const char *file, const int line, const char *s)
|
||||||
#endif /* #ifdef CONFIG_PROVE_RCU_REPEATEDLY */
|
#endif /* #ifdef CONFIG_PROVE_RCU_REPEATEDLY */
|
||||||
/* Note: the following can be executed concurrently, so be careful. */
|
/* Note: the following can be executed concurrently, so be careful. */
|
||||||
printk("\n");
|
printk("\n");
|
||||||
printk("===============================\n");
|
pr_err("===============================\n");
|
||||||
printk("[ INFO: suspicious RCU usage. ]\n");
|
pr_err("[ ERR: suspicious RCU usage. ]\n");
|
||||||
print_kernel_ident();
|
print_kernel_ident();
|
||||||
printk("-------------------------------\n");
|
pr_err("-------------------------------\n");
|
||||||
printk("%s:%d %s!\n", file, line, s);
|
pr_err("%s:%d %s!\n", file, line, s);
|
||||||
printk("\nother info that might help us debug this:\n\n");
|
pr_err("\nother info that might help us debug this:\n\n");
|
||||||
printk("\n%srcu_scheduler_active = %d, debug_locks = %d\n",
|
pr_err("\n%srcu_scheduler_active = %d, debug_locks = %d\n",
|
||||||
!rcu_lockdep_current_cpu_online()
|
!rcu_lockdep_current_cpu_online()
|
||||||
? "RCU used illegally from offline CPU!\n"
|
? "RCU used illegally from offline CPU!\n"
|
||||||
: !rcu_is_watching()
|
: !rcu_is_watching()
|
||||||
|
|
|
@ -780,6 +780,10 @@ static void lock_torture_cleanup(void)
|
||||||
else
|
else
|
||||||
lock_torture_print_module_parms(cxt.cur_ops,
|
lock_torture_print_module_parms(cxt.cur_ops,
|
||||||
"End of test: SUCCESS");
|
"End of test: SUCCESS");
|
||||||
|
|
||||||
|
kfree(cxt.lwsa);
|
||||||
|
kfree(cxt.lrsa);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
torture_cleanup_end();
|
torture_cleanup_end();
|
||||||
}
|
}
|
||||||
|
@ -924,6 +928,8 @@ static int __init lock_torture_init(void)
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (reader_tasks == NULL) {
|
if (reader_tasks == NULL) {
|
||||||
VERBOSE_TOROUT_ERRSTRING("reader_tasks: Out of memory");
|
VERBOSE_TOROUT_ERRSTRING("reader_tasks: Out of memory");
|
||||||
|
kfree(writer_tasks);
|
||||||
|
writer_tasks = NULL;
|
||||||
firsterr = -ENOMEM;
|
firsterr = -ENOMEM;
|
||||||
goto unwind;
|
goto unwind;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
#include <linux/membarrier.h>
|
#include <linux/membarrier.h>
|
||||||
|
#include <linux/tick.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bitmask made from a "or" of all commands within enum membarrier_cmd,
|
* Bitmask made from a "or" of all commands within enum membarrier_cmd,
|
||||||
|
@ -51,6 +52,9 @@
|
||||||
*/
|
*/
|
||||||
SYSCALL_DEFINE2(membarrier, int, cmd, int, flags)
|
SYSCALL_DEFINE2(membarrier, int, cmd, int, flags)
|
||||||
{
|
{
|
||||||
|
/* MEMBARRIER_CMD_SHARED is not compatible with nohz_full. */
|
||||||
|
if (tick_nohz_full_enabled())
|
||||||
|
return -ENOSYS;
|
||||||
if (unlikely(flags))
|
if (unlikely(flags))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
|
|
@ -564,10 +564,25 @@ static void srcu_torture_stats(void)
|
||||||
pr_alert("%s%s per-CPU(idx=%d):",
|
pr_alert("%s%s per-CPU(idx=%d):",
|
||||||
torture_type, TORTURE_FLAG, idx);
|
torture_type, TORTURE_FLAG, idx);
|
||||||
for_each_possible_cpu(cpu) {
|
for_each_possible_cpu(cpu) {
|
||||||
|
unsigned long l0, l1;
|
||||||
|
unsigned long u0, u1;
|
||||||
long c0, c1;
|
long c0, c1;
|
||||||
|
struct srcu_array *counts = per_cpu_ptr(srcu_ctlp->per_cpu_ref, cpu);
|
||||||
|
|
||||||
c0 = (long)per_cpu_ptr(srcu_ctlp->per_cpu_ref, cpu)->c[!idx];
|
u0 = counts->unlock_count[!idx];
|
||||||
c1 = (long)per_cpu_ptr(srcu_ctlp->per_cpu_ref, cpu)->c[idx];
|
u1 = counts->unlock_count[idx];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure that a lock is always counted if the corresponding
|
||||||
|
* unlock is counted.
|
||||||
|
*/
|
||||||
|
smp_rmb();
|
||||||
|
|
||||||
|
l0 = counts->lock_count[!idx];
|
||||||
|
l1 = counts->lock_count[idx];
|
||||||
|
|
||||||
|
c0 = l0 - u0;
|
||||||
|
c1 = l1 - u1;
|
||||||
pr_cont(" %d(%ld,%ld)", cpu, c0, c1);
|
pr_cont(" %d(%ld,%ld)", cpu, c0, c1);
|
||||||
}
|
}
|
||||||
pr_cont("\n");
|
pr_cont("\n");
|
||||||
|
|
|
@ -106,7 +106,7 @@ static int init_srcu_struct_fields(struct srcu_struct *sp)
|
||||||
rcu_batch_init(&sp->batch_check1);
|
rcu_batch_init(&sp->batch_check1);
|
||||||
rcu_batch_init(&sp->batch_done);
|
rcu_batch_init(&sp->batch_done);
|
||||||
INIT_DELAYED_WORK(&sp->work, process_srcu);
|
INIT_DELAYED_WORK(&sp->work, process_srcu);
|
||||||
sp->per_cpu_ref = alloc_percpu(struct srcu_struct_array);
|
sp->per_cpu_ref = alloc_percpu(struct srcu_array);
|
||||||
return sp->per_cpu_ref ? 0 : -ENOMEM;
|
return sp->per_cpu_ref ? 0 : -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,114 +141,77 @@ EXPORT_SYMBOL_GPL(init_srcu_struct);
|
||||||
#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
|
#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns approximate total of the readers' ->seq[] values for the
|
* Returns approximate total of the readers' ->lock_count[] values for the
|
||||||
* rank of per-CPU counters specified by idx.
|
* rank of per-CPU counters specified by idx.
|
||||||
*/
|
*/
|
||||||
static unsigned long srcu_readers_seq_idx(struct srcu_struct *sp, int idx)
|
static unsigned long srcu_readers_lock_idx(struct srcu_struct *sp, int idx)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
unsigned long sum = 0;
|
unsigned long sum = 0;
|
||||||
unsigned long t;
|
|
||||||
|
|
||||||
for_each_possible_cpu(cpu) {
|
for_each_possible_cpu(cpu) {
|
||||||
t = READ_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->seq[idx]);
|
struct srcu_array *cpuc = per_cpu_ptr(sp->per_cpu_ref, cpu);
|
||||||
sum += t;
|
|
||||||
|
sum += READ_ONCE(cpuc->lock_count[idx]);
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns approximate number of readers active on the specified rank
|
* Returns approximate total of the readers' ->unlock_count[] values for the
|
||||||
* of the per-CPU ->c[] counters.
|
* rank of per-CPU counters specified by idx.
|
||||||
*/
|
*/
|
||||||
static unsigned long srcu_readers_active_idx(struct srcu_struct *sp, int idx)
|
static unsigned long srcu_readers_unlock_idx(struct srcu_struct *sp, int idx)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
unsigned long sum = 0;
|
unsigned long sum = 0;
|
||||||
unsigned long t;
|
|
||||||
|
|
||||||
for_each_possible_cpu(cpu) {
|
for_each_possible_cpu(cpu) {
|
||||||
t = READ_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[idx]);
|
struct srcu_array *cpuc = per_cpu_ptr(sp->per_cpu_ref, cpu);
|
||||||
sum += t;
|
|
||||||
|
sum += READ_ONCE(cpuc->unlock_count[idx]);
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return true if the number of pre-existing readers is determined to
|
* Return true if the number of pre-existing readers is determined to
|
||||||
* be stably zero. An example unstable zero can occur if the call
|
* be zero.
|
||||||
* to srcu_readers_active_idx() misses an __srcu_read_lock() increment,
|
|
||||||
* but due to task migration, sees the corresponding __srcu_read_unlock()
|
|
||||||
* decrement. This can happen because srcu_readers_active_idx() takes
|
|
||||||
* time to sum the array, and might in fact be interrupted or preempted
|
|
||||||
* partway through the summation.
|
|
||||||
*/
|
*/
|
||||||
static bool srcu_readers_active_idx_check(struct srcu_struct *sp, int idx)
|
static bool srcu_readers_active_idx_check(struct srcu_struct *sp, int idx)
|
||||||
{
|
{
|
||||||
unsigned long seq;
|
unsigned long unlocks;
|
||||||
|
|
||||||
seq = srcu_readers_seq_idx(sp, idx);
|
unlocks = srcu_readers_unlock_idx(sp, idx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following smp_mb() A pairs with the smp_mb() B located in
|
* Make sure that a lock is always counted if the corresponding unlock
|
||||||
* __srcu_read_lock(). This pairing ensures that if an
|
* is counted. Needs to be a smp_mb() as the read side may contain a
|
||||||
* __srcu_read_lock() increments its counter after the summation
|
* read from a variable that is written to before the synchronize_srcu()
|
||||||
* in srcu_readers_active_idx(), then the corresponding SRCU read-side
|
* in the write side. In this case smp_mb()s A and B act like the store
|
||||||
* critical section will see any changes made prior to the start
|
* buffering pattern.
|
||||||
* of the current SRCU grace period.
|
|
||||||
*
|
*
|
||||||
* Also, if the above call to srcu_readers_seq_idx() saw the
|
* This smp_mb() also pairs with smp_mb() C to prevent accesses after the
|
||||||
* increment of ->seq[], then the call to srcu_readers_active_idx()
|
* synchronize_srcu() from being executed before the grace period ends.
|
||||||
* must see the increment of ->c[].
|
|
||||||
*/
|
*/
|
||||||
smp_mb(); /* A */
|
smp_mb(); /* A */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note that srcu_readers_active_idx() can incorrectly return
|
* If the locks are the same as the unlocks, then there must have
|
||||||
* zero even though there is a pre-existing reader throughout.
|
* been no readers on this index at some time in between. This does not
|
||||||
* To see this, suppose that task A is in a very long SRCU
|
* mean that there are no more readers, as one could have read the
|
||||||
* read-side critical section that started on CPU 0, and that
|
* current index but not have incremented the lock counter yet.
|
||||||
* no other reader exists, so that the sum of the counters
|
|
||||||
* is equal to one. Then suppose that task B starts executing
|
|
||||||
* srcu_readers_active_idx(), summing up to CPU 1, and then that
|
|
||||||
* task C starts reading on CPU 0, so that its increment is not
|
|
||||||
* summed, but finishes reading on CPU 2, so that its decrement
|
|
||||||
* -is- summed. Then when task B completes its sum, it will
|
|
||||||
* incorrectly get zero, despite the fact that task A has been
|
|
||||||
* in its SRCU read-side critical section the whole time.
|
|
||||||
*
|
*
|
||||||
* We therefore do a validation step should srcu_readers_active_idx()
|
* Possible bug: There is no guarantee that there haven't been ULONG_MAX
|
||||||
* return zero.
|
* increments of ->lock_count[] since the unlocks were counted, meaning
|
||||||
|
* that this could return true even if there are still active readers.
|
||||||
|
* Since there are no memory barriers around srcu_flip(), the CPU is not
|
||||||
|
* required to increment ->completed before running
|
||||||
|
* srcu_readers_unlock_idx(), which means that there could be an
|
||||||
|
* arbitrarily large number of critical sections that execute after
|
||||||
|
* srcu_readers_unlock_idx() but use the old value of ->completed.
|
||||||
*/
|
*/
|
||||||
if (srcu_readers_active_idx(sp, idx) != 0)
|
return srcu_readers_lock_idx(sp, idx) == unlocks;
|
||||||
return false;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The remainder of this function is the validation step.
|
|
||||||
* The following smp_mb() D pairs with the smp_mb() C in
|
|
||||||
* __srcu_read_unlock(). If the __srcu_read_unlock() was seen
|
|
||||||
* by srcu_readers_active_idx() above, then any destructive
|
|
||||||
* operation performed after the grace period will happen after
|
|
||||||
* the corresponding SRCU read-side critical section.
|
|
||||||
*
|
|
||||||
* Note that there can be at most NR_CPUS worth of readers using
|
|
||||||
* the old index, which is not enough to overflow even a 32-bit
|
|
||||||
* integer. (Yes, this does mean that systems having more than
|
|
||||||
* a billion or so CPUs need to be 64-bit systems.) Therefore,
|
|
||||||
* the sum of the ->seq[] counters cannot possibly overflow.
|
|
||||||
* Therefore, the only way that the return values of the two
|
|
||||||
* calls to srcu_readers_seq_idx() can be equal is if there were
|
|
||||||
* no increments of the corresponding rank of ->seq[] counts
|
|
||||||
* in the interim. But the missed-increment scenario laid out
|
|
||||||
* above includes an increment of the ->seq[] counter by
|
|
||||||
* the corresponding __srcu_read_lock(). Therefore, if this
|
|
||||||
* scenario occurs, the return values from the two calls to
|
|
||||||
* srcu_readers_seq_idx() will differ, and thus the validation
|
|
||||||
* step below suffices.
|
|
||||||
*/
|
|
||||||
smp_mb(); /* D */
|
|
||||||
|
|
||||||
return srcu_readers_seq_idx(sp, idx) == seq;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -266,8 +229,12 @@ static bool srcu_readers_active(struct srcu_struct *sp)
|
||||||
unsigned long sum = 0;
|
unsigned long sum = 0;
|
||||||
|
|
||||||
for_each_possible_cpu(cpu) {
|
for_each_possible_cpu(cpu) {
|
||||||
sum += READ_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[0]);
|
struct srcu_array *cpuc = per_cpu_ptr(sp->per_cpu_ref, cpu);
|
||||||
sum += READ_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[1]);
|
|
||||||
|
sum += READ_ONCE(cpuc->lock_count[0]);
|
||||||
|
sum += READ_ONCE(cpuc->lock_count[1]);
|
||||||
|
sum -= READ_ONCE(cpuc->unlock_count[0]);
|
||||||
|
sum -= READ_ONCE(cpuc->unlock_count[1]);
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
@ -298,9 +265,8 @@ int __srcu_read_lock(struct srcu_struct *sp)
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
idx = READ_ONCE(sp->completed) & 0x1;
|
idx = READ_ONCE(sp->completed) & 0x1;
|
||||||
__this_cpu_inc(sp->per_cpu_ref->c[idx]);
|
__this_cpu_inc(sp->per_cpu_ref->lock_count[idx]);
|
||||||
smp_mb(); /* B */ /* Avoid leaking the critical section. */
|
smp_mb(); /* B */ /* Avoid leaking the critical section. */
|
||||||
__this_cpu_inc(sp->per_cpu_ref->seq[idx]);
|
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(__srcu_read_lock);
|
EXPORT_SYMBOL_GPL(__srcu_read_lock);
|
||||||
|
@ -314,7 +280,7 @@ EXPORT_SYMBOL_GPL(__srcu_read_lock);
|
||||||
void __srcu_read_unlock(struct srcu_struct *sp, int idx)
|
void __srcu_read_unlock(struct srcu_struct *sp, int idx)
|
||||||
{
|
{
|
||||||
smp_mb(); /* C */ /* Avoid leaking the critical section. */
|
smp_mb(); /* C */ /* Avoid leaking the critical section. */
|
||||||
this_cpu_dec(sp->per_cpu_ref->c[idx]);
|
this_cpu_inc(sp->per_cpu_ref->unlock_count[idx]);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(__srcu_read_unlock);
|
EXPORT_SYMBOL_GPL(__srcu_read_unlock);
|
||||||
|
|
||||||
|
@ -349,12 +315,21 @@ static bool try_check_zero(struct srcu_struct *sp, int idx, int trycount)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Increment the ->completed counter so that future SRCU readers will
|
* Increment the ->completed counter so that future SRCU readers will
|
||||||
* use the other rank of the ->c[] and ->seq[] arrays. This allows
|
* use the other rank of the ->(un)lock_count[] arrays. This allows
|
||||||
* us to wait for pre-existing readers in a starvation-free manner.
|
* us to wait for pre-existing readers in a starvation-free manner.
|
||||||
*/
|
*/
|
||||||
static void srcu_flip(struct srcu_struct *sp)
|
static void srcu_flip(struct srcu_struct *sp)
|
||||||
{
|
{
|
||||||
sp->completed++;
|
WRITE_ONCE(sp->completed, sp->completed + 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure that if the updater misses an __srcu_read_unlock()
|
||||||
|
* increment, that task's next __srcu_read_lock() will see the
|
||||||
|
* above counter update. Note that both this memory barrier
|
||||||
|
* and the one in srcu_readers_active_idx_check() provide the
|
||||||
|
* guarantee for __srcu_read_lock().
|
||||||
|
*/
|
||||||
|
smp_mb(); /* D */ /* Pairs with C. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -392,6 +367,7 @@ void call_srcu(struct srcu_struct *sp, struct rcu_head *head,
|
||||||
head->next = NULL;
|
head->next = NULL;
|
||||||
head->func = func;
|
head->func = func;
|
||||||
spin_lock_irqsave(&sp->queue_lock, flags);
|
spin_lock_irqsave(&sp->queue_lock, flags);
|
||||||
|
smp_mb__after_unlock_lock(); /* Caller's prior accesses before GP. */
|
||||||
rcu_batch_queue(&sp->batch_queue, head);
|
rcu_batch_queue(&sp->batch_queue, head);
|
||||||
if (!sp->running) {
|
if (!sp->running) {
|
||||||
sp->running = true;
|
sp->running = true;
|
||||||
|
@ -425,6 +401,7 @@ static void __synchronize_srcu(struct srcu_struct *sp, int trycount)
|
||||||
head->next = NULL;
|
head->next = NULL;
|
||||||
head->func = wakeme_after_rcu;
|
head->func = wakeme_after_rcu;
|
||||||
spin_lock_irq(&sp->queue_lock);
|
spin_lock_irq(&sp->queue_lock);
|
||||||
|
smp_mb__after_unlock_lock(); /* Caller's prior accesses before GP. */
|
||||||
if (!sp->running) {
|
if (!sp->running) {
|
||||||
/* steal the processing owner */
|
/* steal the processing owner */
|
||||||
sp->running = true;
|
sp->running = true;
|
||||||
|
@ -444,8 +421,11 @@ static void __synchronize_srcu(struct srcu_struct *sp, int trycount)
|
||||||
spin_unlock_irq(&sp->queue_lock);
|
spin_unlock_irq(&sp->queue_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!done)
|
if (!done) {
|
||||||
wait_for_completion(&rcu.completion);
|
wait_for_completion(&rcu.completion);
|
||||||
|
smp_mb(); /* Caller's later accesses after GP. */
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -613,7 +593,8 @@ static void srcu_advance_batches(struct srcu_struct *sp, int trycount)
|
||||||
/*
|
/*
|
||||||
* Invoke a limited number of SRCU callbacks that have passed through
|
* Invoke a limited number of SRCU callbacks that have passed through
|
||||||
* their grace period. If there are more to do, SRCU will reschedule
|
* their grace period. If there are more to do, SRCU will reschedule
|
||||||
* the workqueue.
|
* the workqueue. Note that needed memory barriers have been executed
|
||||||
|
* in this task's context by srcu_readers_active_idx_check().
|
||||||
*/
|
*/
|
||||||
static void srcu_invoke_callbacks(struct srcu_struct *sp)
|
static void srcu_invoke_callbacks(struct srcu_struct *sp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,8 +41,6 @@
|
||||||
|
|
||||||
/* Forward declarations for tiny_plugin.h. */
|
/* Forward declarations for tiny_plugin.h. */
|
||||||
struct rcu_ctrlblk;
|
struct rcu_ctrlblk;
|
||||||
static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp);
|
|
||||||
static void rcu_process_callbacks(struct softirq_action *unused);
|
|
||||||
static void __call_rcu(struct rcu_head *head,
|
static void __call_rcu(struct rcu_head *head,
|
||||||
rcu_callback_t func,
|
rcu_callback_t func,
|
||||||
struct rcu_ctrlblk *rcp);
|
struct rcu_ctrlblk *rcp);
|
||||||
|
|
|
@ -281,6 +281,116 @@ static DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = {
|
||||||
#endif /* #ifdef CONFIG_NO_HZ_FULL_SYSIDLE */
|
#endif /* #ifdef CONFIG_NO_HZ_FULL_SYSIDLE */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record entry into an extended quiescent state. This is only to be
|
||||||
|
* called when not already in an extended quiescent state.
|
||||||
|
*/
|
||||||
|
static void rcu_dynticks_eqs_enter(void)
|
||||||
|
{
|
||||||
|
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
|
||||||
|
int special;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CPUs seeing atomic_inc_return() must see prior RCU read-side
|
||||||
|
* critical sections, and we also must force ordering with the
|
||||||
|
* next idle sojourn.
|
||||||
|
*/
|
||||||
|
special = atomic_inc_return(&rdtp->dynticks);
|
||||||
|
WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && special & 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record exit from an extended quiescent state. This is only to be
|
||||||
|
* called from an extended quiescent state.
|
||||||
|
*/
|
||||||
|
static void rcu_dynticks_eqs_exit(void)
|
||||||
|
{
|
||||||
|
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
|
||||||
|
int special;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CPUs seeing atomic_inc_return() must see prior idle sojourns,
|
||||||
|
* and we also must force ordering with the next RCU read-side
|
||||||
|
* critical section.
|
||||||
|
*/
|
||||||
|
special = atomic_inc_return(&rdtp->dynticks);
|
||||||
|
WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && !(special & 0x1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset the current CPU's ->dynticks counter to indicate that the
|
||||||
|
* newly onlined CPU is no longer in an extended quiescent state.
|
||||||
|
* This will either leave the counter unchanged, or increment it
|
||||||
|
* to the next non-quiescent value.
|
||||||
|
*
|
||||||
|
* The non-atomic test/increment sequence works because the upper bits
|
||||||
|
* of the ->dynticks counter are manipulated only by the corresponding CPU,
|
||||||
|
* or when the corresponding CPU is offline.
|
||||||
|
*/
|
||||||
|
static void rcu_dynticks_eqs_online(void)
|
||||||
|
{
|
||||||
|
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
|
||||||
|
|
||||||
|
if (atomic_read(&rdtp->dynticks) & 0x1)
|
||||||
|
return;
|
||||||
|
atomic_add(0x1, &rdtp->dynticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Is the current CPU in an extended quiescent state?
|
||||||
|
*
|
||||||
|
* No ordering, as we are sampling CPU-local information.
|
||||||
|
*/
|
||||||
|
bool rcu_dynticks_curr_cpu_in_eqs(void)
|
||||||
|
{
|
||||||
|
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
|
||||||
|
|
||||||
|
return !(atomic_read(&rdtp->dynticks) & 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Snapshot the ->dynticks counter with full ordering so as to allow
|
||||||
|
* stable comparison of this counter with past and future snapshots.
|
||||||
|
*/
|
||||||
|
int rcu_dynticks_snap(struct rcu_dynticks *rdtp)
|
||||||
|
{
|
||||||
|
int snap = atomic_add_return(0, &rdtp->dynticks);
|
||||||
|
|
||||||
|
return snap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return true if the snapshot returned from rcu_dynticks_snap()
|
||||||
|
* indicates that RCU is in an extended quiescent state.
|
||||||
|
*/
|
||||||
|
static bool rcu_dynticks_in_eqs(int snap)
|
||||||
|
{
|
||||||
|
return !(snap & 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return true if the CPU corresponding to the specified rcu_dynticks
|
||||||
|
* structure has spent some time in an extended quiescent state since
|
||||||
|
* rcu_dynticks_snap() returned the specified snapshot.
|
||||||
|
*/
|
||||||
|
static bool rcu_dynticks_in_eqs_since(struct rcu_dynticks *rdtp, int snap)
|
||||||
|
{
|
||||||
|
return snap != rcu_dynticks_snap(rdtp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do a double-increment of the ->dynticks counter to emulate a
|
||||||
|
* momentary idle-CPU quiescent state.
|
||||||
|
*/
|
||||||
|
static void rcu_dynticks_momentary_idle(void)
|
||||||
|
{
|
||||||
|
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
|
||||||
|
int special = atomic_add_return(2, &rdtp->dynticks);
|
||||||
|
|
||||||
|
/* It is illegal to call this from idle state. */
|
||||||
|
WARN_ON_ONCE(!(special & 0x1));
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_PER_CPU_SHARED_ALIGNED(unsigned long, rcu_qs_ctr);
|
DEFINE_PER_CPU_SHARED_ALIGNED(unsigned long, rcu_qs_ctr);
|
||||||
EXPORT_PER_CPU_SYMBOL_GPL(rcu_qs_ctr);
|
EXPORT_PER_CPU_SYMBOL_GPL(rcu_qs_ctr);
|
||||||
|
|
||||||
|
@ -300,7 +410,6 @@ EXPORT_PER_CPU_SYMBOL_GPL(rcu_qs_ctr);
|
||||||
static void rcu_momentary_dyntick_idle(void)
|
static void rcu_momentary_dyntick_idle(void)
|
||||||
{
|
{
|
||||||
struct rcu_data *rdp;
|
struct rcu_data *rdp;
|
||||||
struct rcu_dynticks *rdtp;
|
|
||||||
int resched_mask;
|
int resched_mask;
|
||||||
struct rcu_state *rsp;
|
struct rcu_state *rsp;
|
||||||
|
|
||||||
|
@ -327,10 +436,7 @@ static void rcu_momentary_dyntick_idle(void)
|
||||||
* quiescent state, with no need for this CPU to do anything
|
* quiescent state, with no need for this CPU to do anything
|
||||||
* further.
|
* further.
|
||||||
*/
|
*/
|
||||||
rdtp = this_cpu_ptr(&rcu_dynticks);
|
rcu_dynticks_momentary_idle();
|
||||||
smp_mb__before_atomic(); /* Earlier stuff before QS. */
|
|
||||||
atomic_add(2, &rdtp->dynticks); /* QS. */
|
|
||||||
smp_mb__after_atomic(); /* Later stuff after QS. */
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -611,7 +717,7 @@ static int
|
||||||
cpu_has_callbacks_ready_to_invoke(struct rcu_data *rdp)
|
cpu_has_callbacks_ready_to_invoke(struct rcu_data *rdp)
|
||||||
{
|
{
|
||||||
return &rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL] &&
|
return &rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL] &&
|
||||||
rdp->nxttail[RCU_DONE_TAIL] != NULL;
|
rdp->nxttail[RCU_NEXT_TAIL] != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -673,7 +779,7 @@ static void rcu_eqs_enter_common(long long oldval, bool user)
|
||||||
{
|
{
|
||||||
struct rcu_state *rsp;
|
struct rcu_state *rsp;
|
||||||
struct rcu_data *rdp;
|
struct rcu_data *rdp;
|
||||||
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
|
RCU_TRACE(struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);)
|
||||||
|
|
||||||
trace_rcu_dyntick(TPS("Start"), oldval, rdtp->dynticks_nesting);
|
trace_rcu_dyntick(TPS("Start"), oldval, rdtp->dynticks_nesting);
|
||||||
if (IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
|
if (IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
|
||||||
|
@ -692,12 +798,7 @@ static void rcu_eqs_enter_common(long long oldval, bool user)
|
||||||
do_nocb_deferred_wakeup(rdp);
|
do_nocb_deferred_wakeup(rdp);
|
||||||
}
|
}
|
||||||
rcu_prepare_for_idle();
|
rcu_prepare_for_idle();
|
||||||
/* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */
|
rcu_dynticks_eqs_enter();
|
||||||
smp_mb__before_atomic(); /* See above. */
|
|
||||||
atomic_inc(&rdtp->dynticks);
|
|
||||||
smp_mb__after_atomic(); /* Force ordering with next sojourn. */
|
|
||||||
WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
|
|
||||||
atomic_read(&rdtp->dynticks) & 0x1);
|
|
||||||
rcu_dynticks_task_enter();
|
rcu_dynticks_task_enter();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -826,15 +927,10 @@ void rcu_irq_exit_irqson(void)
|
||||||
*/
|
*/
|
||||||
static void rcu_eqs_exit_common(long long oldval, int user)
|
static void rcu_eqs_exit_common(long long oldval, int user)
|
||||||
{
|
{
|
||||||
struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);
|
RCU_TRACE(struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);)
|
||||||
|
|
||||||
rcu_dynticks_task_exit();
|
rcu_dynticks_task_exit();
|
||||||
smp_mb__before_atomic(); /* Force ordering w/previous sojourn. */
|
rcu_dynticks_eqs_exit();
|
||||||
atomic_inc(&rdtp->dynticks);
|
|
||||||
/* CPUs seeing atomic_inc() must see later RCU read-side crit sects */
|
|
||||||
smp_mb__after_atomic(); /* See above. */
|
|
||||||
WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
|
|
||||||
!(atomic_read(&rdtp->dynticks) & 0x1));
|
|
||||||
rcu_cleanup_after_idle();
|
rcu_cleanup_after_idle();
|
||||||
trace_rcu_dyntick(TPS("End"), oldval, rdtp->dynticks_nesting);
|
trace_rcu_dyntick(TPS("End"), oldval, rdtp->dynticks_nesting);
|
||||||
if (IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
|
if (IS_ENABLED(CONFIG_RCU_EQS_DEBUG) &&
|
||||||
|
@ -980,12 +1076,8 @@ void rcu_nmi_enter(void)
|
||||||
* to be in the outermost NMI handler that interrupted an RCU-idle
|
* to be in the outermost NMI handler that interrupted an RCU-idle
|
||||||
* period (observation due to Andy Lutomirski).
|
* period (observation due to Andy Lutomirski).
|
||||||
*/
|
*/
|
||||||
if (!(atomic_read(&rdtp->dynticks) & 0x1)) {
|
if (rcu_dynticks_curr_cpu_in_eqs()) {
|
||||||
smp_mb__before_atomic(); /* Force delay from prior write. */
|
rcu_dynticks_eqs_exit();
|
||||||
atomic_inc(&rdtp->dynticks);
|
|
||||||
/* atomic_inc() before later RCU read-side crit sects */
|
|
||||||
smp_mb__after_atomic(); /* See above. */
|
|
||||||
WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1));
|
|
||||||
incby = 1;
|
incby = 1;
|
||||||
}
|
}
|
||||||
rdtp->dynticks_nmi_nesting += incby;
|
rdtp->dynticks_nmi_nesting += incby;
|
||||||
|
@ -1010,7 +1102,7 @@ void rcu_nmi_exit(void)
|
||||||
* to us!)
|
* to us!)
|
||||||
*/
|
*/
|
||||||
WARN_ON_ONCE(rdtp->dynticks_nmi_nesting <= 0);
|
WARN_ON_ONCE(rdtp->dynticks_nmi_nesting <= 0);
|
||||||
WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1));
|
WARN_ON_ONCE(rcu_dynticks_curr_cpu_in_eqs());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the nesting level is not 1, the CPU wasn't RCU-idle, so
|
* If the nesting level is not 1, the CPU wasn't RCU-idle, so
|
||||||
|
@ -1023,11 +1115,7 @@ void rcu_nmi_exit(void)
|
||||||
|
|
||||||
/* This NMI interrupted an RCU-idle CPU, restore RCU-idleness. */
|
/* This NMI interrupted an RCU-idle CPU, restore RCU-idleness. */
|
||||||
rdtp->dynticks_nmi_nesting = 0;
|
rdtp->dynticks_nmi_nesting = 0;
|
||||||
/* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */
|
rcu_dynticks_eqs_enter();
|
||||||
smp_mb__before_atomic(); /* See above. */
|
|
||||||
atomic_inc(&rdtp->dynticks);
|
|
||||||
smp_mb__after_atomic(); /* Force delay to next write. */
|
|
||||||
WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1040,7 +1128,7 @@ void rcu_nmi_exit(void)
|
||||||
*/
|
*/
|
||||||
bool notrace __rcu_is_watching(void)
|
bool notrace __rcu_is_watching(void)
|
||||||
{
|
{
|
||||||
return atomic_read(this_cpu_ptr(&rcu_dynticks.dynticks)) & 0x1;
|
return !rcu_dynticks_curr_cpu_in_eqs();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1123,9 +1211,9 @@ static int rcu_is_cpu_rrupt_from_idle(void)
|
||||||
static int dyntick_save_progress_counter(struct rcu_data *rdp,
|
static int dyntick_save_progress_counter(struct rcu_data *rdp,
|
||||||
bool *isidle, unsigned long *maxj)
|
bool *isidle, unsigned long *maxj)
|
||||||
{
|
{
|
||||||
rdp->dynticks_snap = atomic_add_return(0, &rdp->dynticks->dynticks);
|
rdp->dynticks_snap = rcu_dynticks_snap(rdp->dynticks);
|
||||||
rcu_sysidle_check_cpu(rdp, isidle, maxj);
|
rcu_sysidle_check_cpu(rdp, isidle, maxj);
|
||||||
if ((rdp->dynticks_snap & 0x1) == 0) {
|
if (rcu_dynticks_in_eqs(rdp->dynticks_snap)) {
|
||||||
trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("dti"));
|
trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("dti"));
|
||||||
if (ULONG_CMP_LT(READ_ONCE(rdp->gpnum) + ULONG_MAX / 4,
|
if (ULONG_CMP_LT(READ_ONCE(rdp->gpnum) + ULONG_MAX / 4,
|
||||||
rdp->mynode->gpnum))
|
rdp->mynode->gpnum))
|
||||||
|
@ -1144,12 +1232,10 @@ static int dyntick_save_progress_counter(struct rcu_data *rdp,
|
||||||
static int rcu_implicit_dynticks_qs(struct rcu_data *rdp,
|
static int rcu_implicit_dynticks_qs(struct rcu_data *rdp,
|
||||||
bool *isidle, unsigned long *maxj)
|
bool *isidle, unsigned long *maxj)
|
||||||
{
|
{
|
||||||
unsigned int curr;
|
unsigned long jtsq;
|
||||||
int *rcrmp;
|
int *rcrmp;
|
||||||
unsigned int snap;
|
unsigned long rjtsc;
|
||||||
|
struct rcu_node *rnp;
|
||||||
curr = (unsigned int)atomic_add_return(0, &rdp->dynticks->dynticks);
|
|
||||||
snap = (unsigned int)rdp->dynticks_snap;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the CPU passed through or entered a dynticks idle phase with
|
* 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,
|
||||||
* read-side critical section that started before the beginning
|
* read-side critical section that started before the beginning
|
||||||
* of the current RCU grace period.
|
* of the current RCU grace period.
|
||||||
*/
|
*/
|
||||||
if ((curr & 0x1) == 0 || UINT_CMP_GE(curr, snap + 2)) {
|
if (rcu_dynticks_in_eqs_since(rdp->dynticks, rdp->dynticks_snap)) {
|
||||||
trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("dti"));
|
trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("dti"));
|
||||||
rdp->dynticks_fqs++;
|
rdp->dynticks_fqs++;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Compute and saturate jiffies_till_sched_qs. */
|
||||||
|
jtsq = jiffies_till_sched_qs;
|
||||||
|
rjtsc = rcu_jiffies_till_stall_check();
|
||||||
|
if (jtsq > rjtsc / 2) {
|
||||||
|
WRITE_ONCE(jiffies_till_sched_qs, rjtsc);
|
||||||
|
jtsq = rjtsc / 2;
|
||||||
|
} else if (jtsq < 1) {
|
||||||
|
WRITE_ONCE(jiffies_till_sched_qs, 1);
|
||||||
|
jtsq = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for the CPU being offline, but only if the grace period
|
* Has this CPU encountered a cond_resched_rcu_qs() since the
|
||||||
* is old enough. We don't need to worry about the CPU changing
|
* beginning of the grace period? For this to be the case,
|
||||||
* state: If we see it offline even once, it has been through a
|
* the CPU has to have noticed the current grace period. This
|
||||||
* quiescent state.
|
* might not be the case for nohz_full CPUs looping in the kernel.
|
||||||
*
|
|
||||||
* The reason for insisting that the grace period be at least
|
|
||||||
* one jiffy old is that CPUs that are not quite online and that
|
|
||||||
* have just gone offline can still execute RCU read-side critical
|
|
||||||
* sections.
|
|
||||||
*/
|
*/
|
||||||
if (ULONG_CMP_GE(rdp->rsp->gp_start + 2, jiffies))
|
rnp = rdp->mynode;
|
||||||
return 0; /* Grace period is not old enough. */
|
if (time_after(jiffies, rdp->rsp->gp_start + jtsq) &&
|
||||||
barrier();
|
READ_ONCE(rdp->rcu_qs_ctr_snap) != per_cpu(rcu_qs_ctr, rdp->cpu) &&
|
||||||
if (cpu_is_offline(rdp->cpu)) {
|
READ_ONCE(rdp->gpnum) == rnp->gpnum && !rdp->gpwrap) {
|
||||||
|
trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("rqc"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for the CPU being offline. */
|
||||||
|
if (!(rdp->grpmask & rcu_rnp_online_cpus(rnp))) {
|
||||||
trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("ofl"));
|
trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, TPS("ofl"));
|
||||||
rdp->offline_fqs++;
|
rdp->offline_fqs++;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1207,9 +1305,8 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp,
|
||||||
* warning delay.
|
* warning delay.
|
||||||
*/
|
*/
|
||||||
rcrmp = &per_cpu(rcu_sched_qs_mask, rdp->cpu);
|
rcrmp = &per_cpu(rcu_sched_qs_mask, rdp->cpu);
|
||||||
if (ULONG_CMP_GE(jiffies,
|
if (time_after(jiffies, rdp->rsp->gp_start + jtsq) ||
|
||||||
rdp->rsp->gp_start + jiffies_till_sched_qs) ||
|
time_after(jiffies, rdp->rsp->jiffies_resched)) {
|
||||||
ULONG_CMP_GE(jiffies, rdp->rsp->jiffies_resched)) {
|
|
||||||
if (!(READ_ONCE(*rcrmp) & rdp->rsp->flavor_mask)) {
|
if (!(READ_ONCE(*rcrmp) & rdp->rsp->flavor_mask)) {
|
||||||
WRITE_ONCE(rdp->cond_resched_completed,
|
WRITE_ONCE(rdp->cond_resched_completed,
|
||||||
READ_ONCE(rdp->mynode->completed));
|
READ_ONCE(rdp->mynode->completed));
|
||||||
|
@ -1220,11 +1317,12 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp,
|
||||||
rdp->rsp->jiffies_resched += 5; /* Re-enable beating. */
|
rdp->rsp->jiffies_resched += 5; /* Re-enable beating. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And if it has been a really long time, kick the CPU as well. */
|
/*
|
||||||
if (ULONG_CMP_GE(jiffies,
|
* If more than halfway to RCU CPU stall-warning time, do
|
||||||
rdp->rsp->gp_start + 2 * jiffies_till_sched_qs) ||
|
* a resched_cpu() to try to loosen things up a bit.
|
||||||
ULONG_CMP_GE(jiffies, rdp->rsp->gp_start + jiffies_till_sched_qs))
|
*/
|
||||||
resched_cpu(rdp->cpu); /* Force CPU into scheduler. */
|
if (jiffies - rdp->rsp->gp_start > rcu_jiffies_till_stall_check() / 2)
|
||||||
|
resched_cpu(rdp->cpu);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1277,7 +1375,10 @@ static void rcu_check_gp_kthread_starvation(struct rcu_state *rsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dump stacks of all tasks running on stalled CPUs.
|
* Dump stacks of all tasks running on stalled CPUs. First try using
|
||||||
|
* NMIs, but fall back to manual remote stack tracing on architectures
|
||||||
|
* that don't support NMI-based stack dumps. The NMI-triggered stack
|
||||||
|
* traces are more accurate because they are printed by the target CPU.
|
||||||
*/
|
*/
|
||||||
static void rcu_dump_cpu_stacks(struct rcu_state *rsp)
|
static void rcu_dump_cpu_stacks(struct rcu_state *rsp)
|
||||||
{
|
{
|
||||||
|
@ -1287,11 +1388,10 @@ static void rcu_dump_cpu_stacks(struct rcu_state *rsp)
|
||||||
|
|
||||||
rcu_for_each_leaf_node(rsp, rnp) {
|
rcu_for_each_leaf_node(rsp, rnp) {
|
||||||
raw_spin_lock_irqsave_rcu_node(rnp, flags);
|
raw_spin_lock_irqsave_rcu_node(rnp, flags);
|
||||||
if (rnp->qsmask != 0) {
|
for_each_leaf_node_possible_cpu(rnp, cpu)
|
||||||
for_each_leaf_node_possible_cpu(rnp, cpu)
|
if (rnp->qsmask & leaf_node_cpu_bit(rnp, cpu))
|
||||||
if (rnp->qsmask & leaf_node_cpu_bit(rnp, cpu))
|
if (!trigger_single_cpu_backtrace(cpu))
|
||||||
dump_cpu_task(cpu);
|
dump_cpu_task(cpu);
|
||||||
}
|
|
||||||
raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
|
raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1379,6 +1479,9 @@ static void print_other_cpu_stall(struct rcu_state *rsp, unsigned long gpnum)
|
||||||
(long)rsp->gpnum, (long)rsp->completed, totqlen);
|
(long)rsp->gpnum, (long)rsp->completed, totqlen);
|
||||||
if (ndetected) {
|
if (ndetected) {
|
||||||
rcu_dump_cpu_stacks(rsp);
|
rcu_dump_cpu_stacks(rsp);
|
||||||
|
|
||||||
|
/* Complain about tasks blocking the grace period. */
|
||||||
|
rcu_print_detail_task_stall(rsp);
|
||||||
} else {
|
} else {
|
||||||
if (READ_ONCE(rsp->gpnum) != gpnum ||
|
if (READ_ONCE(rsp->gpnum) != gpnum ||
|
||||||
READ_ONCE(rsp->completed) == gpnum) {
|
READ_ONCE(rsp->completed) == gpnum) {
|
||||||
|
@ -1395,9 +1498,6 @@ static void print_other_cpu_stall(struct rcu_state *rsp, unsigned long gpnum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Complain about tasks blocking the grace period. */
|
|
||||||
rcu_print_detail_task_stall(rsp);
|
|
||||||
|
|
||||||
rcu_check_gp_kthread_starvation(rsp);
|
rcu_check_gp_kthread_starvation(rsp);
|
||||||
|
|
||||||
panic_on_rcu_stall();
|
panic_on_rcu_stall();
|
||||||
|
@ -2467,10 +2567,8 @@ rcu_report_qs_rdp(int cpu, struct rcu_state *rsp, struct rcu_data *rdp)
|
||||||
|
|
||||||
rnp = rdp->mynode;
|
rnp = rdp->mynode;
|
||||||
raw_spin_lock_irqsave_rcu_node(rnp, flags);
|
raw_spin_lock_irqsave_rcu_node(rnp, flags);
|
||||||
if ((rdp->cpu_no_qs.b.norm &&
|
if (rdp->cpu_no_qs.b.norm || rdp->gpnum != rnp->gpnum ||
|
||||||
rdp->rcu_qs_ctr_snap == __this_cpu_read(rcu_qs_ctr)) ||
|
rnp->completed == rnp->gpnum || rdp->gpwrap) {
|
||||||
rdp->gpnum != rnp->gpnum || rnp->completed == rnp->gpnum ||
|
|
||||||
rdp->gpwrap) {
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The grace period in which this quiescent state was
|
* 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)
|
||||||
* Was there a quiescent state since the beginning of the grace
|
* Was there a quiescent state since the beginning of the grace
|
||||||
* period? If no, then exit and wait for the next call.
|
* period? If no, then exit and wait for the next call.
|
||||||
*/
|
*/
|
||||||
if (rdp->cpu_no_qs.b.norm &&
|
if (rdp->cpu_no_qs.b.norm)
|
||||||
rdp->rcu_qs_ctr_snap == __this_cpu_read(rcu_qs_ctr))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3480,9 +3577,7 @@ static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp)
|
||||||
rdp->core_needs_qs && rdp->cpu_no_qs.b.norm &&
|
rdp->core_needs_qs && rdp->cpu_no_qs.b.norm &&
|
||||||
rdp->rcu_qs_ctr_snap == __this_cpu_read(rcu_qs_ctr)) {
|
rdp->rcu_qs_ctr_snap == __this_cpu_read(rcu_qs_ctr)) {
|
||||||
rdp->n_rp_core_needs_qs++;
|
rdp->n_rp_core_needs_qs++;
|
||||||
} else if (rdp->core_needs_qs &&
|
} else if (rdp->core_needs_qs && !rdp->cpu_no_qs.b.norm) {
|
||||||
(!rdp->cpu_no_qs.b.norm ||
|
|
||||||
rdp->rcu_qs_ctr_snap != __this_cpu_read(rcu_qs_ctr))) {
|
|
||||||
rdp->n_rp_report_qs++;
|
rdp->n_rp_report_qs++;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -3748,7 +3843,7 @@ rcu_boot_init_percpu_data(int cpu, struct rcu_state *rsp)
|
||||||
rdp->grpmask = leaf_node_cpu_bit(rdp->mynode, cpu);
|
rdp->grpmask = leaf_node_cpu_bit(rdp->mynode, cpu);
|
||||||
rdp->dynticks = &per_cpu(rcu_dynticks, cpu);
|
rdp->dynticks = &per_cpu(rcu_dynticks, cpu);
|
||||||
WARN_ON_ONCE(rdp->dynticks->dynticks_nesting != DYNTICK_TASK_EXIT_IDLE);
|
WARN_ON_ONCE(rdp->dynticks->dynticks_nesting != DYNTICK_TASK_EXIT_IDLE);
|
||||||
WARN_ON_ONCE(atomic_read(&rdp->dynticks->dynticks) != 1);
|
WARN_ON_ONCE(rcu_dynticks_in_eqs(rcu_dynticks_snap(rdp->dynticks)));
|
||||||
rdp->cpu = cpu;
|
rdp->cpu = cpu;
|
||||||
rdp->rsp = rsp;
|
rdp->rsp = rsp;
|
||||||
rcu_boot_init_nocb_percpu_data(rdp);
|
rcu_boot_init_nocb_percpu_data(rdp);
|
||||||
|
@ -3765,7 +3860,6 @@ static void
|
||||||
rcu_init_percpu_data(int cpu, struct rcu_state *rsp)
|
rcu_init_percpu_data(int cpu, struct rcu_state *rsp)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned long mask;
|
|
||||||
struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
|
struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
|
||||||
struct rcu_node *rnp = rcu_get_root(rsp);
|
struct rcu_node *rnp = rcu_get_root(rsp);
|
||||||
|
|
||||||
|
@ -3778,8 +3872,7 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp)
|
||||||
init_callback_list(rdp); /* Re-enable callbacks on this CPU. */
|
init_callback_list(rdp); /* Re-enable callbacks on this CPU. */
|
||||||
rdp->dynticks->dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
|
rdp->dynticks->dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
|
||||||
rcu_sysidle_init_percpu_data(rdp->dynticks);
|
rcu_sysidle_init_percpu_data(rdp->dynticks);
|
||||||
atomic_set(&rdp->dynticks->dynticks,
|
rcu_dynticks_eqs_online();
|
||||||
(atomic_read(&rdp->dynticks->dynticks) & ~0x1) + 1);
|
|
||||||
raw_spin_unlock_rcu_node(rnp); /* irqs remain disabled. */
|
raw_spin_unlock_rcu_node(rnp); /* irqs remain disabled. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3788,7 +3881,6 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp)
|
||||||
* of the next grace period.
|
* of the next grace period.
|
||||||
*/
|
*/
|
||||||
rnp = rdp->mynode;
|
rnp = rdp->mynode;
|
||||||
mask = rdp->grpmask;
|
|
||||||
raw_spin_lock_rcu_node(rnp); /* irqs already disabled. */
|
raw_spin_lock_rcu_node(rnp); /* irqs already disabled. */
|
||||||
if (!rdp->beenonline)
|
if (!rdp->beenonline)
|
||||||
WRITE_ONCE(rsp->ncpus, READ_ONCE(rsp->ncpus) + 1);
|
WRITE_ONCE(rsp->ncpus, READ_ONCE(rsp->ncpus) + 1);
|
||||||
|
@ -3872,7 +3964,7 @@ void rcu_cpu_starting(unsigned int cpu)
|
||||||
struct rcu_state *rsp;
|
struct rcu_state *rsp;
|
||||||
|
|
||||||
for_each_rcu_flavor(rsp) {
|
for_each_rcu_flavor(rsp) {
|
||||||
rdp = this_cpu_ptr(rsp->rda);
|
rdp = per_cpu_ptr(rsp->rda, cpu);
|
||||||
rnp = rdp->mynode;
|
rnp = rdp->mynode;
|
||||||
mask = rdp->grpmask;
|
mask = rdp->grpmask;
|
||||||
raw_spin_lock_irqsave_rcu_node(rnp, flags);
|
raw_spin_lock_irqsave_rcu_node(rnp, flags);
|
||||||
|
|
|
@ -521,7 +521,6 @@ struct rcu_state {
|
||||||
struct mutex exp_mutex; /* Serialize expedited GP. */
|
struct mutex exp_mutex; /* Serialize expedited GP. */
|
||||||
struct mutex exp_wake_mutex; /* Serialize wakeup. */
|
struct mutex exp_wake_mutex; /* Serialize wakeup. */
|
||||||
unsigned long expedited_sequence; /* Take a ticket. */
|
unsigned long expedited_sequence; /* Take a ticket. */
|
||||||
atomic_long_t expedited_normal; /* # fallbacks to normal. */
|
|
||||||
atomic_t expedited_need_qs; /* # CPUs left to check in. */
|
atomic_t expedited_need_qs; /* # CPUs left to check in. */
|
||||||
struct swait_queue_head expedited_wq; /* Wait for check-ins. */
|
struct swait_queue_head expedited_wq; /* Wait for check-ins. */
|
||||||
int ncpus_snap; /* # CPUs seen last time. */
|
int ncpus_snap; /* # CPUs seen last time. */
|
||||||
|
@ -595,6 +594,8 @@ extern struct rcu_state rcu_bh_state;
|
||||||
extern struct rcu_state rcu_preempt_state;
|
extern struct rcu_state rcu_preempt_state;
|
||||||
#endif /* #ifdef CONFIG_PREEMPT_RCU */
|
#endif /* #ifdef CONFIG_PREEMPT_RCU */
|
||||||
|
|
||||||
|
int rcu_dynticks_snap(struct rcu_dynticks *rdtp);
|
||||||
|
|
||||||
#ifdef CONFIG_RCU_BOOST
|
#ifdef CONFIG_RCU_BOOST
|
||||||
DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status);
|
DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status);
|
||||||
DECLARE_PER_CPU(int, rcu_cpu_kthread_cpu);
|
DECLARE_PER_CPU(int, rcu_cpu_kthread_cpu);
|
||||||
|
@ -687,18 +688,6 @@ static inline void rcu_nocb_q_lengths(struct rcu_data *rdp, long *ql, long *qll)
|
||||||
}
|
}
|
||||||
#endif /* #ifdef CONFIG_RCU_TRACE */
|
#endif /* #ifdef CONFIG_RCU_TRACE */
|
||||||
|
|
||||||
/*
|
|
||||||
* Place this after a lock-acquisition primitive to guarantee that
|
|
||||||
* an UNLOCK+LOCK pair act as a full barrier. This guarantee applies
|
|
||||||
* if the UNLOCK and LOCK are executed by the same CPU or if the
|
|
||||||
* UNLOCK and LOCK operate on the same lock variable.
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_PPC
|
|
||||||
#define smp_mb__after_unlock_lock() smp_mb() /* Full ordering for lock. */
|
|
||||||
#else /* #ifdef CONFIG_PPC */
|
|
||||||
#define smp_mb__after_unlock_lock() do { } while (0)
|
|
||||||
#endif /* #else #ifdef CONFIG_PPC */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wrappers for the rcu_node::lock acquire and release.
|
* Wrappers for the rcu_node::lock acquire and release.
|
||||||
*
|
*
|
||||||
|
|
|
@ -20,16 +20,26 @@
|
||||||
* Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
|
* Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Wrapper functions for expedited grace periods. */
|
/*
|
||||||
|
* Record the start of an expedited grace period.
|
||||||
|
*/
|
||||||
static void rcu_exp_gp_seq_start(struct rcu_state *rsp)
|
static void rcu_exp_gp_seq_start(struct rcu_state *rsp)
|
||||||
{
|
{
|
||||||
rcu_seq_start(&rsp->expedited_sequence);
|
rcu_seq_start(&rsp->expedited_sequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record the end of an expedited grace period.
|
||||||
|
*/
|
||||||
static void rcu_exp_gp_seq_end(struct rcu_state *rsp)
|
static void rcu_exp_gp_seq_end(struct rcu_state *rsp)
|
||||||
{
|
{
|
||||||
rcu_seq_end(&rsp->expedited_sequence);
|
rcu_seq_end(&rsp->expedited_sequence);
|
||||||
smp_mb(); /* Ensure that consecutive grace periods serialize. */
|
smp_mb(); /* Ensure that consecutive grace periods serialize. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Take a snapshot of the expedited-grace-period counter.
|
||||||
|
*/
|
||||||
static unsigned long rcu_exp_gp_seq_snap(struct rcu_state *rsp)
|
static unsigned long rcu_exp_gp_seq_snap(struct rcu_state *rsp)
|
||||||
{
|
{
|
||||||
unsigned long s;
|
unsigned long s;
|
||||||
|
@ -39,6 +49,12 @@ static unsigned long rcu_exp_gp_seq_snap(struct rcu_state *rsp)
|
||||||
trace_rcu_exp_grace_period(rsp->name, s, TPS("snap"));
|
trace_rcu_exp_grace_period(rsp->name, s, TPS("snap"));
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given a counter snapshot from rcu_exp_gp_seq_snap(), return true
|
||||||
|
* if a full expedited grace period has elapsed since that snapshot
|
||||||
|
* was taken.
|
||||||
|
*/
|
||||||
static bool rcu_exp_gp_seq_done(struct rcu_state *rsp, unsigned long s)
|
static bool rcu_exp_gp_seq_done(struct rcu_state *rsp, unsigned long s)
|
||||||
{
|
{
|
||||||
return rcu_seq_done(&rsp->expedited_sequence, s);
|
return rcu_seq_done(&rsp->expedited_sequence, s);
|
||||||
|
@ -356,12 +372,11 @@ static void sync_rcu_exp_select_cpus(struct rcu_state *rsp,
|
||||||
mask_ofl_test = 0;
|
mask_ofl_test = 0;
|
||||||
for_each_leaf_node_possible_cpu(rnp, cpu) {
|
for_each_leaf_node_possible_cpu(rnp, cpu) {
|
||||||
struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
|
struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
|
||||||
struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu);
|
|
||||||
|
|
||||||
rdp->exp_dynticks_snap =
|
rdp->exp_dynticks_snap =
|
||||||
atomic_add_return(0, &rdtp->dynticks);
|
rcu_dynticks_snap(rdp->dynticks);
|
||||||
if (raw_smp_processor_id() == cpu ||
|
if (raw_smp_processor_id() == cpu ||
|
||||||
!(rdp->exp_dynticks_snap & 0x1) ||
|
rcu_dynticks_in_eqs(rdp->exp_dynticks_snap) ||
|
||||||
!(rnp->qsmaskinitnext & rdp->grpmask))
|
!(rnp->qsmaskinitnext & rdp->grpmask))
|
||||||
mask_ofl_test |= rdp->grpmask;
|
mask_ofl_test |= rdp->grpmask;
|
||||||
}
|
}
|
||||||
|
@ -380,13 +395,12 @@ static void sync_rcu_exp_select_cpus(struct rcu_state *rsp,
|
||||||
for_each_leaf_node_possible_cpu(rnp, cpu) {
|
for_each_leaf_node_possible_cpu(rnp, cpu) {
|
||||||
unsigned long mask = leaf_node_cpu_bit(rnp, cpu);
|
unsigned long mask = leaf_node_cpu_bit(rnp, cpu);
|
||||||
struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
|
struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
|
||||||
struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu);
|
|
||||||
|
|
||||||
if (!(mask_ofl_ipi & mask))
|
if (!(mask_ofl_ipi & mask))
|
||||||
continue;
|
continue;
|
||||||
retry_ipi:
|
retry_ipi:
|
||||||
if (atomic_add_return(0, &rdtp->dynticks) !=
|
if (rcu_dynticks_in_eqs_since(rdp->dynticks,
|
||||||
rdp->exp_dynticks_snap) {
|
rdp->exp_dynticks_snap)) {
|
||||||
mask_ofl_test |= mask;
|
mask_ofl_test |= mask;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -623,6 +637,11 @@ void synchronize_sched_expedited(void)
|
||||||
{
|
{
|
||||||
struct rcu_state *rsp = &rcu_sched_state;
|
struct rcu_state *rsp = &rcu_sched_state;
|
||||||
|
|
||||||
|
RCU_LOCKDEP_WARN(lock_is_held(&rcu_bh_lock_map) ||
|
||||||
|
lock_is_held(&rcu_lock_map) ||
|
||||||
|
lock_is_held(&rcu_sched_lock_map),
|
||||||
|
"Illegal synchronize_sched_expedited() in RCU read-side critical section");
|
||||||
|
|
||||||
/* If only one CPU, this is automatically a grace period. */
|
/* If only one CPU, this is automatically a grace period. */
|
||||||
if (rcu_blocking_is_gp())
|
if (rcu_blocking_is_gp())
|
||||||
return;
|
return;
|
||||||
|
@ -692,6 +711,11 @@ void synchronize_rcu_expedited(void)
|
||||||
{
|
{
|
||||||
struct rcu_state *rsp = rcu_state_p;
|
struct rcu_state *rsp = rcu_state_p;
|
||||||
|
|
||||||
|
RCU_LOCKDEP_WARN(lock_is_held(&rcu_bh_lock_map) ||
|
||||||
|
lock_is_held(&rcu_lock_map) ||
|
||||||
|
lock_is_held(&rcu_sched_lock_map),
|
||||||
|
"Illegal synchronize_rcu_expedited() in RCU read-side critical section");
|
||||||
|
|
||||||
if (rcu_scheduler_active == RCU_SCHEDULER_INACTIVE)
|
if (rcu_scheduler_active == RCU_SCHEDULER_INACTIVE)
|
||||||
return;
|
return;
|
||||||
_synchronize_rcu_expedited(rsp, sync_rcu_exp_handler);
|
_synchronize_rcu_expedited(rsp, sync_rcu_exp_handler);
|
||||||
|
|
|
@ -1643,7 +1643,7 @@ static void print_cpu_stall_info(struct rcu_state *rsp, int cpu)
|
||||||
"o."[!!(rdp->grpmask & rdp->mynode->qsmaskinit)],
|
"o."[!!(rdp->grpmask & rdp->mynode->qsmaskinit)],
|
||||||
"N."[!!(rdp->grpmask & rdp->mynode->qsmaskinitnext)],
|
"N."[!!(rdp->grpmask & rdp->mynode->qsmaskinitnext)],
|
||||||
ticks_value, ticks_title,
|
ticks_value, ticks_title,
|
||||||
atomic_read(&rdtp->dynticks) & 0xfff,
|
rcu_dynticks_snap(rdtp) & 0xfff,
|
||||||
rdtp->dynticks_nesting, rdtp->dynticks_nmi_nesting,
|
rdtp->dynticks_nesting, rdtp->dynticks_nmi_nesting,
|
||||||
rdp->softirq_snap, kstat_softirqs_cpu(RCU_SOFTIRQ, cpu),
|
rdp->softirq_snap, kstat_softirqs_cpu(RCU_SOFTIRQ, cpu),
|
||||||
READ_ONCE(rsp->n_force_qs) - rsp->n_force_qs_gpstart,
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Each pass through this loop sets up one rcu_data structure and
|
* Each pass through this loop sets up one rcu_data structure.
|
||||||
* spawns one rcu_nocb_kthread().
|
* Should the corresponding CPU come online in the future, then
|
||||||
|
* we will spawn the needed set of rcu_nocb_kthread() kthreads.
|
||||||
*/
|
*/
|
||||||
for_each_cpu(cpu, rcu_nocb_mask) {
|
for_each_cpu(cpu, rcu_nocb_mask) {
|
||||||
rdp = per_cpu_ptr(rsp->rda, cpu);
|
rdp = per_cpu_ptr(rsp->rda, cpu);
|
||||||
|
|
|
@ -124,7 +124,7 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp)
|
||||||
rdp->rcu_qs_ctr_snap == per_cpu(rcu_qs_ctr, rdp->cpu),
|
rdp->rcu_qs_ctr_snap == per_cpu(rcu_qs_ctr, rdp->cpu),
|
||||||
rdp->core_needs_qs);
|
rdp->core_needs_qs);
|
||||||
seq_printf(m, " dt=%d/%llx/%d df=%lu",
|
seq_printf(m, " dt=%d/%llx/%d df=%lu",
|
||||||
atomic_read(&rdp->dynticks->dynticks),
|
rcu_dynticks_snap(rdp->dynticks),
|
||||||
rdp->dynticks->dynticks_nesting,
|
rdp->dynticks->dynticks_nesting,
|
||||||
rdp->dynticks->dynticks_nmi_nesting,
|
rdp->dynticks->dynticks_nmi_nesting,
|
||||||
rdp->dynticks_fqs);
|
rdp->dynticks_fqs);
|
||||||
|
@ -194,9 +194,8 @@ static int show_rcuexp(struct seq_file *m, void *v)
|
||||||
s2 += atomic_long_read(&rdp->exp_workdone2);
|
s2 += atomic_long_read(&rdp->exp_workdone2);
|
||||||
s3 += atomic_long_read(&rdp->exp_workdone3);
|
s3 += atomic_long_read(&rdp->exp_workdone3);
|
||||||
}
|
}
|
||||||
seq_printf(m, "s=%lu wd0=%lu wd1=%lu wd2=%lu wd3=%lu n=%lu enq=%d sc=%lu\n",
|
seq_printf(m, "s=%lu wd0=%lu wd1=%lu wd2=%lu wd3=%lu enq=%d sc=%lu\n",
|
||||||
rsp->expedited_sequence, s0, s1, s2, s3,
|
rsp->expedited_sequence, s0, s1, s2, s3,
|
||||||
atomic_long_read(&rsp->expedited_normal),
|
|
||||||
atomic_read(&rsp->expedited_need_qs),
|
atomic_read(&rsp->expedited_need_qs),
|
||||||
rsp->expedited_sequence / 2);
|
rsp->expedited_sequence / 2);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -132,8 +132,7 @@ bool rcu_gp_is_normal(void)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rcu_gp_is_normal);
|
EXPORT_SYMBOL_GPL(rcu_gp_is_normal);
|
||||||
|
|
||||||
static atomic_t rcu_expedited_nesting =
|
static atomic_t rcu_expedited_nesting = ATOMIC_INIT(1);
|
||||||
ATOMIC_INIT(IS_ENABLED(CONFIG_RCU_EXPEDITE_BOOT) ? 1 : 0);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Should normal grace-period primitives be expedited? Intended for
|
* Should normal grace-period primitives be expedited? Intended for
|
||||||
|
@ -182,8 +181,7 @@ EXPORT_SYMBOL_GPL(rcu_unexpedite_gp);
|
||||||
*/
|
*/
|
||||||
void rcu_end_inkernel_boot(void)
|
void rcu_end_inkernel_boot(void)
|
||||||
{
|
{
|
||||||
if (IS_ENABLED(CONFIG_RCU_EXPEDITE_BOOT))
|
rcu_unexpedite_gp();
|
||||||
rcu_unexpedite_gp();
|
|
||||||
if (rcu_normal_after_boot)
|
if (rcu_normal_after_boot)
|
||||||
WRITE_ONCE(rcu_normal, 1);
|
WRITE_ONCE(rcu_normal, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1436,6 +1436,7 @@ config RCU_CPU_STALL_TIMEOUT
|
||||||
config RCU_TRACE
|
config RCU_TRACE
|
||||||
bool "Enable tracing for RCU"
|
bool "Enable tracing for RCU"
|
||||||
depends on DEBUG_KERNEL
|
depends on DEBUG_KERNEL
|
||||||
|
default y if TREE_RCU
|
||||||
select TRACE_CLOCK
|
select TRACE_CLOCK
|
||||||
help
|
help
|
||||||
This option provides tracing in RCU which presents stats
|
This option provides tracing in RCU which presents stats
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
CONFIG_RCU_TORTURE_TEST=y
|
CONFIG_RCU_TORTURE_TEST=y
|
||||||
CONFIG_PRINTK_TIME=y
|
CONFIG_PRINTK_TIME=y
|
||||||
CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y
|
|
||||||
CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y
|
|
||||||
CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ CONFIG_HZ_PERIODIC=n
|
||||||
CONFIG_NO_HZ_IDLE=y
|
CONFIG_NO_HZ_IDLE=y
|
||||||
CONFIG_NO_HZ_FULL=n
|
CONFIG_NO_HZ_FULL=n
|
||||||
CONFIG_RCU_TRACE=n
|
CONFIG_RCU_TRACE=n
|
||||||
|
#CHECK#CONFIG_RCU_STALL_COMMON=n
|
||||||
CONFIG_DEBUG_LOCK_ALLOC=n
|
CONFIG_DEBUG_LOCK_ALLOC=n
|
||||||
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
||||||
CONFIG_PREEMPT_COUNT=n
|
CONFIG_PREEMPT_COUNT=n
|
||||||
|
|
|
@ -8,7 +8,8 @@ CONFIG_NO_HZ_IDLE=n
|
||||||
CONFIG_NO_HZ_FULL=n
|
CONFIG_NO_HZ_FULL=n
|
||||||
CONFIG_RCU_TRACE=y
|
CONFIG_RCU_TRACE=y
|
||||||
CONFIG_PROVE_LOCKING=y
|
CONFIG_PROVE_LOCKING=y
|
||||||
|
CONFIG_PROVE_RCU_REPEATEDLY=y
|
||||||
#CHECK#CONFIG_PROVE_RCU=y
|
#CHECK#CONFIG_PROVE_RCU=y
|
||||||
CONFIG_DEBUG_LOCK_ALLOC=y
|
CONFIG_DEBUG_LOCK_ALLOC=y
|
||||||
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
|
||||||
CONFIG_PREEMPT_COUNT=y
|
CONFIG_PREEMPT_COUNT=y
|
||||||
|
|
|
@ -16,3 +16,6 @@ CONFIG_DEBUG_LOCK_ALLOC=n
|
||||||
CONFIG_RCU_BOOST=n
|
CONFIG_RCU_BOOST=n
|
||||||
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
||||||
CONFIG_RCU_EXPERT=y
|
CONFIG_RCU_EXPERT=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y
|
||||||
|
|
|
@ -20,3 +20,7 @@ CONFIG_PROVE_LOCKING=n
|
||||||
CONFIG_RCU_BOOST=n
|
CONFIG_RCU_BOOST=n
|
||||||
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
||||||
CONFIG_RCU_EXPERT=y
|
CONFIG_RCU_EXPERT=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y
|
||||||
|
CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
|
||||||
|
|
|
@ -17,3 +17,6 @@ CONFIG_RCU_BOOST=y
|
||||||
CONFIG_RCU_KTHREAD_PRIO=2
|
CONFIG_RCU_KTHREAD_PRIO=2
|
||||||
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
||||||
CONFIG_RCU_EXPERT=y
|
CONFIG_RCU_EXPERT=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y
|
||||||
|
|
|
@ -19,3 +19,7 @@ CONFIG_RCU_NOCB_CPU=n
|
||||||
CONFIG_DEBUG_LOCK_ALLOC=n
|
CONFIG_DEBUG_LOCK_ALLOC=n
|
||||||
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
||||||
CONFIG_RCU_EXPERT=y
|
CONFIG_RCU_EXPERT=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y
|
||||||
|
CONFIG_RCU_EQS_DEBUG=y
|
||||||
|
|
|
@ -19,3 +19,6 @@ CONFIG_PROVE_LOCKING=y
|
||||||
#CHECK#CONFIG_PROVE_RCU=y
|
#CHECK#CONFIG_PROVE_RCU=y
|
||||||
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
||||||
CONFIG_RCU_EXPERT=y
|
CONFIG_RCU_EXPERT=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y
|
||||||
|
|
|
@ -20,3 +20,6 @@ CONFIG_PROVE_LOCKING=y
|
||||||
#CHECK#CONFIG_PROVE_RCU=y
|
#CHECK#CONFIG_PROVE_RCU=y
|
||||||
CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
|
CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
|
||||||
CONFIG_RCU_EXPERT=y
|
CONFIG_RCU_EXPERT=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y
|
||||||
|
|
|
@ -19,3 +19,6 @@ CONFIG_RCU_NOCB_CPU=n
|
||||||
CONFIG_DEBUG_LOCK_ALLOC=n
|
CONFIG_DEBUG_LOCK_ALLOC=n
|
||||||
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
||||||
CONFIG_RCU_EXPERT=y
|
CONFIG_RCU_EXPERT=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y
|
||||||
|
|
|
@ -17,8 +17,8 @@ CONFIG_RCU_FANOUT_LEAF=2
|
||||||
CONFIG_RCU_NOCB_CPU=y
|
CONFIG_RCU_NOCB_CPU=y
|
||||||
CONFIG_RCU_NOCB_CPU_ALL=y
|
CONFIG_RCU_NOCB_CPU_ALL=y
|
||||||
CONFIG_DEBUG_LOCK_ALLOC=n
|
CONFIG_DEBUG_LOCK_ALLOC=n
|
||||||
CONFIG_PROVE_LOCKING=y
|
CONFIG_PROVE_LOCKING=n
|
||||||
#CHECK#CONFIG_PROVE_RCU=y
|
|
||||||
CONFIG_RCU_BOOST=n
|
CONFIG_RCU_BOOST=n
|
||||||
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
|
||||||
CONFIG_RCU_EXPERT=y
|
CONFIG_RCU_EXPERT=y
|
||||||
|
CONFIG_RCU_EQS_DEBUG=y
|
||||||
|
|
|
@ -14,6 +14,7 @@ CONFIG_NO_HZ_FULL_SYSIDLE -- Do one.
|
||||||
CONFIG_PREEMPT -- Do half. (First three and #8.)
|
CONFIG_PREEMPT -- Do half. (First three and #8.)
|
||||||
CONFIG_PROVE_LOCKING -- Do several, covering CONFIG_DEBUG_LOCK_ALLOC=y and not.
|
CONFIG_PROVE_LOCKING -- Do several, covering CONFIG_DEBUG_LOCK_ALLOC=y and not.
|
||||||
CONFIG_PROVE_RCU -- Hardwired to CONFIG_PROVE_LOCKING.
|
CONFIG_PROVE_RCU -- Hardwired to CONFIG_PROVE_LOCKING.
|
||||||
|
CONFIG_PROVE_RCU_REPEATEDLY -- Do one.
|
||||||
CONFIG_RCU_BOOST -- one of PREEMPT_RCU.
|
CONFIG_RCU_BOOST -- one of PREEMPT_RCU.
|
||||||
CONFIG_RCU_KTHREAD_PRIO -- set to 2 for _BOOST testing.
|
CONFIG_RCU_KTHREAD_PRIO -- set to 2 for _BOOST testing.
|
||||||
CONFIG_RCU_FANOUT -- Cover hierarchy, but overlap with others.
|
CONFIG_RCU_FANOUT -- Cover hierarchy, but overlap with others.
|
||||||
|
@ -25,7 +26,12 @@ CONFIG_RCU_NOCB_CPU_NONE -- Do one.
|
||||||
CONFIG_RCU_NOCB_CPU_ZERO -- Do one.
|
CONFIG_RCU_NOCB_CPU_ZERO -- Do one.
|
||||||
CONFIG_RCU_TRACE -- Do half.
|
CONFIG_RCU_TRACE -- Do half.
|
||||||
CONFIG_SMP -- Need one !SMP for PREEMPT_RCU.
|
CONFIG_SMP -- Need one !SMP for PREEMPT_RCU.
|
||||||
!RCU_EXPERT -- Do a few, but these have to be vanilla configurations.
|
CONFIG_RCU_EXPERT=n -- Do a few, but these have to be vanilla configurations.
|
||||||
|
CONFIG_RCU_EQS_DEBUG -- Do at least one for CONFIG_NO_HZ_FULL and not.
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP -- Do for all but a couple TREE scenarios.
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_INIT -- Do for all but a couple TREE scenarios.
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT -- Do for all but a couple TREE scenarios.
|
||||||
|
|
||||||
RCU-bh: Do one with PREEMPT and one with !PREEMPT.
|
RCU-bh: Do one with PREEMPT and one with !PREEMPT.
|
||||||
RCU-sched: Do one with PREEMPT but not BOOST.
|
RCU-sched: Do one with PREEMPT but not BOOST.
|
||||||
|
|
||||||
|
@ -72,7 +78,30 @@ CONFIG_RCU_TORTURE_TEST_RUNNABLE
|
||||||
|
|
||||||
Always used in KVM testing.
|
Always used in KVM testing.
|
||||||
|
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT_DELAY
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY
|
||||||
|
CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP_DELAY
|
||||||
|
|
||||||
|
Inspection suffices, ignore.
|
||||||
|
|
||||||
CONFIG_PREEMPT_RCU
|
CONFIG_PREEMPT_RCU
|
||||||
CONFIG_TREE_RCU
|
CONFIG_TREE_RCU
|
||||||
|
CONFIG_TINY_RCU
|
||||||
|
|
||||||
These are controlled by CONFIG_PREEMPT.
|
These are controlled by CONFIG_PREEMPT and/or CONFIG_SMP.
|
||||||
|
|
||||||
|
CONFIG_SPARSE_RCU_POINTER
|
||||||
|
|
||||||
|
Makes sense only for sparse runs, not for kernel builds.
|
||||||
|
|
||||||
|
CONFIG_SRCU
|
||||||
|
CONFIG_TASKS_RCU
|
||||||
|
|
||||||
|
Selected by CONFIG_RCU_TORTURE_TEST, so cannot disable.
|
||||||
|
|
||||||
|
CONFIG_RCU_TRACE
|
||||||
|
|
||||||
|
Implied by CONFIG_RCU_TRACE for Tree RCU.
|
||||||
|
|
||||||
|
|
||||||
|
boot parameters ignored: TBD
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
srcu.c
|
|
@ -0,0 +1,16 @@
|
||||||
|
all: srcu.c store_buffering
|
||||||
|
|
||||||
|
LINUX_SOURCE = ../../../../../..
|
||||||
|
|
||||||
|
modified_srcu_input = $(LINUX_SOURCE)/include/linux/srcu.h \
|
||||||
|
$(LINUX_SOURCE)/kernel/rcu/srcu.c
|
||||||
|
|
||||||
|
modified_srcu_output = include/linux/srcu.h srcu.c
|
||||||
|
|
||||||
|
include/linux/srcu.h: srcu.c
|
||||||
|
|
||||||
|
srcu.c: modify_srcu.awk Makefile $(modified_srcu_input)
|
||||||
|
awk -f modify_srcu.awk $(modified_srcu_input) $(modified_srcu_output)
|
||||||
|
|
||||||
|
store_buffering:
|
||||||
|
@cd tests/store_buffering; make
|
|
@ -0,0 +1 @@
|
||||||
|
srcu.h
|
|
@ -0,0 +1 @@
|
||||||
|
#include <LINUX_SOURCE/linux/kconfig.h>
|
|
@ -0,0 +1,155 @@
|
||||||
|
/*
|
||||||
|
* This header has been modifies to remove definitions of types that
|
||||||
|
* are defined in standard userspace headers or are problematic for some
|
||||||
|
* other reason.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LINUX_TYPES_H
|
||||||
|
#define _LINUX_TYPES_H
|
||||||
|
|
||||||
|
#define __EXPORTED_HEADERS__
|
||||||
|
#include <uapi/linux/types.h>
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
#define DECLARE_BITMAP(name, bits) \
|
||||||
|
unsigned long name[BITS_TO_LONGS(bits)]
|
||||||
|
|
||||||
|
typedef __u32 __kernel_dev_t;
|
||||||
|
|
||||||
|
/* bsd */
|
||||||
|
typedef unsigned char u_char;
|
||||||
|
typedef unsigned short u_short;
|
||||||
|
typedef unsigned int u_int;
|
||||||
|
typedef unsigned long u_long;
|
||||||
|
|
||||||
|
/* sysv */
|
||||||
|
typedef unsigned char unchar;
|
||||||
|
typedef unsigned short ushort;
|
||||||
|
typedef unsigned int uint;
|
||||||
|
typedef unsigned long ulong;
|
||||||
|
|
||||||
|
#ifndef __BIT_TYPES_DEFINED__
|
||||||
|
#define __BIT_TYPES_DEFINED__
|
||||||
|
|
||||||
|
typedef __u8 u_int8_t;
|
||||||
|
typedef __s8 int8_t;
|
||||||
|
typedef __u16 u_int16_t;
|
||||||
|
typedef __s16 int16_t;
|
||||||
|
typedef __u32 u_int32_t;
|
||||||
|
typedef __s32 int32_t;
|
||||||
|
|
||||||
|
#endif /* !(__BIT_TYPES_DEFINED__) */
|
||||||
|
|
||||||
|
typedef __u8 uint8_t;
|
||||||
|
typedef __u16 uint16_t;
|
||||||
|
typedef __u32 uint32_t;
|
||||||
|
|
||||||
|
/* this is a special 64bit data type that is 8-byte aligned */
|
||||||
|
#define aligned_u64 __u64 __attribute__((aligned(8)))
|
||||||
|
#define aligned_be64 __be64 __attribute__((aligned(8)))
|
||||||
|
#define aligned_le64 __le64 __attribute__((aligned(8)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type used for indexing onto a disc or disc partition.
|
||||||
|
*
|
||||||
|
* Linux always considers sectors to be 512 bytes long independently
|
||||||
|
* of the devices real block size.
|
||||||
|
*
|
||||||
|
* blkcnt_t is the type of the inode's block count.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_LBDAF
|
||||||
|
typedef u64 sector_t;
|
||||||
|
#else
|
||||||
|
typedef unsigned long sector_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The type of an index into the pagecache.
|
||||||
|
*/
|
||||||
|
#define pgoff_t unsigned long
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A dma_addr_t can hold any valid DMA address, i.e., any address returned
|
||||||
|
* by the DMA API.
|
||||||
|
*
|
||||||
|
* If the DMA API only uses 32-bit addresses, dma_addr_t need only be 32
|
||||||
|
* bits wide. Bus addresses, e.g., PCI BARs, may be wider than 32 bits,
|
||||||
|
* but drivers do memory-mapped I/O to ioremapped kernel virtual addresses,
|
||||||
|
* so they don't care about the size of the actual bus addresses.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
|
||||||
|
typedef u64 dma_addr_t;
|
||||||
|
#else
|
||||||
|
typedef u32 dma_addr_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PHYS_ADDR_T_64BIT
|
||||||
|
typedef u64 phys_addr_t;
|
||||||
|
#else
|
||||||
|
typedef u32 phys_addr_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef phys_addr_t resource_size_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This type is the placeholder for a hardware interrupt number. It has to be
|
||||||
|
* big enough to enclose whatever representation is used by a given platform.
|
||||||
|
*/
|
||||||
|
typedef unsigned long irq_hw_number_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int counter;
|
||||||
|
} atomic_t;
|
||||||
|
|
||||||
|
#ifdef CONFIG_64BIT
|
||||||
|
typedef struct {
|
||||||
|
long counter;
|
||||||
|
} atomic64_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct list_head {
|
||||||
|
struct list_head *next, *prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hlist_head {
|
||||||
|
struct hlist_node *first;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hlist_node {
|
||||||
|
struct hlist_node *next, **pprev;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct callback_head - callback structure for use with RCU and task_work
|
||||||
|
* @next: next update requests in a list
|
||||||
|
* @func: actual update function to call after the grace period.
|
||||||
|
*
|
||||||
|
* The struct is aligned to size of pointer. On most architectures it happens
|
||||||
|
* naturally due ABI requirements, but some architectures (like CRIS) have
|
||||||
|
* weird ABI and we need to ask it explicitly.
|
||||||
|
*
|
||||||
|
* The alignment is required to guarantee that bits 0 and 1 of @next will be
|
||||||
|
* clear under normal conditions -- as long as we use call_rcu(),
|
||||||
|
* call_rcu_bh(), call_rcu_sched(), or call_srcu() to queue callback.
|
||||||
|
*
|
||||||
|
* This guarantee is important for few reasons:
|
||||||
|
* - future call_rcu_lazy() will make use of lower bits in the pointer;
|
||||||
|
* - the structure shares storage spacer in struct page with @compound_head,
|
||||||
|
* which encode PageTail() in bit 0. The guarantee is needed to avoid
|
||||||
|
* false-positive PageTail().
|
||||||
|
*/
|
||||||
|
struct callback_head {
|
||||||
|
struct callback_head *next;
|
||||||
|
void (*func)(struct callback_head *head);
|
||||||
|
} __attribute__((aligned(sizeof(void *))));
|
||||||
|
#define rcu_head callback_head
|
||||||
|
|
||||||
|
typedef void (*rcu_callback_t)(struct rcu_head *head);
|
||||||
|
typedef void (*call_rcu_func_t)(struct rcu_head *head, rcu_callback_t func);
|
||||||
|
|
||||||
|
/* clocksource cycle base type */
|
||||||
|
typedef u64 cycle_t;
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLY__ */
|
||||||
|
#endif /* _LINUX_TYPES_H */
|
|
@ -0,0 +1,375 @@
|
||||||
|
#!/bin/awk -f
|
||||||
|
|
||||||
|
# Modify SRCU for formal verification. The first argument should be srcu.h and
|
||||||
|
# the second should be srcu.c. Outputs modified srcu.h and srcu.c into the
|
||||||
|
# current directory.
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
if (ARGC != 5) {
|
||||||
|
print "Usange: input.h input.c output.h output.c" > "/dev/stderr";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
h_output = ARGV[3];
|
||||||
|
c_output = ARGV[4];
|
||||||
|
ARGC = 3;
|
||||||
|
|
||||||
|
# Tokenize using FS and not RS as FS supports regular expressions. Each
|
||||||
|
# record is one line of source, except that backslashed lines are
|
||||||
|
# combined. Comments are treated as field separators, as are quotes.
|
||||||
|
quote_regexp="\"([^\\\\\"]|\\\\.)*\"";
|
||||||
|
comment_regexp="\\/\\*([^*]|\\*+[^*/])*\\*\\/|\\/\\/.*(\n|$)";
|
||||||
|
FS="([ \\\\\t\n\v\f;,.=(){}+*/<>&|^-]|\\[|\\]|" comment_regexp "|" quote_regexp ")+";
|
||||||
|
|
||||||
|
inside_srcu_struct = 0;
|
||||||
|
inside_srcu_init_def = 0;
|
||||||
|
srcu_init_param_name = "";
|
||||||
|
in_macro = 0;
|
||||||
|
brace_nesting = 0;
|
||||||
|
paren_nesting = 0;
|
||||||
|
|
||||||
|
# Allow the manipulation of the last field separator after has been
|
||||||
|
# seen.
|
||||||
|
last_fs = "";
|
||||||
|
# Whether the last field separator was intended to be output.
|
||||||
|
last_fs_print = 0;
|
||||||
|
|
||||||
|
# rcu_batches stores the initialization for each instance of struct
|
||||||
|
# rcu_batch
|
||||||
|
|
||||||
|
in_comment = 0;
|
||||||
|
|
||||||
|
outputfile = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
prev_outputfile = outputfile;
|
||||||
|
if (FILENAME ~ /\.h$/) {
|
||||||
|
outputfile = h_output;
|
||||||
|
if (FNR != NR) {
|
||||||
|
print "Incorrect file order" > "/dev/stderr";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
outputfile = c_output;
|
||||||
|
|
||||||
|
if (prev_outputfile && outputfile != prev_outputfile) {
|
||||||
|
new_outputfile = outputfile;
|
||||||
|
outputfile = prev_outputfile;
|
||||||
|
update_fieldsep("", 0);
|
||||||
|
outputfile = new_outputfile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Combine the next line into $0.
|
||||||
|
function combine_line() {
|
||||||
|
ret = getline next_line;
|
||||||
|
if (ret == 0) {
|
||||||
|
# Don't allow two consecutive getlines at the end of the file
|
||||||
|
if (eof_found) {
|
||||||
|
print "Error: expected more input." > "/dev/stderr";
|
||||||
|
exit 1;
|
||||||
|
} else {
|
||||||
|
eof_found = 1;
|
||||||
|
}
|
||||||
|
} else if (ret == -1) {
|
||||||
|
print "Error reading next line of file" FILENAME > "/dev/stderr";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
$0 = $0 "\n" next_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Combine backslashed lines and multiline comments.
|
||||||
|
function combine_backslashes() {
|
||||||
|
while (/\\$|\/\*([^*]|\*+[^*\/])*\**$/) {
|
||||||
|
combine_line();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function read_line() {
|
||||||
|
combine_line();
|
||||||
|
combine_backslashes();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print out field separators and update variables that depend on them. Only
|
||||||
|
# print if p is true. Call with sep="" and p=0 to print out the last field
|
||||||
|
# separator.
|
||||||
|
function update_fieldsep(sep, p) {
|
||||||
|
# Count braces
|
||||||
|
sep_tmp = sep;
|
||||||
|
gsub(quote_regexp "|" comment_regexp, "", sep_tmp);
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (sub("[^{}()]*\\{", "", sep_tmp)) {
|
||||||
|
brace_nesting++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (sub("[^{}()]*\\}", "", sep_tmp)) {
|
||||||
|
brace_nesting--;
|
||||||
|
if (brace_nesting < 0) {
|
||||||
|
print "Unbalanced braces!" > "/dev/stderr";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (sub("[^{}()]*\\(", "", sep_tmp)) {
|
||||||
|
paren_nesting++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (sub("[^{}()]*\\)", "", sep_tmp)) {
|
||||||
|
paren_nesting--;
|
||||||
|
if (paren_nesting < 0) {
|
||||||
|
print "Unbalanced parenthesis!" > "/dev/stderr";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_fs_print)
|
||||||
|
printf("%s", last_fs) > outputfile;
|
||||||
|
last_fs = sep;
|
||||||
|
last_fs_print = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Shifts the fields down by n positions. Calls next if there are no more. If p
|
||||||
|
# is true then print out field separators.
|
||||||
|
function shift_fields(n, p) {
|
||||||
|
do {
|
||||||
|
if (match($0, FS) > 0) {
|
||||||
|
update_fieldsep(substr($0, RSTART, RLENGTH), p);
|
||||||
|
if (RSTART + RLENGTH <= length())
|
||||||
|
$0 = substr($0, RSTART + RLENGTH);
|
||||||
|
else
|
||||||
|
$0 = "";
|
||||||
|
} else {
|
||||||
|
update_fieldsep("", 0);
|
||||||
|
print "" > outputfile;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
} while (--n > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Shifts and prints the first n fields.
|
||||||
|
function print_fields(n) {
|
||||||
|
do {
|
||||||
|
update_fieldsep("", 0);
|
||||||
|
printf("%s", $1) > outputfile;
|
||||||
|
shift_fields(1, 1);
|
||||||
|
} while (--n > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
combine_backslashes();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print leading FS
|
||||||
|
{
|
||||||
|
if (match($0, "^(" FS ")+") > 0) {
|
||||||
|
update_fieldsep(substr($0, RSTART, RLENGTH), 1);
|
||||||
|
if (RSTART + RLENGTH <= length())
|
||||||
|
$0 = substr($0, RSTART + RLENGTH);
|
||||||
|
else
|
||||||
|
$0 = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse the line.
|
||||||
|
{
|
||||||
|
while (NF > 0) {
|
||||||
|
if ($1 == "struct" && NF < 3) {
|
||||||
|
read_line();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FILENAME ~ /\.h$/ && !inside_srcu_struct &&
|
||||||
|
brace_nesting == 0 && paren_nesting == 0 &&
|
||||||
|
$1 == "struct" && $2 == "srcu_struct" &&
|
||||||
|
$0 ~ "^struct(" FS ")+srcu_struct(" FS ")+\\{") {
|
||||||
|
inside_srcu_struct = 1;
|
||||||
|
print_fields(2);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (inside_srcu_struct && brace_nesting == 0 &&
|
||||||
|
paren_nesting == 0) {
|
||||||
|
inside_srcu_struct = 0;
|
||||||
|
update_fieldsep("", 0);
|
||||||
|
for (name in rcu_batches)
|
||||||
|
print "extern struct rcu_batch " name ";" > outputfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inside_srcu_struct && $1 == "struct" && $2 == "rcu_batch") {
|
||||||
|
# Move rcu_batches outside of the struct.
|
||||||
|
rcu_batches[$3] = "";
|
||||||
|
shift_fields(3, 1);
|
||||||
|
sub(/;[[:space:]]*$/, "", last_fs);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FILENAME ~ /\.h$/ && !inside_srcu_init_def &&
|
||||||
|
$1 == "#define" && $2 == "__SRCU_STRUCT_INIT") {
|
||||||
|
inside_srcu_init_def = 1;
|
||||||
|
srcu_init_param_name = $3;
|
||||||
|
in_macro = 1;
|
||||||
|
print_fields(3);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (inside_srcu_init_def && brace_nesting == 0 &&
|
||||||
|
paren_nesting == 0) {
|
||||||
|
inside_srcu_init_def = 0;
|
||||||
|
in_macro = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inside_srcu_init_def && brace_nesting == 1 &&
|
||||||
|
paren_nesting == 0 && last_fs ~ /\.[[:space:]]*$/ &&
|
||||||
|
$1 ~ /^[[:alnum:]_]+$/) {
|
||||||
|
name = $1;
|
||||||
|
if (name in rcu_batches) {
|
||||||
|
# Remove the dot.
|
||||||
|
sub(/\.[[:space:]]*$/, "", last_fs);
|
||||||
|
|
||||||
|
old_record = $0;
|
||||||
|
do
|
||||||
|
shift_fields(1, 0);
|
||||||
|
while (last_fs !~ /,/ || paren_nesting > 0);
|
||||||
|
end_loc = length(old_record) - length($0);
|
||||||
|
end_loc += index(last_fs, ",") - length(last_fs);
|
||||||
|
|
||||||
|
last_fs = substr(last_fs, index(last_fs, ",") + 1);
|
||||||
|
last_fs_print = 1;
|
||||||
|
|
||||||
|
match(old_record, "^"name"("FS")+=");
|
||||||
|
start_loc = RSTART + RLENGTH;
|
||||||
|
|
||||||
|
len = end_loc - start_loc;
|
||||||
|
initializer = substr(old_record, start_loc, len);
|
||||||
|
gsub(srcu_init_param_name "\\.", "", initializer);
|
||||||
|
rcu_batches[name] = initializer;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Don't include a nonexistent file
|
||||||
|
if (!in_macro && $1 == "#include" && /^#include[[:space:]]+"rcu\.h"/) {
|
||||||
|
update_fieldsep("", 0);
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ignore most preprocessor stuff.
|
||||||
|
if (!in_macro && $1 ~ /#/) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (brace_nesting > 0 && $1 ~ "^[[:alnum:]_]+$" && NF < 2) {
|
||||||
|
read_line();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (brace_nesting > 0 &&
|
||||||
|
$0 ~ "^[[:alnum:]_]+[[:space:]]*(\\.|->)[[:space:]]*[[:alnum:]_]+" &&
|
||||||
|
$2 in rcu_batches) {
|
||||||
|
# Make uses of rcu_batches global. Somewhat unreliable.
|
||||||
|
shift_fields(1, 0);
|
||||||
|
print_fields(1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($1 == "static" && NF < 3) {
|
||||||
|
read_line();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($1 == "static" && ($2 == "bool" && $3 == "try_check_zero" ||
|
||||||
|
$2 == "void" && $3 == "srcu_flip")) {
|
||||||
|
shift_fields(1, 1);
|
||||||
|
print_fields(2);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Distinguish between read-side and write-side memory barriers.
|
||||||
|
if ($1 == "smp_mb" && NF < 2) {
|
||||||
|
read_line();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (match($0, /^smp_mb[[:space:]();\/*]*[[:alnum:]]/)) {
|
||||||
|
barrier_letter = substr($0, RLENGTH, 1);
|
||||||
|
if (barrier_letter ~ /A|D/)
|
||||||
|
new_barrier_name = "sync_smp_mb";
|
||||||
|
else if (barrier_letter ~ /B|C/)
|
||||||
|
new_barrier_name = "rs_smp_mb";
|
||||||
|
else {
|
||||||
|
print "Unrecognized memory barrier." > "/dev/null";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
shift_fields(1, 1);
|
||||||
|
printf("%s", new_barrier_name) > outputfile;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Skip definition of rcu_synchronize, since it is already
|
||||||
|
# defined in misc.h. Only present in old versions of srcu.
|
||||||
|
if (brace_nesting == 0 && paren_nesting == 0 &&
|
||||||
|
$1 == "struct" && $2 == "rcu_synchronize" &&
|
||||||
|
$0 ~ "^struct(" FS ")+rcu_synchronize(" FS ")+\\{") {
|
||||||
|
shift_fields(2, 0);
|
||||||
|
while (brace_nesting) {
|
||||||
|
if (NF < 2)
|
||||||
|
read_line();
|
||||||
|
shift_fields(1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Skip definition of wakeme_after_rcu for the same reason
|
||||||
|
if (brace_nesting == 0 && $1 == "static" && $2 == "void" &&
|
||||||
|
$3 == "wakeme_after_rcu") {
|
||||||
|
while (NF < 5)
|
||||||
|
read_line();
|
||||||
|
shift_fields(3, 0);
|
||||||
|
do {
|
||||||
|
while (NF < 3)
|
||||||
|
read_line();
|
||||||
|
shift_fields(1, 0);
|
||||||
|
} while (paren_nesting || brace_nesting);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($1 ~ /^(unsigned|long)$/ && NF < 3) {
|
||||||
|
read_line();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Give srcu_batches_completed the correct type for old SRCU.
|
||||||
|
if (brace_nesting == 0 && $1 == "long" &&
|
||||||
|
$2 == "srcu_batches_completed") {
|
||||||
|
update_fieldsep("", 0);
|
||||||
|
printf("unsigned ") > outputfile;
|
||||||
|
print_fields(2);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (brace_nesting == 0 && $1 == "unsigned" && $2 == "long" &&
|
||||||
|
$3 == "srcu_batches_completed") {
|
||||||
|
print_fields(3);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Just print out the input code by default.
|
||||||
|
print_fields(1);
|
||||||
|
}
|
||||||
|
update_fieldsep("", 0);
|
||||||
|
print > outputfile;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
END {
|
||||||
|
update_fieldsep("", 0);
|
||||||
|
|
||||||
|
if (brace_nesting != 0) {
|
||||||
|
print "Unbalanced braces!" > "/dev/stderr";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Define the rcu_batches
|
||||||
|
for (name in rcu_batches)
|
||||||
|
print "struct rcu_batch " name " = " rcu_batches[name] ";" > c_output;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef ASSUME_H
|
||||||
|
#define ASSUME_H
|
||||||
|
|
||||||
|
/* Provide an assumption macro that can be disabled for gcc. */
|
||||||
|
#ifdef RUN
|
||||||
|
#define assume(x) \
|
||||||
|
do { \
|
||||||
|
/* Evaluate x to suppress warnings. */ \
|
||||||
|
(void) (x); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define assume(x) __CPROVER_assume(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,41 @@
|
||||||
|
#ifndef BARRIERS_H
|
||||||
|
#define BARRIERS_H
|
||||||
|
|
||||||
|
#define barrier() __asm__ __volatile__("" : : : "memory")
|
||||||
|
|
||||||
|
#ifdef RUN
|
||||||
|
#define smp_mb() __sync_synchronize()
|
||||||
|
#define smp_mb__after_unlock_lock() __sync_synchronize()
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* Copied from CBMC's implementation of __sync_synchronize(), which
|
||||||
|
* seems to be disabled by default.
|
||||||
|
*/
|
||||||
|
#define smp_mb() __CPROVER_fence("WWfence", "RRfence", "RWfence", "WRfence", \
|
||||||
|
"WWcumul", "RRcumul", "RWcumul", "WRcumul")
|
||||||
|
#define smp_mb__after_unlock_lock() __CPROVER_fence("WWfence", "RRfence", "RWfence", "WRfence", \
|
||||||
|
"WWcumul", "RRcumul", "RWcumul", "WRcumul")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allow memory barriers to be disabled in either the read or write side
|
||||||
|
* of SRCU individually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NO_SYNC_SMP_MB
|
||||||
|
#define sync_smp_mb() smp_mb()
|
||||||
|
#else
|
||||||
|
#define sync_smp_mb() do {} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NO_READ_SIDE_SMP_MB
|
||||||
|
#define rs_smp_mb() smp_mb()
|
||||||
|
#else
|
||||||
|
#define rs_smp_mb() do {} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ACCESS_ONCE(x) (*(volatile typeof(x) *) &(x))
|
||||||
|
#define READ_ONCE(x) ACCESS_ONCE(x)
|
||||||
|
#define WRITE_ONCE(x, val) (ACCESS_ONCE(x) = (val))
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef BUG_ON_H
|
||||||
|
#define BUG_ON_H
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#define BUG() assert(0)
|
||||||
|
#define BUG_ON(x) assert(!(x))
|
||||||
|
|
||||||
|
/* Does it make sense to treat warnings as errors? */
|
||||||
|
#define WARN() BUG()
|
||||||
|
#define WARN_ON(x) (BUG_ON(x), false)
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
/* Include all source files. */
|
||||||
|
|
||||||
|
#include "include_srcu.c"
|
||||||
|
|
||||||
|
#include "preempt.c"
|
||||||
|
#include "misc.c"
|
||||||
|
|
||||||
|
/* Used by test.c files */
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <linux/srcu.h>
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* "Cheater" definitions based on restricted Kconfig choices. */
|
||||||
|
|
||||||
|
#undef CONFIG_TINY_RCU
|
||||||
|
#undef __CHECKER__
|
||||||
|
#undef CONFIG_DEBUG_LOCK_ALLOC
|
||||||
|
#undef CONFIG_DEBUG_OBJECTS_RCU_HEAD
|
||||||
|
#undef CONFIG_HOTPLUG_CPU
|
||||||
|
#undef CONFIG_MODULES
|
||||||
|
#undef CONFIG_NO_HZ_FULL_SYSIDLE
|
||||||
|
#undef CONFIG_PREEMPT_COUNT
|
||||||
|
#undef CONFIG_PREEMPT_RCU
|
||||||
|
#undef CONFIG_PROVE_RCU
|
||||||
|
#undef CONFIG_RCU_NOCB_CPU
|
||||||
|
#undef CONFIG_RCU_NOCB_CPU_ALL
|
||||||
|
#undef CONFIG_RCU_STALL_COMMON
|
||||||
|
#undef CONFIG_RCU_TRACE
|
||||||
|
#undef CONFIG_RCU_USER_QS
|
||||||
|
#undef CONFIG_TASKS_RCU
|
||||||
|
#define CONFIG_TREE_RCU
|
||||||
|
|
||||||
|
#define CONFIG_GENERIC_ATOMIC64
|
||||||
|
|
||||||
|
#if NR_CPUS > 1
|
||||||
|
#define CONFIG_SMP
|
||||||
|
#else
|
||||||
|
#undef CONFIG_SMP
|
||||||
|
#endif
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "int_typedefs.h"
|
||||||
|
|
||||||
|
#include "barriers.h"
|
||||||
|
#include "bug_on.h"
|
||||||
|
#include "locks.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "preempt.h"
|
||||||
|
#include "percpu.h"
|
||||||
|
#include "workqueues.h"
|
||||||
|
|
||||||
|
#ifdef USE_SIMPLE_SYNC_SRCU
|
||||||
|
#define synchronize_srcu(sp) synchronize_srcu_original(sp)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <srcu.c>
|
||||||
|
|
||||||
|
#ifdef USE_SIMPLE_SYNC_SRCU
|
||||||
|
#undef synchronize_srcu
|
||||||
|
|
||||||
|
#include "simple_sync_srcu.c"
|
||||||
|
#endif
|
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef INT_TYPEDEFS_H
|
||||||
|
#define INT_TYPEDEFS_H
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
typedef int8_t s8;
|
||||||
|
typedef uint8_t u8;
|
||||||
|
typedef int16_t s16;
|
||||||
|
typedef uint16_t u16;
|
||||||
|
typedef int32_t s32;
|
||||||
|
typedef uint32_t u32;
|
||||||
|
typedef int64_t s64;
|
||||||
|
typedef uint64_t u64;
|
||||||
|
|
||||||
|
typedef int8_t __s8;
|
||||||
|
typedef uint8_t __u8;
|
||||||
|
typedef int16_t __s16;
|
||||||
|
typedef uint16_t __u16;
|
||||||
|
typedef int32_t __s32;
|
||||||
|
typedef uint32_t __u32;
|
||||||
|
typedef int64_t __s64;
|
||||||
|
typedef uint64_t __u64;
|
||||||
|
|
||||||
|
#define S8_C(x) INT8_C(x)
|
||||||
|
#define U8_C(x) UINT8_C(x)
|
||||||
|
#define S16_C(x) INT16_C(x)
|
||||||
|
#define U16_C(x) UINT16_C(x)
|
||||||
|
#define S32_C(x) INT32_C(x)
|
||||||
|
#define U32_C(x) UINT32_C(x)
|
||||||
|
#define S64_C(x) INT64_C(x)
|
||||||
|
#define U64_C(x) UINT64_C(x)
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,220 @@
|
||||||
|
#ifndef LOCKS_H
|
||||||
|
#define LOCKS_H
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "assume.h"
|
||||||
|
#include "bug_on.h"
|
||||||
|
#include "preempt.h"
|
||||||
|
|
||||||
|
int nondet_int(void);
|
||||||
|
|
||||||
|
#define __acquire(x)
|
||||||
|
#define __acquires(x)
|
||||||
|
#define __release(x)
|
||||||
|
#define __releases(x)
|
||||||
|
|
||||||
|
/* Only use one lock mechanism. Select which one. */
|
||||||
|
#ifdef PTHREAD_LOCK
|
||||||
|
struct lock_impl {
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void lock_impl_lock(struct lock_impl *lock)
|
||||||
|
{
|
||||||
|
BUG_ON(pthread_mutex_lock(&lock->mutex));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lock_impl_unlock(struct lock_impl *lock)
|
||||||
|
{
|
||||||
|
BUG_ON(pthread_mutex_unlock(&lock->mutex));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool lock_impl_trylock(struct lock_impl *lock)
|
||||||
|
{
|
||||||
|
int err = pthread_mutex_trylock(&lock->mutex);
|
||||||
|
|
||||||
|
if (!err)
|
||||||
|
return true;
|
||||||
|
else if (err == EBUSY)
|
||||||
|
return false;
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lock_impl_init(struct lock_impl *lock)
|
||||||
|
{
|
||||||
|
pthread_mutex_init(&lock->mutex, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LOCK_IMPL_INITIALIZER {.mutex = PTHREAD_MUTEX_INITIALIZER}
|
||||||
|
|
||||||
|
#else /* !defined(PTHREAD_LOCK) */
|
||||||
|
/* Spinlock that assumes that it always gets the lock immediately. */
|
||||||
|
|
||||||
|
struct lock_impl {
|
||||||
|
bool locked;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline bool lock_impl_trylock(struct lock_impl *lock)
|
||||||
|
{
|
||||||
|
#ifdef RUN
|
||||||
|
/* TODO: Should this be a test and set? */
|
||||||
|
return __sync_bool_compare_and_swap(&lock->locked, false, true);
|
||||||
|
#else
|
||||||
|
__CPROVER_atomic_begin();
|
||||||
|
bool old_locked = lock->locked;
|
||||||
|
lock->locked = true;
|
||||||
|
__CPROVER_atomic_end();
|
||||||
|
|
||||||
|
/* Minimal barrier to prevent accesses leaking out of lock. */
|
||||||
|
__CPROVER_fence("RRfence", "RWfence");
|
||||||
|
|
||||||
|
return !old_locked;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lock_impl_lock(struct lock_impl *lock)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* CBMC doesn't support busy waiting, so just assume that the
|
||||||
|
* lock is available.
|
||||||
|
*/
|
||||||
|
assume(lock_impl_trylock(lock));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the lock was already held by this thread then the assumption
|
||||||
|
* is unsatisfiable (deadlock).
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lock_impl_unlock(struct lock_impl *lock)
|
||||||
|
{
|
||||||
|
#ifdef RUN
|
||||||
|
BUG_ON(!__sync_bool_compare_and_swap(&lock->locked, true, false));
|
||||||
|
#else
|
||||||
|
/* Minimal barrier to prevent accesses leaking out of lock. */
|
||||||
|
__CPROVER_fence("RWfence", "WWfence");
|
||||||
|
|
||||||
|
__CPROVER_atomic_begin();
|
||||||
|
bool old_locked = lock->locked;
|
||||||
|
lock->locked = false;
|
||||||
|
__CPROVER_atomic_end();
|
||||||
|
|
||||||
|
BUG_ON(!old_locked);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lock_impl_init(struct lock_impl *lock)
|
||||||
|
{
|
||||||
|
lock->locked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LOCK_IMPL_INITIALIZER {.locked = false}
|
||||||
|
|
||||||
|
#endif /* !defined(PTHREAD_LOCK) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implement spinlocks using the lock mechanism. Wrap the lock to prevent mixing
|
||||||
|
* locks of different types.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
struct lock_impl internal_lock;
|
||||||
|
} spinlock_t;
|
||||||
|
|
||||||
|
#define SPIN_LOCK_UNLOCKED {.internal_lock = LOCK_IMPL_INITIALIZER}
|
||||||
|
#define __SPIN_LOCK_UNLOCKED(x) SPIN_LOCK_UNLOCKED
|
||||||
|
#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
|
||||||
|
|
||||||
|
static inline void spin_lock_init(spinlock_t *lock)
|
||||||
|
{
|
||||||
|
lock_impl_init(&lock->internal_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void spin_lock(spinlock_t *lock)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Spin locks also need to be removed in order to eliminate all
|
||||||
|
* memory barriers. They are only used by the write side anyway.
|
||||||
|
*/
|
||||||
|
#ifndef NO_SYNC_SMP_MB
|
||||||
|
preempt_disable();
|
||||||
|
lock_impl_lock(&lock->internal_lock);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void spin_unlock(spinlock_t *lock)
|
||||||
|
{
|
||||||
|
#ifndef NO_SYNC_SMP_MB
|
||||||
|
lock_impl_unlock(&lock->internal_lock);
|
||||||
|
preempt_enable();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't bother with interrupts */
|
||||||
|
#define spin_lock_irq(lock) spin_lock(lock)
|
||||||
|
#define spin_unlock_irq(lock) spin_unlock(lock)
|
||||||
|
#define spin_lock_irqsave(lock, flags) spin_lock(lock)
|
||||||
|
#define spin_unlock_irqrestore(lock, flags) spin_unlock(lock)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is supposed to return an int, but I think that a bool should work as
|
||||||
|
* well.
|
||||||
|
*/
|
||||||
|
static inline bool spin_trylock(spinlock_t *lock)
|
||||||
|
{
|
||||||
|
#ifndef NO_SYNC_SMP_MB
|
||||||
|
preempt_disable();
|
||||||
|
return lock_impl_trylock(&lock->internal_lock);
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
struct completion {
|
||||||
|
/* Hopefuly this won't overflow. */
|
||||||
|
unsigned int count;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define COMPLETION_INITIALIZER(x) {.count = 0}
|
||||||
|
#define DECLARE_COMPLETION(x) struct completion x = COMPLETION_INITIALIZER(x)
|
||||||
|
#define DECLARE_COMPLETION_ONSTACK(x) DECLARE_COMPLETION(x)
|
||||||
|
|
||||||
|
static inline void init_completion(struct completion *c)
|
||||||
|
{
|
||||||
|
c->count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void wait_for_completion(struct completion *c)
|
||||||
|
{
|
||||||
|
unsigned int prev_count = __sync_fetch_and_sub(&c->count, 1);
|
||||||
|
|
||||||
|
assume(prev_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void complete(struct completion *c)
|
||||||
|
{
|
||||||
|
unsigned int prev_count = __sync_fetch_and_add(&c->count, 1);
|
||||||
|
|
||||||
|
BUG_ON(prev_count == UINT_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function probably isn't very useful for CBMC. */
|
||||||
|
static inline bool try_wait_for_completion(struct completion *c)
|
||||||
|
{
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool completion_done(struct completion *c)
|
||||||
|
{
|
||||||
|
return c->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Implement complete_all */
|
||||||
|
static inline void complete_all(struct completion *c)
|
||||||
|
{
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "misc.h"
|
||||||
|
#include "bug_on.h"
|
||||||
|
|
||||||
|
struct rcu_head;
|
||||||
|
|
||||||
|
void wakeme_after_rcu(struct rcu_head *head)
|
||||||
|
{
|
||||||
|
BUG();
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
#ifndef MISC_H
|
||||||
|
#define MISC_H
|
||||||
|
|
||||||
|
#include "assume.h"
|
||||||
|
#include "int_typedefs.h"
|
||||||
|
#include "locks.h"
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
/* Probably won't need to deal with bottom halves. */
|
||||||
|
static inline void local_bh_disable(void) {}
|
||||||
|
static inline void local_bh_enable(void) {}
|
||||||
|
|
||||||
|
#define MODULE_ALIAS(X)
|
||||||
|
#define module_param(...)
|
||||||
|
#define EXPORT_SYMBOL_GPL(x)
|
||||||
|
|
||||||
|
#define container_of(ptr, type, member) ({ \
|
||||||
|
const typeof(((type *)0)->member) *__mptr = (ptr); \
|
||||||
|
(type *)((char *)__mptr - offsetof(type, member)); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#ifndef USE_SIMPLE_SYNC_SRCU
|
||||||
|
/* Abuse udelay to make sure that busy loops terminate. */
|
||||||
|
#define udelay(x) assume(0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* The simple custom synchronize_srcu is ok with try_check_zero failing. */
|
||||||
|
#define udelay(x) do { } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define trace_rcu_torture_read(rcutorturename, rhp, secs, c_old, c) \
|
||||||
|
do { } while (0)
|
||||||
|
|
||||||
|
#define notrace
|
||||||
|
|
||||||
|
/* Avoid including rcupdate.h */
|
||||||
|
struct rcu_synchronize {
|
||||||
|
struct rcu_head head;
|
||||||
|
struct completion completion;
|
||||||
|
};
|
||||||
|
|
||||||
|
void wakeme_after_rcu(struct rcu_head *head);
|
||||||
|
|
||||||
|
#define rcu_lock_acquire(a) do { } while (0)
|
||||||
|
#define rcu_lock_release(a) do { } while (0)
|
||||||
|
#define rcu_lockdep_assert(c, s) do { } while (0)
|
||||||
|
#define RCU_LOCKDEP_WARN(c, s) do { } while (0)
|
||||||
|
|
||||||
|
/* Let CBMC non-deterministically choose switch between normal and expedited. */
|
||||||
|
bool rcu_gp_is_normal(void);
|
||||||
|
bool rcu_gp_is_expedited(void);
|
||||||
|
|
||||||
|
/* Do the same for old versions of rcu. */
|
||||||
|
#define rcu_expedited (rcu_gp_is_expedited())
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,92 @@
|
||||||
|
#ifndef PERCPU_H
|
||||||
|
#define PERCPU_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "bug_on.h"
|
||||||
|
#include "preempt.h"
|
||||||
|
|
||||||
|
#define __percpu
|
||||||
|
|
||||||
|
/* Maximum size of any percpu data. */
|
||||||
|
#define PERCPU_OFFSET (4 * sizeof(long))
|
||||||
|
|
||||||
|
/* Ignore alignment, as CBMC doesn't care about false sharing. */
|
||||||
|
#define alloc_percpu(type) __alloc_percpu(sizeof(type), 1)
|
||||||
|
|
||||||
|
static inline void *__alloc_percpu(size_t size, size_t align)
|
||||||
|
{
|
||||||
|
BUG();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void free_percpu(void *ptr)
|
||||||
|
{
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define per_cpu_ptr(ptr, cpu) \
|
||||||
|
((typeof(ptr)) ((char *) (ptr) + PERCPU_OFFSET * cpu))
|
||||||
|
|
||||||
|
#define __this_cpu_inc(pcp) __this_cpu_add(pcp, 1)
|
||||||
|
#define __this_cpu_dec(pcp) __this_cpu_sub(pcp, 1)
|
||||||
|
#define __this_cpu_sub(pcp, n) __this_cpu_add(pcp, -(typeof(pcp)) (n))
|
||||||
|
|
||||||
|
#define this_cpu_inc(pcp) this_cpu_add(pcp, 1)
|
||||||
|
#define this_cpu_dec(pcp) this_cpu_sub(pcp, 1)
|
||||||
|
#define this_cpu_sub(pcp, n) this_cpu_add(pcp, -(typeof(pcp)) (n))
|
||||||
|
|
||||||
|
/* Make CBMC use atomics to work around bug. */
|
||||||
|
#ifdef RUN
|
||||||
|
#define THIS_CPU_ADD_HELPER(ptr, x) (*(ptr) += (x))
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* Split the atomic into a read and a write so that it has the least
|
||||||
|
* possible ordering.
|
||||||
|
*/
|
||||||
|
#define THIS_CPU_ADD_HELPER(ptr, x) \
|
||||||
|
do { \
|
||||||
|
typeof(ptr) this_cpu_add_helper_ptr = (ptr); \
|
||||||
|
typeof(ptr) this_cpu_add_helper_x = (x); \
|
||||||
|
typeof(*ptr) this_cpu_add_helper_temp; \
|
||||||
|
__CPROVER_atomic_begin(); \
|
||||||
|
this_cpu_add_helper_temp = *(this_cpu_add_helper_ptr); \
|
||||||
|
__CPROVER_atomic_end(); \
|
||||||
|
this_cpu_add_helper_temp += this_cpu_add_helper_x; \
|
||||||
|
__CPROVER_atomic_begin(); \
|
||||||
|
*(this_cpu_add_helper_ptr) = this_cpu_add_helper_temp; \
|
||||||
|
__CPROVER_atomic_end(); \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For some reason CBMC needs an atomic operation even though this is percpu
|
||||||
|
* data.
|
||||||
|
*/
|
||||||
|
#define __this_cpu_add(pcp, n) \
|
||||||
|
do { \
|
||||||
|
BUG_ON(preemptible()); \
|
||||||
|
THIS_CPU_ADD_HELPER(per_cpu_ptr(&(pcp), thread_cpu_id), \
|
||||||
|
(typeof(pcp)) (n)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define this_cpu_add(pcp, n) \
|
||||||
|
do { \
|
||||||
|
int this_cpu_add_impl_cpu = get_cpu(); \
|
||||||
|
THIS_CPU_ADD_HELPER(per_cpu_ptr(&(pcp), this_cpu_add_impl_cpu), \
|
||||||
|
(typeof(pcp)) (n)); \
|
||||||
|
put_cpu(); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This will cause a compiler warning because of the cast from char[][] to
|
||||||
|
* type*. This will cause a compile time error if type is too big.
|
||||||
|
*/
|
||||||
|
#define DEFINE_PER_CPU(type, name) \
|
||||||
|
char name[NR_CPUS][PERCPU_OFFSET]; \
|
||||||
|
typedef char percpu_too_big_##name \
|
||||||
|
[sizeof(type) > PERCPU_OFFSET ? -1 : 1]
|
||||||
|
|
||||||
|
#define for_each_possible_cpu(cpu) \
|
||||||
|
for ((cpu) = 0; (cpu) < NR_CPUS; ++(cpu))
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,78 @@
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "preempt.h"
|
||||||
|
|
||||||
|
#include "assume.h"
|
||||||
|
#include "locks.h"
|
||||||
|
|
||||||
|
/* Support NR_CPUS of at most 64 */
|
||||||
|
#define CPU_PREEMPTION_LOCKS_INIT0 LOCK_IMPL_INITIALIZER
|
||||||
|
#define CPU_PREEMPTION_LOCKS_INIT1 \
|
||||||
|
CPU_PREEMPTION_LOCKS_INIT0, CPU_PREEMPTION_LOCKS_INIT0
|
||||||
|
#define CPU_PREEMPTION_LOCKS_INIT2 \
|
||||||
|
CPU_PREEMPTION_LOCKS_INIT1, CPU_PREEMPTION_LOCKS_INIT1
|
||||||
|
#define CPU_PREEMPTION_LOCKS_INIT3 \
|
||||||
|
CPU_PREEMPTION_LOCKS_INIT2, CPU_PREEMPTION_LOCKS_INIT2
|
||||||
|
#define CPU_PREEMPTION_LOCKS_INIT4 \
|
||||||
|
CPU_PREEMPTION_LOCKS_INIT3, CPU_PREEMPTION_LOCKS_INIT3
|
||||||
|
#define CPU_PREEMPTION_LOCKS_INIT5 \
|
||||||
|
CPU_PREEMPTION_LOCKS_INIT4, CPU_PREEMPTION_LOCKS_INIT4
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simulate disabling preemption by locking a particular cpu. NR_CPUS
|
||||||
|
* should be the actual number of cpus, not just the maximum.
|
||||||
|
*/
|
||||||
|
struct lock_impl cpu_preemption_locks[NR_CPUS] = {
|
||||||
|
CPU_PREEMPTION_LOCKS_INIT0
|
||||||
|
#if (NR_CPUS - 1) & 1
|
||||||
|
, CPU_PREEMPTION_LOCKS_INIT0
|
||||||
|
#endif
|
||||||
|
#if (NR_CPUS - 1) & 2
|
||||||
|
, CPU_PREEMPTION_LOCKS_INIT1
|
||||||
|
#endif
|
||||||
|
#if (NR_CPUS - 1) & 4
|
||||||
|
, CPU_PREEMPTION_LOCKS_INIT2
|
||||||
|
#endif
|
||||||
|
#if (NR_CPUS - 1) & 8
|
||||||
|
, CPU_PREEMPTION_LOCKS_INIT3
|
||||||
|
#endif
|
||||||
|
#if (NR_CPUS - 1) & 16
|
||||||
|
, CPU_PREEMPTION_LOCKS_INIT4
|
||||||
|
#endif
|
||||||
|
#if (NR_CPUS - 1) & 32
|
||||||
|
, CPU_PREEMPTION_LOCKS_INIT5
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef CPU_PREEMPTION_LOCKS_INIT0
|
||||||
|
#undef CPU_PREEMPTION_LOCKS_INIT1
|
||||||
|
#undef CPU_PREEMPTION_LOCKS_INIT2
|
||||||
|
#undef CPU_PREEMPTION_LOCKS_INIT3
|
||||||
|
#undef CPU_PREEMPTION_LOCKS_INIT4
|
||||||
|
#undef CPU_PREEMPTION_LOCKS_INIT5
|
||||||
|
|
||||||
|
__thread int thread_cpu_id;
|
||||||
|
__thread int preempt_disable_count;
|
||||||
|
|
||||||
|
void preempt_disable(void)
|
||||||
|
{
|
||||||
|
BUG_ON(preempt_disable_count < 0 || preempt_disable_count == INT_MAX);
|
||||||
|
|
||||||
|
if (preempt_disable_count++)
|
||||||
|
return;
|
||||||
|
|
||||||
|
thread_cpu_id = nondet_int();
|
||||||
|
assume(thread_cpu_id >= 0);
|
||||||
|
assume(thread_cpu_id < NR_CPUS);
|
||||||
|
lock_impl_lock(&cpu_preemption_locks[thread_cpu_id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void preempt_enable(void)
|
||||||
|
{
|
||||||
|
BUG_ON(preempt_disable_count < 1);
|
||||||
|
|
||||||
|
if (--preempt_disable_count)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lock_impl_unlock(&cpu_preemption_locks[thread_cpu_id]);
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
#ifndef PREEMPT_H
|
||||||
|
#define PREEMPT_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "bug_on.h"
|
||||||
|
|
||||||
|
/* This flag contains garbage if preempt_disable_count is 0. */
|
||||||
|
extern __thread int thread_cpu_id;
|
||||||
|
|
||||||
|
/* Support recursive preemption disabling. */
|
||||||
|
extern __thread int preempt_disable_count;
|
||||||
|
|
||||||
|
void preempt_disable(void);
|
||||||
|
void preempt_enable(void);
|
||||||
|
|
||||||
|
static inline void preempt_disable_notrace(void)
|
||||||
|
{
|
||||||
|
preempt_disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void preempt_enable_no_resched(void)
|
||||||
|
{
|
||||||
|
preempt_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void preempt_enable_notrace(void)
|
||||||
|
{
|
||||||
|
preempt_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int preempt_count(void)
|
||||||
|
{
|
||||||
|
return preempt_disable_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool preemptible(void)
|
||||||
|
{
|
||||||
|
return !preempt_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int get_cpu(void)
|
||||||
|
{
|
||||||
|
preempt_disable();
|
||||||
|
return thread_cpu_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void put_cpu(void)
|
||||||
|
{
|
||||||
|
preempt_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void might_sleep(void)
|
||||||
|
{
|
||||||
|
BUG_ON(preempt_disable_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,50 @@
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "int_typedefs.h"
|
||||||
|
|
||||||
|
#include "barriers.h"
|
||||||
|
#include "bug_on.h"
|
||||||
|
#include "locks.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "preempt.h"
|
||||||
|
#include "percpu.h"
|
||||||
|
#include "workqueues.h"
|
||||||
|
|
||||||
|
#include <linux/srcu.h>
|
||||||
|
|
||||||
|
/* Functions needed from modify_srcu.c */
|
||||||
|
bool try_check_zero(struct srcu_struct *sp, int idx, int trycount);
|
||||||
|
void srcu_flip(struct srcu_struct *sp);
|
||||||
|
|
||||||
|
/* Simpler implementation of synchronize_srcu that ignores batching. */
|
||||||
|
void synchronize_srcu(struct srcu_struct *sp)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
/*
|
||||||
|
* This code assumes that try_check_zero will succeed anyway,
|
||||||
|
* so there is no point in multiple tries.
|
||||||
|
*/
|
||||||
|
const int trycount = 1;
|
||||||
|
|
||||||
|
might_sleep();
|
||||||
|
|
||||||
|
/* Ignore the lock, as multiple writers aren't working yet anyway. */
|
||||||
|
|
||||||
|
idx = 1 ^ (sp->completed & 1);
|
||||||
|
|
||||||
|
/* For comments see srcu_advance_batches. */
|
||||||
|
|
||||||
|
assume(try_check_zero(sp, idx, trycount));
|
||||||
|
|
||||||
|
srcu_flip(sp);
|
||||||
|
|
||||||
|
assume(try_check_zero(sp, idx^1, trycount));
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
#ifndef WORKQUEUES_H
|
||||||
|
#define WORKQUEUES_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "barriers.h"
|
||||||
|
#include "bug_on.h"
|
||||||
|
#include "int_typedefs.h"
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
/* Stub workqueue implementation. */
|
||||||
|
|
||||||
|
struct work_struct;
|
||||||
|
typedef void (*work_func_t)(struct work_struct *work);
|
||||||
|
void delayed_work_timer_fn(unsigned long __data);
|
||||||
|
|
||||||
|
struct work_struct {
|
||||||
|
/* atomic_long_t data; */
|
||||||
|
unsigned long data;
|
||||||
|
|
||||||
|
struct list_head entry;
|
||||||
|
work_func_t func;
|
||||||
|
#ifdef CONFIG_LOCKDEP
|
||||||
|
struct lockdep_map lockdep_map;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct timer_list {
|
||||||
|
struct hlist_node entry;
|
||||||
|
unsigned long expires;
|
||||||
|
void (*function)(unsigned long);
|
||||||
|
unsigned long data;
|
||||||
|
u32 flags;
|
||||||
|
int slack;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct delayed_work {
|
||||||
|
struct work_struct work;
|
||||||
|
struct timer_list timer;
|
||||||
|
|
||||||
|
/* target workqueue and CPU ->timer uses to queue ->work */
|
||||||
|
struct workqueue_struct *wq;
|
||||||
|
int cpu;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool schedule_work(struct work_struct *work)
|
||||||
|
{
|
||||||
|
BUG();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool schedule_work_on(int cpu, struct work_struct *work)
|
||||||
|
{
|
||||||
|
BUG();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool queue_work(struct workqueue_struct *wq,
|
||||||
|
struct work_struct *work)
|
||||||
|
{
|
||||||
|
BUG();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool queue_delayed_work(struct workqueue_struct *wq,
|
||||||
|
struct delayed_work *dwork,
|
||||||
|
unsigned long delay)
|
||||||
|
{
|
||||||
|
BUG();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INIT_WORK(w, f) \
|
||||||
|
do { \
|
||||||
|
(w)->data = 0; \
|
||||||
|
(w)->func = (f); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define INIT_DELAYED_WORK(w, f) INIT_WORK(&(w)->work, (f))
|
||||||
|
|
||||||
|
#define __WORK_INITIALIZER(n, f) { \
|
||||||
|
.data = 0, \
|
||||||
|
.entry = { &(n).entry, &(n).entry }, \
|
||||||
|
.func = f \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't bother initializing timer. */
|
||||||
|
#define __DELAYED_WORK_INITIALIZER(n, f, tflags) { \
|
||||||
|
.work = __WORK_INITIALIZER((n).work, (f)), \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DECLARE_WORK(n, f) \
|
||||||
|
struct workqueue_struct n = __WORK_INITIALIZER
|
||||||
|
|
||||||
|
#define DECLARE_DELAYED_WORK(n, f) \
|
||||||
|
struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f, 0)
|
||||||
|
|
||||||
|
#define system_power_efficient_wq ((struct workqueue_struct *) NULL)
|
||||||
|
|
||||||
|
#endif
|
1
tools/testing/selftests/rcutorture/formal/srcu-cbmc/tests/store_buffering/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
*.out
|
|
@ -0,0 +1,11 @@
|
||||||
|
CBMC_FLAGS = -I../.. -I../../src -I../../include -I../../empty_includes -32 -pointer-check -mm pso
|
||||||
|
|
||||||
|
all:
|
||||||
|
for i in ./*.pass; do \
|
||||||
|
echo $$i ; \
|
||||||
|
CBMC_FLAGS="$(CBMC_FLAGS)" sh ../test_script.sh --should-pass $$i > $$i.out 2>&1 ; \
|
||||||
|
done
|
||||||
|
for i in ./*.fail; do \
|
||||||
|
echo $$i ; \
|
||||||
|
CBMC_FLAGS="$(CBMC_FLAGS)" sh ../test_script.sh --should-fail $$i > $$i.out 2>&1 ; \
|
||||||
|
done
|
|
@ -0,0 +1 @@
|
||||||
|
test_cbmc_options="-DASSERT_END"
|
|
@ -0,0 +1 @@
|
||||||
|
test_cbmc_options="-DFORCE_FAILURE"
|
|
@ -0,0 +1 @@
|
||||||
|
test_cbmc_options="-DFORCE_FAILURE_2"
|
|
@ -0,0 +1 @@
|
||||||
|
test_cbmc_options="-DFORCE_FAILURE_3"
|
|
@ -0,0 +1,72 @@
|
||||||
|
#include <src/combined_source.c>
|
||||||
|
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
|
||||||
|
int __unbuffered_tpr_x;
|
||||||
|
int __unbuffered_tpr_y;
|
||||||
|
|
||||||
|
DEFINE_SRCU(ss);
|
||||||
|
|
||||||
|
void rcu_reader(void)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
#ifndef FORCE_FAILURE_3
|
||||||
|
idx = srcu_read_lock(&ss);
|
||||||
|
#endif
|
||||||
|
might_sleep();
|
||||||
|
|
||||||
|
__unbuffered_tpr_y = READ_ONCE(y);
|
||||||
|
#ifdef FORCE_FAILURE
|
||||||
|
srcu_read_unlock(&ss, idx);
|
||||||
|
idx = srcu_read_lock(&ss);
|
||||||
|
#endif
|
||||||
|
WRITE_ONCE(x, 1);
|
||||||
|
|
||||||
|
#ifndef FORCE_FAILURE_3
|
||||||
|
srcu_read_unlock(&ss, idx);
|
||||||
|
#endif
|
||||||
|
might_sleep();
|
||||||
|
}
|
||||||
|
|
||||||
|
void *thread_update(void *arg)
|
||||||
|
{
|
||||||
|
WRITE_ONCE(y, 1);
|
||||||
|
#ifndef FORCE_FAILURE_2
|
||||||
|
synchronize_srcu(&ss);
|
||||||
|
#endif
|
||||||
|
might_sleep();
|
||||||
|
__unbuffered_tpr_x = READ_ONCE(x);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *thread_process_reader(void *arg)
|
||||||
|
{
|
||||||
|
rcu_reader();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
pthread_t tu;
|
||||||
|
pthread_t tpr;
|
||||||
|
|
||||||
|
if (pthread_create(&tu, NULL, thread_update, NULL))
|
||||||
|
abort();
|
||||||
|
if (pthread_create(&tpr, NULL, thread_process_reader, NULL))
|
||||||
|
abort();
|
||||||
|
if (pthread_join(tu, NULL))
|
||||||
|
abort();
|
||||||
|
if (pthread_join(tpr, NULL))
|
||||||
|
abort();
|
||||||
|
assert(__unbuffered_tpr_y != 0 || __unbuffered_tpr_x != 0);
|
||||||
|
|
||||||
|
#ifdef ASSERT_END
|
||||||
|
assert(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# This script expects a mode (either --should-pass or --should-fail) followed by
|
||||||
|
# an input file. The script uses the following environment variables. The test C
|
||||||
|
# source file is expected to be named test.c in the directory containing the
|
||||||
|
# input file.
|
||||||
|
#
|
||||||
|
# CBMC: The command to run CBMC. Default: cbmc
|
||||||
|
# CBMC_FLAGS: Additional flags to pass to CBMC
|
||||||
|
# NR_CPUS: Number of cpus to run tests with. Default specified by the test
|
||||||
|
# SYNC_SRCU_MODE: Choose implementation of synchronize_srcu. Defaults to simple.
|
||||||
|
# kernel: Version included in the linux kernel source.
|
||||||
|
# simple: Use try_check_zero directly.
|
||||||
|
#
|
||||||
|
# The input file is a script that is sourced by this file. It can define any of
|
||||||
|
# the following variables to configure the test.
|
||||||
|
#
|
||||||
|
# test_cbmc_options: Extra options to pass to CBMC.
|
||||||
|
# min_cpus_fail: Minimum number of CPUs (NR_CPUS) for verification to fail.
|
||||||
|
# The test is expected to pass if it is run with fewer. (Only
|
||||||
|
# useful for .fail files)
|
||||||
|
# default_cpus: Quantity of CPUs to use for the test, if not specified on the
|
||||||
|
# command line. Default: Larger of 2 and MIN_CPUS_FAIL.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if test "$#" -ne 2; then
|
||||||
|
echo "Expected one option followed by an input file" 1>&2
|
||||||
|
exit 99
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$1" = "x--should-pass"; then
|
||||||
|
should_pass="yes"
|
||||||
|
elif test "x$1" = "x--should-fail"; then
|
||||||
|
should_pass="no"
|
||||||
|
else
|
||||||
|
echo "Unrecognized argument '$1'" 1>&2
|
||||||
|
|
||||||
|
# Exit code 99 indicates a hard error.
|
||||||
|
exit 99
|
||||||
|
fi
|
||||||
|
|
||||||
|
CBMC=${CBMC:-cbmc}
|
||||||
|
|
||||||
|
SYNC_SRCU_MODE=${SYNC_SRCU_MODE:-simple}
|
||||||
|
|
||||||
|
case ${SYNC_SRCU_MODE} in
|
||||||
|
kernel) sync_srcu_mode_flags="" ;;
|
||||||
|
simple) sync_srcu_mode_flags="-DUSE_SIMPLE_SYNC_SRCU" ;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Unrecognized argument '${SYNC_SRCU_MODE}'" 1>&2
|
||||||
|
exit 99
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
min_cpus_fail=1
|
||||||
|
|
||||||
|
c_file=`dirname "$2"`/test.c
|
||||||
|
|
||||||
|
# Source the input file.
|
||||||
|
. $2
|
||||||
|
|
||||||
|
if test ${min_cpus_fail} -gt 2; then
|
||||||
|
default_default_cpus=${min_cpus_fail}
|
||||||
|
else
|
||||||
|
default_default_cpus=2
|
||||||
|
fi
|
||||||
|
default_cpus=${default_cpus:-${default_default_cpus}}
|
||||||
|
cpus=${NR_CPUS:-${default_cpus}}
|
||||||
|
|
||||||
|
# Check if there are two few cpus to make the test fail.
|
||||||
|
if test $cpus -lt ${min_cpus_fail:-0}; then
|
||||||
|
should_pass="yes"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cbmc_opts="-DNR_CPUS=${cpus} ${sync_srcu_mode_flags} ${test_cbmc_options} ${CBMC_FLAGS}"
|
||||||
|
|
||||||
|
echo "Running CBMC: ${CBMC} ${cbmc_opts} ${c_file}"
|
||||||
|
if ${CBMC} ${cbmc_opts} "${c_file}"; then
|
||||||
|
# Verification successful. Make sure that it was supposed to verify.
|
||||||
|
test "x${should_pass}" = xyes
|
||||||
|
else
|
||||||
|
cbmc_exit_status=$?
|
||||||
|
|
||||||
|
# An exit status of 10 indicates a failed verification.
|
||||||
|
# (see cbmc_parse_optionst::do_bmc in the CBMC source code)
|
||||||
|
if test ${cbmc_exit_status} -eq 10 && test "x${should_pass}" = xno; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
echo "CBMC returned ${cbmc_exit_status} exit status" 1>&2
|
||||||
|
|
||||||
|
# Parse errors have exit status 6. Any other type of error
|
||||||
|
# should be considered a hard error.
|
||||||
|
if test ${cbmc_exit_status} -ne 6 && \
|
||||||
|
test ${cbmc_exit_status} -ne 10; then
|
||||||
|
exit 99
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|