Messages in this thread Patch in this message | | | From | "Paul E. McKenney" <> | Subject | [PATCH tip/core/rcu 1/8] documentation: Record RCU requirements | Date | Fri, 4 Dec 2015 15:50:19 -0800 |
| |
This commit adds RCU requirements as published in a 2015 LWN series. Bringing these requirements in-tree allows them to be updated as changes are discovered.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> --- .../RCU/Design/Requirements/2013-08-is-it-dead.png | Bin 0 -> 100825 bytes .../Design/Requirements/GPpartitionReaders1.svg | 374 +++ .../RCU/Design/Requirements/RCUApplicability.svg | 237 ++ .../Design/Requirements/ReadersPartitionGP1.svg | 639 +++++ .../RCU/Design/Requirements/Requirements.html | 2799 ++++++++++++++++++++ .../RCU/Design/Requirements/Requirements.htmlx | 2643 ++++++++++++++++++ Documentation/RCU/Design/htmlqqz.sh | 108 + 7 files changed, 6800 insertions(+) create mode 100644 Documentation/RCU/Design/Requirements/2013-08-is-it-dead.png create mode 100644 Documentation/RCU/Design/Requirements/GPpartitionReaders1.svg create mode 100644 Documentation/RCU/Design/Requirements/RCUApplicability.svg create mode 100644 Documentation/RCU/Design/Requirements/ReadersPartitionGP1.svg create mode 100644 Documentation/RCU/Design/Requirements/Requirements.html create mode 100644 Documentation/RCU/Design/Requirements/Requirements.htmlx create mode 100755 Documentation/RCU/Design/htmlqqz.sh
diff --git a/Documentation/RCU/Design/Requirements/2013-08-is-it-dead.png b/Documentation/RCU/Design/Requirements/2013-08-is-it-dead.png new file mode 100644 index 0000000000000000000000000000000000000000..7496a55e4e7b41becdb658a2bd34765fbe80013f GIT binary patch literal 100825 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%0D$*HLiRV!ggZGI)J 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"P~*Tft8wmLSEAkP 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
literal 0 HcmV?d00001
diff --git a/Documentation/RCU/Design/Requirements/GPpartitionReaders1.svg b/Documentation/RCU/Design/Requirements/GPpartitionReaders1.svg new file mode 100644 index 000000000000..4b4014fda770 --- /dev/null +++ b/Documentation/RCU/Design/Requirements/GPpartitionReaders1.svg @@ -0,0 +1,374 @@ +<?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="447.99197" + height="428.19299" + id="svg2" + version="1.1" + inkscape:version="0.48.3.1 r9886" + sodipodi:docname="GPpartitionReaders1.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> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.6184291" + inkscape:cx="223.99599" + inkscape:cy="214.0965" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="979" + inkscape:window-height="836" + inkscape:window-x="571" + inkscape:window-y="335" + 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></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-28.441125,-185.60612)"> + <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"></flowPara></flowRoot> <g + id="g4433" + transform="translate(2,0)"> + <text + sodipodi:linespacing="125%" + id="text2993" + y="-261.66608" + x="412.12299" + 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" + xml:space="preserve" + transform="matrix(0,1,-1,0,0,0)"><tspan + y="-261.66608" + x="412.12299" + id="tspan2995" + sodipodi:role="line">synchronize_rcu()</tspan></text> + <g + id="g4417" + transform="matrix(0,1,-1,0,730.90257,222.4928)"> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow2Lstart);marker-end:url(#Arrow2Lend)" + d="m 97.580736,477.4048 183.140664,0" + id="path2997" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 96.752718,465.38398 0,22.62742" + id="path4397" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 281.54942,465.38397 0,22.62742" + id="path4397-5" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + </g> + </g> + <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="112.04738" + y="268.18076" + id="text4429" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4431" + x="112.04738" + y="268.18076">WRITE_ONCE(a, 1);</tspan></text> + <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="112.04738" + y="439.13766" + id="text4441" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4443" + x="112.04738" + y="439.13766">WRITE_ONCE(b, 1);</tspan></text> + <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="255.60869" + y="309.29346" + id="text4445" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4447" + x="255.60869" + y="309.29346">r1 = READ_ONCE(a);</tspan></text> + <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="255.14423" + y="520.61786" + id="text4449" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4451" + x="255.14423" + y="520.61786">WRITE_ONCE(c, 1);</tspan></text> + <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="396.10254" + y="384.71124" + id="text4453" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4455" + x="396.10254" + y="384.71124">r2 = READ_ONCE(b);</tspan></text> + <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="396.10254" + y="582.13617" + id="text4457" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4459" + x="396.10254" + y="582.13617">r3 = READ_ONCE(c);</tspan></text> + <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="112.08231" + y="213.91006" + id="text4461" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4463" + x="112.08231" + y="213.91006">thread0()</tspan></text> + <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="252.34512" + y="213.91006" + id="text4461-6" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4463-0" + x="252.34512" + y="213.91006">thread1()</tspan></text> + <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="396.42557" + y="213.91006" + id="text4461-2" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4463-2" + x="396.42557" + y="213.91006">thread2()</tspan></text> + <rect + style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="rect4495" + width="436.28488" + height="416.4859" + x="34.648232" + y="191.10612" /> + <path + style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + d="m 183.14066,191.10612 0,417.193 -0.70711,0" + id="path4497" + inkscape:connector-curvature="0" /> + <path + style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + d="m 325.13867,191.10612 0,417.193 -0.70711,0" + id="path4497-5" + inkscape:connector-curvature="0" /> + <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="111.75929" + y="251.53981" + id="text4429-8" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4431-9" + x="111.75929" + y="251.53981">rcu_read_lock();</tspan></text> + <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="396.10254" + y="367.91556" + id="text4429-8-9" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4431-9-4" + x="396.10254" + y="367.91556">rcu_read_lock();</tspan></text> + <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="396.10254" + y="597.40289" + id="text4429-8-9-3" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4431-9-4-4" + x="396.10254" + y="597.40289">rcu_read_unlock();</tspan></text> + <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="111.75929" + y="453.15311" + id="text4429-8-9-3-1" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4431-9-4-4-6" + x="111.75929" + y="453.15311">rcu_read_unlock();</tspan></text> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 33.941125,227.87568 436.284885,0 0,0.7071" + id="path4608" + inkscape:connector-curvature="0" /> + <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="394.94427" + y="345.66351" + id="text4648" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4650" + x="394.94427" + y="345.66351">QS</tspan></text> + <path + sodipodi:type="arc" + style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path4652" + sodipodi:cx="358.85669" + sodipodi:cy="142.87541" + sodipodi:rx="10.960155" + sodipodi:ry="10.253048" + d="m 358.86939,132.62237 a 10.960155,10.253048 0 1 1 -0.0228,0" + transform="translate(36.441125,199.60612)" + sodipodi:start="4.7135481" + sodipodi:end="10.994651" + sodipodi:open="true" /> + <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="112.11968" + y="475.77856" + id="text4648-4" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4650-4" + x="112.11968" + y="475.77856">QS</tspan></text> + <path + sodipodi:type="arc" + style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path4652-7" + sodipodi:cx="358.85669" + sodipodi:cy="142.87541" + sodipodi:rx="10.960155" + sodipodi:ry="10.253048" + d="m 358.86939,132.62237 a 10.960155,10.253048 0 1 1 -0.0228,0" + transform="translate(-246.38346,329.72117)" + sodipodi:start="4.7135481" + sodipodi:end="10.994651" + sodipodi:open="true" /> + <path + sodipodi:type="arc" + style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path4652-7-7" + sodipodi:cx="358.85669" + sodipodi:cy="142.87541" + sodipodi:rx="10.960155" + sodipodi:ry="10.253048" + d="m 358.86939,132.62237 a 10.960155,10.253048 0 1 1 -0.0228,0" + transform="translate(-103.65246,202.90878)" + sodipodi:start="4.7135481" + sodipodi:end="10.994651" + sodipodi:open="true" /> + <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="254.85066" + y="348.96619" + id="text4648-4-3" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4650-4-5" + x="254.85066" + y="348.96619">QS</tspan></text> + </g> +</svg> diff --git a/Documentation/RCU/Design/Requirements/RCUApplicability.svg b/Documentation/RCU/Design/Requirements/RCUApplicability.svg new file mode 100644 index 000000000000..ebcbeee391ed --- /dev/null +++ b/Documentation/RCU/Design/Requirements/RCUApplicability.svg @@ -0,0 +1,237 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Creator: fig2dev Version 3.2 Patchlevel 5d --> + +<!-- CreationDate: Tue Mar 4 18:34:25 2014 --> + +<!-- 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="1089.1382" + height="668.21368" + viewBox="-2121 -36 14554.634 8876.4061" + id="svg2" + version="1.1" + inkscape:version="0.48.3.1 r9886" + sodipodi:docname="RCUApplicability.svg"> + <metadata + id="metadata40"> + <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="defs38" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="849" + inkscape:window-height="639" + id="namedview36" + showgrid="false" + inkscape:zoom="0.51326165" + inkscape:cx="544.56912" + inkscape:cy="334.10686" + inkscape:window-x="149" + inkscape:window-y="448" + inkscape:window-maximized="0" + inkscape:current-layer="g4" + fit-margin-top="5" + fit-margin-left="5" + fit-margin-right="5" + fit-margin-bottom="5" /> + <g + style="fill:none;stroke-width:0.025in" + id="g4" + transform="translate(-2043.6828,14.791398)"> + <!-- Line: box --> + <rect + x="0" + y="0" + width="14400" + height="8775" + rx="0" + style="fill:#ffa1a1;stroke:#000000;stroke-width:21;stroke-linecap:butt;stroke-linejoin:miter" + id="rect6" /> + <!-- Line: box --> + <rect + x="1350" + y="0" + width="11700" + height="6075" + rx="0" + style="fill:#ffff00;stroke:#000000;stroke-width:21;stroke-linecap:butt;stroke-linejoin:miter" + id="rect8" /> + <!-- Line: box --> + <rect + x="2700" + y="0" + width="9000" + height="4275" + rx="0" + style="fill:#00ff00;stroke:#000000;stroke-width:21;stroke-linecap:butt;stroke-linejoin:miter" + id="rect10" /> + <!-- Line: box --> + <rect + x="4050" + y="0" + width="6300" + height="2475" + rx="0" + style="fill:#87cfff;stroke:#000000;stroke-width:21;stroke-linecap:butt;stroke-linejoin:miter" + id="rect12" /> + <!-- Text --> + <text + xml:space="preserve" + x="7200" + y="900" + font-style="normal" + font-weight="normal" + font-size="324" + id="text14" + sodipodi:linespacing="125%" + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L"><tspan + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" + id="tspan3017">Read-Mostly, Stale &</tspan></text> + <!-- Text --> + <text + xml:space="preserve" + x="7200" + y="1350" + font-style="normal" + font-weight="normal" + font-size="324" + id="text16" + sodipodi:linespacing="125%" + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L"><tspan + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" + id="tspan3019">Inconsistent Data OK</tspan></text> + <!-- Text --> + <text + xml:space="preserve" + x="7200" + y="1800" + font-style="normal" + font-weight="normal" + font-size="324" + id="text18" + sodipodi:linespacing="125%" + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L"><tspan + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" + id="tspan3021">(RCU Works Great!!!)</tspan></text> + <!-- Text --> + <text + xml:space="preserve" + x="7200" + y="3825" + font-style="normal" + font-weight="normal" + font-size="324" + id="text20" + sodipodi:linespacing="125%" + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L"><tspan + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" + id="tspan3023">(RCU Works Well)</tspan></text> + <!-- Text --> + <text + xml:space="preserve" + x="7200" + y="3375" + font-style="normal" + font-weight="normal" + font-size="324" + id="text22" + sodipodi:linespacing="125%" + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L"><tspan + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" + id="tspan3025">Read-Mostly, Need Consistent Data</tspan></text> + <!-- Text --> + <text + xml:space="preserve" + x="7200" + y="5175" + font-style="normal" + font-weight="normal" + font-size="324" + id="text24" + sodipodi:linespacing="125%" + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L"><tspan + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" + id="tspan3027">Read-Write, Need Consistent Data</tspan></text> + <!-- Text --> + <text + xml:space="preserve" + x="7200" + y="6975" + font-style="normal" + font-weight="normal" + font-size="324" + id="text26" + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" + sodipodi:linespacing="125%">Update-Mostly, Need Consistent Data</text> + <!-- Text --> + <text + xml:space="preserve" + x="7200" + y="5625" + font-style="normal" + font-weight="normal" + font-size="324" + id="text28" + sodipodi:linespacing="125%" + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L"><tspan + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" + id="tspan3029">(RCU Might Be OK...)</tspan></text> + <!-- Text --> + <text + xml:space="preserve" + x="7200" + y="7875" + font-style="normal" + font-weight="normal" + font-size="324" + id="text30" + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" + sodipodi:linespacing="125%">(1) Provide Existence Guarantees For Update-Friendly Mechanisms</text> + <!-- Text --> + <text + xml:space="preserve" + x="7200" + y="8325" + font-style="normal" + font-weight="normal" + font-size="324" + id="text32" + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" + sodipodi:linespacing="125%">(2) Provide Wait-Free Read-Side Primitives for Real-Time Use)</text> + <!-- Text --> + <text + xml:space="preserve" + x="7200" + y="7425" + font-style="normal" + font-weight="normal" + font-size="324" + id="text34" + style="font-size:427.63009644px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L" + sodipodi:linespacing="125%">(RCU is Very Unlikely to be the Right Tool For The Job, But it Can:</text> + </g> +</svg> diff --git a/Documentation/RCU/Design/Requirements/ReadersPartitionGP1.svg b/Documentation/RCU/Design/Requirements/ReadersPartitionGP1.svg new file mode 100644 index 000000000000..48cd1623d4d4 --- /dev/null +++ b/Documentation/RCU/Design/Requirements/ReadersPartitionGP1.svg @@ -0,0 +1,639 @@ +<?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="735.25" + height="516.21875" + id="svg2" + version="1.1" + inkscape:version="0.48.3.1 r9886" + sodipodi:docname="ReadersPartitionGP1.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="367.26465" + inkscape:cy="258.46182" + inkscape:document-units="px" + inkscape:current-layer="g4433-6" + showgrid="false" + inkscape:window-width="1351" + inkscape:window-height="836" + inkscape:window-x="438" + inkscape:window-y="335" + 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(-29.15625,-185.59375)"> + <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> <g + id="g4433" + transform="translate(2,-12)"> + <text + sodipodi:linespacing="125%" + id="text2993" + y="-261.66608" + x="436.12299" + 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" + xml:space="preserve" + transform="matrix(0,1,-1,0,0,0)"><tspan + y="-261.66608" + x="436.12299" + id="tspan2995" + sodipodi:role="line">synchronize_rcu()</tspan></text> + <g + id="g4417" + transform="matrix(0,1,-1,0,730.90257,222.4928)"> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow2Lstart);marker-end:url(#Arrow2Lend)" + d="M 97.580736,477.4048 327.57913,476.09759" + id="path2997" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 96.752718,465.38398 0,22.62742" + id="path4397" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 328.40703,465.38397 0,22.62742" + id="path4397-5" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + </g> + </g> + <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="112.04738" + y="268.18076" + id="text4429" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4431" + x="112.04738" + y="268.18076">WRITE_ONCE(a, 1);</tspan></text> + <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="112.04738" + y="487.13766" + id="text4441" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4443" + x="112.04738" + y="487.13766">WRITE_ONCE(b, 1);</tspan></text> + <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="255.60869" + y="297.29346" + id="text4445" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4447" + x="255.60869" + y="297.29346">r1 = READ_ONCE(a);</tspan></text> + <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="255.14423" + y="554.61786" + id="text4449" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4451" + x="255.14423" + y="554.61786">WRITE_ONCE(c, 1);</tspan></text> + <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="396.10254" + y="370.71124" + id="text4453" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4455" + x="396.10254" + y="370.71124">WRITE_ONCE(d, 1);</tspan></text> + <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="396.10254" + y="572.13617" + id="text4457" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4459" + x="396.10254" + y="572.13617">r2 = READ_ONCE(c);</tspan></text> + <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="112.08231" + y="213.91006" + id="text4461" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4463" + x="112.08231" + y="213.91006">thread0()</tspan></text> + <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="252.34512" + y="213.91006" + id="text4461-6" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4463-0" + x="252.34512" + y="213.91006">thread1()</tspan></text> + <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="396.42557" + y="213.91006" + id="text4461-2" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4463-2" + x="396.42557" + y="213.91006">thread2()</tspan></text> + <rect + style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="rect4495" + width="724.25244" + height="505.21201" + x="34.648232" + y="191.10612" /> + <path + style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + d="m 183.14066,191.10612 0,504.24243" + id="path4497" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + d="m 325.13867,191.10612 0,504.24243" + id="path4497-5" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <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="111.75929" + y="251.53981" + id="text4429-8" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4431-9" + x="111.75929" + y="251.53981">rcu_read_lock();</tspan></text> + <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="396.10254" + y="353.91556" + id="text4429-8-9" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4431-9-4" + x="396.10254" + y="353.91556">rcu_read_lock();</tspan></text> + <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="396.10254" + y="587.40289" + id="text4429-8-9-3" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4431-9-4-4" + x="396.10254" + y="587.40289">rcu_read_unlock();</tspan></text> + <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="111.75929" + y="501.15311" + id="text4429-8-9-3-1" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4431-9-4-4-6" + x="111.75929" + y="501.15311">rcu_read_unlock();</tspan></text> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 33.941125,227.87568 724.941765,0" + id="path4608" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <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="394.94427" + y="331.66351" + id="text4648" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4650" + x="394.94427" + y="331.66351">QS</tspan></text> + <path + sodipodi:type="arc" + style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path4652" + sodipodi:cx="358.85669" + sodipodi:cy="142.87541" + sodipodi:rx="10.960155" + sodipodi:ry="10.253048" + d="m 358.86939,132.62237 a 10.960155,10.253048 0 1 1 -0.0228,0" + transform="translate(36.441125,185.60612)" + sodipodi:start="4.7135481" + sodipodi:end="10.994651" + sodipodi:open="true" /> + <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="112.11968" + y="523.77856" + id="text4648-4" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4650-4" + x="112.11968" + y="523.77856">QS</tspan></text> + <path + sodipodi:type="arc" + style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path4652-7" + sodipodi:cx="358.85669" + sodipodi:cy="142.87541" + sodipodi:rx="10.960155" + sodipodi:ry="10.253048" + d="m 358.86939,132.62237 a 10.960155,10.253048 0 1 1 -0.0228,0" + transform="translate(-246.38346,377.72117)" + sodipodi:start="4.7135481" + sodipodi:end="10.994651" + sodipodi:open="true" /> + <path + sodipodi:type="arc" + style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path4652-7-7" + sodipodi:cx="358.85669" + sodipodi:cy="142.87541" + sodipodi:rx="10.960155" + sodipodi:ry="10.253048" + d="m 358.86939,132.62237 a 10.960155,10.253048 0 1 1 -0.0228,0" + transform="translate(-103.65246,190.90878)" + sodipodi:start="4.7135481" + sodipodi:end="10.994651" + sodipodi:open="true" /> + <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="254.85066" + y="336.96619" + id="text4648-4-3" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4650-4-5" + x="254.85066" + y="336.96619">QS</tspan></text> + <path + style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + d="m 470.93311,190.39903 0,504.24243" + id="path4497-5-6" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + d="m 616.22755,190.38323 0,504.24243" + id="path4497-5-2" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <g + id="g4433-6" + transform="translate(288.0964,78.32827)"> + <text + sodipodi:linespacing="125%" + id="text2993-7" + y="-261.66608" + x="440.12299" + 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" + xml:space="preserve" + transform="matrix(0,1,-1,0,0,0)"><tspan + y="-261.66608" + x="440.12299" + id="tspan2995-1" + sodipodi:role="line">synchronize_rcu()</tspan></text> + <g + id="g4417-1" + transform="matrix(0,1,-1,0,730.90257,222.4928)"> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow2Lstart);marker-end:url(#Arrow2Lend)" + d="M 97.580736,477.4048 328.5624,477.07246" + id="path2997-2" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 96.752718,465.38398 0,22.62742" + id="path4397-3" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 329.39039,465.38397 0,22.62742" + id="path4397-5-4" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + </g> + </g> + <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="541.70508" + y="387.6217" + id="text4445-0" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4447-5" + x="541.70508" + y="387.6217">r3 = READ_ONCE(d);</tspan></text> + <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="541.2406" + y="646.94611" + id="text4449-6" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4451-6" + x="541.2406" + y="646.94611">WRITE_ONCE(e, 1);</tspan></text> + <path + sodipodi:type="arc" + style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path4652-7-7-5" + sodipodi:cx="358.85669" + sodipodi:cy="142.87541" + sodipodi:rx="10.960155" + sodipodi:ry="10.253048" + d="m 358.86939,132.62237 a 10.960155,10.253048 0 1 1 -0.0228,0" + transform="translate(182.44393,281.23704)" + sodipodi:start="4.7135481" + sodipodi:end="10.994651" + sodipodi:open="true" /> + <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="540.94702" + y="427.29443" + id="text4648-4-3-1" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4650-4-5-7" + x="540.94702" + y="427.29443">QS</tspan></text> + <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="686.27747" + y="461.83929" + id="text4453-7" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4455-1" + x="686.27747" + y="461.83929">r4 = READ_ONCE(b);</tspan></text> + <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="686.27747" + y="669.26422" + id="text4457-9" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4459-2" + x="686.27747" + y="669.26422">r5 = READ_ONCE(e);</tspan></text> + <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="686.27747" + y="445.04358" + id="text4429-8-9-33" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4431-9-4-2" + x="686.27747" + y="445.04358">rcu_read_lock();</tspan></text> + <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="686.27747" + y="684.53094" + id="text4429-8-9-3-8" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4431-9-4-4-5" + x="686.27747" + y="684.53094">rcu_read_unlock();</tspan></text> + <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="685.11914" + y="422.79153" + id="text4648-9" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4650-7" + x="685.11914" + y="422.79153">QS</tspan></text> + <path + sodipodi:type="arc" + style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path4652-8" + sodipodi:cx="358.85669" + sodipodi:cy="142.87541" + sodipodi:rx="10.960155" + sodipodi:ry="10.253048" + d="m 358.86939,132.62237 a 10.960155,10.253048 0 1 1 -0.0228,0" + transform="translate(326.61602,276.73415)" + sodipodi:start="4.7135481" + sodipodi:end="10.994651" + sodipodi:open="true" /> + <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="397.85934" + y="609.59003" + id="text4648-5" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4650-77" + x="397.85934" + y="609.59003">QS</tspan></text> + <path + sodipodi:type="arc" + style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path4652-80" + sodipodi:cx="358.85669" + sodipodi:cy="142.87541" + sodipodi:rx="10.960155" + sodipodi:ry="10.253048" + d="m 358.86939,132.62237 a 10.960155,10.253048 0 1 1 -0.0228,0" + transform="translate(39.356201,463.53264)" + sodipodi:start="4.7135481" + sodipodi:end="10.994651" + sodipodi:open="true" /> + <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="256.75986" + y="586.99133" + id="text4648-5-2" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4650-77-7" + x="256.75986" + y="586.99133">QS</tspan></text> + <path + sodipodi:type="arc" + style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="path4652-80-5" + sodipodi:cx="358.85669" + sodipodi:cy="142.87541" + sodipodi:rx="10.960155" + sodipodi:ry="10.253048" + d="m 358.86939,132.62237 a 10.960155,10.253048 0 1 1 -0.0228,0" + transform="translate(-101.74328,440.93395)" + sodipodi:start="4.7135481" + sodipodi:end="10.994651" + sodipodi:open="true" /> + <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="546.22791" + y="213.91006" + id="text4461-2-5" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4463-2-6" + x="546.22791" + y="213.91006">thread3()</tspan></text> + <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="684.00067" + y="213.91006" + id="text4461-2-1" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan4463-2-0" + x="684.00067" + y="213.91006">thread4()</tspan></text> + </g> +</svg> diff --git a/Documentation/RCU/Design/Requirements/Requirements.html b/Documentation/RCU/Design/Requirements/Requirements.html new file mode 100644 index 000000000000..95ef7b5de951 --- /dev/null +++ b/Documentation/RCU/Design/Requirements/Requirements.html @@ -0,0 +1,2799 @@ +<!-- DO NOT HAND EDIT. --> +<!-- Instead, edit Requirements.htmlx and run 'sh htmlqqz.sh Requirements' --> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + <html> + <head><title>A Tour Through RCU's Requirements [LWN.net]</title> + <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> + +<h1>A Tour Through RCU's Requirements</h1> + +<p>Copyright IBM Corporation, 2015</p> +<p>Author: Paul E. McKenney</p> +<p><i>The initial version of this document appeared in the +<a href="http://lwn.net/">LWN</a> articles +<a href="http://lwn.net/Articles/652156/">here</a>, +<a href="http://lwn.net/Articles/652677/">here</a>, and +<a href="http://lwn.net/Articles/653326/">here</a>.</i></p> + +<h2>Introduction</h2> + +<p> +Read-copy update (RCU) is a synchronization mechanism that is often +used as a replacement for reader-writer locking. +RCU is unusual in that updaters do not block readers, +which means that RCU's read-side primitives can be exceedingly fast +and scalable. +In addition, updaters can make useful forward progress concurrently +with readers. +However, all this concurrency between RCU readers and updaters does raise +the question of exactly what RCU readers are doing, which in turn +raises the question of exactly what RCU's requirements are. + +<p> +This document therefore summarizes RCU's requirements, and can be thought +of as an informal, high-level specification for RCU. +It is important to understand that RCU's specification is primarily +empirical in nature; +in fact, I learned about many of these requirements the hard way. +This situation might cause some consternation, however, not only +has this learning process been a lot of fun, but it has also been +a great privilege to work with so many people willing to apply +technologies in interesting new ways. + +<p> +All that aside, here are the categories of currently known RCU requirements: +</p> + +<ol> +<li> <a href="#Fundamental Requirements"> + Fundamental Requirements</a> +<li> <a href="#Fundamental Non-Requirements">Fundamental Non-Requirements</a> +<li> <a href="#Parallelism Facts of Life"> + Parallelism Facts of Life</a> +<li> <a href="#Quality-of-Implementation Requirements"> + Quality-of-Implementation Requirements</a> +<li> <a href="#Linux Kernel Complications"> + Linux Kernel Complications</a> +<li> <a href="#Software-Engineering Requirements"> + Software-Engineering Requirements</a> +<li> <a href="#Other RCU Flavors"> + Other RCU Flavors</a> +<li> <a href="#Possible Future Changes"> + Possible Future Changes</a> +</ol> + +<p> +This is followed by a <a href="#Summary">summary</a>, +which is in turn followed by the inevitable +<a href="#Answers to Quick Quizzes">answers to the quick quizzes</a>. + +<h2><a name="Fundamental Requirements">Fundamental Requirements</a></h2> + +<p> +RCU's fundamental requirements are the closest thing RCU has to hard +mathematical requirements. +These are: + +<ol> +<li> <a href="#Grace-Period Guarantee"> + Grace-Period Guarantee</a> +<li> <a href="#Publish-Subscribe Guarantee"> + Publish-Subscribe Guarantee</a> +<li> <a href="#RCU Primitives Guaranteed to Execute Unconditionally"> + RCU Primitives Guaranteed to Execute Unconditionally</a> +<li> <a href="#Guaranteed Read-to-Write Upgrade"> + Guaranteed Read-to-Write Upgrade</a> +</ol> + +<h3><a name="Grace-Period Guarantee">Grace-Period Guarantee</a></h3> + +<p> +RCU's grace-period guarantee is unusual in being premeditated: +Jack Slingwine and I had this guarantee firmly in mind when we started +work on RCU (then called “rclock”) in the early 1990s. +That said, the past two decades of experience with RCU have produced +a much more detailed understanding of this guarantee. + +<p> +RCU's grace-period guarantee allows updaters to wait for the completion +of all pre-existing RCU read-side critical sections. +An RCU read-side critical section +begins with the marker <tt>rcu_read_lock()</tt> and ends with +the marker <tt>rcu_read_unlock()</tt>. +These markers may be nested, and RCU treats a nested set as one +big RCU read-side critical section. +Production-quality implementations of <tt>rcu_read_lock()</tt> and +<tt>rcu_read_unlock()</tt> are extremely lightweight, and in +fact have exactly zero overhead in Linux kernels built for production +use with <tt>CONFIG_PREEMPT=n</tt>. + +<p> +This guarantee allows ordering to be enforced with extremely low +overhead to readers, for example: + +<blockquote> +<pre> + 1 int x, y; + 2 + 3 void thread0(void) + 4 { + 5 rcu_read_lock(); + 6 r1 = READ_ONCE(x); + 7 r2 = READ_ONCE(y); + 8 rcu_read_unlock(); + 9 } +10 +11 void thread1(void) +12 { +13 WRITE_ONCE(x, 1); +14 synchronize_rcu(); +15 WRITE_ONCE(y, 1); +16 } +</pre> +</blockquote> + +<p> +Because the <tt>synchronize_rcu()</tt> on line 14 waits for +all pre-existing readers, any instance of <tt>thread0()</tt> that +loads a value of zero from <tt>x</tt> must complete before +<tt>thread1()</tt> stores to <tt>y</tt>, so that instance must +also load a value of zero from <tt>y</tt>. +Similarly, any instance of <tt>thread0()</tt> that loads a value of +one from <tt>y</tt> must have started after the +<tt>synchronize_rcu()</tt> started, and must therefore also load +a value of one from <tt>x</tt>. +Therefore, the outcome: +<blockquote> +<pre> +(r1 == 0 && r2 == 1) +</pre> +</blockquote> +cannot happen. + +<p><a name="Quick Quiz 1"><b>Quick Quiz 1</b>:</a> +Wait a minute! +You said that updaters can make useful forward progress concurrently +with readers, but pre-existing readers will block +<tt>synchronize_rcu()</tt>!!! +Just who are you trying to fool??? +<br><a href="#qq1answer">Answer</a> + +<p> +This scenario resembles one of the first uses of RCU in +<a href="http://en.wikipedia.org/wiki/DYNIX">DYNIX/ptx</a>, +which managed a distributed lock manager's transition into +a state suitable for handling recovery from node failure, +more or less as follows: + +<blockquote> +<pre> + 1 #define STATE_NORMAL 0 + 2 #define STATE_WANT_RECOVERY 1 + 3 #define STATE_RECOVERING 2 + 4 #define STATE_WANT_NORMAL 3 + 5 + 6 int state = STATE_NORMAL; + 7 + 8 void do_something_dlm(void) + 9 { +10 int state_snap; +11 +12 rcu_read_lock(); +13 state_snap = READ_ONCE(state); +14 if (state_snap == STATE_NORMAL) +15 do_something(); +16 else +17 do_something_carefully(); +18 rcu_read_unlock(); +19 } +20 +21 void start_recovery(void) +22 { +23 WRITE_ONCE(state, STATE_WANT_RECOVERY); +24 synchronize_rcu(); +25 WRITE_ONCE(state, STATE_RECOVERING); +26 recovery(); +27 WRITE_ONCE(state, STATE_WANT_NORMAL); +28 synchronize_rcu(); +29 WRITE_ONCE(state, STATE_NORMAL); +30 } +</pre> +</blockquote> + +<p> +The RCU read-side critical section in <tt>do_something_dlm()</tt> +works with the <tt>synchronize_rcu()</tt> in <tt>start_recovery()</tt> +to guarantee that <tt>do_something()</tt> never runs concurrently +with <tt>recovery()</tt>, but with little or no synchronization +overhead in <tt>do_something_dlm()</tt>. + +<p><a name="Quick Quiz 2"><b>Quick Quiz 2</b>:</a> +Why is the <tt>synchronize_rcu()</tt> on line 28 needed? +<br><a href="#qq2answer">Answer</a> + +<p> +In order to avoid fatal problems such as deadlocks, +an RCU read-side critical section must not contain calls to +<tt>synchronize_rcu()</tt>. +Similarly, an RCU read-side critical section must not +contain anything that waits, directly or indirectly, on completion of +an invocation of <tt>synchronize_rcu()</tt>. + +<p> +Although RCU's grace-period guarantee is useful in and of itself, with +<a href="https://lwn.net/Articles/573497/">quite a few use cases</a>, +it would be good to be able to use RCU to coordinate read-side +access to linked data structures. +For this, the grace-period guarantee is not sufficient, as can +be seen in function <tt>add_gp_buggy()</tt> below. +We will look at the reader's code later, but in the meantime, just think of +the reader as locklessly picking up the <tt>gp</tt> pointer, +and, if the value loaded is non-<tt>NULL</tt>, locklessly accessing the +<tt>->a</tt> and <tt>->b</tt> fields. + +<blockquote> +<pre> + 1 bool add_gp_buggy(int a, int b) + 2 { + 3 p = kmalloc(sizeof(*p), GFP_KERNEL); + 4 if (!p) + 5 return -ENOMEM; + 6 spin_lock(&gp_lock); + 7 if (rcu_access_pointer(gp)) { + 8 spin_unlock(&gp_lock); + 9 return false; +10 } +11 p->a = a; +12 p->b = a; +13 gp = p; /* ORDERING BUG */ +14 spin_unlock(&gp_lock); +15 return true; +16 } +</pre> +</blockquote> + +<p> +The problem is that both the compiler and weakly ordered CPUs are within +their rights to reorder this code as follows: + +<blockquote> +<pre> + 1 bool add_gp_buggy_optimized(int a, int b) + 2 { + 3 p = kmalloc(sizeof(*p), GFP_KERNEL); + 4 if (!p) + 5 return -ENOMEM; + 6 spin_lock(&gp_lock); + 7 if (rcu_access_pointer(gp)) { + 8 spin_unlock(&gp_lock); + 9 return false; +10 } +<b>11 gp = p; /* ORDERING BUG */ +12 p->a = a; +13 p->b = a;</b> +14 spin_unlock(&gp_lock); +15 return true; +16 } +</pre> +</blockquote> + +<p> +If an RCU reader fetches <tt>gp</tt> just after +<tt>add_gp_buggy_optimized</tt> executes line 11, +it will see garbage in the <tt>->a</tt> and <tt>->b</tt> +fields. +And this is but one of many ways in which compiler and hardware optimizations +could cause trouble. +Therefore, we clearly need some way to prevent the compiler and the CPU from +reordering in this manner, which brings us to the publish-subscribe +guarantee discussed in the next section. + +<h3><a name="Publish-Subscribe Guarantee">Publish/Subscribe Guarantee</a></h3> + +<p> +RCU's publish-subscribe guarantee allows data to be inserted +into a linked data structure without disrupting RCU readers. +The updater uses <tt>rcu_assign_pointer()</tt> to insert the +new data, and readers use <tt>rcu_dereference()</tt> to +access data, whether new or old. +The following shows an example of insertion: + +<blockquote> +<pre> + 1 bool add_gp(int a, int b) + 2 { + 3 p = kmalloc(sizeof(*p), GFP_KERNEL); + 4 if (!p) + 5 return -ENOMEM; + 6 spin_lock(&gp_lock); + 7 if (rcu_access_pointer(gp)) { + 8 spin_unlock(&gp_lock); + 9 return false; +10 } +11 p->a = a; +12 p->b = a; +13 rcu_assign_pointer(gp, p); +14 spin_unlock(&gp_lock); +15 return true; +16 } +</pre> +</blockquote> + +<p> +The <tt>rcu_assign_pointer()</tt> on line 13 is conceptually +equivalent to a simple assignment statement, but also guarantees +that its assignment will +happen after the two assignments in lines 11 and 12, +similar to the C11 <tt>memory_order_release</tt> store operation. +It also prevents any number of “interesting” compiler +optimizations, for example, the use of <tt>gp</tt> as a scratch +location immediately preceding the assignment. + +<p><a name="Quick Quiz 3"><b>Quick Quiz 3</b>:</a> +But <tt>rcu_assign_pointer()</tt> does nothing to prevent the +two assignments to <tt>p->a</tt> and <tt>p->b</tt> +from being reordered. +Can't that also cause problems? +<br><a href="#qq3answer">Answer</a> + +<p> +It is tempting to assume that the reader need not do anything special +to control its accesses to the RCU-protected data, +as shown in <tt>do_something_gp_buggy()</tt> below: + +<blockquote> +<pre> + 1 bool do_something_gp_buggy(void) + 2 { + 3 rcu_read_lock(); + 4 p = gp; /* OPTIMIZATIONS GALORE!!! */ + 5 if (p) { + 6 do_something(p->a, p->b); + 7 rcu_read_unlock(); + 8 return true; + 9 } +10 rcu_read_unlock(); +11 return false; +12 } +</pre> +</blockquote> + +<p> +However, this temptation must be resisted because there are a +surprisingly large number of ways that the compiler +(to say nothing of +<a href="http://www.openvms.compaq.com/wizard/wiz_2637.html">DEC Alpha CPUs</a>) +can trip this code up. +For but one example, if the compiler were short of registers, it +might choose to refetch from <tt>gp</tt> rather than keeping +a separate copy in <tt>p</tt> as follows: + +<blockquote> +<pre> + 1 bool do_something_gp_buggy_optimized(void) + 2 { + 3 rcu_read_lock(); + 4 if (gp) { /* OPTIMIZATIONS GALORE!!! */ +<b> 5 do_something(gp->a, gp->b);</b> + 6 rcu_read_unlock(); + 7 return true; + 8 } + 9 rcu_read_unlock(); +10 return false; +11 } +</pre> +</blockquote> + +<p> +If this function ran concurrently with a series of updates that +replaced the current structure with a new one, +the fetches of <tt>gp->a</tt> +and <tt>gp->b</tt> might well come from two different structures, +which could cause serious confusion. +To prevent this (and much else besides), <tt>do_something_gp()</tt> uses +<tt>rcu_dereference()</tt> to fetch from <tt>gp</tt>: + +<blockquote> +<pre> + 1 bool do_something_gp(void) + 2 { + 3 rcu_read_lock(); + 4 p = rcu_dereference(gp); + 5 if (p) { + 6 do_something(p->a, p->b); + 7 rcu_read_unlock(); + 8 return true; + 9 } +10 rcu_read_unlock(); +11 return false; +12 } +</pre> +</blockquote> + +<p> +The <tt>rcu_dereference()</tt> uses volatile casts and (for DEC Alpha) +memory barriers in the Linux kernel. +Should a +<a href="http://www.rdrop.com/users/paulmck/RCU/consume.2015.07.13a.pdf">high-quality implementation of C11 <tt>memory_order_consume</tt> [PDF]</a> +ever appear, then <tt>rcu_dereference()</tt> could be implemented +as a <tt>memory_order_consume</tt> load. +Regardless of the exact implementation, a pointer fetched by +<tt>rcu_dereference()</tt> may not be used outside of the +outermost RCU read-side critical section containing that +<tt>rcu_dereference()</tt>, unless protection of +the corresponding data element has been passed from RCU to some +other synchronization mechanism, most commonly locking or +<a href="https://www.kernel.org/doc/Documentation/RCU/rcuref.txt">reference counting</a>. + +<p> +In short, updaters use <tt>rcu_assign_pointer()</tt> and readers +use <tt>rcu_dereference()</tt>, and these two RCU API elements +work together to ensure that readers have a consistent view of +newly added data elements. + +<p> +Of course, it is also necessary to remove elements from RCU-protected +data structures, for example, using the following process: + +<ol> +<li> Remove the data element from the enclosing structure. +<li> Wait for all pre-existing RCU read-side critical sections + to complete (because only pre-existing readers can possibly have + a reference to the newly removed data element). +<li> At this point, only the updater has a reference to the + newly removed data element, so it can safely reclaim + the data element, for example, by passing it to <tt>kfree()</tt>. +</ol> + +This process is implemented by <tt>remove_gp_synchronous()</tt>: + +<blockquote> +<pre> + 1 bool remove_gp_synchronous(void) + 2 { + 3 struct foo *p; + 4 + 5 spin_lock(&gp_lock); + 6 p = rcu_access_pointer(gp); + 7 if (!p) { + 8 spin_unlock(&gp_lock); + 9 return false; +10 } +11 rcu_assign_pointer(gp, NULL); +12 spin_unlock(&gp_lock); +13 synchronize_rcu(); +14 kfree(p); +15 return true; +16 } +</pre> +</blockquote> + +<p> +This function is straightforward, with line 13 waiting for a grace +period before line 14 frees the old data element. +This waiting ensures that readers will reach line 7 of +<tt>do_something_gp()</tt> before the data element referenced by +<tt>p</tt> is freed. +The <tt>rcu_access_pointer()</tt> on line 6 is similar to +<tt>rcu_dereference()</tt>, except that: + +<ol> +<li> The value returned by <tt>rcu_access_pointer()</tt> + cannot be dereferenced. + If you want to access the value pointed to as well as + the pointer itself, use <tt>rcu_dereference()</tt> + instead of <tt>rcu_access_pointer()</tt>. +<li> The call to <tt>rcu_access_pointer()</tt> need not be + protected. + In contrast, <tt>rcu_dereference()</tt> must either be + within an RCU read-side critical section or in a code + segment where the pointer cannot change, for example, in + code protected by the corresponding update-side lock. +</ol> + +<p><a name="Quick Quiz 4"><b>Quick Quiz 4</b>:</a> +Without the <tt>rcu_dereference()</tt> or the +<tt>rcu_access_pointer()</tt>, what destructive optimizations +might the compiler make use of? +<br><a href="#qq4answer">Answer</a> + +<p> +This simple linked-data-structure scenario clearly demonstrates the need +for RCU's stringent memory-ordering guarantees on systems with more than +one CPU: + +<ol> +<li> Each CPU that has an RCU read-side critical section that + begins before <tt>synchronize_rcu()</tt> starts is + guaranteed to execute a full memory barrier between the time + that the RCU read-side critical section ends and the time that + <tt>synchronize_rcu()</tt> returns. + Without this guarantee, a pre-existing RCU read-side critical section + might hold a reference to the newly removed <tt>struct foo</tt> + after the <tt>kfree()</tt> on line 14 of + <tt>remove_gp_synchronous()</tt>. +<li> Each CPU that has an RCU read-side critical section that ends + after <tt>synchronize_rcu()</tt> returns is guaranteed + to execute a full memory barrier between the time that + <tt>synchronize_rcu()</tt> begins and the time that the RCU + read-side critical section begins. + Without this guarantee, a later RCU read-side critical section + running after the <tt>kfree()</tt> on line 14 of + <tt>remove_gp_synchronous()</tt> might + later run <tt>do_something_gp()</tt> and find the + newly deleted <tt>struct foo</tt>. +<li> If the task invoking <tt>synchronize_rcu()</tt> remains + on a given CPU, then that CPU is guaranteed to execute a full + memory barrier sometime during the execution of + <tt>synchronize_rcu()</tt>. + This guarantee ensures that the <tt>kfree()</tt> on + line 14 of <tt>remove_gp_synchronous()</tt> really does + execute after the removal on line 11. +<li> If the task invoking <tt>synchronize_rcu()</tt> migrates + among a group of CPUs during that invocation, then each of the + CPUs in that group is guaranteed to execute a full memory barrier + sometime during the execution of <tt>synchronize_rcu()</tt>. + This guarantee also ensures that the <tt>kfree()</tt> on + line 14 of <tt>remove_gp_synchronous()</tt> really does + execute after the removal on + line 11, but also in the case where the thread executing the + <tt>synchronize_rcu()</tt> migrates in the meantime. +</ol> + +<p><a name="Quick Quiz 5"><b>Quick Quiz 5</b>:</a> +Given that multiple CPUs can start RCU read-side critical sections +at any time without any ordering whatsoever, how can RCU possibly tell whether +or not a given RCU read-side critical section starts before a +given instance of <tt>synchronize_rcu()</tt>? +<br><a href="#qq5answer">Answer</a> + +<p><a name="Quick Quiz 6"><b>Quick Quiz 6</b>:</a> +The first and second guarantees require unbelievably strict ordering! +Are all these memory barriers <i> really</i> required? +<br><a href="#qq6answer">Answer</a> + +<p> +In short, RCU's publish-subscribe guarantee is provided by the combination +of <tt>rcu_assign_pointer()</tt> and <tt>rcu_dereference()</tt>. +This guarantee allows data elements to be safely added to RCU-protected +linked data structures without disrupting RCU readers. +This guarantee can be used in combination with the grace-period +guarantee to also allow data elements to be removed from RCU-protected +linked data structures, again without disrupting RCU readers. + +<p> +This guarantee was only partially premeditated. +DYNIX/ptx used an explicit memory barrier for publication, but had nothing +resembling <tt>rcu_dereference()</tt> for subscription, nor did it +have anything resembling the <tt>smp_read_barrier_depends()</tt> +that was later subsumed into <tt>rcu_dereference()</tt>. +The need for these operations made itself known quite suddenly at a +late-1990s meeting with the DEC Alpha architects, back in the days when +DEC was still a free-standing company. +It took the Alpha architects a good hour to convince me that any sort +of barrier would ever be needed, and it then took me a good <i>two</i> hours +to convince them that their documentation did not make this point clear. +More recent work with the C and C++ standards committees have provided +much education on tricks and traps from the compiler. +In short, compilers were much less tricky in the early 1990s, but in +2015, don't even think about omitting <tt>rcu_dereference()</tt>! + +<h3><a name="RCU Primitives Guaranteed to Execute Unconditionally">RCU Primitives Guaranteed to Execute Unconditionally</a></h3> + +<p> +The common-case RCU primitives are unconditional. +They are invoked, they do their job, and they return, with no possibility +of error, and no need to retry. +This is a key RCU design philosophy. + +<p> +However, this philosophy is pragmatic rather than pigheaded. +If someone comes up with a good justification for a particular conditional +RCU primitive, it might well be implemented and added. +After all, this guarantee was reverse-engineered, not premeditated. +The unconditional nature of the RCU primitives was initially an +accident of implementation, and later experience with synchronization +primitives with conditional primitives caused me to elevate this +accident to a guarantee. +Therefore, the justification for adding a conditional primitive to +RCU would need to be based on detailed and compelling use cases. + +<h3><a name="Guaranteed Read-to-Write Upgrade">Guaranteed Read-to-Write Upgrade</a></h3> + +<p> +As far as RCU is concerned, it is always possible to carry out an +update within an RCU read-side critical section. +For example, that RCU read-side critical section might search for +a given data element, and then might acquire the update-side +spinlock in order to update that element, all while remaining +in that RCU read-side critical section. +Of course, it is necessary to exit the RCU read-side critical section +before invoking <tt>synchronize_rcu()</tt>, however, this +inconvenience can be avoided through use of the +<tt>call_rcu()</tt> and <tt>kfree_rcu()</tt> API members +described later in this document. + +<p><a name="Quick Quiz 7"><b>Quick Quiz 7</b>:</a> +But how does the upgrade-to-write operation exclude other readers? +<br><a href="#qq7answer">Answer</a> + +<p> +This guarantee allows lookup code to be shared between read-side +and update-side code, and was premeditated, appearing in the earliest +DYNIX/ptx RCU documentation. + +<h2><a name="Fundamental Non-Requirements">Fundamental Non-Requirements</a></h2> + +<p> +RCU provides extremely lightweight readers, and its read-side guarantees, +though quite useful, are correspondingly lightweight. +It is therefore all too easy to assume that RCU is guaranteeing more +than it really is. +Of course, the list of things that RCU does not guarantee is infinitely +long, however, the following sections list a few non-guarantees that +have caused confusion. +Except where otherwise noted, these non-guarantees were premeditated. + +<ol> +<li> <a href="#Readers Impose Minimal Ordering"> + Readers Impose Minimal Ordering</a> +<li> <a href="#Readers Do Not Exclude Updaters"> + Readers Do Not Exclude Updaters</a> +<li> <a href="#Updaters Only Wait For Old Readers"> + Updaters Only Wait For Old Readers</a> +<li> <a href="#Grace Periods Don't Partition Read-Side Critical Sections"> + Grace Periods Don't Partition Read-Side Critical Sections</a> +<li> <a href="#Read-Side Critical Sections Don't Partition Grace Periods"> + Read-Side Critical Sections Don't Partition Grace Periods</a> +<li> <a href="#Disabling Preemption Does Not Block Grace Periods"> + Disabling Preemption Does Not Block Grace Periods</a> +</ol> + +<h3><a name="Readers Impose Minimal Ordering">Readers Impose Minimal Ordering</a></h3> + +<p> +Reader-side markers such as <tt>rcu_read_lock()</tt> and +<tt>rcu_read_unlock()</tt> provide absolutely no ordering guarantees +except through their interaction with the grace-period APIs such as +<tt>synchronize_rcu()</tt>. +To see this, consider the following pair of threads: + +<blockquote> +<pre> + 1 void thread0(void) + 2 { + 3 rcu_read_lock(); + 4 WRITE_ONCE(x, 1); + 5 rcu_read_unlock(); + 6 rcu_read_lock(); + 7 WRITE_ONCE(y, 1); + 8 rcu_read_unlock(); + 9 } +10 +11 void thread1(void) +12 { +13 rcu_read_lock(); +14 r1 = READ_ONCE(y); +15 rcu_read_unlock(); +16 rcu_read_lock(); +17 r2 = READ_ONCE(x); +18 rcu_read_unlock(); +19 } +</pre> +</blockquote> + +<p> +After <tt>thread0()</tt> and <tt>thread1()</tt> execute +concurrently, it is quite possible to have + +<blockquote> +<pre> +(r1 == 1 && r2 == 0) +</pre> +</blockquote> + +(that is, <tt>y</tt> appears to have been assigned before <tt>x</tt>), +which would not be possible if <tt>rcu_read_lock()</tt> and +<tt>rcu_read_unlock()</tt> had much in the way of ordering +properties. +But they do not, so the CPU is within its rights +to do significant reordering. +This is by design: Any significant ordering constraints would slow down +these fast-path APIs. + +<p><a name="Quick Quiz 8"><b>Quick Quiz 8</b>:</a> +Can't the compiler also reorder this code? +<br><a href="#qq8answer">Answer</a> + +<h3><a name="Readers Do Not Exclude Updaters">Readers Do Not Exclude Updaters</a></h3> + +<p> +Neither <tt>rcu_read_lock()</tt> nor <tt>rcu_read_unlock()</tt> +exclude updates. +All they do is to prevent grace periods from ending. +The following example illustrates this: + +<blockquote> +<pre> + 1 void thread0(void) + 2 { + 3 rcu_read_lock(); + 4 r1 = READ_ONCE(y); + 5 if (r1) { + 6 do_something_with_nonzero_x(); + 7 r2 = READ_ONCE(x); + 8 WARN_ON(!r2); /* BUG!!! */ + 9 } +10 rcu_read_unlock(); +11 } +12 +13 void thread1(void) +14 { +15 spin_lock(&my_lock); +16 WRITE_ONCE(x, 1); +17 WRITE_ONCE(y, 1); +18 spin_unlock(&my_lock); +19 } +</pre> +</blockquote> + +<p> +If the <tt>thread0()</tt> function's <tt>rcu_read_lock()</tt> +excluded the <tt>thread1()</tt> function's update, +the <tt>WARN_ON()</tt> could never fire. +But the fact is that <tt>rcu_read_lock()</tt> does not exclude +much of anything aside from subsequent grace periods, of which +<tt>thread1()</tt> has none, so the +<tt>WARN_ON()</tt> can and does fire. + +<h3><a name="Updaters Only Wait For Old Readers">Updaters Only Wait For Old Readers</a></h3> + +<p> +It might be tempting to assume that after <tt>synchronize_rcu()</tt> +completes, there are no readers executing. +This temptation must be avoided because +new readers can start immediately after <tt>synchronize_rcu()</tt> +starts, and <tt>synchronize_rcu()</tt> is under no +obligation to wait for these new readers. + +<p><a name="Quick Quiz 9"><b>Quick Quiz 9</b>:</a> +Suppose that synchronize_rcu() did wait until all readers had completed. +Would the updater be able to rely on this? +<br><a href="#qq9answer">Answer</a> + +<h3><a name="Grace Periods Don't Partition Read-Side Critical Sections"> +Grace Periods Don't Partition Read-Side Critical Sections</a></h3> + +<p> +It is tempting to assume that if any part of one RCU read-side critical +section precedes a given grace period, and if any part of another RCU +read-side critical section follows that same grace period, then all of +the first RCU read-side critical section must precede all of the second. +However, this just isn't the case: A single grace period does not +partition the set of RCU read-side critical sections. +An example of this situation can be illustrated as follows, where +<tt>x</tt>, <tt>y</tt>, and <tt>z</tt> are initially all zero: + +<blockquote> +<pre> + 1 void thread0(void) + 2 { + 3 rcu_read_lock(); + 4 WRITE_ONCE(a, 1); + 5 WRITE_ONCE(b, 1); + 6 rcu_read_unlock(); + 7 } + 8 + 9 void thread1(void) +10 { +11 r1 = READ_ONCE(a); +12 synchronize_rcu(); +13 WRITE_ONCE(c, 1); +14 } +15 +16 void thread2(void) +17 { +18 rcu_read_lock(); +19 r2 = READ_ONCE(b); +20 r3 = READ_ONCE(c); +21 rcu_read_unlock(); +22 } +</pre> +</blockquote> + +<p> +It turns out that the outcome: + +<blockquote> +<pre> +(r1 == 1 && r2 == 0 && r3 == 1) +</pre> +</blockquote> + +is entirely possible. +The following figure show how this can happen, with each circled +<tt>QS</tt> indicating the point at which RCU recorded a +<i>quiescent state</i> for each thread, that is, a state in which +RCU knows that the thread cannot be in the midst of an RCU read-side +critical section that started before the current grace period: + +<p><img src="GPpartitionReaders1.svg" alt="GPpartitionReaders1.svg" width="60%"></p> + +<p> +If it is necessary to partition RCU read-side critical sections in this +manner, it is necessary to use two grace periods, where the first +grace period is known to end before the second grace period starts: + +<blockquote> +<pre> + 1 void thread0(void) + 2 { + 3 rcu_read_lock(); + 4 WRITE_ONCE(a, 1); + 5 WRITE_ONCE(b, 1); + 6 rcu_read_unlock(); + 7 } + 8 + 9 void thread1(void) +10 { +11 r1 = READ_ONCE(a); +12 synchronize_rcu(); +13 WRITE_ONCE(c, 1); +14 } +15 +16 void thread2(void) +17 { +18 r2 = READ_ONCE(c); +19 synchronize_rcu(); +20 WRITE_ONCE(d, 1); +21 } +22 +23 void thread3(void) +24 { +25 rcu_read_lock(); +26 r3 = READ_ONCE(b); +27 r4 = READ_ONCE(d); +28 rcu_read_unlock(); +29 } +</pre> +</blockquote> + +<p> +Here, if <tt>(r1 == 1)</tt>, then +<tt>thread0()</tt>'s write to <tt>b</tt> must happen +before the end of <tt>thread1()</tt>'s grace period. +If in addition <tt>(r4 == 1)</tt>, then +<tt>thread3()</tt>'s read from <tt>b</tt> must happen +after the beginning of <tt>thread2()</tt>'s grace period. +If it is also the case that <tt>(r2 == 1)</tt>, then the +end of <tt>thread1()</tt>'s grace period must precede the +beginning of <tt>thread2()</tt>'s grace period. +This mean that the two RCU read-side critical sections cannot overlap, +guaranteeing that <tt>(r3 == 1)</tt>. +As a result, the outcome: + +<blockquote> +<pre> +(r1 == 1 && r2 == 1 && r3 == 0 && r4 == 1) +</pre> +</blockquote> + +cannot happen. + +<p> +This non-requirement was also non-premeditated, but became apparent +when studying RCU's interaction with memory ordering. + +<h3><a name="Read-Side Critical Sections Don't Partition Grace Periods"> +Read-Side Critical Sections Don't Partition Grace Periods</a></h3> + +<p> +It is also tempting to assume that if an RCU read-side critical section +happens between a pair of grace periods, then those grace periods cannot +overlap. +However, this temptation leads nowhere good, as can be illustrated by +the following, with all variables initially zero: + +<blockquote> +<pre> + 1 void thread0(void) + 2 { + 3 rcu_read_lock(); + 4 WRITE_ONCE(a, 1); + 5 WRITE_ONCE(b, 1); + 6 rcu_read_unlock(); + 7 } + 8 + 9 void thread1(void) +10 { +11 r1 = READ_ONCE(a); +12 synchronize_rcu(); +13 WRITE_ONCE(c, 1); +14 } +15 +16 void thread2(void) +17 { +18 rcu_read_lock(); +19 WRITE_ONCE(d, 1); +20 r2 = READ_ONCE(c); +21 rcu_read_unlock(); +22 } +23 +24 void thread3(void) +25 { +26 r3 = READ_ONCE(d); +27 synchronize_rcu(); +28 WRITE_ONCE(e, 1); +29 } +30 +31 void thread4(void) +32 { +33 rcu_read_lock(); +34 r4 = READ_ONCE(b); +35 r5 = READ_ONCE(e); +36 rcu_read_unlock(); +37 } +</pre> +</blockquote> + +<p> +In this case, the outcome: + +<blockquote> +<pre> +(r1 == 1 && r2 == 1 && r3 == 1 && r4 == 0 && r5 == 1) +</pre> +</blockquote> + +is entirely possible, as illustrated below: + +<p><img src="ReadersPartitionGP1.svg" alt="ReadersPartitionGP1.svg" width="100%"></p> + +<p> +Again, an RCU read-side critical section can overlap almost all of a +given grace period, just so long as it does not overlap the entire +grace period. +As a result, an RCU read-side critical section cannot partition a pair +of RCU grace periods. + +<p><a name="Quick Quiz 10"><b>Quick Quiz 10</b>:</a> +How long a sequence of grace periods, each separated by an RCU read-side +critical section, would be required to partition the RCU read-side +critical sections at the beginning and end of the chain? +<br><a href="#qq10answer">Answer</a> + +<h3><a name="Disabling Preemption Does Not Block Grace Periods"> +Disabling Preemption Does Not Block Grace Periods</a></h3> + +<p> +There was a time when disabling preemption on any given CPU would block +subsequent grace periods. +However, this was an accident of implementation and is not a requirement. +And in the current Linux-kernel implementation, disabling preemption +on a given CPU in fact does not block grace periods, as Oleg Nesterov +<a href="http://marc.info/?l=linux-kernel&m=143431078202914&w=2">demonstrated</a>. + +<p> +If you need a preempt-disable region to block grace periods, you need to add +<tt>rcu_read_lock()</tt> and <tt>rcu_read_unlock()</tt>, for example +as follows: + +<blockquote> +<pre> + 1 preempt_disable(); + 2 rcu_read_lock(); + 3 do_something(); + 4 rcu_read_unlock(); + 5 preempt_enable(); + 6 + 7 /* Spinlocks implicitly disable preemption. */ + 8 spin_lock(&mylock); + 9 rcu_read_lock(); +10 do_something(); +11 rcu_read_unlock(); +12 spin_unlock(&mylock); +</pre> +</blockquote> + +<p> +In theory, you could enter the RCU read-side critical section first, +but it is more efficient to keep the entire RCU read-side critical +section contained in the preempt-disable region as shown above. +Of course, RCU read-side critical sections that extend outside of +preempt-disable regions will work correctly, but such critical sections +can be preempted, which forces <tt>rcu_read_unlock()</tt> to do +more work. +And no, this is <i>not</i> an invitation to enclose all of your RCU +read-side critical sections within preempt-disable regions, because +doing so would degrade real-time response. + +<p> +This non-requirement appeared with preemptible RCU. +If you need a grace period that waits on non-preemptible code regions, use +<a href="#Sched Flavor">RCU-sched</a>. + +<h2><a name="Parallelism Facts of Life">Parallelism Facts of Life</a></h2> + +<p> +These parallelism facts of life are by no means specific to RCU, but +the RCU implementation must abide by them. +They therefore bear repeating: + +<ol> +<li> Any CPU or task may be delayed at any time, + and any attempts to avoid these delays by disabling + preemption, interrupts, or whatever are completely futile. + This is most obvious in preemptible user-level + environments and in virtualized environments (where + a given guest OS's VCPUs can be preempted at any time by + the underlying hypervisor), but can also happen in bare-metal + environments due to ECC errors, NMIs, and other hardware + events. + Although a delay of more than about 20 seconds can result + in splats, the RCU implementation is obligated to use + algorithms that can tolerate extremely long delays, but where + “extremely long” is not long enough to allow + wrap-around when incrementing a 64-bit counter. +<li> Both the compiler and the CPU can reorder memory accesses. + Where it matters, RCU must use compiler directives and + memory-barrier instructions to preserve ordering. +<li> Conflicting writes to memory locations in any given cache line + will result in expensive cache misses. + Greater numbers of concurrent writes and more-frequent + concurrent writes will result in more dramatic slowdowns. + RCU is therefore obligated to use algorithms that have + sufficient locality to avoid significant performance and + scalability problems. +<li> As a rough rule of thumb, only one CPU's worth of processing + may be carried out under the protection of any given exclusive + lock. + RCU must therefore use scalable locking designs. +<li> Counters are finite, especially on 32-bit systems. + RCU's use of counters must therefore tolerate counter wrap, + or be designed such that counter wrap would take way more + time than a single system is likely to run. + An uptime of ten years is quite possible, a runtime + of a century much less so. + As an example of the latter, RCU's dyntick-idle nesting counter + allows 54 bits for interrupt nesting level (this counter + is 64 bits even on a 32-bit system). + Overflowing this counter requires 2<sup>54</sup> + half-interrupts on a given CPU without that CPU ever going idle. + If a half-interrupt happened every microsecond, it would take + 570 years of runtime to overflow this counter, which is currently + believed to be an acceptably long time. +<li> Linux systems can have thousands of CPUs running a single + Linux kernel in a single shared-memory environment. + RCU must therefore pay close attention to high-end scalability. +</ol> + +<p> +This last parallelism fact of life means that RCU must pay special +attention to the preceding facts of life. +The idea that Linux might scale to systems with thousands of CPUs would +have been met with some skepticism in the 1990s, but these requirements +would have otherwise have been unsurprising, even in the early 1990s. + +<h2><a name="Quality-of-Implementation Requirements">Quality-of-Implementation Requirements</a></h2> + +<p> +These sections list quality-of-implementation requirements. +Although an RCU implementation that ignores these requirements could +still be used, it would likely be subject to limitations that would +make it inappropriate for industrial-strength production use. +Classes of quality-of-implementation requirements are as follows: + +<ol> +<li> <a href="#Specialization">Specialization</a> +<li> <a href="#Performance and Scalability">Performance and Scalability</a> +<li> <a href="#Composability">Composability</a> +<li> <a href="#Corner Cases">Corner Cases</a> +</ol> + +<p> +These classes is covered in the following sections. + +<h3><a name="Specialization">Specialization</a></h3> + +<p> +RCU is and always has been intended primarily for read-mostly situations, as +illustrated by the following figure. +This means that RCU's read-side primitives are optimized, often at the +expense of its update-side primitives. + +<p><img src="RCUApplicability.svg" alt="RCUApplicability.svg" width="70%"></p> + +<p> +This focus on read-mostly situations means that RCU must interoperate +with other synchronization primitives. +For example, the <tt>add_gp()</tt> and <tt>remove_gp_synchronous()</tt> +examples discussed earlier use RCU to protect readers and locking to +coordinate updaters. +However, the need extends much farther, requiring that a variety of +synchronization primitives be legal within RCU read-side critical sections, +including spinlocks, sequence locks, atomic operations, reference +counters, and memory barriers. + +<p><a name="Quick Quiz 11"><b>Quick Quiz 11</b>:</a> +What about sleeping locks? +<br><a href="#qq11answer">Answer</a> + +<p> +It often comes as a surprise that many algorithms do not require a +consistent view of data, but many can function in that mode, +with network routing being the poster child. +Internet routing algorithms take significant time to propagate +updates, so that by the time an update arrives at a given system, +that system has been sending network traffic the wrong way for +a considerable length of time. +Having a few threads continue to send traffic the wrong way for a +few more milliseconds is clearly not a problem: In the worst case, +TCP retransmissions will eventually get the data where it needs to go. +In general, when tracking the state of the universe outside of the +computer, some level of inconsistency must be tolerated due to +speed-of-light delays if nothing else. + +<p> +Furthermore, uncertainty about external state is inherent in many cases. +For example, a pair of veternarians might use heartbeat to determine +whether or not a given cat was alive. +But how long should they wait after the last heartbeat to decide that +the cat is in fact dead? +Waiting less than 400 milliseconds makes no sense because this would +mean that a relaxed cat would be considered to cycle between death +and life more than 100 times per minute. +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. +One of our pair of veternarians might wait 30 seconds before pronouncing +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 final 30 seconds of the minute following the last heartbeat, as +fancifully illustrated below: + +<p><img src="2013-08-is-it-dead.png" alt="2013-08-is-it-dead.png" width="431"></p> + +<p> +Interestingly enough, this same situation applies to hardware. +When push comes to shove, how do we tell whether or not some +external server has failed? +We send messages to it periodically, and declare it failed if we +don't receive a response within a given period of time. +Policy decisions can usually tolerate short +periods of inconsistency. +The policy was decided some time ago, and is only now being put into +effect, so a few milliseconds of delay is normally inconsequential. + +<p> +However, there are algorithms that absolutely must see consistent data. +For example, the translation between a user-level SystemV semaphore +ID to the corresponding in-kernel data structure is protected by RCU, +but it is absolutely forbidden to update a semaphore that has just been +removed. +In the Linux kernel, this need for consistency is accommodated by acquiring +spinlocks located in the in-kernel data structure from within +the RCU read-side critical section, and this is indicated by the +green box in the figure above. +Many other techniques may be used, and are in fact used within the +Linux kernel. + +<p> +In short, RCU is not required to maintain consistency, and other +mechanisms may be used in concert with RCU when consistency is required. +RCU's specialization allows it to do its job extremely well, and its +ability to interoperate with other synchronization mechanisms allows +the right mix of synchronization tools to be used for a given job. + +<h3><a name="Performance and Scalability">Performance and Scalability</a></h3> + +<p> +Energy efficiency is a critical component of performance today, +and Linux-kernel RCU implementations must therefore avoid unnecessarily +awakening idle CPUs. +I cannot claim that this requirement was premeditated. +In fact, I learned of it during a telephone conversation in which I +was given “frank and open” feedback on the importance +of energy efficiency in battery-powered systems and on specific +energy-efficiency shortcomings of the Linux-kernel RCU implementation. +In my experience, the battery-powered embedded community will consider +any unnecessary wakeups to be extremely unfriendly acts. +So much so that mere Linux-kernel-mailing-list posts are +insufficient to vent their ire. + +<p> +Memory consumption is not particularly important for in most +situations, and has become decreasingly +so as memory sizes have expanded and memory +costs have plummeted. +However, as I learned from Matt Mackall's +<a href="http://elinux.org/Linux_Tiny-FAQ">bloatwatch</a> +efforts, memory footprint is critically important on single-CPU systems with +non-preemptible (<tt>CONFIG_PREEMPT=n</tt>) kernels, and thus +<a href="http://lkml.org/lkml/2009/1/14/449">tiny RCU</a> +was born. +Josh Triplett has since taken over the small-memory banner with his +<a href="https://tiny.wiki.kernel.org/">Linux kernel tinification</a> +project, which resulted in +<a href="#Sleepable RCU">SRCU</a> +becoming optional for those kernels not needing it. + +<p> +The remaining performance requirements are, for the most part, +unsurprising. +For example, in keeping with RCU's read-side specialization, +<tt>rcu_dereference()</tt> should have negligible overhead (for +example, suppression of a few minor compiler optimizations). +Similarly, in non-preemptible environments, <tt>rcu_read_lock()</tt> and +<tt>rcu_read_unlock()</tt> should have exactly zero overhead. + +<p> +In preemptible environments, in the case where the RCU read-side +critical section was not preempted (as will be the case for the +highest-priority real-time process), <tt>rcu_read_lock()</tt> and +<tt>rcu_read_unlock()</tt> should have minimal overhead. +In particular, they should not contain atomic read-modify-write +operations, memory-barrier instructions, preemption disabling, +interrupt disabling, or backwards branches. +However, in the case where the RCU read-side critical section was preempted, +<tt>rcu_read_unlock()</tt> may acquire spinlocks and disable interrupts. +This is why it is better to nest an RCU read-side critical section +within a preempt-disable region than vice versa, at least in cases +where that critical section is short enough to avoid unduly degrading +real-time latencies. + +<p> +The <tt>synchronize_rcu()</tt> grace-period-wait primitive is +optimized for throughput. +It may therefore incur several milliseconds of latency in addition to +the duration of the longest RCU read-side critical section. +On the other hand, multiple concurrent invocations of +<tt>synchronize_rcu()</tt> are required to use batching optimizations +so that they can be satisfied by a single underlying grace-period-wait +operation. +For example, in the Linux kernel, it is not unusual for a single +grace-period-wait operation to serve more than +<a href="https://www.usenix.org/conference/2004-usenix-annual-technical-conference/making-rcu-safe-deep-sub-millisecond-response">1,000 separate invocations</a> +of <tt>synchronize_rcu()</tt>, thus amortizing the per-invocation +overhead down to nearly zero. +However, the grace-period optimization is also required to avoid +measurable degradation of real-time scheduling and interrupt latencies. + +<p> +In some cases, the multi-millisecond <tt>synchronize_rcu()</tt> +latencies are unacceptable. +In these cases, <tt>synchronize_rcu_expedited()</tt> may be used +instead, reducing the grace-period latency down to a few tens of +microseconds on small systems, at least in cases where the RCU read-side +critical sections are short. +There are currently no special latency requirements for +<tt>synchronize_rcu_expedited()</tt> on large systems, but, +consistent with the empirical nature of the RCU specification, +that is subject to change. +However, there most definitely are scalability requirements: +A storm of <tt>synchronize_rcu_expedited()</tt> invocations on 4096 +CPUs should at least make reasonable forward progress. +In return for its shorter latencies, <tt>synchronize_rcu_expedited()</tt> +is permitted to impose modest degradation of real-time latency +on non-idle online CPUs. +That said, it will likely be necessary to take further steps to reduce this +degradation, hopefully to roughly that of a scheduling-clock interrupt. + +<p> +There are a number of situations where even +<tt>synchronize_rcu_expedited()</tt>'s reduced grace-period +latency is unacceptable. +In these situations, the asynchronous <tt>call_rcu()</tt> can be +used in place of <tt>synchronize_rcu()</tt> as follows: + +<blockquote> +<pre> + 1 struct foo { + 2 int a; + 3 int b; + 4 struct rcu_head rh; + 5 }; + 6 + 7 static void remove_gp_cb(struct rcu_head *rhp) + 8 { + 9 struct foo *p = container_of(rhp, struct foo, rh); +10 +11 kfree(p); +12 } +13 +14 bool remove_gp_asynchronous(void) +15 { +16 struct foo *p; +17 +18 spin_lock(&gp_lock); +19 p = rcu_dereference(gp); +20 if (!p) { +21 spin_unlock(&gp_lock); +22 return false; +23 } +24 rcu_assign_pointer(gp, NULL); +25 call_rcu(&p->rh, remove_gp_cb); +26 spin_unlock(&gp_lock); +27 return true; +28 } +</pre> +</blockquote> + +<p> +A definition of <tt>struct foo</tt> is finally needed, and appears +on lines 1-5. +The function <tt>remove_gp_cb()</tt> is passed to <tt>call_rcu()</tt> +on line 25, and will be invoked after the end of a subsequent +grace period. +This gets the same effect as <tt>remove_gp_synchronous()</tt>, +but without forcing the updater to wait for a grace period to elapse. +The <tt>call_rcu()</tt> function may be used in a number of +situations where neither <tt>synchronize_rcu()</tt> nor +<tt>synchronize_rcu_expedited()</tt> would be legal, +including within preempt-disable code, <tt>local_bh_disable()</tt> code, +interrupt-disable code, and interrupt handlers. +However, even <tt>call_rcu()</tt> is illegal within NMI handlers. +The callback function (<tt>remove_gp_cb()</tt> in this case) will be +executed within softirq (software interrupt) environment within the +Linux kernel, +either within a real softirq handler or under the protection +of <tt>local_bh_disable()</tt>. +In both the Linux kernel and in userspace, it is bad practice to +write an RCU callback function that takes too long. +Long-running operations should be relegated to separate threads or +(in the Linux kernel) workqueues. + +<p><a name="Quick Quiz 12"><b>Quick Quiz 12</b>:</a> +Why does line 19 use <tt>rcu_access_pointer()</tt>? +After all, <tt>call_rcu()</tt> on line 25 stores into the +structure, which would interact badly with concurrent insertions. +Doesn't this mean that <tt>rcu_dereference()</tt> is required? +<br><a href="#qq12answer">Answer</a> + +<p> +However, all that <tt>remove_gp_cb()</tt> is doing is +invoking <tt>kfree()</tt> on the data element. +This is a common idiom, and is supported by <tt>kfree_rcu()</tt>, +which allows “fire and forget” operation as shown below: + +<blockquote> +<pre> + 1 struct foo { + 2 int a; + 3 int b; + 4 struct rcu_head rh; + 5 }; + 6 + 7 bool remove_gp_faf(void) + 8 { + 9 struct foo *p; +10 +11 spin_lock(&gp_lock); +12 p = rcu_dereference(gp); +13 if (!p) { +14 spin_unlock(&gp_lock); +15 return false; +16 } +17 rcu_assign_pointer(gp, NULL); +18 kfree_rcu(p, rh); +19 spin_unlock(&gp_lock); +20 return true; +21 } +</pre> +</blockquote> + +<p> +Note that <tt>remove_gp_faf()</tt> simply invokes +<tt>kfree_rcu()</tt> and proceeds, without any need to pay any +further attention to the subsequent grace period and <tt>kfree()</tt>. +It is permissible to invoke <tt>kfree_rcu()</tt> from the same +environments as for <tt>call_rcu()</tt>. +Interestingly enough, DYNIX/ptx had the equivalents of +<tt>call_rcu()</tt> and <tt>kfree_rcu()</tt>, but not +<tt>synchronize_rcu()</tt>. +This was due to the fact that RCU was not heavily used within DYNIX/ptx, +so the very few places that needed something like +<tt>synchronize_rcu()</tt> simply open-coded it. + +<p><a name="Quick Quiz 13"><b>Quick Quiz 13</b>:</a> +Earlier it was claimed that <tt>call_rcu()</tt> and +<tt>kfree_rcu()</tt> allowed updaters to avoid being blocked +by readers. +But how can that be correct, given that the invocation of the callback +and the freeing of the memory (respectively) must still wait for +a grace period to elapse? +<br><a href="#qq13answer">Answer</a> + +<p> +But what if the updater must wait for the completion of code to be +executed after the end of the grace period, but has other tasks +that can be carried out in the meantime? +The polling-style <tt>get_state_synchronize_rcu()</tt> and +<tt>cond_synchronize_rcu()</tt> functions may be used for this +purpose, as shown below: + +<blockquote> +<pre> + 1 bool remove_gp_poll(void) + 2 { + 3 struct foo *p; + 4 unsigned long s; + 5 + 6 spin_lock(&gp_lock); + 7 p = rcu_access_pointer(gp); + 8 if (!p) { + 9 spin_unlock(&gp_lock); +10 return false; +11 } +12 rcu_assign_pointer(gp, NULL); +13 spin_unlock(&gp_lock); +14 s = get_state_synchronize_rcu(); +15 do_something_while_waiting(); +16 cond_synchronize_rcu(s); +17 kfree(p); +18 return true; +19 } +</pre> +</blockquote> + +<p> +On line 14, <tt>get_state_synchronize_rcu()</tt> obtains a +“cookie” from RCU, +then line 15 carries out other tasks, +and finally, line 16 returns immediately if a grace period has +elapsed in the meantime, but otherwise waits as required. +The need for <tt>get_state_synchronize_rcu</tt> and +<tt>cond_synchronize_rcu()</tt> has appeared quite recently, +so it is too early to tell whether they will stand the test of time. + +<p> +RCU thus provides a range of tools to allow updaters to strike the +required tradeoff between latency, flexibility and CPU overhead. + +<h3><a name="Composability">Composability</a></h3> + +<p> +Composability has received much attention in recent years, perhaps in part +due to the collision of multicore hardware with object-oriented techniques +designed in single-threaded environments for single-threaded use. +And in theory, RCU read-side critical sections may be composed, and in +fact may be nested arbitrarily deeply. +In practice, as with all real-world implementations of composable +constructs, there are limitations. + +<p> +Implementations of RCU for which <tt>rcu_read_lock()</tt> +and <tt>rcu_read_unlock()</tt> generate no code, such as +Linux-kernel RCU when <tt>CONFIG_PREEMPT=n</tt>, can be +nested arbitrarily deeply. +After all, there is no overhead. +Except that if all these instances of <tt>rcu_read_lock()</tt> +and <tt>rcu_read_unlock()</tt> are visible to the compiler, +compilation will eventually fail due to exhausting memory, +mass storage, or user patience, whichever comes first. +If the nesting is not visible to the compiler, as is the case with +mutually recursive functions each in its own translation unit, +stack overflow will result. +If the nesting takes the form of loops, either the control variable +will overflow or (in the Linux kernel) you will get an RCU CPU stall warning. +Nevertheless, this class of RCU implementations is one +of the most composable constructs in existence. + +<p> +RCU implementations that explicitly track nesting depth +are limited by the nesting-depth counter. +For example, the Linux kernel's preemptible RCU limits nesting to +<tt>INT_MAX</tt>. +This should suffice for almost all practical purposes. +That said, a consecutive pair of RCU read-side critical sections +between which there is an operation that waits for a grace period +cannot be enclosed in another RCU read-side critical section. +This is because it is not legal to wait for a grace period within +an RCU read-side critical section: To do so would result either +in deadlock or +in RCU implicitly splitting the enclosing RCU read-side critical +section, neither of which is conducive to a long-lived and prosperous +kernel. + +<p> +In short, although RCU read-side critical sections are highly composable, +care is required in some situations, just as is the case for any other +composable synchronization mechanism. + +<h3><a name="Corner Cases">Corner Cases</a></h3> + +<p> +A given RCU workload might have an endless and intense stream of +RCU read-side critical sections, perhaps even so intense that there +was never a point in time during which there was not at least one +RCU read-side critical section in flight. +RCU cannot allow this situation to block grace periods: As long as +all the RCU read-side critical sections are finite, grace periods +must also be finite. + +<p> +That said, preemptible RCU implementations could potentially result +in RCU read-side critical sections being preempted for long durations, +which has the effect of creating a long-duration RCU read-side +critical section. +This situation can arise only in heavily loaded systems, but systems using +real-time priorities are of course more vulnerable. +Therefore, RCU priority boosting is provided to help deal with this +case. +That said, the exact requirements on RCU priority boosting will likely +evolve as more experience accumulates. + +<p> +Other workloads might have very high update rates. +Although one can argue that such workloads should instead use +something other than RCU, the fact remains that RCU must +handle such workloads gracefully. +This requirement is another factor driving batching of grace periods, +but it is also the driving force behind the checks for large numbers +of queued RCU callbacks in the <tt>call_rcu()</tt> code path. +Finally, high update rates should not delay RCU read-side critical +sections, although some read-side delays can occur when using +<tt>synchronize_rcu_expedited()</tt>, courtesy of this function's use +of <tt>try_stop_cpus()</tt>. +(In the future, <tt>synchronize_rcu_expedited()</tt> will be +converted to use lighter-weight inter-processor interrupts (IPIs), +but this will still disturb readers, though to a much smaller degree.) + +<p> +Although all three of these corner cases were understood in the early +1990s, a simple user-level test consisting of <tt>close(open(path))</tt> +in a tight loop +in the early 2000s suddenly provided a much deeper appreciation of the +high-update-rate corner case. +This test also motivated addition of some RCU code to react to high update +rates, for example, if a given CPU finds itself with more than 10,000 +RCU callbacks queued, it will cause RCU to take evasive action by +more aggressively starting grace periods and more aggressively forcing +completion of grace-period processing. +This evasive action causes the grace period to complete more quickly, +but at the cost of restricting RCU's batching optimizations, thus +increasing the CPU overhead incurred by that grace period. + +<h2><a name="Software-Engineering Requirements"> +Software-Engineering Requirements</a></h2> + +<p> +Between Murphy's Law and “To err is human”, it is necessary to +guard against mishaps and misuse: + +<ol> +<li> It is all too easy to forget to use <tt>rcu_read_lock()</tt> + everywhere that it is needed, so kernels built with + <tt>CONFIG_PROVE_RCU=y</tt> will spat if + <tt>rcu_dereference()</tt> is used outside of an + RCU read-side critical section. + Update-side code can use <tt>rcu_dereference_protected()</tt>, + which takes a + <a href="https://lwn.net/Articles/371986/">lockdep expression</a> + to indicate what is providing the protection. + If the indicated protection is not provided, a lockdep splat + is emitted. + + <p> + Code shared between readers and updaters can use + <tt>rcu_dereference_check()</tt>, which also takes a + lockdep expression, and emits a lockdep splat if neither + <tt>rcu_read_lock()</tt> nor the indicated protection + is in place. + In addition, <tt>rcu_dereference_raw()</tt> is used in those + (hopefully rare) cases where the required protection cannot + be easily described. + Finally, <tt>rcu_read_lock_held()</tt> is provided to + allow a function to verify that it has been invoked within + an RCU read-side critical section. + I was made aware of this set of requirements shortly after Thomas + Gleixner audited a number of RCU uses. +<li> A given function might wish to check for RCU-related preconditions + upon entry, before using any other RCU API. + The <tt>rcu_lockdep_assert()</tt> does this job, + asserting the expression in kernels having lockdep enabled + and doing nothing otherwise. +<li> It is also easy to forget to use <tt>rcu_assign_pointer()</tt> + and <tt>rcu_dereference()</tt>, perhaps (incorrectly) + substituting a simple assignment. + To catch this sort of error, a given RCU-protected pointer may be + tagged with <tt>__rcu</tt>, after which running sparse + with <tt>CONFIG_SPARSE_RCU_POINTER=y</tt> will complain + about simple-assignment accesses to that pointer. + Arnd Bergmann made me aware of this requirement, and also + supplied the needed + <a href="http://lwn.net/Articles/376011/">patch series</a>. +<li> Kernels built with <tt>CONFIG_DEBUG_OBJECTS_RCU_HEAD=y</tt> + will splat if a data element is passed to <tt>call_rcu()</tt> + twice in a row, without a grace period in between. + (This error is similar to a double free.) + The corresponding <tt>rcu_head</tt> structures that are + dynamically allocated are automatically tracked, but + <tt>rcu_head</tt> structures allocated on the stack + must be initialized with <tt>init_rcu_head_on_stack()</tt> + and cleaned up with <tt>destroy_rcu_head_on_stack()</tt>. + Similarly, statically allocated non-stack <tt>rcu_head</tt> + structures must be initialized with <tt>init_rcu_head()</tt> + and cleaned up with <tt>destroy_rcu_head()</tt>. + Mathieu Desnoyers made me aware of this requirement, and also + supplied the needed + <a href="https://lkml.org/lkml/2010/3/18/417">patch</a>. +<li> An infinite loop in an RCU read-side critical section will + eventually trigger an RCU CPU stall warning splat. + However, RCU is not obligated to produce this splat + unless there is a grace period waiting on that particular + RCU read-side critical section. + This requirement made itself known in the early 1990s, pretty + much the first time that it was necessary to debug a CPU stall. +<li> Although it would be very good to detect pointers leaking out + of RCU read-side critical sections, there is currently no + good way of doing this. + One complication is the need to distinguish between pointers + leaking and pointers that have been handed off from RCU to + some other synchronization mechanism, for example, reference + counting. +<li> In kernels built with <tt>CONFIG_RCU_TRACE=y</tt>, RCU-related + information is provided via both debugfs and event tracing. +<li> Open-coded use of <tt>rcu_assign_pointer()</tt> and + <tt>rcu_dereference()</tt> to create typical linked + data structures can be surprisingly error-prone. + Therefore, RCU-protected + <a href="http://lwn.net/Articles/609973/#RCU List APIs">linked lists</a> + and, more recently, RCU-protected + <a href="https://lwn.net/Articles/612100/">hash tables</a> + are available. + Many other special-purpose RCU-protected data structures are + available in the Linux kernel and the userspace RCU library. +<li> Some linked structures are created at compile time, but still + require <tt>__rcu</tt> checking. + The <tt>RCU_POINTER_INITIALIZER()</tt> macro serves this + purpose. +<li> It is not necessary to use <tt>rcu_assign_pointer()</tt> + when creating linked structures that are to be published via + a single external pointer. + The <tt>RCU_INIT_POINTER()</tt> macro is provided for + this task and also for assigning <tt>NULL</tt> pointers + at runtime. +</ol> + +<p> +This not a hard-and-fast list: RCU's diagnostic capabilities will +continue to be guided by the number and type of usage bugs found +in real-world RCU usage. + +<h2><a name="Linux Kernel Complications">Linux Kernel Complications</a></h2> + +<p> +The Linux kernel provides an interesting environment for all kinds of +software, including RCU. +Some of the relevant points of interest are as follows: + +<ol> +<li> <a href="#Configuration">Configuration</a>. +<li> <a href="#Firmware Interface">Firmware Interface</a>. +<li> <a href="#Early Boot">Early Boot</a>. +<li> <a href="#Interrupts and NMIs"> + Interrupts and non-maskable interrupts (NMIs)</a>. +<li> <a href="#Loadable Modules">Loadable Modules</a>. +<li> <a href="#Hotplug CPU">Hotplug CPU</a>. +<li> <a href="#Scheduler and RCU">Scheduler and RCU</a>. +<li> <a href="#Tracing and RCU">Tracing and RCU</a>. +<li> <a href="#Energy Efficiency">Energy Efficiency</a>. +<li> <a href="#Performance, Scalability, Response Time, and Reliability"> + Performance, Scalability, Response Time, and Reliability</a>. +</ol> + +<p> +This list is probably incomplete, but it does give a feel for the +most notable Linux-kernel complications. +Each of the following sections covers one of the above topics. + +<h3><a name="Configuration">Configuration</a></h3> + +<p> +RCU's goal is automatic configuration, so that almost nobody +needs to worry about RCU's <tt>Kconfig</tt> options. +And for almost all users, RCU does in fact work well +“out of the box.” + +<p> +However, there are specialized use cases that are handled by +kernel boot parameters and <tt>Kconfig</tt> options. +Unfortunately, the <tt>Kconfig</tt> system will explicitly ask users +about new <tt>Kconfig</tt> options, which requires almost all of them +be hidden behind a <tt>CONFIG_RCU_EXPERT</tt> <tt>Kconfig</tt> option. + +<p> +This all should be quite obvious, but the fact remains that +Linus Torvalds recently had to +<a href="http://marc.info/?l=linux-kernel&m=142905739823385">remind</a> +me of this requirement. + +<h3><a name="Firmware Interface">Firmware Interface</a></h3> + +<p> +In many cases, kernel obtains information about the system from the +firmware, and sometimes things are lost in translation. +Or the translation is accurate, but the original message is bogus. + +<p> +For example, some systems' firmware overreports the number of CPUs, +sometimes by a large factor. +If RCU naively believed the firmware, as it used to do, +it would create too many per-CPU kthreads. +Although the resulting system will still run correctly, the extra +kthreads needlessly consume memory and can cause confusion +when they show up in <tt>ps</tt> listings. + +<p> +RCU must therefore wait for a given CPU to actually come online before +it can allow itself to believe that the CPU actually exists. +The resulting “ghost CPUs” (which are never going to +come online) cause a number of +<a href="http://paulmck.livejournal.com/37494.html">interesting complications</a>. + +<h3><a name="Early Boot">Early Boot</a></h3> + +<p> +The Linux kernel's boot sequence is an interesting process, +and RCU is used early, even before <tt>rcu_init()</tt> +is invoked. +In fact, a number of RCU's primitives can be used as soon as the +initial task's <tt>task_struct</tt> is available and the +boot CPU's per-CPU variables are set up. +The read-side primitives (<tt>rcu_read_lock()</tt>, +<tt>rcu_read_unlock()</tt>, <tt>rcu_dereference()</tt>, +and <tt>rcu_access_pointer()</tt>) will operate normally very early on, +as will <tt>rcu_assign_pointer()</tt>. + +<p> +Although <tt>call_rcu()</tt> may be invoked at any +time during boot, callbacks are not guaranteed to be invoked until after +the scheduler is fully up and running. +This delay in callback invocation is due to the fact that RCU does not +invoke callbacks until it is fully initialized, and this full initialization +cannot occur until after the scheduler has initialized itself to the +point where RCU can spawn and run its kthreads. +In theory, it would be possible to invoke callbacks earlier, +however, this is not a panacea because there would be severe restrictions +on what operations those callbacks could invoke. + +<p> +Perhaps surprisingly, <tt>synchronize_rcu()</tt>, +<a href="#Bottom-Half Flavor"><tt>synchronize_rcu_bh()</tt></a> +(<a href="#Bottom-Half Flavor">discussed below</a>), +and +<a href="#Sched Flavor"><tt>synchronize_sched()</tt></a> +will all operate normally +during very early boot, the reason being that there is only one CPU +and preemption is disabled. +This means that the call <tt>synchronize_rcu()</tt> (or friends) +itself is a quiescent +state and thus a grace period, so the early-boot implementation can +be a no-op. + +<p> +Both <tt>synchronize_rcu_bh()</tt> and <tt>synchronize_sched()</tt> +continue to operate normally through the remainder of boot, courtesy +of the fact that preemption is disabled across their RCU read-side +critical sections and also courtesy of the fact that there is still +only one CPU. +However, once the scheduler starts initializing, preemption is enabled. +There is still only a single CPU, but the fact that preemption is enabled +means that the no-op implementation of <tt>synchronize_rcu()</tt> no +longer works in <tt>CONFIG_PREEMPT=y</tt> kernels. +Therefore, as soon as the scheduler starts initializing, the early-boot +fastpath is disabled. +This means that <tt>synchronize_rcu()</tt> switches to its runtime +mode of operation where it posts callbacks, which in turn means that +any call to <tt>synchronize_rcu()</tt> will block until the corresponding +callback is invoked. +Unfortunately, the callback cannot be invoked until RCU's runtime +grace-period machinery is up and running, which cannot happen until +the scheduler has initialized itself sufficiently to allow RCU's +kthreads to be spawned. +Therefore, invoking <tt>synchronize_rcu()</tt> during scheduler +initialization can result in deadlock. + +<p><a name="Quick Quiz 14"><b>Quick Quiz 14</b>:</a> +So what happens with <tt>synchronize_rcu()</tt> during +scheduler initialization for <tt>CONFIG_PREEMPT=n</tt> +kernels? +<br><a href="#qq14answer">Answer</a> + +<p> +I learned of these boot-time requirements as a result of a series of +system hangs. + +<h3><a name="Interrupts and NMIs">Interrupts and NMIs</a></h3> + +<p> +The Linux kernel has interrupts, and RCU read-side critical sections are +legal within interrupt handlers and within interrupt-disabled regions +of code, as are invocations of <tt>call_rcu()</tt>. + +<p> +Some Linux-kernel architectures can enter an interrupt handler from +non-idle process context, and then just never leave it, instead stealthily +transitioning back to process context. +This trick is sometimes used to invoke system calls from inside the kernel. +These “half-interrupts” mean that RCU has to be very careful +about how it counts interrupt nesting levels. +I learned of this requirement the hard way during a rewrite +of RCU's dyntick-idle code. + +<p> +The Linux kernel has non-maskable interrupts (NMIs), and +RCU read-side critical sections are legal within NMI handlers. +Thankfully, RCU update-side primitives, including +<tt>call_rcu()</tt>, are prohibited within NMI handlers. + +<p> +The name notwithstanding, some Linux-kernel architectures +can have nested NMIs, which RCU must handle correctly. +Andy Lutomirski +<a href="https://lkml.org/lkml/2014/11/21/642">surprised me</a> +with this requirement; +he also kindly surprised me with +<a href="https://lkml.org/lkml/2014/11/22/1">an algorithm</a> +that meets this requirement. + +<h3><a name="Loadable Modules">Loadable Modules</a></h3> + +<p> +The Linux kernel has loadable modules, and these modules can +also be unloaded. +After a given module has been unloaded, any attempt to call +one of its functions results in a segmentation fault. +The module-unload functions must therefore cancel any +delayed calls to loadable-module functions, for example, +any outstanding <tt>mod_timer()</tt> must be dealt with +via <tt>del_timer_sync()</tt> or similar. + +<p> +Unfortunately, there is no way to cancel an RCU callback; +once you invoke <tt>call_rcu()</tt>, the callback function is +going to eventually be invoked, unless the system goes down first. +Because it is normally considered socially irresponsible to crash the system +in response to a module unload request, we need some other way +to deal with in-flight RCU callbacks. + +<p> +RCU therefore provides +<tt><a href="http://lwn.net/Articles/217484/">rcu_barrier()</a></tt>, +which waits until all in-flight RCU callbacks have been invoked. +If a module uses <tt>call_rcu()</tt>, its exit function should therefore +prevent any future invocation of <tt>call_rcu()</tt>, then invoke +<tt>rcu_barrier()</tt>. +In theory, the underlying module-unload code could invoke +<tt>rcu_barrier()</tt> unconditionally, but in practice this would +incur unacceptable latencies. + +<p> +Nikita Danilov noted this requirement for an analogous filesystem-unmount +situation, and Dipankar Sarma incorporated <tt>rcu_barrier()</tt> into RCU. +The need for <tt>rcu_barrier()</tt> for module unloading became +apparent later. + +<h3><a name="Hotplug CPU">Hotplug CPU</a></h3> + +<p> +The Linux kernel supports CPU hotplug, which means that CPUs +can come and go. +It is of course illegal to use any RCU API member from an offline CPU. +This requirement was present from day one in DYNIX/ptx, but +on the other hand, the Linux kernel's CPU-hotplug implementation +is “interesting.” + +<p> +The Linux-kernel CPU-hotplug implementation has notifiers that +are used to allow the various kernel subsystems (including RCU) +to respond appropriately to a given CPU-hotplug operation. +Most RCU operations may be invoked from CPU-hotplug notifiers, +including even normal synchronous grace-period operations +such as <tt>synchronize_rcu()</tt>. +However, expedited grace-period operations such as +<tt>synchronize_rcu_expedited()</tt> are not supported, +due to the fact that current implementations block CPU-hotplug +operations, which could result in deadlock. + +<p> +In addition, all-callback-wait operations such as +<tt>rcu_barrier()</tt> are also not supported, due to the +fact that there are phases of CPU-hotplug operations where +the outgoing CPU's callbacks will not be invoked until after +the CPU-hotplug operation ends, which could also result in deadlock. + +<h3><a name="Scheduler and RCU">Scheduler and RCU</a></h3> + +<p> +RCU depends on the scheduler, and the scheduler uses RCU to +protect some of its data structures. +This means the scheduler is forbidden from acquiring +the runqueue locks and the priority-inheritance locks +in the middle of an outermost RCU read-side critical section unless +it also releases them before exiting that same +RCU read-side critical section. +This same prohibition also applies to any lock that is acquired +while holding any lock to which this prohibition applies. +Violating this rule results in deadlock. + +<p> +For RCU's part, the preemptible-RCU <tt>rcu_read_unlock()</tt> +implementation must be written carefully to avoid similar deadlocks. +In particular, <tt>rcu_read_unlock()</tt> must tolerate an +interrupt where the interrupt handler invokes both +<tt>rcu_read_lock()</tt> and <tt>rcu_read_unlock()</tt>. +This possibility requires <tt>rcu_read_unlock()</tt> to use +negative nesting levels to avoid destructive recursion via +interrupt handler's use of RCU. + +<p> +This pair of mutual scheduler-RCU requirements came as a +<a href="http://lwn.net/Articles/453002/">complete surprise</a>. + +<p> +As noted above, RCU makes use of kthreads, and it is necessary to +avoid excessive CPU-time accumulation by these kthreads. +This requirement was no surprise, but RCU's violation of it +when running context-switch-heavy workloads when built with +<tt>CONFIG_NO_HZ_FULL=y</tt> +<a href="http://www.rdrop.com/users/paulmck/scalability/paper/BareMetal.2015.01.15b.pdf">did come as a surprise [PDF]</a>. +RCU has made good progress towards meeting this requirement, even +for context-switch-have <tt>CONFIG_NO_HZ_FULL=y</tt> workloads, +but there is room for further improvement. + +<h3><a name="Tracing and RCU">Tracing and RCU</a></h3> + +<p> +It is possible to use tracing on RCU code, but tracing itself +uses RCU. +For this reason, <tt>rcu_dereference_raw_notrace()</tt> +is provided for use by tracing, which avoids the destructive +recursion that could otherwise ensue. +This API is also used by virtualization in some architectures, +where RCU readers execute in environments in which tracing +cannot be used. +The tracing folks both located the requirement and provided the +needed fix, so this surprise requirement was relatively painless. + +<h3><a name="Energy Efficiency">Energy Efficiency</a></h3> + +<p> +Interrupting idle CPUs is considered socially unacceptable, +especially by people with battery-powered embedded systems. +RCU therefore conserves energy by detecting which CPUs are +idle, including tracking CPUs that have been interrupted from idle. +This is a large part of the energy-efficiency requirement, +so I learned of this via an irate phone call. + +<p> +Because RCU avoids interrupting idle CPUs, it is illegal to +execute an RCU read-side critical section on an idle CPU. +(Kernels built with <tt>CONFIG_PROVE_RCU=y</tt> will splat +if you try it.) +The <tt>RCU_NONIDLE()</tt> macro and <tt>_rcuidle</tt> +event tracing is provided to work around this restriction. +In addition, <tt>rcu_is_watching()</tt> may be used to +test whether or not it is currently legal to run RCU read-side +critical sections on this CPU. +I learned of the need for diagnostics on the one hand +and <tt>RCU_NONIDLE()</tt> on the other while inspecting +idle-loop code. +Steven Rostedt supplied <tt>_rcuidle</tt> event tracing, +which is used quite heavily in the idle loop. + +<p> +It is similarly socially unacceptable to interrupt an +<tt>nohz_full</tt> CPU running in userspace. +RCU must therefore track <tt>nohz_full</tt> userspace +execution. +And in +<a href="https://lwn.net/Articles/558284/"><tt>CONFIG_NO_HZ_FULL_SYSIDLE=y</tt></a> +kernels, RCU must separately track idle CPUs on the one hand and +CPUs that are either idle or executing in userspace on the other. +In both cases, RCU must be able to sample state at two points in +time, and be able to determine whether or not some other CPU spent +any time idle and/or executing in userspace. + +<p> +These energy-efficiency requirements have proven quite difficult to +understand and to meet, for example, there have been more than five +clean-sheet rewrites of RCU's energy-efficiency code, the last of +which was finally able to demonstrate +<a href="http://www.rdrop.com/users/paulmck/realtime/paper/AMPenergy.2013.04.19a.pdf">real energy savings running on real hardware [PDF]</a>. +As noted earlier, +I learned of many of these requirements via angry phone calls: +Flaming me on the Linux-kernel mailing list was apparently not +sufficient to fully vent their ire at RCU's energy-efficiency bugs! + +<h3><a name="Performance, Scalability, Response Time, and Reliability"> +Performance, Scalability, Response Time, and Reliability</a></h3> + +<p> +Expanding on the +<a href="#Performance and Scalability">earlier discussion</a>, +RCU is used heavily by hot code paths in performance-critical +portions of the Linux kernel's networking, security, virtualization, +and scheduling code paths. +RCU must therefore use efficient implementations, especially in its +read-side primitives. +To that end, it would be good if preemptible RCU's implementation +of <tt>rcu_read_lock()</tt> could be inlined, however, doing +this requires resolving <tt>#include</tt> issues with the +<tt>task_struct</tt> structure. + +<p> +The Linux kernel supports hardware configurations with up to +4096 CPUs, which means that RCU must be extremely scalable. +Algorithms that involve frequent acquisitions of global locks or +frequent atomic operations on global variables simply cannot be +tolerated within the RCU implementation. +RCU therefore makes heavy use of a combining tree based on the +<tt>rcu_node</tt> structure. +RCU is required to tolerate all CPUs continuously invoking any +combination of RCU's runtime primitives with minimal per-operation +overhead. +In fact, in many cases, increasing load must <i>decrease</i> the +per-operation overhead, witness the batching optimizations for +<tt>synchronize_rcu()</tt>, <tt>call_rcu()</tt>, +<tt>synchronize_rcu_expedited()</tt>, and <tt>rcu_barrier()</tt>. +As a general rule, RCU must cheerfully accept whatever the +rest of the Linux kernel decides to throw at it. + +<p> +The Linux kernel is used for real-time workloads, especially +in conjunction with the +<a href="https://rt.wiki.kernel.org/index.php/Main_Page">-rt patchset</a>. +The real-time-latency response requirements are such that the +traditional approach of disabling preemption across RCU +read-side critical sections is inappropriate. +Kernels built with <tt>CONFIG_PREEMPT=y</tt> therefore +use an RCU implementation that allows RCU read-side critical +sections to be preempted. +This requirement made its presence known after users made it +clear that an earlier +<a href="http://lwn.net/Articles/107930/">real-time patch</a> +did not meet their needs, in conjunction with some +<a href="https://lkml.org/lkml/2005/3/17/199">RCU issues</a> +encountered by a very early version of the -rt patchset. + +<p> +In addition, RCU must make do with a sub-100-microsecond real-time latency +budget. +In fact, on smaller systems with the -rt patchset, the Linux kernel +provides sub-20-microsecond real-time latencies for the whole kernel, +including RCU. +RCU's scalability and latency must therefore be sufficient for +these sorts of configurations. +To my surprise, the sub-100-microsecond real-time latency budget +<a href="http://www.rdrop.com/users/paulmck/realtime/paper/bigrt.2013.01.31a.LCA.pdf"> +applies to even the largest systems [PDF]</a>, +up to and including systems with 4096 CPUs. +This real-time requirement motivated the grace-period kthread, which +also simplified handling of a number of race conditions. + +<p> +Finally, RCU's status as a synchronization primitive means that +any RCU failure can result in arbitrary memory corruption that can be +extremely difficult to debug. +This means that RCU must be extremely reliable, which in +practice also means that RCU must have an aggressive stress-test +suite. +This stress-test suite is called <tt>rcutorture</tt>. + +<p> +Although the need for <tt>rcutorture</tt> was no surprise, +the current immense popularity of the Linux kernel is posing +interesting—and perhaps unprecedented—validation +challenges. +To see this, keep in mind that there are well over one billion +instances of the Linux kernel running today, given Android +smartphones, Linux-powered televisions, and servers. +This number can be expected to increase sharply with the advent of +the celebrated Internet of Things. + +<p> +Suppose that RCU contains a race condition that manifests on average +once per million years of runtime. +This bug will be occurring about three times per <i>day</i> across +the installed base. +RCU could simply hide behind hardware error rates, given that no one +should really expect their smartphone to last for a million years. +However, anyone taking too much comfort from this thought should +consider the fact that in most jurisdictions, a successful multi-year +test of a given mechanism, which might include a Linux kernel, +suffices for a number of types of safety-critical certifications. +In fact, rumor has it that the Linux kernel is already being used +in production for safety-critical applications. +I don't know about you, but I would feel quite bad if a bug in RCU +killed someone. +Which might explain my recent focus on validation and verification. + +<h2><a name="Other RCU Flavors">Other RCU Flavors</a></h2> + +<p> +One of the more surprising things about RCU is that there are now +no fewer than five <i>flavors</i>, or API families. +In addition, the primary flavor that has been the sole focus up to +this point has two different implementations, non-preemptible and +preemptible. +The other four flavors are listed below, with requirements for each +described in a separate section. + +<ol> +<li> <a href="#Bottom-Half Flavor">Bottom-Half Flavor</a> +<li> <a href="#Sched Flavor">Sched Flavor</a> +<li> <a href="#Sleepable RCU">Sleepable RCU</a> +<li> <a href="#Tasks RCU">Tasks RCU</a> +</ol> + +<h3><a name="Bottom-Half Flavor">Bottom-Half Flavor</a></h3> + +<p> +The softirq-disable (AKA “bottom-half”, +hence the “_bh” abbreviations) +flavor of RCU, or <i>RCU-bh</i>, was developed by +Dipankar Sarma to provide a flavor of RCU that could withstand the +network-based denial-of-service attacks researched by Robert +Olsson. +These attacks placed so much networking load on the system +that some of the CPUs never exited softirq execution, +which in turn prevented those CPUs from ever executing a context switch, +which, in the RCU implementation of that time, prevented grace periods +from ever ending. +The result was an out-of-memory condition and a system hang. + +<p> +The solution was the creation of RCU-bh, which does +<tt>local_bh_disable()</tt> +across its read-side critical sections, and which uses the transition +from one type of softirq processing to another as a quiescent state +in addition to context switch, idle, user mode, and offline. +This means that RCU-bh grace periods can complete even when some of +the CPUs execute in softirq indefinitely, thus allowing algorithms +based on RCU-bh to withstand network-based denial-of-service attacks. + +<p> +Because +<tt>rcu_read_lock_bh()</tt> and <tt>rcu_read_unlock_bh()</tt> +disable and re-enable softirq handlers, any attempt to start a softirq +handlers during the +RCU-bh read-side critical section will be deferred. +In this case, <tt>rcu_read_unlock_bh()</tt> +will invoke softirq processing, which can take considerable time. +One can of course argue that this softirq overhead should be associated +with the code following the RCU-bh read-side critical section rather +than <tt>rcu_read_unlock_bh()</tt>, but the fact +is that most profiling tools cannot be expected to make this sort +of fine distinction. +For example, suppose that a three-millisecond-long RCU-bh read-side +critical section executes during a time of heavy networking load. +There will very likely be an attempt to invoke at least one softirq +handler during that three milliseconds, but any such invocation will +be delayed until the time of the <tt>rcu_read_unlock_bh()</tt>. +This can of course make it appear at first glance as if +<tt>rcu_read_unlock_bh()</tt> was executing very slowly. + +<p> +The +<a href="http://lwn.net/Articles/609973/#RCU Per-Flavor API Table">RCU-bh API</a> +includes +<tt>rcu_read_lock_bh()</tt>, +<tt>rcu_read_unlock_bh()</tt>, +<tt>rcu_dereference_bh()</tt>, +<tt>rcu_dereference_bh_check()</tt>, +<tt>synchronize_rcu_bh()</tt>, +<tt>synchronize_rcu_bh_expedited()</tt>, +<tt>call_rcu_bh()</tt>, +<tt>rcu_barrier_bh()</tt>, and +<tt>rcu_read_lock_bh_held()</tt>. + +<h3><a name="Sched Flavor">Sched Flavor</a></h3> + +<p> +Before preemptible RCU, waiting for an RCU grace period had the +side effect of also waiting for all pre-existing interrupt +and NMI handlers. +However, there are legitimate preemptible-RCU implementations that +do not have this property, given that any point in the code outside +of an RCU read-side critical section can be a quiescent state. +Therefore, <i>RCU-sched</i> was created, which follows “classic” +RCU in that an RCU-sched grace period waits for for pre-existing +interrupt and NMI handlers. +In kernels built with <tt>CONFIG_PREEMPT=n</tt>, the RCU and RCU-sched +APIs have identical implementations, while kernels built with +<tt>CONFIG_PREEMPT=y</tt> provide a separate implementation for each. + +<p> +Note well that in <tt>CONFIG_PREEMPT=y</tt> kernels, +<tt>rcu_read_lock_sched()</tt> and <tt>rcu_read_unlock_sched()</tt> +disable and re-enable preemption, respectively. +This means that if there was a preemption attempt during the +RCU-sched read-side critical section, <tt>rcu_read_unlock_sched()</tt> +will enter the scheduler, with all the latency and overhead entailed. +Just as with <tt>rcu_read_unlock_bh()</tt>, this can make it look +as if <tt>rcu_read_unlock_sched()</tt> was executing very slowly. +However, the highest-priority task won't be preempted, so that task +will enjoy low-overhead <tt>rcu_read_unlock_sched()</tt> invocations. + +<p> +The +<a href="http://lwn.net/Articles/609973/#RCU Per-Flavor API Table">RCU-sched API</a> +includes +<tt>rcu_read_lock_sched()</tt>, +<tt>rcu_read_unlock_sched()</tt>, +<tt>rcu_read_lock_sched_notrace()</tt>, +<tt>rcu_read_unlock_sched_notrace()</tt>, +<tt>rcu_dereference_sched()</tt>, +<tt>rcu_dereference_sched_check()</tt>, +<tt>synchronize_sched()</tt>, +<tt>synchronize_rcu_sched_expedited()</tt>, +<tt>call_rcu_sched()</tt>, +<tt>rcu_barrier_sched()</tt>, and +<tt>rcu_read_lock_sched_held()</tt>. +However, anything that disables preemption also marks an RCU-sched +read-side critical section, including +<tt>preempt_disable()</tt> and <tt>preempt_enable()</tt>, +<tt>local_irq_save()</tt> and <tt>local_irq_restore()</tt>, +and so on. + +<h3><a name="Sleepable RCU">Sleepable RCU</a></h3> + +<p> +For well over a decade, someone saying “I need to block within +an RCU read-side critical section” was a reliable indication +that this someone did not understand RCU. +After all, if you are always blocking in an RCU read-side critical +section, you can probably afford to use a higher-overhead synchronization +mechanism. +However, that changed with the advent of the Linux kernel's notifiers, +whose RCU read-side critical +sections almost never sleep, but sometimes need to. +This resulted in the introduction of +<a href="https://lwn.net/Articles/202847/">sleepable RCU</a>, +or <i>SRCU</i>. + +<p> +SRCU allows different domains to be defined, with each such domain +defined by an instance of an <tt>srcu_struct</tt> structure. +A pointer to this structure must be passed in to each SRCU function, +for example, <tt>synchronize_srcu(&ss)</tt>, where +<tt>ss</tt> is the <tt>srcu_struct</tt> structure. +The key benefit of these domains is that a slow SRCU reader in one +domain does not delay an SRCU grace period in some other domain. +That said, one consequence of these domains is that read-side code +must pass a “cookie” from <tt>srcu_read_lock()</tt> +to <tt>srcu_read_unlock()</tt>, for example, as follows: + +<blockquote> +<pre> + 1 int idx; + 2 + 3 idx = srcu_read_lock(&ss); + 4 do_something(); + 5 srcu_read_unlock(&ss, idx); +</pre> +</blockquote> + +<p> +As noted above, it is legal to block within SRCU read-side critical sections, +however, with great power comes great responsibility. +If you block forever in one of a given domain's SRCU read-side critical +sections, then that domain's grace periods will also be blocked forever. +Of course, one good way to block forever is to deadlock, which can +happen if any operation in a given domain's SRCU read-side critical +section can block waiting, either directly or indirectly, for that domain's +grace period to elapse. +For example, this results in a self-deadlock: + +<blockquote> +<pre> + 1 int idx; + 2 + 3 idx = srcu_read_lock(&ss); + 4 do_something(); + 5 synchronize_srcu(&ss); + 6 srcu_read_unlock(&ss, idx); +</pre> +</blockquote> + +<p> +However, if line 5 acquired a mutex that was held across +a <tt>synchronize_srcu()</tt> for domain <tt>ss</tt>, +deadlock would still be possible. +Furthermore, if line 5 acquired a mutex that was held across +a <tt>synchronize_srcu()</tt> for some other domain <tt>ss1</tt>, +and if an <tt>ss1</tt>-domain SRCU read-side critical section +acquired another mutex that was held across as <tt>ss</tt>-domain +<tt>synchronize_srcu()</tt>, +deadlock would again be possible. +Such a deadlock cycle could extend across an arbitrarily large number +of different SRCU domains. +Again, with great power comes great responsibility. + +<p> +Unlike the other RCU flavors, SRCU read-side critical sections can +run on idle and even offline CPUs. +This ability requires that <tt>srcu_read_lock()</tt> and +<tt>srcu_read_unlock()</tt> contain memory barriers, which means +that SRCU readers will run a bit slower than would RCU readers. +It also motivates the <tt>smp_mb__after_srcu_read_unlock()</tt> +API, which, in combination with <tt>srcu_read_unlock()</tt>, +guarantees a full memory barrier. + +<p> +The +<a href="http://lwn.net/Articles/609973/#RCU Per-Flavor API Table">SRCU API</a> +includes +<tt>srcu_read_lock()</tt>, +<tt>srcu_read_unlock()</tt>, +<tt>srcu_dereference()</tt>, +<tt>srcu_dereference_check()</tt>, +<tt>synchronize_srcu()</tt>, +<tt>synchronize_srcu_expedited()</tt>, +<tt>call_srcu()</tt>, +<tt>srcu_barrier()</tt>, and +<tt>srcu_read_lock_held()</tt>. +It also includes +<tt>DEFINE_SRCU()</tt>, +<tt>DEFINE_STATIC_SRCU()</tt>, and +<tt>init_srcu_struct()</tt> +APIs for defining and initializing <tt>srcu_struct</tt> structures. + +<h3><a name="Tasks RCU">Tasks RCU</a></h3> + +<p> +Some forms of tracing use “tramopolines” to handle the +binary rewriting required to install different types of probes. +It would be good to be able to free old trampolines, which sounds +like a job for some form of RCU. +However, because it is necessary to be able to install a trace +anywhere in the code, it is not possible to use read-side markers +such as <tt>rcu_read_lock()</tt> and <tt>rcu_read_unlock()</tt>. +In addition, it does not work to have these markers in the trampoline +itself, because there would need to be instructions following +<tt>rcu_read_unlock()</tt>. +Although <tt>synchronize_rcu()</tt> would guarantee that execution +reached the <tt>rcu_read_unlock()</tt>, it would not be able to +guarantee that execution had completely left the trampoline. + +<p> +The solution, in the form of +<a href="http://lwn.net/Articles/607117/"><i>Tasks RCU</i></a>, +is to have implicit +read-side critical sections that are delimited by voluntary context +switches, that is, calls to <tt>schedule()</tt>, +<tt>cond_resched_rcu_qs()</tt>, and +<tt>synchronize_rcu_tasks()</tt>. +In addition, transitions to and from userspace execution also delimit +tasks-RCU read-side critical sections. + +<p> +The tasks-RCU API is quite compact, consisting only of +<tt>call_rcu_tasks()</tt>, +<tt>synchronize_rcu_tasks()</tt>, and +<tt>rcu_barrier_tasks()</tt>. + +<h2><a name="Possible Future Changes">Possible Future Changes</a></h2> + +<p> +One of the tricks that RCU uses to attain update-side scalability is +to increase grace-period latency with increasing numbers of CPUs. +If this becomes a serious problem, it will be necessary to rework the +grace-period state machine so as to avoid the need for the additional +latency. + +<p> +Expedited grace periods scan the CPUs, so their latency and overhead +increases with increasing numbers of CPUs. +If this becomes a serious problem on large systems, it will be necessary +to do some redesign to avoid this scalability problem. + +<p> +RCU disables CPU hotplug in a few places, perhaps most notably in the +expedited grace-period and <tt>rcu_barrier()</tt> operations. +If there is a strong reason to use expedited grace periods in CPU-hotplug +notifiers, it will be necessary to avoid disabling CPU hotplug. +This would introduce some complexity, so there had better be a <i>very</i> +good reason. + +<p> +The tradeoff between grace-period latency on the one hand and interruptions +of other CPUs on the other hand may need to be re-examined. +The desire is of course for zero grace-period latency as well as zero +interprocessor interrupts undertaken during an expedited grace period +operation. +While this ideal is unlikely to be achievable, it is quite possible that +further improvements can be made. + +<p> +The multiprocessor implementations of RCU use a combining tree that +groups CPUs so as to reduce lock contention and increase cache locality. +However, this combining tree does not spread its memory across NUMA +nodes nor does it align the CPU groups with hardware features such +as sockets or cores. +Such spreading and alignment is currently believed to be unnecessary +because the hotpath read-side primitives do not access the combining +tree, nor does <tt>call_rcu()</tt> in the common case. +If you believe that your architecture needs such spreading and alignment, +then your architecture should also benefit from the +<tt>rcutree.rcu_fanout_leaf</tt> boot parameter, which can be set +to the number of CPUs in a socket, NUMA node, or whatever. +If the number of CPUs is too large, use a fraction of the number of +CPUs. +If the number of CPUs is a large prime number, well, that certainly +is an “interesting” architectural choice! +More flexible arrangements might be considered, but only if +<tt>rcutree.rcu_fanout_leaf</tt> has proven inadequate, and only +if the inadequacy has been demonstrated by a carefully run and +realistic system-level workload. + +<p> +Please note that arrangements that require RCU to remap CPU numbers will +require extremely good demonstration of need and full exploration of +alternatives. + +<p> +There is an embarrassingly large number of flavors of RCU, and this +number has been increasing over time. +Perhaps it will be possible to combine some at some future date. + +<p> +RCU's various kthreads are reasonably recent additions. +It is quite likely that adjustments will be required to more gracefully +handle extreme loads. +It might also be necessary to be able to relate CPU utilization by +RCU's kthreads and softirq handlers to the code that instigated this +CPU utilization. +For example, RCU callback overhead might be charged back to the +originating <tt>call_rcu()</tt> instance, though probably not +in production kernels. + +<h2><a name="Summary">Summary</a></h2> + +<p> +This document has presented more than two decade's worth of RCU +requirements. +Given that the requirements keep changing, this will not be the last +word on this subject, but at least it serves to get an important +subset of the requirements set forth. + +<h2><a name="Acknowledgments">Acknowledgments</a></h2> + +I am grateful to Steven Rostedt, Lai Jiangshan, Ingo Molnar, +Oleg Nesterov, Borislav Petkov, Peter Zijlstra, Boqun Feng, and +Andy Lutomirski for their help in rendering +this article human readable, and to Michelle Rankin for her support +of this effort. +Other contributions are acknowledged in the Linux kernel's git archive. +The cartoon is copyright (c) 2013 by Melissa Broussard, +and is provided +under the terms of the Creative Commons Attribution-Share Alike 3.0 +United States license. + +<h3><a name="Answers to Quick Quizzes"> +Answers to Quick Quizzes</a></h3> + +<a name="qq1answer"></a> +<p><b>Quick Quiz 1</b>: +Wait a minute! +You said that updaters can make useful forward progress concurrently +with readers, but pre-existing readers will block +<tt>synchronize_rcu()</tt>!!! +Just who are you trying to fool??? + + +</p><p><b>Answer</b>: +First, if updaters do not wish to be blocked by readers, they can use +<tt>call_rcu()</tt> or <tt>kfree_rcu()</tt>, which will +be discussed later. +Second, even when using <tt>synchronize_rcu()</tt>, the other +update-side code does run concurrently with readers, whether pre-existing +or not. + + +</p><p><a href="#Quick%20Quiz%201"><b>Back to Quick Quiz 1</b>.</a> + +<a name="qq2answer"></a> +<p><b>Quick Quiz 2</b>: +Why is the <tt>synchronize_rcu()</tt> on line 28 needed? + + +</p><p><b>Answer</b>: +Without that extra grace period, memory reordering could result in +<tt>do_something_dlm()</tt> executing <tt>do_something()</tt> +concurrently with the last bits of <tt>recovery()</tt>. + + +</p><p><a href="#Quick%20Quiz%202"><b>Back to Quick Quiz 2</b>.</a> + +<a name="qq3answer"></a> +<p><b>Quick Quiz 3</b>: +But <tt>rcu_assign_pointer()</tt> does nothing to prevent the +two assignments to <tt>p->a</tt> and <tt>p->b</tt> +from being reordered. +Can't that also cause problems? + + +</p><p><b>Answer</b>: +No, it cannot. +The readers cannot see either of these two fields until +the assignment to <tt>gp</tt>, by which time both fields are +fully initialized. +So reordering the assignments +to <tt>p->a</tt> and <tt>p->b</tt> cannot possibly +cause any problems. + + +</p><p><a href="#Quick%20Quiz%203"><b>Back to Quick Quiz 3</b>.</a> + +<a name="qq4answer"></a> +<p><b>Quick Quiz 4</b>: +Without the <tt>rcu_dereference()</tt> or the +<tt>rcu_access_pointer()</tt>, what destructive optimizations +might the compiler make use of? + + +</p><p><b>Answer</b>: +Let's start with what happens to <tt>do_something_gp()</tt> +if it fails to use <tt>rcu_dereference()</tt>. +It could reuse a value formerly fetched from this same pointer. +It could also fetch the pointer from <tt>gp</tt> in a byte-at-a-time +manner, resulting in <i>load tearing</i>, in turn resulting a bytewise +mash-up of two distince pointer values. +It might even use value-speculation optimizations, where it makes a wrong +guess, but by the time it gets around to checking the value, an update +has changed the pointer to match the wrong guess. +Too bad about any dereferences that returned pre-initialization garbage +in the meantime! + +<p> +For <tt>remove_gp_synchronous()</tt>, as long as all modifications +to <tt>gp</tt> are carried out while holding <tt>gp_lock</tt>, +the above optimizations are harmless. +However, +with <tt>CONFIG_SPARSE_RCU_POINTER=y</tt>, +<tt>sparse</tt> will complain if you +define <tt>gp</tt> with <tt>__rcu</tt> and then +access it without using +either <tt>rcu_access_pointer()</tt> or <tt>rcu_dereference()</tt>. + + +</p><p><a href="#Quick%20Quiz%204"><b>Back to Quick Quiz 4</b>.</a> + +<a name="qq5answer"></a> +<p><b>Quick Quiz 5</b>: +Given that multiple CPUs can start RCU read-side critical sections +at any time without any ordering whatsoever, how can RCU possibly tell whether +or not a given RCU read-side critical section starts before a +given instance of <tt>synchronize_rcu()</tt>? + + +</p><p><b>Answer</b>: +If RCU cannot tell whether or not a given +RCU read-side critical section starts before a +given instance of <tt>synchronize_rcu()</tt>, +then it must assume that the RCU read-side critical section +started first. +In other words, a given instance of <tt>synchronize_rcu()</tt> +can avoid waiting on a given RCU read-side critical section only +if it can prove that <tt>synchronize_rcu()</tt> started first. + + +</p><p><a href="#Quick%20Quiz%205"><b>Back to Quick Quiz 5</b>.</a> + +<a name="qq6answer"></a> +<p><b>Quick Quiz 6</b>: +The first and second guarantees require unbelievably strict ordering! +Are all these memory barriers <i> really</i> required? + + +</p><p><b>Answer</b>: +Yes, they really are required. +To see why the first guarantee is required, consider the following +sequence of events: + +<ol> +<li> CPU 1: <tt>rcu_read_lock()</tt> +<li> CPU 1: <tt>q = rcu_dereference(gp); + /* Very likely to return p. */</tt> +<li> CPU 0: <tt>list_del_rcu(p);</tt> +<li> CPU 0: <tt>synchronize_rcu()</tt> starts. +<li> CPU 1: <tt>do_something_with(q->a); + /* No smp_mb(), so might happen after kfree(). */</tt> +<li> CPU 1: <tt>rcu_read_unlock()</tt> +<li> CPU 0: <tt>synchronize_rcu()</tt> returns. +<li> CPU 0: <tt>kfree(p);</tt> +</ol> + +<p> +Therefore, there absolutely must be a full memory barrier between the +end of the RCU read-side critical section and the end of the +grace period. + +<p> +The sequence of events demonstrating the necessity of the second rule +is roughly similar: + +<ol> +<li> CPU 0: <tt>list_del_rcu(p);</tt> +<li> CPU 0: <tt>synchronize_rcu()</tt> starts. +<li> CPU 1: <tt>rcu_read_lock()</tt> +<li> CPU 1: <tt>q = rcu_dereference(gp); + /* Might return p if no memory barrier. */</tt> +<li> CPU 0: <tt>synchronize_rcu()</tt> returns. +<li> CPU 0: <tt>kfree(p);</tt> +<li> CPU 1: <tt>do_something_with(q->a); /* Boom!!! */</tt> +<li> CPU 1: <tt>rcu_read_unlock()</tt> +</ol> + +<p> +And similarly, without a memory barrier between the beginning of the +grace period and the beginning of the RCU read-side critical section, +CPU 1 might end up accessing the freelist. + +<p> +The “as if” rule of course applies, so that any implementation +that acts as if the appropriate memory barriers were in place is a +correct implementation. +That said, it is much easier to fool yourself into believing that you have +adhered to the as-if rule than it is to actually adhere to it! + + +</p><p><a href="#Quick%20Quiz%206"><b>Back to Quick Quiz 6</b>.</a> + +<a name="qq7answer"></a> +<p><b>Quick Quiz 7</b>: +But how does the upgrade-to-write operation exclude other readers? + + +</p><p><b>Answer</b>: +It doesn't, just like normal RCU updates, which also do not exclude +RCU readers. + + +</p><p><a href="#Quick%20Quiz%207"><b>Back to Quick Quiz 7</b>.</a> + +<a name="qq8answer"></a> +<p><b>Quick Quiz 8</b>: +Can't the compiler also reorder this code? + + +</p><p><b>Answer</b>: +No, the volatile casts in <tt>READ_ONCE()</tt> and +<tt>WRITE_ONCE()</tt> prevent the compiler from reordering in +this particular case. + + +</p><p><a href="#Quick%20Quiz%208"><b>Back to Quick Quiz 8</b>.</a> + +<a name="qq9answer"></a> +<p><b>Quick Quiz 9</b>: +Suppose that synchronize_rcu() did wait until all readers had completed. +Would the updater be able to rely on this? + + +</p><p><b>Answer</b>: +No. +Even if <tt>synchronize_rcu()</tt> were to wait until +all readers had completed, a new reader might start immediately after +<tt>synchronize_rcu()</tt> completed. +Therefore, the code following +<tt>synchronize_rcu()</tt> cannot rely on there being no readers +in any case. + + +</p><p><a href="#Quick%20Quiz%209"><b>Back to Quick Quiz 9</b>.</a> + +<a name="qq10answer"></a> +<p><b>Quick Quiz 10</b>: +How long a sequence of grace periods, each separated by an RCU read-side +critical section, would be required to partition the RCU read-side +critical sections at the beginning and end of the chain? + + +</p><p><b>Answer</b>: +In theory, an infinite number. +In practice, an unknown number that is sensitive to both implementation +details and timing considerations. +Therefore, even in practice, RCU users must abide by the theoretical rather +than the practical answer. + + +</p><p><a href="#Quick%20Quiz%2010"><b>Back to Quick Quiz 10</b>.</a> + +<a name="qq11answer"></a> +<p><b>Quick Quiz 11</b>: +What about sleeping locks? + + +</p><p><b>Answer</b>: +These are forbidden within Linux-kernel RCU read-side critical sections +because it is not legal to place a quiescent state (in this case, +voluntary context switch) within an RCU read-side critical section. +However, sleeping locks may be used within userspace RCU read-side critical +sections, and also within Linux-kernel sleepable RCU +<a href="#Sleepable RCU">(SRCU)</a> +read-side critical sections. +In addition, the -rt patchset turns spinlocks into a sleeping locks so +that the corresponding critical sections can be preempted, which +also means that these sleeplockified spinlocks (but not other sleeping locks!) +may be acquire within -rt-Linux-kernel RCU read-side critical sections. + +<p> +Note that it <i>is</i> legal for a normal RCU read-side critical section +to conditionally acquire a sleeping locks (as in <tt>mutex_trylock()</tt>), +but only as long as it does not loop indefinitely attempting to +conditionally acquire that sleeping locks. +The key point is that things like <tt>mutex_trylock()</tt> +either return with the mutex held, or return an error indication if +the mutex was not immediately available. +Either way, <tt>mutex_trylock()</tt> returns immediately without sleeping. + + +</p><p><a href="#Quick%20Quiz%2011"><b>Back to Quick Quiz 11</b>.</a> + +<a name="qq12answer"></a> +<p><b>Quick Quiz 12</b>: +Why does line 19 use <tt>rcu_access_pointer()</tt>? +After all, <tt>call_rcu()</tt> on line 25 stores into the +structure, which would interact badly with concurrent insertions. +Doesn't this mean that <tt>rcu_dereference()</tt> is required? + + +</p><p><b>Answer</b>: +Presumably the <tt>->gp_lock</tt> acquired on line 18 excludes +any changes, including any insertions that <tt>rcu_dereference()</tt> +would protect against. +Therefore, any insertions will be delayed until after <tt>->gp_lock</tt> +is released on line 25, which in turn means that +<tt>rcu_access_pointer()</tt> suffices. + + +</p><p><a href="#Quick%20Quiz%2012"><b>Back to Quick Quiz 12</b>.</a> + +<a name="qq13answer"></a> +<p><b>Quick Quiz 13</b>: +Earlier it was claimed that <tt>call_rcu()</tt> and +<tt>kfree_rcu()</tt> allowed updaters to avoid being blocked +by readers. +But how can that be correct, given that the invocation of the callback +and the freeing of the memory (respectively) must still wait for +a grace period to elapse? + + +</p><p><b>Answer</b>: +We could define things this way, but keep in mind that this sort of +definition would say that updates in garbage-collected languages +cannot complete until the next time the garbage collector runs, +which does not seem at all reasonable. +The key point is that in most cases, an updater using either +<tt>call_rcu()</tt> or <tt>kfree_rcu()</tt> can proceed to the +next update as soon as it has invoked <tt>call_rcu()</tt> or +<tt>kfree_rcu()</tt>, without having to wait for a subsequent +grace period. + + +</p><p><a href="#Quick%20Quiz%2013"><b>Back to Quick Quiz 13</b>.</a> + +<a name="qq14answer"></a> +<p><b>Quick Quiz 14</b>: +So what happens with <tt>synchronize_rcu()</tt> during +scheduler initialization for <tt>CONFIG_PREEMPT=n</tt> +kernels? + + +</p><p><b>Answer</b>: +In <tt>CONFIG_PREEMPT=n</tt> kernel, <tt>synchronize_rcu()</tt> +maps directly to <tt>synchronize_sched()</tt>. +Therefore, <tt>synchronize_rcu()</tt> works normally throughout +boot in <tt>CONFIG_PREEMPT=n</tt> kernels. +However, your code must also work in <tt>CONFIG_PREEMPT=y</tt> kernels, +so it is still necessary to avoid invoking <tt>synchronize_rcu()</tt> +during scheduler initialization. + + +</p><p><a href="#Quick%20Quiz%2014"><b>Back to Quick Quiz 14</b>.</a> + + +</body></html> diff --git a/Documentation/RCU/Design/Requirements/Requirements.htmlx b/Documentation/RCU/Design/Requirements/Requirements.htmlx new file mode 100644 index 000000000000..c5bb5bddd7ee --- /dev/null +++ b/Documentation/RCU/Design/Requirements/Requirements.htmlx @@ -0,0 +1,2643 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + <html> + <head><title>A Tour Through RCU's Requirements [LWN.net]</title> + <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> + +<h1>A Tour Through RCU's Requirements</h1> + +<p>Copyright IBM Corporation, 2015</p> +<p>Author: Paul E. McKenney</p> +<p><i>The initial version of this document appeared in the +<a href="http://lwn.net/">LWN</a> articles +<a href="http://lwn.net/Articles/652156/">here</a>, +<a href="http://lwn.net/Articles/652677/">here</a>, and +<a href="http://lwn.net/Articles/653326/">here</a>.</i></p> + +<h2>Introduction</h2> + +<p> +Read-copy update (RCU) is a synchronization mechanism that is often +used as a replacement for reader-writer locking. +RCU is unusual in that updaters do not block readers, +which means that RCU's read-side primitives can be exceedingly fast +and scalable. +In addition, updaters can make useful forward progress concurrently +with readers. +However, all this concurrency between RCU readers and updaters does raise +the question of exactly what RCU readers are doing, which in turn +raises the question of exactly what RCU's requirements are. + +<p> +This document therefore summarizes RCU's requirements, and can be thought +of as an informal, high-level specification for RCU. +It is important to understand that RCU's specification is primarily +empirical in nature; +in fact, I learned about many of these requirements the hard way. +This situation might cause some consternation, however, not only +has this learning process been a lot of fun, but it has also been +a great privilege to work with so many people willing to apply +technologies in interesting new ways. + +<p> +All that aside, here are the categories of currently known RCU requirements: +</p> + +<ol> +<li> <a href="#Fundamental Requirements"> + Fundamental Requirements</a> +<li> <a href="#Fundamental Non-Requirements">Fundamental Non-Requirements</a> +<li> <a href="#Parallelism Facts of Life"> + Parallelism Facts of Life</a> +<li> <a href="#Quality-of-Implementation Requirements"> + Quality-of-Implementation Requirements</a> +<li> <a href="#Linux Kernel Complications"> + Linux Kernel Complications</a> +<li> <a href="#Software-Engineering Requirements"> + Software-Engineering Requirements</a> +<li> <a href="#Other RCU Flavors"> + Other RCU Flavors</a> +<li> <a href="#Possible Future Changes"> + Possible Future Changes</a> +</ol> + +<p> +This is followed by a <a href="#Summary">summary</a>, +which is in turn followed by the inevitable +<a href="#Answers to Quick Quizzes">answers to the quick quizzes</a>. + +<h2><a name="Fundamental Requirements">Fundamental Requirements</a></h2> + +<p> +RCU's fundamental requirements are the closest thing RCU has to hard +mathematical requirements. +These are: + +<ol> +<li> <a href="#Grace-Period Guarantee"> + Grace-Period Guarantee</a> +<li> <a href="#Publish-Subscribe Guarantee"> + Publish-Subscribe Guarantee</a> +<li> <a href="#RCU Primitives Guaranteed to Execute Unconditionally"> + RCU Primitives Guaranteed to Execute Unconditionally</a> +<li> <a href="#Guaranteed Read-to-Write Upgrade"> + Guaranteed Read-to-Write Upgrade</a> +</ol> + +<h3><a name="Grace-Period Guarantee">Grace-Period Guarantee</a></h3> + +<p> +RCU's grace-period guarantee is unusual in being premeditated: +Jack Slingwine and I had this guarantee firmly in mind when we started +work on RCU (then called “rclock”) in the early 1990s. +That said, the past two decades of experience with RCU have produced +a much more detailed understanding of this guarantee. + +<p> +RCU's grace-period guarantee allows updaters to wait for the completion +of all pre-existing RCU read-side critical sections. +An RCU read-side critical section +begins with the marker <tt>rcu_read_lock()</tt> and ends with +the marker <tt>rcu_read_unlock()</tt>. +These markers may be nested, and RCU treats a nested set as one +big RCU read-side critical section. +Production-quality implementations of <tt>rcu_read_lock()</tt> and +<tt>rcu_read_unlock()</tt> are extremely lightweight, and in +fact have exactly zero overhead in Linux kernels built for production +use with <tt>CONFIG_PREEMPT=n</tt>. + +<p> +This guarantee allows ordering to be enforced with extremely low +overhead to readers, for example: + +<blockquote> +<pre> + 1 int x, y; + 2 + 3 void thread0(void) + 4 { + 5 rcu_read_lock(); + 6 r1 = READ_ONCE(x); + 7 r2 = READ_ONCE(y); + 8 rcu_read_unlock(); + 9 } +10 +11 void thread1(void) +12 { +13 WRITE_ONCE(x, 1); +14 synchronize_rcu(); +15 WRITE_ONCE(y, 1); +16 } +</pre> +</blockquote> + +<p> +Because the <tt>synchronize_rcu()</tt> on line 14 waits for +all pre-existing readers, any instance of <tt>thread0()</tt> that +loads a value of zero from <tt>x</tt> must complete before +<tt>thread1()</tt> stores to <tt>y</tt>, so that instance must +also load a value of zero from <tt>y</tt>. +Similarly, any instance of <tt>thread0()</tt> that loads a value of +one from <tt>y</tt> must have started after the +<tt>synchronize_rcu()</tt> started, and must therefore also load +a value of one from <tt>x</tt>. +Therefore, the outcome: +<blockquote> +<pre> +(r1 == 0 && r2 == 1) +</pre> +</blockquote> +cannot happen. + +<p>@@QQ@@ +Wait a minute! +You said that updaters can make useful forward progress concurrently +with readers, but pre-existing readers will block +<tt>synchronize_rcu()</tt>!!! +Just who are you trying to fool??? +<p>@@QQA@@ +First, if updaters do not wish to be blocked by readers, they can use +<tt>call_rcu()</tt> or <tt>kfree_rcu()</tt>, which will +be discussed later. +Second, even when using <tt>synchronize_rcu()</tt>, the other +update-side code does run concurrently with readers, whether pre-existing +or not. +<p>@@QQE@@ + +<p> +This scenario resembles one of the first uses of RCU in +<a href="http://en.wikipedia.org/wiki/DYNIX">DYNIX/ptx</a>, +which managed a distributed lock manager's transition into +a state suitable for handling recovery from node failure, +more or less as follows: + +<blockquote> +<pre> + 1 #define STATE_NORMAL 0 + 2 #define STATE_WANT_RECOVERY 1 + 3 #define STATE_RECOVERING 2 + 4 #define STATE_WANT_NORMAL 3 + 5 + 6 int state = STATE_NORMAL; + 7 + 8 void do_something_dlm(void) + 9 { +10 int state_snap; +11 +12 rcu_read_lock(); +13 state_snap = READ_ONCE(state); +14 if (state_snap == STATE_NORMAL) +15 do_something(); +16 else +17 do_something_carefully(); +18 rcu_read_unlock(); +19 } +20 +21 void start_recovery(void) +22 { +23 WRITE_ONCE(state, STATE_WANT_RECOVERY); +24 synchronize_rcu(); +25 WRITE_ONCE(state, STATE_RECOVERING); +26 recovery(); +27 WRITE_ONCE(state, STATE_WANT_NORMAL); +28 synchronize_rcu(); +29 WRITE_ONCE(state, STATE_NORMAL); +30 } +</pre> +</blockquote> + +<p> +The RCU read-side critical section in <tt>do_something_dlm()</tt> +works with the <tt>synchronize_rcu()</tt> in <tt>start_recovery()</tt> +to guarantee that <tt>do_something()</tt> never runs concurrently +with <tt>recovery()</tt>, but with little or no synchronization +overhead in <tt>do_something_dlm()</tt>. + +<p>@@QQ@@ +Why is the <tt>synchronize_rcu()</tt> on line 28 needed? +<p>@@QQA@@ +Without that extra grace period, memory reordering could result in +<tt>do_something_dlm()</tt> executing <tt>do_something()</tt> +concurrently with the last bits of <tt>recovery()</tt>. +<p>@@QQE@@ + +<p> +In order to avoid fatal problems such as deadlocks, +an RCU read-side critical section must not contain calls to +<tt>synchronize_rcu()</tt>. +Similarly, an RCU read-side critical section must not +contain anything that waits, directly or indirectly, on completion of +an invocation of <tt>synchronize_rcu()</tt>. + +<p> +Although RCU's grace-period guarantee is useful in and of itself, with +<a href="https://lwn.net/Articles/573497/">quite a few use cases</a>, +it would be good to be able to use RCU to coordinate read-side +access to linked data structures. +For this, the grace-period guarantee is not sufficient, as can +be seen in function <tt>add_gp_buggy()</tt> below. +We will look at the reader's code later, but in the meantime, just think of +the reader as locklessly picking up the <tt>gp</tt> pointer, +and, if the value loaded is non-<tt>NULL</tt>, locklessly accessing the +<tt>->a</tt> and <tt>->b</tt> fields. + +<blockquote> +<pre> + 1 bool add_gp_buggy(int a, int b) + 2 { + 3 p = kmalloc(sizeof(*p), GFP_KERNEL); + 4 if (!p) + 5 return -ENOMEM; + 6 spin_lock(&gp_lock); + 7 if (rcu_access_pointer(gp)) { + 8 spin_unlock(&gp_lock); + 9 return false; +10 } +11 p->a = a; +12 p->b = a; +13 gp = p; /* ORDERING BUG */ +14 spin_unlock(&gp_lock); +15 return true; +16 } +</pre> +</blockquote> + +<p> +The problem is that both the compiler and weakly ordered CPUs are within +their rights to reorder this code as follows: + +<blockquote> +<pre> + 1 bool add_gp_buggy_optimized(int a, int b) + 2 { + 3 p = kmalloc(sizeof(*p), GFP_KERNEL); + 4 if (!p) + 5 return -ENOMEM; + 6 spin_lock(&gp_lock); + 7 if (rcu_access_pointer(gp)) { + 8 spin_unlock(&gp_lock); + 9 return false; +10 } +<b>11 gp = p; /* ORDERING BUG */ +12 p->a = a; +13 p->b = a;</b> +14 spin_unlock(&gp_lock); +15 return true; +16 } +</pre> +</blockquote> + +<p> +If an RCU reader fetches <tt>gp</tt> just after +<tt>add_gp_buggy_optimized</tt> executes line 11, +it will see garbage in the <tt>->a</tt> and <tt>->b</tt> +fields. +And this is but one of many ways in which compiler and hardware optimizations +could cause trouble. +Therefore, we clearly need some way to prevent the compiler and the CPU from +reordering in this manner, which brings us to the publish-subscribe +guarantee discussed in the next section. + +<h3><a name="Publish-Subscribe Guarantee">Publish/Subscribe Guarantee</a></h3> + +<p> +RCU's publish-subscribe guarantee allows data to be inserted +into a linked data structure without disrupting RCU readers. +The updater uses <tt>rcu_assign_pointer()</tt> to insert the +new data, and readers use <tt>rcu_dereference()</tt> to +access data, whether new or old. +The following shows an example of insertion: + +<blockquote> +<pre> + 1 bool add_gp(int a, int b) + 2 { + 3 p = kmalloc(sizeof(*p), GFP_KERNEL); + 4 if (!p) + 5 return -ENOMEM; + 6 spin_lock(&gp_lock); + 7 if (rcu_access_pointer(gp)) { + 8 spin_unlock(&gp_lock); + 9 return false; +10 } +11 p->a = a; +12 p->b = a; +13 rcu_assign_pointer(gp, p); +14 spin_unlock(&gp_lock); +15 return true; +16 } +</pre> +</blockquote> + +<p> +The <tt>rcu_assign_pointer()</tt> on line 13 is conceptually +equivalent to a simple assignment statement, but also guarantees +that its assignment will +happen after the two assignments in lines 11 and 12, +similar to the C11 <tt>memory_order_release</tt> store operation. +It also prevents any number of “interesting” compiler +optimizations, for example, the use of <tt>gp</tt> as a scratch +location immediately preceding the assignment. + +<p>@@QQ@@ +But <tt>rcu_assign_pointer()</tt> does nothing to prevent the +two assignments to <tt>p->a</tt> and <tt>p->b</tt> +from being reordered. +Can't that also cause problems? +<p>@@QQA@@ +No, it cannot. +The readers cannot see either of these two fields until +the assignment to <tt>gp</tt>, by which time both fields are +fully initialized. +So reordering the assignments +to <tt>p->a</tt> and <tt>p->b</tt> cannot possibly +cause any problems. +<p>@@QQE@@ + +<p> +It is tempting to assume that the reader need not do anything special +to control its accesses to the RCU-protected data, +as shown in <tt>do_something_gp_buggy()</tt> below: + +<blockquote> +<pre> + 1 bool do_something_gp_buggy(void) + 2 { + 3 rcu_read_lock(); + 4 p = gp; /* OPTIMIZATIONS GALORE!!! */ + 5 if (p) { + 6 do_something(p->a, p->b); + 7 rcu_read_unlock(); + 8 return true; + 9 } +10 rcu_read_unlock(); +11 return false; +12 } +</pre> +</blockquote> + +<p> +However, this temptation must be resisted because there are a +surprisingly large number of ways that the compiler +(to say nothing of +<a href="http://www.openvms.compaq.com/wizard/wiz_2637.html">DEC Alpha CPUs</a>) +can trip this code up. +For but one example, if the compiler were short of registers, it +might choose to refetch from <tt>gp</tt> rather than keeping +a separate copy in <tt>p</tt> as follows: + +<blockquote> +<pre> + 1 bool do_something_gp_buggy_optimized(void) + 2 { + 3 rcu_read_lock(); + 4 if (gp) { /* OPTIMIZATIONS GALORE!!! */ +<b> 5 do_something(gp->a, gp->b);</b> + 6 rcu_read_unlock(); + 7 return true; + 8 } + 9 rcu_read_unlock(); +10 return false; +11 } +</pre> +</blockquote> + +<p> +If this function ran concurrently with a series of updates that +replaced the current structure with a new one, +the fetches of <tt>gp->a</tt> +and <tt>gp->b</tt> might well come from two different structures, +which could cause serious confusion. +To prevent this (and much else besides), <tt>do_something_gp()</tt> uses +<tt>rcu_dereference()</tt> to fetch from <tt>gp</tt>: + +<blockquote> +<pre> + 1 bool do_something_gp(void) + 2 { + 3 rcu_read_lock(); + 4 p = rcu_dereference(gp); + 5 if (p) { + 6 do_something(p->a, p->b); + 7 rcu_read_unlock(); + 8 return true; + 9 } +10 rcu_read_unlock(); +11 return false; +12 } +</pre> +</blockquote> + +<p> +The <tt>rcu_dereference()</tt> uses volatile casts and (for DEC Alpha) +memory barriers in the Linux kernel. +Should a +<a href="http://www.rdrop.com/users/paulmck/RCU/consume.2015.07.13a.pdf">high-quality implementation of C11 <tt>memory_order_consume</tt> [PDF]</a> +ever appear, then <tt>rcu_dereference()</tt> could be implemented +as a <tt>memory_order_consume</tt> load. +Regardless of the exact implementation, a pointer fetched by +<tt>rcu_dereference()</tt> may not be used outside of the +outermost RCU read-side critical section containing that +<tt>rcu_dereference()</tt>, unless protection of +the corresponding data element has been passed from RCU to some +other synchronization mechanism, most commonly locking or +<a href="https://www.kernel.org/doc/Documentation/RCU/rcuref.txt">reference counting</a>. + +<p> +In short, updaters use <tt>rcu_assign_pointer()</tt> and readers +use <tt>rcu_dereference()</tt>, and these two RCU API elements +work together to ensure that readers have a consistent view of +newly added data elements. + +<p> +Of course, it is also necessary to remove elements from RCU-protected +data structures, for example, using the following process: + +<ol> +<li> Remove the data element from the enclosing structure. +<li> Wait for all pre-existing RCU read-side critical sections + to complete (because only pre-existing readers can possibly have + a reference to the newly removed data element). +<li> At this point, only the updater has a reference to the + newly removed data element, so it can safely reclaim + the data element, for example, by passing it to <tt>kfree()</tt>. +</ol> + +This process is implemented by <tt>remove_gp_synchronous()</tt>: + +<blockquote> +<pre> + 1 bool remove_gp_synchronous(void) + 2 { + 3 struct foo *p; + 4 + 5 spin_lock(&gp_lock); + 6 p = rcu_access_pointer(gp); + 7 if (!p) { + 8 spin_unlock(&gp_lock); + 9 return false; +10 } +11 rcu_assign_pointer(gp, NULL); +12 spin_unlock(&gp_lock); +13 synchronize_rcu(); +14 kfree(p); +15 return true; +16 } +</pre> +</blockquote> + +<p> +This function is straightforward, with line 13 waiting for a grace +period before line 14 frees the old data element. +This waiting ensures that readers will reach line 7 of +<tt>do_something_gp()</tt> before the data element referenced by +<tt>p</tt> is freed. +The <tt>rcu_access_pointer()</tt> on line 6 is similar to +<tt>rcu_dereference()</tt>, except that: + +<ol> +<li> The value returned by <tt>rcu_access_pointer()</tt> + cannot be dereferenced. + If you want to access the value pointed to as well as + the pointer itself, use <tt>rcu_dereference()</tt> + instead of <tt>rcu_access_pointer()</tt>. +<li> The call to <tt>rcu_access_pointer()</tt> need not be + protected. + In contrast, <tt>rcu_dereference()</tt> must either be + within an RCU read-side critical section or in a code + segment where the pointer cannot change, for example, in + code protected by the corresponding update-side lock. +</ol> + +<p>@@QQ@@ +Without the <tt>rcu_dereference()</tt> or the +<tt>rcu_access_pointer()</tt>, what destructive optimizations +might the compiler make use of? +<p>@@QQA@@ +Let's start with what happens to <tt>do_something_gp()</tt> +if it fails to use <tt>rcu_dereference()</tt>. +It could reuse a value formerly fetched from this same pointer. +It could also fetch the pointer from <tt>gp</tt> in a byte-at-a-time +manner, resulting in <i>load tearing</i>, in turn resulting a bytewise +mash-up of two distince pointer values. +It might even use value-speculation optimizations, where it makes a wrong +guess, but by the time it gets around to checking the value, an update +has changed the pointer to match the wrong guess. +Too bad about any dereferences that returned pre-initialization garbage +in the meantime! + +<p> +For <tt>remove_gp_synchronous()</tt>, as long as all modifications +to <tt>gp</tt> are carried out while holding <tt>gp_lock</tt>, +the above optimizations are harmless. +However, +with <tt>CONFIG_SPARSE_RCU_POINTER=y</tt>, +<tt>sparse</tt> will complain if you +define <tt>gp</tt> with <tt>__rcu</tt> and then +access it without using +either <tt>rcu_access_pointer()</tt> or <tt>rcu_dereference()</tt>. +<p>@@QQE@@ + +<p> +This simple linked-data-structure scenario clearly demonstrates the need +for RCU's stringent memory-ordering guarantees on systems with more than +one CPU: + +<ol> +<li> Each CPU that has an RCU read-side critical section that + begins before <tt>synchronize_rcu()</tt> starts is + guaranteed to execute a full memory barrier between the time + that the RCU read-side critical section ends and the time that + <tt>synchronize_rcu()</tt> returns. + Without this guarantee, a pre-existing RCU read-side critical section + might hold a reference to the newly removed <tt>struct foo</tt> + after the <tt>kfree()</tt> on line 14 of + <tt>remove_gp_synchronous()</tt>. +<li> Each CPU that has an RCU read-side critical section that ends + after <tt>synchronize_rcu()</tt> returns is guaranteed + to execute a full memory barrier between the time that + <tt>synchronize_rcu()</tt> begins and the time that the RCU + read-side critical section begins. + Without this guarantee, a later RCU read-side critical section + running after the <tt>kfree()</tt> on line 14 of + <tt>remove_gp_synchronous()</tt> might + later run <tt>do_something_gp()</tt> and find the + newly deleted <tt>struct foo</tt>. +<li> If the task invoking <tt>synchronize_rcu()</tt> remains + on a given CPU, then that CPU is guaranteed to execute a full + memory barrier sometime during the execution of + <tt>synchronize_rcu()</tt>. + This guarantee ensures that the <tt>kfree()</tt> on + line 14 of <tt>remove_gp_synchronous()</tt> really does + execute after the removal on line 11. +<li> If the task invoking <tt>synchronize_rcu()</tt> migrates + among a group of CPUs during that invocation, then each of the + CPUs in that group is guaranteed to execute a full memory barrier + sometime during the execution of <tt>synchronize_rcu()</tt>. + This guarantee also ensures that the <tt>kfree()</tt> on + line 14 of <tt>remove_gp_synchronous()</tt> really does + execute after the removal on + line 11, but also in the case where the thread executing the + <tt>synchronize_rcu()</tt> migrates in the meantime. +</ol> + +<p>@@QQ@@ +Given that multiple CPUs can start RCU read-side critical sections +at any time without any ordering whatsoever, how can RCU possibly tell whether +or not a given RCU read-side critical section starts before a +given instance of <tt>synchronize_rcu()</tt>? +<p>@@QQA@@ +If RCU cannot tell whether or not a given +RCU read-side critical section starts before a +given instance of <tt>synchronize_rcu()</tt>, +then it must assume that the RCU read-side critical section +started first. +In other words, a given instance of <tt>synchronize_rcu()</tt> +can avoid waiting on a given RCU read-side critical section only +if it can prove that <tt>synchronize_rcu()</tt> started first. +<p>@@QQE@@ + +<p>@@QQ@@ +The first and second guarantees require unbelievably strict ordering! +Are all these memory barriers <i> really</i> required? +<p>@@QQA@@ +Yes, they really are required. +To see why the first guarantee is required, consider the following +sequence of events: + +<ol> +<li> CPU 1: <tt>rcu_read_lock()</tt> +<li> CPU 1: <tt>q = rcu_dereference(gp); + /* Very likely to return p. */</tt> +<li> CPU 0: <tt>list_del_rcu(p);</tt> +<li> CPU 0: <tt>synchronize_rcu()</tt> starts. +<li> CPU 1: <tt>do_something_with(q->a); + /* No smp_mb(), so might happen after kfree(). */</tt> +<li> CPU 1: <tt>rcu_read_unlock()</tt> +<li> CPU 0: <tt>synchronize_rcu()</tt> returns. +<li> CPU 0: <tt>kfree(p);</tt> +</ol> + +<p> +Therefore, there absolutely must be a full memory barrier between the +end of the RCU read-side critical section and the end of the +grace period. + +<p> +The sequence of events demonstrating the necessity of the second rule +is roughly similar: + +<ol> +<li> CPU 0: <tt>list_del_rcu(p);</tt> +<li> CPU 0: <tt>synchronize_rcu()</tt> starts. +<li> CPU 1: <tt>rcu_read_lock()</tt> +<li> CPU 1: <tt>q = rcu_dereference(gp); + /* Might return p if no memory barrier. */</tt> +<li> CPU 0: <tt>synchronize_rcu()</tt> returns. +<li> CPU 0: <tt>kfree(p);</tt> +<li> CPU 1: <tt>do_something_with(q->a); /* Boom!!! */</tt> +<li> CPU 1: <tt>rcu_read_unlock()</tt> +</ol> + +<p> +And similarly, without a memory barrier between the beginning of the +grace period and the beginning of the RCU read-side critical section, +CPU 1 might end up accessing the freelist. + +<p> +The “as if” rule of course applies, so that any implementation +that acts as if the appropriate memory barriers were in place is a +correct implementation. +That said, it is much easier to fool yourself into believing that you have +adhered to the as-if rule than it is to actually adhere to it! +<p>@@QQE@@ + +<p> +In short, RCU's publish-subscribe guarantee is provided by the combination +of <tt>rcu_assign_pointer()</tt> and <tt>rcu_dereference()</tt>. +This guarantee allows data elements to be safely added to RCU-protected +linked data structures without disrupting RCU readers. +This guarantee can be used in combination with the grace-period +guarantee to also allow data elements to be removed from RCU-protected +linked data structures, again without disrupting RCU readers. + +<p> +This guarantee was only partially premeditated. +DYNIX/ptx used an explicit memory barrier for publication, but had nothing +resembling <tt>rcu_dereference()</tt> for subscription, nor did it +have anything resembling the <tt>smp_read_barrier_depends()</tt> +that was later subsumed into <tt>rcu_dereference()</tt>. +The need for these operations made itself known quite suddenly at a +late-1990s meeting with the DEC Alpha architects, back in the days when +DEC was still a free-standing company. +It took the Alpha architects a good hour to convince me that any sort +of barrier would ever be needed, and it then took me a good <i>two</i> hours +to convince them that their documentation did not make this point clear. +More recent work with the C and C++ standards committees have provided +much education on tricks and traps from the compiler. +In short, compilers were much less tricky in the early 1990s, but in +2015, don't even think about omitting <tt>rcu_dereference()</tt>! + +<h3><a name="RCU Primitives Guaranteed to Execute Unconditionally">RCU Primitives Guaranteed to Execute Unconditionally</a></h3> + +<p> +The common-case RCU primitives are unconditional. +They are invoked, they do their job, and they return, with no possibility +of error, and no need to retry. +This is a key RCU design philosophy. + +<p> +However, this philosophy is pragmatic rather than pigheaded. +If someone comes up with a good justification for a particular conditional +RCU primitive, it might well be implemented and added. +After all, this guarantee was reverse-engineered, not premeditated. +The unconditional nature of the RCU primitives was initially an +accident of implementation, and later experience with synchronization +primitives with conditional primitives caused me to elevate this +accident to a guarantee. +Therefore, the justification for adding a conditional primitive to +RCU would need to be based on detailed and compelling use cases. + +<h3><a name="Guaranteed Read-to-Write Upgrade">Guaranteed Read-to-Write Upgrade</a></h3> + +<p> +As far as RCU is concerned, it is always possible to carry out an +update within an RCU read-side critical section. +For example, that RCU read-side critical section might search for +a given data element, and then might acquire the update-side +spinlock in order to update that element, all while remaining +in that RCU read-side critical section. +Of course, it is necessary to exit the RCU read-side critical section +before invoking <tt>synchronize_rcu()</tt>, however, this +inconvenience can be avoided through use of the +<tt>call_rcu()</tt> and <tt>kfree_rcu()</tt> API members +described later in this document. + +<p>@@QQ@@ +But how does the upgrade-to-write operation exclude other readers? +<p>@@QQA@@ +It doesn't, just like normal RCU updates, which also do not exclude +RCU readers. +<p>@@QQE@@ + +<p> +This guarantee allows lookup code to be shared between read-side +and update-side code, and was premeditated, appearing in the earliest +DYNIX/ptx RCU documentation. + +<h2><a name="Fundamental Non-Requirements">Fundamental Non-Requirements</a></h2> + +<p> +RCU provides extremely lightweight readers, and its read-side guarantees, +though quite useful, are correspondingly lightweight. +It is therefore all too easy to assume that RCU is guaranteeing more +than it really is. +Of course, the list of things that RCU does not guarantee is infinitely +long, however, the following sections list a few non-guarantees that +have caused confusion. +Except where otherwise noted, these non-guarantees were premeditated. + +<ol> +<li> <a href="#Readers Impose Minimal Ordering"> + Readers Impose Minimal Ordering</a> +<li> <a href="#Readers Do Not Exclude Updaters"> + Readers Do Not Exclude Updaters</a> +<li> <a href="#Updaters Only Wait For Old Readers"> + Updaters Only Wait For Old Readers</a> +<li> <a href="#Grace Periods Don't Partition Read-Side Critical Sections"> + Grace Periods Don't Partition Read-Side Critical Sections</a> +<li> <a href="#Read-Side Critical Sections Don't Partition Grace Periods"> + Read-Side Critical Sections Don't Partition Grace Periods</a> +<li> <a href="#Disabling Preemption Does Not Block Grace Periods"> + Disabling Preemption Does Not Block Grace Periods</a> +</ol> + +<h3><a name="Readers Impose Minimal Ordering">Readers Impose Minimal Ordering</a></h3> + +<p> +Reader-side markers such as <tt>rcu_read_lock()</tt> and +<tt>rcu_read_unlock()</tt> provide absolutely no ordering guarantees +except through their interaction with the grace-period APIs such as +<tt>synchronize_rcu()</tt>. +To see this, consider the following pair of threads: + +<blockquote> +<pre> + 1 void thread0(void) + 2 { + 3 rcu_read_lock(); + 4 WRITE_ONCE(x, 1); + 5 rcu_read_unlock(); + 6 rcu_read_lock(); + 7 WRITE_ONCE(y, 1); + 8 rcu_read_unlock(); + 9 } +10 +11 void thread1(void) +12 { +13 rcu_read_lock(); +14 r1 = READ_ONCE(y); +15 rcu_read_unlock(); +16 rcu_read_lock(); +17 r2 = READ_ONCE(x); +18 rcu_read_unlock(); +19 } +</pre> +</blockquote> + +<p> +After <tt>thread0()</tt> and <tt>thread1()</tt> execute +concurrently, it is quite possible to have + +<blockquote> +<pre> +(r1 == 1 && r2 == 0) +</pre> +</blockquote> + +(that is, <tt>y</tt> appears to have been assigned before <tt>x</tt>), +which would not be possible if <tt>rcu_read_lock()</tt> and +<tt>rcu_read_unlock()</tt> had much in the way of ordering +properties. +But they do not, so the CPU is within its rights +to do significant reordering. +This is by design: Any significant ordering constraints would slow down +these fast-path APIs. + +<p>@@QQ@@ +Can't the compiler also reorder this code? +<p>@@QQA@@ +No, the volatile casts in <tt>READ_ONCE()</tt> and +<tt>WRITE_ONCE()</tt> prevent the compiler from reordering in +this particular case. +<p>@@QQE@@ + +<h3><a name="Readers Do Not Exclude Updaters">Readers Do Not Exclude Updaters</a></h3> + +<p> +Neither <tt>rcu_read_lock()</tt> nor <tt>rcu_read_unlock()</tt> +exclude updates. +All they do is to prevent grace periods from ending. +The following example illustrates this: + +<blockquote> +<pre> + 1 void thread0(void) + 2 { + 3 rcu_read_lock(); + 4 r1 = READ_ONCE(y); + 5 if (r1) { + 6 do_something_with_nonzero_x(); + 7 r2 = READ_ONCE(x); + 8 WARN_ON(!r2); /* BUG!!! */ + 9 } +10 rcu_read_unlock(); +11 } +12 +13 void thread1(void) +14 { +15 spin_lock(&my_lock); +16 WRITE_ONCE(x, 1); +17 WRITE_ONCE(y, 1); +18 spin_unlock(&my_lock); +19 } +</pre> +</blockquote> + +<p> +If the <tt>thread0()</tt> function's <tt>rcu_read_lock()</tt> +excluded the <tt>thread1()</tt> function's update, +the <tt>WARN_ON()</tt> could never fire. +But the fact is that <tt>rcu_read_lock()</tt> does not exclude +much of anything aside from subsequent grace periods, of which +<tt>thread1()</tt> has none, so the +<tt>WARN_ON()</tt> can and does fire. + +<h3><a name="Updaters Only Wait For Old Readers">Updaters Only Wait For Old Readers</a></h3> + +<p> +It might be tempting to assume that after <tt>synchronize_rcu()</tt> +completes, there are no readers executing. +This temptation must be avoided because +new readers can start immediately after <tt>synchronize_rcu()</tt> +starts, and <tt>synchronize_rcu()</tt> is under no +obligation to wait for these new readers. + +<p>@@QQ@@ +Suppose that synchronize_rcu() did wait until all readers had completed. +Would the updater be able to rely on this? +<p>@@QQA@@ +No. +Even if <tt>synchronize_rcu()</tt> were to wait until +all readers had completed, a new reader might start immediately after +<tt>synchronize_rcu()</tt> completed. +Therefore, the code following +<tt>synchronize_rcu()</tt> cannot rely on there being no readers +in any case. +<p>@@QQE@@ + +<h3><a name="Grace Periods Don't Partition Read-Side Critical Sections"> +Grace Periods Don't Partition Read-Side Critical Sections</a></h3> + +<p> +It is tempting to assume that if any part of one RCU read-side critical +section precedes a given grace period, and if any part of another RCU +read-side critical section follows that same grace period, then all of +the first RCU read-side critical section must precede all of the second. +However, this just isn't the case: A single grace period does not +partition the set of RCU read-side critical sections. +An example of this situation can be illustrated as follows, where +<tt>x</tt>, <tt>y</tt>, and <tt>z</tt> are initially all zero: + +<blockquote> +<pre> + 1 void thread0(void) + 2 { + 3 rcu_read_lock(); + 4 WRITE_ONCE(a, 1); + 5 WRITE_ONCE(b, 1); + 6 rcu_read_unlock(); + 7 } + 8 + 9 void thread1(void) +10 { +11 r1 = READ_ONCE(a); +12 synchronize_rcu(); +13 WRITE_ONCE(c, 1); +14 } +15 +16 void thread2(void) +17 { +18 rcu_read_lock(); +19 r2 = READ_ONCE(b); +20 r3 = READ_ONCE(c); +21 rcu_read_unlock(); +22 } +</pre> +</blockquote> + +<p> +It turns out that the outcome: + +<blockquote> +<pre> +(r1 == 1 && r2 == 0 && r3 == 1) +</pre> +</blockquote> + +is entirely possible. +The following figure show how this can happen, with each circled +<tt>QS</tt> indicating the point at which RCU recorded a +<i>quiescent state</i> for each thread, that is, a state in which +RCU knows that the thread cannot be in the midst of an RCU read-side +critical section that started before the current grace period: + +<p><img src="GPpartitionReaders1.svg" alt="GPpartitionReaders1.svg" width="60%"></p> + +<p> +If it is necessary to partition RCU read-side critical sections in this +manner, it is necessary to use two grace periods, where the first +grace period is known to end before the second grace period starts: + +<blockquote> +<pre> + 1 void thread0(void) + 2 { + 3 rcu_read_lock(); + 4 WRITE_ONCE(a, 1); + 5 WRITE_ONCE(b, 1); + 6 rcu_read_unlock(); + 7 } + 8 + 9 void thread1(void) +10 { +11 r1 = READ_ONCE(a); +12 synchronize_rcu(); +13 WRITE_ONCE(c, 1); +14 } +15 +16 void thread2(void) +17 { +18 r2 = READ_ONCE(c); +19 synchronize_rcu(); +20 WRITE_ONCE(d, 1); +21 } +22 +23 void thread3(void) +24 { +25 rcu_read_lock(); +26 r3 = READ_ONCE(b); +27 r4 = READ_ONCE(d); +28 rcu_read_unlock(); +29 } +</pre> +</blockquote> + +<p> +Here, if <tt>(r1 == 1)</tt>, then +<tt>thread0()</tt>'s write to <tt>b</tt> must happen +before the end of <tt>thread1()</tt>'s grace period. +If in addition <tt>(r4 == 1)</tt>, then +<tt>thread3()</tt>'s read from <tt>b</tt> must happen +after the beginning of <tt>thread2()</tt>'s grace period. +If it is also the case that <tt>(r2 == 1)</tt>, then the +end of <tt>thread1()</tt>'s grace period must precede the +beginning of <tt>thread2()</tt>'s grace period. +This mean that the two RCU read-side critical sections cannot overlap, +guaranteeing that <tt>(r3 == 1)</tt>. +As a result, the outcome: + +<blockquote> +<pre> +(r1 == 1 && r2 == 1 && r3 == 0 && r4 == 1) +</pre> +</blockquote> + +cannot happen. + +<p> +This non-requirement was also non-premeditated, but became apparent +when studying RCU's interaction with memory ordering. + +<h3><a name="Read-Side Critical Sections Don't Partition Grace Periods"> +Read-Side Critical Sections Don't Partition Grace Periods</a></h3> + +<p> +It is also tempting to assume that if an RCU read-side critical section +happens between a pair of grace periods, then those grace periods cannot +overlap. +However, this temptation leads nowhere good, as can be illustrated by +the following, with all variables initially zero: + +<blockquote> +<pre> + 1 void thread0(void) + 2 { + 3 rcu_read_lock(); + 4 WRITE_ONCE(a, 1); + 5 WRITE_ONCE(b, 1); + 6 rcu_read_unlock(); + 7 } + 8 + 9 void thread1(void) +10 { +11 r1 = READ_ONCE(a); +12 synchronize_rcu(); +13 WRITE_ONCE(c, 1); +14 } +15 +16 void thread2(void) +17 { +18 rcu_read_lock(); +19 WRITE_ONCE(d, 1); +20 r2 = READ_ONCE(c); +21 rcu_read_unlock(); +22 } +23 +24 void thread3(void) +25 { +26 r3 = READ_ONCE(d); +27 synchronize_rcu(); +28 WRITE_ONCE(e, 1); +29 } +30 +31 void thread4(void) +32 { +33 rcu_read_lock(); +34 r4 = READ_ONCE(b); +35 r5 = READ_ONCE(e); +36 rcu_read_unlock(); +37 } +</pre> +</blockquote> + +<p> +In this case, the outcome: + +<blockquote> +<pre> +(r1 == 1 && r2 == 1 && r3 == 1 && r4 == 0 && r5 == 1) +</pre> +</blockquote> + +is entirely possible, as illustrated below: + +<p><img src="ReadersPartitionGP1.svg" alt="ReadersPartitionGP1.svg" width="100%"></p> + +<p> +Again, an RCU read-side critical section can overlap almost all of a +given grace period, just so long as it does not overlap the entire +grace period. +As a result, an RCU read-side critical section cannot partition a pair +of RCU grace periods. + +<p>@@QQ@@ +How long a sequence of grace periods, each separated by an RCU read-side +critical section, would be required to partition the RCU read-side +critical sections at the beginning and end of the chain? +<p>@@QQA@@ +In theory, an infinite number. +In practice, an unknown number that is sensitive to both implementation +details and timing considerations. +Therefore, even in practice, RCU users must abide by the theoretical rather +than the practical answer. +<p>@@QQE@@ + +<h3><a name="Disabling Preemption Does Not Block Grace Periods"> +Disabling Preemption Does Not Block Grace Periods</a></h3> + +<p> +There was a time when disabling preemption on any given CPU would block +subsequent grace periods. +However, this was an accident of implementation and is not a requirement. +And in the current Linux-kernel implementation, disabling preemption +on a given CPU in fact does not block grace periods, as Oleg Nesterov +<a href="http://marc.info/?l=linux-kernel&m=143431078202914&w=2">demonstrated</a>. + +<p> +If you need a preempt-disable region to block grace periods, you need to add +<tt>rcu_read_lock()</tt> and <tt>rcu_read_unlock()</tt>, for example +as follows: + +<blockquote> +<pre> + 1 preempt_disable(); + 2 rcu_read_lock(); + 3 do_something(); + 4 rcu_read_unlock(); + 5 preempt_enable(); + 6 + 7 /* Spinlocks implicitly disable preemption. */ + 8 spin_lock(&mylock); + 9 rcu_read_lock(); +10 do_something(); +11 rcu_read_unlock(); +12 spin_unlock(&mylock); +</pre> +</blockquote> + +<p> +In theory, you could enter the RCU read-side critical section first, +but it is more efficient to keep the entire RCU read-side critical +section contained in the preempt-disable region as shown above. +Of course, RCU read-side critical sections that extend outside of +preempt-disable regions will work correctly, but such critical sections +can be preempted, which forces <tt>rcu_read_unlock()</tt> to do +more work. +And no, this is <i>not</i> an invitation to enclose all of your RCU +read-side critical sections within preempt-disable regions, because +doing so would degrade real-time response. + +<p> +This non-requirement appeared with preemptible RCU. +If you need a grace period that waits on non-preemptible code regions, use +<a href="#Sched Flavor">RCU-sched</a>. + +<h2><a name="Parallelism Facts of Life">Parallelism Facts of Life</a></h2> + +<p> +These parallelism facts of life are by no means specific to RCU, but +the RCU implementation must abide by them. +They therefore bear repeating: + +<ol> +<li> Any CPU or task may be delayed at any time, + and any attempts to avoid these delays by disabling + preemption, interrupts, or whatever are completely futile. + This is most obvious in preemptible user-level + environments and in virtualized environments (where + a given guest OS's VCPUs can be preempted at any time by + the underlying hypervisor), but can also happen in bare-metal + environments due to ECC errors, NMIs, and other hardware + events. + Although a delay of more than about 20 seconds can result + in splats, the RCU implementation is obligated to use + algorithms that can tolerate extremely long delays, but where + “extremely long” is not long enough to allow + wrap-around when incrementing a 64-bit counter. +<li> Both the compiler and the CPU can reorder memory accesses. + Where it matters, RCU must use compiler directives and + memory-barrier instructions to preserve ordering. +<li> Conflicting writes to memory locations in any given cache line + will result in expensive cache misses. + Greater numbers of concurrent writes and more-frequent + concurrent writes will result in more dramatic slowdowns. + RCU is therefore obligated to use algorithms that have + sufficient locality to avoid significant performance and + scalability problems. +<li> As a rough rule of thumb, only one CPU's worth of processing + may be carried out under the protection of any given exclusive + lock. + RCU must therefore use scalable locking designs. +<li> Counters are finite, especially on 32-bit systems. + RCU's use of counters must therefore tolerate counter wrap, + or be designed such that counter wrap would take way more + time than a single system is likely to run. + An uptime of ten years is quite possible, a runtime + of a century much less so. + As an example of the latter, RCU's dyntick-idle nesting counter + allows 54 bits for interrupt nesting level (this counter + is 64 bits even on a 32-bit system). + Overflowing this counter requires 2<sup>54</sup> + half-interrupts on a given CPU without that CPU ever going idle. + If a half-interrupt happened every microsecond, it would take + 570 years of runtime to overflow this counter, which is currently + believed to be an acceptably long time. +<li> Linux systems can have thousands of CPUs running a single + Linux kernel in a single shared-memory environment. + RCU must therefore pay close attention to high-end scalability. +</ol> + +<p> +This last parallelism fact of life means that RCU must pay special +attention to the preceding facts of life. +The idea that Linux might scale to systems with thousands of CPUs would +have been met with some skepticism in the 1990s, but these requirements +would have otherwise have been unsurprising, even in the early 1990s. + +<h2><a name="Quality-of-Implementation Requirements">Quality-of-Implementation Requirements</a></h2> + +<p> +These sections list quality-of-implementation requirements. +Although an RCU implementation that ignores these requirements could +still be used, it would likely be subject to limitations that would +make it inappropriate for industrial-strength production use. +Classes of quality-of-implementation requirements are as follows: + +<ol> +<li> <a href="#Specialization">Specialization</a> +<li> <a href="#Performance and Scalability">Performance and Scalability</a> +<li> <a href="#Composability">Composability</a> +<li> <a href="#Corner Cases">Corner Cases</a> +</ol> + +<p> +These classes is covered in the following sections. + +<h3><a name="Specialization">Specialization</a></h3> + +<p> +RCU is and always has been intended primarily for read-mostly situations, as +illustrated by the following figure. +This means that RCU's read-side primitives are optimized, often at the +expense of its update-side primitives. + +<p><img src="RCUApplicability.svg" alt="RCUApplicability.svg" width="70%"></p> + +<p> +This focus on read-mostly situations means that RCU must interoperate +with other synchronization primitives. +For example, the <tt>add_gp()</tt> and <tt>remove_gp_synchronous()</tt> +examples discussed earlier use RCU to protect readers and locking to +coordinate updaters. +However, the need extends much farther, requiring that a variety of +synchronization primitives be legal within RCU read-side critical sections, +including spinlocks, sequence locks, atomic operations, reference +counters, and memory barriers. + +<p>@@QQ@@ +What about sleeping locks? +<p>@@QQA@@ +These are forbidden within Linux-kernel RCU read-side critical sections +because it is not legal to place a quiescent state (in this case, +voluntary context switch) within an RCU read-side critical section. +However, sleeping locks may be used within userspace RCU read-side critical +sections, and also within Linux-kernel sleepable RCU +<a href="#Sleepable RCU">(SRCU)</a> +read-side critical sections. +In addition, the -rt patchset turns spinlocks into a sleeping locks so +that the corresponding critical sections can be preempted, which +also means that these sleeplockified spinlocks (but not other sleeping locks!) +may be acquire within -rt-Linux-kernel RCU read-side critical sections. + +<p> +Note that it <i>is</i> legal for a normal RCU read-side critical section +to conditionally acquire a sleeping locks (as in <tt>mutex_trylock()</tt>), +but only as long as it does not loop indefinitely attempting to +conditionally acquire that sleeping locks. +The key point is that things like <tt>mutex_trylock()</tt> +either return with the mutex held, or return an error indication if +the mutex was not immediately available. +Either way, <tt>mutex_trylock()</tt> returns immediately without sleeping. +<p>@@QQE@@ + +<p> +It often comes as a surprise that many algorithms do not require a +consistent view of data, but many can function in that mode, +with network routing being the poster child. +Internet routing algorithms take significant time to propagate +updates, so that by the time an update arrives at a given system, +that system has been sending network traffic the wrong way for +a considerable length of time. +Having a few threads continue to send traffic the wrong way for a +few more milliseconds is clearly not a problem: In the worst case, +TCP retransmissions will eventually get the data where it needs to go. +In general, when tracking the state of the universe outside of the +computer, some level of inconsistency must be tolerated due to +speed-of-light delays if nothing else. + +<p> +Furthermore, uncertainty about external state is inherent in many cases. +For example, a pair of veternarians might use heartbeat to determine +whether or not a given cat was alive. +But how long should they wait after the last heartbeat to decide that +the cat is in fact dead? +Waiting less than 400 milliseconds makes no sense because this would +mean that a relaxed cat would be considered to cycle between death +and life more than 100 times per minute. +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. +One of our pair of veternarians might wait 30 seconds before pronouncing +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 final 30 seconds of the minute following the last heartbeat, as +fancifully illustrated below: + +<p><img src="2013-08-is-it-dead.png" alt="2013-08-is-it-dead.png" width="431"></p> + +<p> +Interestingly enough, this same situation applies to hardware. +When push comes to shove, how do we tell whether or not some +external server has failed? +We send messages to it periodically, and declare it failed if we +don't receive a response within a given period of time. +Policy decisions can usually tolerate short +periods of inconsistency. +The policy was decided some time ago, and is only now being put into +effect, so a few milliseconds of delay is normally inconsequential. + +<p> +However, there are algorithms that absolutely must see consistent data. +For example, the translation between a user-level SystemV semaphore +ID to the corresponding in-kernel data structure is protected by RCU, +but it is absolutely forbidden to update a semaphore that has just been +removed. +In the Linux kernel, this need for consistency is accommodated by acquiring +spinlocks located in the in-kernel data structure from within +the RCU read-side critical section, and this is indicated by the +green box in the figure above. +Many other techniques may be used, and are in fact used within the +Linux kernel. + +<p> +In short, RCU is not required to maintain consistency, and other +mechanisms may be used in concert with RCU when consistency is required. +RCU's specialization allows it to do its job extremely well, and its +ability to interoperate with other synchronization mechanisms allows +the right mix of synchronization tools to be used for a given job. + +<h3><a name="Performance and Scalability">Performance and Scalability</a></h3> + +<p> +Energy efficiency is a critical component of performance today, +and Linux-kernel RCU implementations must therefore avoid unnecessarily +awakening idle CPUs. +I cannot claim that this requirement was premeditated. +In fact, I learned of it during a telephone conversation in which I +was given “frank and open” feedback on the importance +of energy efficiency in battery-powered systems and on specific +energy-efficiency shortcomings of the Linux-kernel RCU implementation. +In my experience, the battery-powered embedded community will consider +any unnecessary wakeups to be extremely unfriendly acts. +So much so that mere Linux-kernel-mailing-list posts are +insufficient to vent their ire. + +<p> +Memory consumption is not particularly important for in most +situations, and has become decreasingly +so as memory sizes have expanded and memory +costs have plummeted. +However, as I learned from Matt Mackall's +<a href="http://elinux.org/Linux_Tiny-FAQ">bloatwatch</a> +efforts, memory footprint is critically important on single-CPU systems with +non-preemptible (<tt>CONFIG_PREEMPT=n</tt>) kernels, and thus +<a href="http://lkml.org/lkml/2009/1/14/449">tiny RCU</a> +was born. +Josh Triplett has since taken over the small-memory banner with his +<a href="https://tiny.wiki.kernel.org/">Linux kernel tinification</a> +project, which resulted in +<a href="#Sleepable RCU">SRCU</a> +becoming optional for those kernels not needing it. + +<p> +The remaining performance requirements are, for the most part, +unsurprising. +For example, in keeping with RCU's read-side specialization, +<tt>rcu_dereference()</tt> should have negligible overhead (for +example, suppression of a few minor compiler optimizations). +Similarly, in non-preemptible environments, <tt>rcu_read_lock()</tt> and +<tt>rcu_read_unlock()</tt> should have exactly zero overhead. + +<p> +In preemptible environments, in the case where the RCU read-side +critical section was not preempted (as will be the case for the +highest-priority real-time process), <tt>rcu_read_lock()</tt> and +<tt>rcu_read_unlock()</tt> should have minimal overhead. +In particular, they should not contain atomic read-modify-write +operations, memory-barrier instructions, preemption disabling, +interrupt disabling, or backwards branches. +However, in the case where the RCU read-side critical section was preempted, +<tt>rcu_read_unlock()</tt> may acquire spinlocks and disable interrupts. +This is why it is better to nest an RCU read-side critical section +within a preempt-disable region than vice versa, at least in cases +where that critical section is short enough to avoid unduly degrading +real-time latencies. + +<p> +The <tt>synchronize_rcu()</tt> grace-period-wait primitive is +optimized for throughput. +It may therefore incur several milliseconds of latency in addition to +the duration of the longest RCU read-side critical section. +On the other hand, multiple concurrent invocations of +<tt>synchronize_rcu()</tt> are required to use batching optimizations +so that they can be satisfied by a single underlying grace-period-wait +operation. +For example, in the Linux kernel, it is not unusual for a single +grace-period-wait operation to serve more than +<a href="https://www.usenix.org/conference/2004-usenix-annual-technical-conference/making-rcu-safe-deep-sub-millisecond-response">1,000 separate invocations</a> +of <tt>synchronize_rcu()</tt>, thus amortizing the per-invocation +overhead down to nearly zero. +However, the grace-period optimization is also required to avoid +measurable degradation of real-time scheduling and interrupt latencies. + +<p> +In some cases, the multi-millisecond <tt>synchronize_rcu()</tt> +latencies are unacceptable. +In these cases, <tt>synchronize_rcu_expedited()</tt> may be used +instead, reducing the grace-period latency down to a few tens of +microseconds on small systems, at least in cases where the RCU read-side +critical sections are short. +There are currently no special latency requirements for +<tt>synchronize_rcu_expedited()</tt> on large systems, but, +consistent with the empirical nature of the RCU specification, +that is subject to change. +However, there most definitely are scalability requirements: +A storm of <tt>synchronize_rcu_expedited()</tt> invocations on 4096 +CPUs should at least make reasonable forward progress. +In return for its shorter latencies, <tt>synchronize_rcu_expedited()</tt> +is permitted to impose modest degradation of real-time latency +on non-idle online CPUs. +That said, it will likely be necessary to take further steps to reduce this +degradation, hopefully to roughly that of a scheduling-clock interrupt. + +<p> +There are a number of situations where even +<tt>synchronize_rcu_expedited()</tt>'s reduced grace-period +latency is unacceptable. +In these situations, the asynchronous <tt>call_rcu()</tt> can be +used in place of <tt>synchronize_rcu()</tt> as follows: + +<blockquote> +<pre> + 1 struct foo { + 2 int a; + 3 int b; + 4 struct rcu_head rh; + 5 }; + 6 + 7 static void remove_gp_cb(struct rcu_head *rhp) + 8 { + 9 struct foo *p = container_of(rhp, struct foo, rh); +10 +11 kfree(p); +12 } +13 +14 bool remove_gp_asynchronous(void) +15 { +16 struct foo *p; +17 +18 spin_lock(&gp_lock); +19 p = rcu_dereference(gp); +20 if (!p) { +21 spin_unlock(&gp_lock); +22 return false; +23 } +24 rcu_assign_pointer(gp, NULL); +25 call_rcu(&p->rh, remove_gp_cb); +26 spin_unlock(&gp_lock); +27 return true; +28 } +</pre> +</blockquote> + +<p> +A definition of <tt>struct foo</tt> is finally needed, and appears +on lines 1-5. +The function <tt>remove_gp_cb()</tt> is passed to <tt>call_rcu()</tt> +on line 25, and will be invoked after the end of a subsequent +grace period. +This gets the same effect as <tt>remove_gp_synchronous()</tt>, +but without forcing the updater to wait for a grace period to elapse. +The <tt>call_rcu()</tt> function may be used in a number of +situations where neither <tt>synchronize_rcu()</tt> nor +<tt>synchronize_rcu_expedited()</tt> would be legal, +including within preempt-disable code, <tt>local_bh_disable()</tt> code, +interrupt-disable code, and interrupt handlers. +However, even <tt>call_rcu()</tt> is illegal within NMI handlers. +The callback function (<tt>remove_gp_cb()</tt> in this case) will be +executed within softirq (software interrupt) environment within the +Linux kernel, +either within a real softirq handler or under the protection +of <tt>local_bh_disable()</tt>. +In both the Linux kernel and in userspace, it is bad practice to +write an RCU callback function that takes too long. +Long-running operations should be relegated to separate threads or +(in the Linux kernel) workqueues. + +<p>@@QQ@@ +Why does line 19 use <tt>rcu_access_pointer()</tt>? +After all, <tt>call_rcu()</tt> on line 25 stores into the +structure, which would interact badly with concurrent insertions. +Doesn't this mean that <tt>rcu_dereference()</tt> is required? +<p>@@QQA@@ +Presumably the <tt>->gp_lock</tt> acquired on line 18 excludes +any changes, including any insertions that <tt>rcu_dereference()</tt> +would protect against. +Therefore, any insertions will be delayed until after <tt>->gp_lock</tt> +is released on line 25, which in turn means that +<tt>rcu_access_pointer()</tt> suffices. +<p>@@QQE@@ + +<p> +However, all that <tt>remove_gp_cb()</tt> is doing is +invoking <tt>kfree()</tt> on the data element. +This is a common idiom, and is supported by <tt>kfree_rcu()</tt>, +which allows “fire and forget” operation as shown below: + +<blockquote> +<pre> + 1 struct foo { + 2 int a; + 3 int b; + 4 struct rcu_head rh; + 5 }; + 6 + 7 bool remove_gp_faf(void) + 8 { + 9 struct foo *p; +10 +11 spin_lock(&gp_lock); +12 p = rcu_dereference(gp); +13 if (!p) { +14 spin_unlock(&gp_lock); +15 return false; +16 } +17 rcu_assign_pointer(gp, NULL); +18 kfree_rcu(p, rh); +19 spin_unlock(&gp_lock); +20 return true; +21 } +</pre> +</blockquote> + +<p> +Note that <tt>remove_gp_faf()</tt> simply invokes +<tt>kfree_rcu()</tt> and proceeds, without any need to pay any +further attention to the subsequent grace period and <tt>kfree()</tt>. +It is permissible to invoke <tt>kfree_rcu()</tt> from the same +environments as for <tt>call_rcu()</tt>. +Interestingly enough, DYNIX/ptx had the equivalents of +<tt>call_rcu()</tt> and <tt>kfree_rcu()</tt>, but not +<tt>synchronize_rcu()</tt>. +This was due to the fact that RCU was not heavily used within DYNIX/ptx, +so the very few places that needed something like +<tt>synchronize_rcu()</tt> simply open-coded it. + +<p>@@QQ@@ +Earlier it was claimed that <tt>call_rcu()</tt> and +<tt>kfree_rcu()</tt> allowed updaters to avoid being blocked +by readers. +But how can that be correct, given that the invocation of the callback +and the freeing of the memory (respectively) must still wait for +a grace period to elapse? +<p>@@QQA@@ +We could define things this way, but keep in mind that this sort of +definition would say that updates in garbage-collected languages +cannot complete until the next time the garbage collector runs, +which does not seem at all reasonable. +The key point is that in most cases, an updater using either +<tt>call_rcu()</tt> or <tt>kfree_rcu()</tt> can proceed to the +next update as soon as it has invoked <tt>call_rcu()</tt> or +<tt>kfree_rcu()</tt>, without having to wait for a subsequent +grace period. +<p>@@QQE@@ + +<p> +But what if the updater must wait for the completion of code to be +executed after the end of the grace period, but has other tasks +that can be carried out in the meantime? +The polling-style <tt>get_state_synchronize_rcu()</tt> and +<tt>cond_synchronize_rcu()</tt> functions may be used for this +purpose, as shown below: + +<blockquote> +<pre> + 1 bool remove_gp_poll(void) + 2 { + 3 struct foo *p; + 4 unsigned long s; + 5 + 6 spin_lock(&gp_lock); + 7 p = rcu_access_pointer(gp); + 8 if (!p) { + 9 spin_unlock(&gp_lock); +10 return false; +11 } +12 rcu_assign_pointer(gp, NULL); +13 spin_unlock(&gp_lock); +14 s = get_state_synchronize_rcu(); +15 do_something_while_waiting(); +16 cond_synchronize_rcu(s); +17 kfree(p); +18 return true; +19 } +</pre> +</blockquote> + +<p> +On line 14, <tt>get_state_synchronize_rcu()</tt> obtains a +“cookie” from RCU, +then line 15 carries out other tasks, +and finally, line 16 returns immediately if a grace period has +elapsed in the meantime, but otherwise waits as required. +The need for <tt>get_state_synchronize_rcu</tt> and +<tt>cond_synchronize_rcu()</tt> has appeared quite recently, +so it is too early to tell whether they will stand the test of time. + +<p> +RCU thus provides a range of tools to allow updaters to strike the +required tradeoff between latency, flexibility and CPU overhead. + +<h3><a name="Composability">Composability</a></h3> + +<p> +Composability has received much attention in recent years, perhaps in part +due to the collision of multicore hardware with object-oriented techniques +designed in single-threaded environments for single-threaded use. +And in theory, RCU read-side critical sections may be composed, and in +fact may be nested arbitrarily deeply. +In practice, as with all real-world implementations of composable +constructs, there are limitations. + +<p> +Implementations of RCU for which <tt>rcu_read_lock()</tt> +and <tt>rcu_read_unlock()</tt> generate no code, such as +Linux-kernel RCU when <tt>CONFIG_PREEMPT=n</tt>, can be +nested arbitrarily deeply. +After all, there is no overhead. +Except that if all these instances of <tt>rcu_read_lock()</tt> +and <tt>rcu_read_unlock()</tt> are visible to the compiler, +compilation will eventually fail due to exhausting memory, +mass storage, or user patience, whichever comes first. +If the nesting is not visible to the compiler, as is the case with +mutually recursive functions each in its own translation unit, +stack overflow will result. +If the nesting takes the form of loops, either the control variable +will overflow or (in the Linux kernel) you will get an RCU CPU stall warning. +Nevertheless, this class of RCU implementations is one +of the most composable constructs in existence. + +<p> +RCU implementations that explicitly track nesting depth +are limited by the nesting-depth counter. +For example, the Linux kernel's preemptible RCU limits nesting to +<tt>INT_MAX</tt>. +This should suffice for almost all practical purposes. +That said, a consecutive pair of RCU read-side critical sections +between which there is an operation that waits for a grace period +cannot be enclosed in another RCU read-side critical section. +This is because it is not legal to wait for a grace period within +an RCU read-side critical section: To do so would result either +in deadlock or +in RCU implicitly splitting the enclosing RCU read-side critical +section, neither of which is conducive to a long-lived and prosperous +kernel. + +<p> +In short, although RCU read-side critical sections are highly composable, +care is required in some situations, just as is the case for any other +composable synchronization mechanism. + +<h3><a name="Corner Cases">Corner Cases</a></h3> + +<p> +A given RCU workload might have an endless and intense stream of +RCU read-side critical sections, perhaps even so intense that there +was never a point in time during which there was not at least one +RCU read-side critical section in flight. +RCU cannot allow this situation to block grace periods: As long as +all the RCU read-side critical sections are finite, grace periods +must also be finite. + +<p> +That said, preemptible RCU implementations could potentially result +in RCU read-side critical sections being preempted for long durations, +which has the effect of creating a long-duration RCU read-side +critical section. +This situation can arise only in heavily loaded systems, but systems using +real-time priorities are of course more vulnerable. +Therefore, RCU priority boosting is provided to help deal with this +case. +That said, the exact requirements on RCU priority boosting will likely +evolve as more experience accumulates. + +<p> +Other workloads might have very high update rates. +Although one can argue that such workloads should instead use +something other than RCU, the fact remains that RCU must +handle such workloads gracefully. +This requirement is another factor driving batching of grace periods, +but it is also the driving force behind the checks for large numbers +of queued RCU callbacks in the <tt>call_rcu()</tt> code path. +Finally, high update rates should not delay RCU read-side critical +sections, although some read-side delays can occur when using +<tt>synchronize_rcu_expedited()</tt>, courtesy of this function's use +of <tt>try_stop_cpus()</tt>. +(In the future, <tt>synchronize_rcu_expedited()</tt> will be +converted to use lighter-weight inter-processor interrupts (IPIs), +but this will still disturb readers, though to a much smaller degree.) + +<p> +Although all three of these corner cases were understood in the early +1990s, a simple user-level test consisting of <tt>close(open(path))</tt> +in a tight loop +in the early 2000s suddenly provided a much deeper appreciation of the +high-update-rate corner case. +This test also motivated addition of some RCU code to react to high update +rates, for example, if a given CPU finds itself with more than 10,000 +RCU callbacks queued, it will cause RCU to take evasive action by +more aggressively starting grace periods and more aggressively forcing +completion of grace-period processing. +This evasive action causes the grace period to complete more quickly, +but at the cost of restricting RCU's batching optimizations, thus +increasing the CPU overhead incurred by that grace period. + +<h2><a name="Software-Engineering Requirements"> +Software-Engineering Requirements</a></h2> + +<p> +Between Murphy's Law and “To err is human”, it is necessary to +guard against mishaps and misuse: + +<ol> +<li> It is all too easy to forget to use <tt>rcu_read_lock()</tt> + everywhere that it is needed, so kernels built with + <tt>CONFIG_PROVE_RCU=y</tt> will spat if + <tt>rcu_dereference()</tt> is used outside of an + RCU read-side critical section. + Update-side code can use <tt>rcu_dereference_protected()</tt>, + which takes a + <a href="https://lwn.net/Articles/371986/">lockdep expression</a> + to indicate what is providing the protection. + If the indicated protection is not provided, a lockdep splat + is emitted. + + <p> + Code shared between readers and updaters can use + <tt>rcu_dereference_check()</tt>, which also takes a + lockdep expression, and emits a lockdep splat if neither + <tt>rcu_read_lock()</tt> nor the indicated protection + is in place. + In addition, <tt>rcu_dereference_raw()</tt> is used in those + (hopefully rare) cases where the required protection cannot + be easily described. + Finally, <tt>rcu_read_lock_held()</tt> is provided to + allow a function to verify that it has been invoked within + an RCU read-side critical section. + I was made aware of this set of requirements shortly after Thomas + Gleixner audited a number of RCU uses. +<li> A given function might wish to check for RCU-related preconditions + upon entry, before using any other RCU API. + The <tt>rcu_lockdep_assert()</tt> does this job, + asserting the expression in kernels having lockdep enabled + and doing nothing otherwise. +<li> It is also easy to forget to use <tt>rcu_assign_pointer()</tt> + and <tt>rcu_dereference()</tt>, perhaps (incorrectly) + substituting a simple assignment. + To catch this sort of error, a given RCU-protected pointer may be + tagged with <tt>__rcu</tt>, after which running sparse + with <tt>CONFIG_SPARSE_RCU_POINTER=y</tt> will complain + about simple-assignment accesses to that pointer. + Arnd Bergmann made me aware of this requirement, and also + supplied the needed + <a href="http://lwn.net/Articles/376011/">patch series</a>. +<li> Kernels built with <tt>CONFIG_DEBUG_OBJECTS_RCU_HEAD=y</tt> + will splat if a data element is passed to <tt>call_rcu()</tt> + twice in a row, without a grace period in between. + (This error is similar to a double free.) + The corresponding <tt>rcu_head</tt> structures that are + dynamically allocated are automatically tracked, but + <tt>rcu_head</tt> structures allocated on the stack + must be initialized with <tt>init_rcu_head_on_stack()</tt> + and cleaned up with <tt>destroy_rcu_head_on_stack()</tt>. + Similarly, statically allocated non-stack <tt>rcu_head</tt> + structures must be initialized with <tt>init_rcu_head()</tt> + and cleaned up with <tt>destroy_rcu_head()</tt>. + Mathieu Desnoyers made me aware of this requirement, and also + supplied the needed + <a href="https://lkml.org/lkml/2010/3/18/417">patch</a>. +<li> An infinite loop in an RCU read-side critical section will + eventually trigger an RCU CPU stall warning splat. + However, RCU is not obligated to produce this splat + unless there is a grace period waiting on that particular + RCU read-side critical section. + This requirement made itself known in the early 1990s, pretty + much the first time that it was necessary to debug a CPU stall. +<li> Although it would be very good to detect pointers leaking out + of RCU read-side critical sections, there is currently no + good way of doing this. + One complication is the need to distinguish between pointers + leaking and pointers that have been handed off from RCU to + some other synchronization mechanism, for example, reference + counting. +<li> In kernels built with <tt>CONFIG_RCU_TRACE=y</tt>, RCU-related + information is provided via both debugfs and event tracing. +<li> Open-coded use of <tt>rcu_assign_pointer()</tt> and + <tt>rcu_dereference()</tt> to create typical linked + data structures can be surprisingly error-prone. + Therefore, RCU-protected + <a href="http://lwn.net/Articles/609973/#RCU List APIs">linked lists</a> + and, more recently, RCU-protected + <a href="https://lwn.net/Articles/612100/">hash tables</a> + are available. + Many other special-purpose RCU-protected data structures are + available in the Linux kernel and the userspace RCU library. +<li> Some linked structures are created at compile time, but still + require <tt>__rcu</tt> checking. + The <tt>RCU_POINTER_INITIALIZER()</tt> macro serves this + purpose. +<li> It is not necessary to use <tt>rcu_assign_pointer()</tt> + when creating linked structures that are to be published via + a single external pointer. + The <tt>RCU_INIT_POINTER()</tt> macro is provided for + this task and also for assigning <tt>NULL</tt> pointers + at runtime. +</ol> + +<p> +This not a hard-and-fast list: RCU's diagnostic capabilities will +continue to be guided by the number and type of usage bugs found +in real-world RCU usage. + +<h2><a name="Linux Kernel Complications">Linux Kernel Complications</a></h2> + +<p> +The Linux kernel provides an interesting environment for all kinds of +software, including RCU. +Some of the relevant points of interest are as follows: + +<ol> +<li> <a href="#Configuration">Configuration</a>. +<li> <a href="#Firmware Interface">Firmware Interface</a>. +<li> <a href="#Early Boot">Early Boot</a>. +<li> <a href="#Interrupts and NMIs"> + Interrupts and non-maskable interrupts (NMIs)</a>. +<li> <a href="#Loadable Modules">Loadable Modules</a>. +<li> <a href="#Hotplug CPU">Hotplug CPU</a>. +<li> <a href="#Scheduler and RCU">Scheduler and RCU</a>. +<li> <a href="#Tracing and RCU">Tracing and RCU</a>. +<li> <a href="#Energy Efficiency">Energy Efficiency</a>. +<li> <a href="#Performance, Scalability, Response Time, and Reliability"> + Performance, Scalability, Response Time, and Reliability</a>. +</ol> + +<p> +This list is probably incomplete, but it does give a feel for the +most notable Linux-kernel complications. +Each of the following sections covers one of the above topics. + +<h3><a name="Configuration">Configuration</a></h3> + +<p> +RCU's goal is automatic configuration, so that almost nobody +needs to worry about RCU's <tt>Kconfig</tt> options. +And for almost all users, RCU does in fact work well +“out of the box.” + +<p> +However, there are specialized use cases that are handled by +kernel boot parameters and <tt>Kconfig</tt> options. +Unfortunately, the <tt>Kconfig</tt> system will explicitly ask users +about new <tt>Kconfig</tt> options, which requires almost all of them +be hidden behind a <tt>CONFIG_RCU_EXPERT</tt> <tt>Kconfig</tt> option. + +<p> +This all should be quite obvious, but the fact remains that +Linus Torvalds recently had to +<a href="http://marc.info/?l=linux-kernel&m=142905739823385">remind</a> +me of this requirement. + +<h3><a name="Firmware Interface">Firmware Interface</a></h3> + +<p> +In many cases, kernel obtains information about the system from the +firmware, and sometimes things are lost in translation. +Or the translation is accurate, but the original message is bogus. + +<p> +For example, some systems' firmware overreports the number of CPUs, +sometimes by a large factor. +If RCU naively believed the firmware, as it used to do, +it would create too many per-CPU kthreads. +Although the resulting system will still run correctly, the extra +kthreads needlessly consume memory and can cause confusion +when they show up in <tt>ps</tt> listings. + +<p> +RCU must therefore wait for a given CPU to actually come online before +it can allow itself to believe that the CPU actually exists. +The resulting “ghost CPUs” (which are never going to +come online) cause a number of +<a href="http://paulmck.livejournal.com/37494.html">interesting complications</a>. + +<h3><a name="Early Boot">Early Boot</a></h3> + +<p> +The Linux kernel's boot sequence is an interesting process, +and RCU is used early, even before <tt>rcu_init()</tt> +is invoked. +In fact, a number of RCU's primitives can be used as soon as the +initial task's <tt>task_struct</tt> is available and the +boot CPU's per-CPU variables are set up. +The read-side primitives (<tt>rcu_read_lock()</tt>, +<tt>rcu_read_unlock()</tt>, <tt>rcu_dereference()</tt>, +and <tt>rcu_access_pointer()</tt>) will operate normally very early on, +as will <tt>rcu_assign_pointer()</tt>. + +<p> +Although <tt>call_rcu()</tt> may be invoked at any +time during boot, callbacks are not guaranteed to be invoked until after +the scheduler is fully up and running. +This delay in callback invocation is due to the fact that RCU does not +invoke callbacks until it is fully initialized, and this full initialization +cannot occur until after the scheduler has initialized itself to the +point where RCU can spawn and run its kthreads. +In theory, it would be possible to invoke callbacks earlier, +however, this is not a panacea because there would be severe restrictions +on what operations those callbacks could invoke. + +<p> +Perhaps surprisingly, <tt>synchronize_rcu()</tt>, +<a href="#Bottom-Half Flavor"><tt>synchronize_rcu_bh()</tt></a> +(<a href="#Bottom-Half Flavor">discussed below</a>), +and +<a href="#Sched Flavor"><tt>synchronize_sched()</tt></a> +will all operate normally +during very early boot, the reason being that there is only one CPU +and preemption is disabled. +This means that the call <tt>synchronize_rcu()</tt> (or friends) +itself is a quiescent +state and thus a grace period, so the early-boot implementation can +be a no-op. + +<p> +Both <tt>synchronize_rcu_bh()</tt> and <tt>synchronize_sched()</tt> +continue to operate normally through the remainder of boot, courtesy +of the fact that preemption is disabled across their RCU read-side +critical sections and also courtesy of the fact that there is still +only one CPU. +However, once the scheduler starts initializing, preemption is enabled. +There is still only a single CPU, but the fact that preemption is enabled +means that the no-op implementation of <tt>synchronize_rcu()</tt> no +longer works in <tt>CONFIG_PREEMPT=y</tt> kernels. +Therefore, as soon as the scheduler starts initializing, the early-boot +fastpath is disabled. +This means that <tt>synchronize_rcu()</tt> switches to its runtime +mode of operation where it posts callbacks, which in turn means that +any call to <tt>synchronize_rcu()</tt> will block until the corresponding +callback is invoked. +Unfortunately, the callback cannot be invoked until RCU's runtime +grace-period machinery is up and running, which cannot happen until +the scheduler has initialized itself sufficiently to allow RCU's +kthreads to be spawned. +Therefore, invoking <tt>synchronize_rcu()</tt> during scheduler +initialization can result in deadlock. + +<p>@@QQ@@ +So what happens with <tt>synchronize_rcu()</tt> during +scheduler initialization for <tt>CONFIG_PREEMPT=n</tt> +kernels? +<p>@@QQA@@ +In <tt>CONFIG_PREEMPT=n</tt> kernel, <tt>synchronize_rcu()</tt> +maps directly to <tt>synchronize_sched()</tt>. +Therefore, <tt>synchronize_rcu()</tt> works normally throughout +boot in <tt>CONFIG_PREEMPT=n</tt> kernels. +However, your code must also work in <tt>CONFIG_PREEMPT=y</tt> kernels, +so it is still necessary to avoid invoking <tt>synchronize_rcu()</tt> +during scheduler initialization. +<p>@@QQE@@ + +<p> +I learned of these boot-time requirements as a result of a series of +system hangs. + +<h3><a name="Interrupts and NMIs">Interrupts and NMIs</a></h3> + +<p> +The Linux kernel has interrupts, and RCU read-side critical sections are +legal within interrupt handlers and within interrupt-disabled regions +of code, as are invocations of <tt>call_rcu()</tt>. + +<p> +Some Linux-kernel architectures can enter an interrupt handler from +non-idle process context, and then just never leave it, instead stealthily +transitioning back to process context. +This trick is sometimes used to invoke system calls from inside the kernel. +These “half-interrupts” mean that RCU has to be very careful +about how it counts interrupt nesting levels. +I learned of this requirement the hard way during a rewrite +of RCU's dyntick-idle code. + +<p> +The Linux kernel has non-maskable interrupts (NMIs), and +RCU read-side critical sections are legal within NMI handlers. +Thankfully, RCU update-side primitives, including +<tt>call_rcu()</tt>, are prohibited within NMI handlers. + +<p> +The name notwithstanding, some Linux-kernel architectures +can have nested NMIs, which RCU must handle correctly. +Andy Lutomirski +<a href="https://lkml.org/lkml/2014/11/21/642">surprised me</a> +with this requirement; +he also kindly surprised me with +<a href="https://lkml.org/lkml/2014/11/22/1">an algorithm</a> +that meets this requirement. + +<h3><a name="Loadable Modules">Loadable Modules</a></h3> + +<p> +The Linux kernel has loadable modules, and these modules can +also be unloaded. +After a given module has been unloaded, any attempt to call +one of its functions results in a segmentation fault. +The module-unload functions must therefore cancel any +delayed calls to loadable-module functions, for example, +any outstanding <tt>mod_timer()</tt> must be dealt with +via <tt>del_timer_sync()</tt> or similar. + +<p> +Unfortunately, there is no way to cancel an RCU callback; +once you invoke <tt>call_rcu()</tt>, the callback function is +going to eventually be invoked, unless the system goes down first. +Because it is normally considered socially irresponsible to crash the system +in response to a module unload request, we need some other way +to deal with in-flight RCU callbacks. + +<p> +RCU therefore provides +<tt><a href="http://lwn.net/Articles/217484/">rcu_barrier()</a></tt>, +which waits until all in-flight RCU callbacks have been invoked. +If a module uses <tt>call_rcu()</tt>, its exit function should therefore +prevent any future invocation of <tt>call_rcu()</tt>, then invoke +<tt>rcu_barrier()</tt>. +In theory, the underlying module-unload code could invoke +<tt>rcu_barrier()</tt> unconditionally, but in practice this would +incur unacceptable latencies. + +<p> +Nikita Danilov noted this requirement for an analogous filesystem-unmount +situation, and Dipankar Sarma incorporated <tt>rcu_barrier()</tt> into RCU. +The need for <tt>rcu_barrier()</tt> for module unloading became +apparent later. + +<h3><a name="Hotplug CPU">Hotplug CPU</a></h3> + +<p> +The Linux kernel supports CPU hotplug, which means that CPUs +can come and go. +It is of course illegal to use any RCU API member from an offline CPU. +This requirement was present from day one in DYNIX/ptx, but +on the other hand, the Linux kernel's CPU-hotplug implementation +is “interesting.” + +<p> +The Linux-kernel CPU-hotplug implementation has notifiers that +are used to allow the various kernel subsystems (including RCU) +to respond appropriately to a given CPU-hotplug operation. +Most RCU operations may be invoked from CPU-hotplug notifiers, +including even normal synchronous grace-period operations +such as <tt>synchronize_rcu()</tt>. +However, expedited grace-period operations such as +<tt>synchronize_rcu_expedited()</tt> are not supported, +due to the fact that current implementations block CPU-hotplug +operations, which could result in deadlock. + +<p> +In addition, all-callback-wait operations such as +<tt>rcu_barrier()</tt> are also not supported, due to the +fact that there are phases of CPU-hotplug operations where +the outgoing CPU's callbacks will not be invoked until after +the CPU-hotplug operation ends, which could also result in deadlock. + +<h3><a name="Scheduler and RCU">Scheduler and RCU</a></h3> + +<p> +RCU depends on the scheduler, and the scheduler uses RCU to +protect some of its data structures. +This means the scheduler is forbidden from acquiring +the runqueue locks and the priority-inheritance locks +in the middle of an outermost RCU read-side critical section unless +it also releases them before exiting that same +RCU read-side critical section. +This same prohibition also applies to any lock that is acquired +while holding any lock to which this prohibition applies. +Violating this rule results in deadlock. + +<p> +For RCU's part, the preemptible-RCU <tt>rcu_read_unlock()</tt> +implementation must be written carefully to avoid similar deadlocks. +In particular, <tt>rcu_read_unlock()</tt> must tolerate an +interrupt where the interrupt handler invokes both +<tt>rcu_read_lock()</tt> and <tt>rcu_read_unlock()</tt>. +This possibility requires <tt>rcu_read_unlock()</tt> to use +negative nesting levels to avoid destructive recursion via +interrupt handler's use of RCU. + +<p> +This pair of mutual scheduler-RCU requirements came as a +<a href="http://lwn.net/Articles/453002/">complete surprise</a>. + +<p> +As noted above, RCU makes use of kthreads, and it is necessary to +avoid excessive CPU-time accumulation by these kthreads. +This requirement was no surprise, but RCU's violation of it +when running context-switch-heavy workloads when built with +<tt>CONFIG_NO_HZ_FULL=y</tt> +<a href="http://www.rdrop.com/users/paulmck/scalability/paper/BareMetal.2015.01.15b.pdf">did come as a surprise [PDF]</a>. +RCU has made good progress towards meeting this requirement, even +for context-switch-have <tt>CONFIG_NO_HZ_FULL=y</tt> workloads, +but there is room for further improvement. + +<h3><a name="Tracing and RCU">Tracing and RCU</a></h3> + +<p> +It is possible to use tracing on RCU code, but tracing itself +uses RCU. +For this reason, <tt>rcu_dereference_raw_notrace()</tt> +is provided for use by tracing, which avoids the destructive +recursion that could otherwise ensue. +This API is also used by virtualization in some architectures, +where RCU readers execute in environments in which tracing +cannot be used. +The tracing folks both located the requirement and provided the +needed fix, so this surprise requirement was relatively painless. + +<h3><a name="Energy Efficiency">Energy Efficiency</a></h3> + +<p> +Interrupting idle CPUs is considered socially unacceptable, +especially by people with battery-powered embedded systems. +RCU therefore conserves energy by detecting which CPUs are +idle, including tracking CPUs that have been interrupted from idle. +This is a large part of the energy-efficiency requirement, +so I learned of this via an irate phone call. + +<p> +Because RCU avoids interrupting idle CPUs, it is illegal to +execute an RCU read-side critical section on an idle CPU. +(Kernels built with <tt>CONFIG_PROVE_RCU=y</tt> will splat +if you try it.) +The <tt>RCU_NONIDLE()</tt> macro and <tt>_rcuidle</tt> +event tracing is provided to work around this restriction. +In addition, <tt>rcu_is_watching()</tt> may be used to +test whether or not it is currently legal to run RCU read-side +critical sections on this CPU. +I learned of the need for diagnostics on the one hand +and <tt>RCU_NONIDLE()</tt> on the other while inspecting +idle-loop code. +Steven Rostedt supplied <tt>_rcuidle</tt> event tracing, +which is used quite heavily in the idle loop. + +<p> +It is similarly socially unacceptable to interrupt an +<tt>nohz_full</tt> CPU running in userspace. +RCU must therefore track <tt>nohz_full</tt> userspace +execution. +And in +<a href="https://lwn.net/Articles/558284/"><tt>CONFIG_NO_HZ_FULL_SYSIDLE=y</tt></a> +kernels, RCU must separately track idle CPUs on the one hand and +CPUs that are either idle or executing in userspace on the other. +In both cases, RCU must be able to sample state at two points in +time, and be able to determine whether or not some other CPU spent +any time idle and/or executing in userspace. + +<p> +These energy-efficiency requirements have proven quite difficult to +understand and to meet, for example, there have been more than five +clean-sheet rewrites of RCU's energy-efficiency code, the last of +which was finally able to demonstrate +<a href="http://www.rdrop.com/users/paulmck/realtime/paper/AMPenergy.2013.04.19a.pdf">real energy savings running on real hardware [PDF]</a>. +As noted earlier, +I learned of many of these requirements via angry phone calls: +Flaming me on the Linux-kernel mailing list was apparently not +sufficient to fully vent their ire at RCU's energy-efficiency bugs! + +<h3><a name="Performance, Scalability, Response Time, and Reliability"> +Performance, Scalability, Response Time, and Reliability</a></h3> + +<p> +Expanding on the +<a href="#Performance and Scalability">earlier discussion</a>, +RCU is used heavily by hot code paths in performance-critical +portions of the Linux kernel's networking, security, virtualization, +and scheduling code paths. +RCU must therefore use efficient implementations, especially in its +read-side primitives. +To that end, it would be good if preemptible RCU's implementation +of <tt>rcu_read_lock()</tt> could be inlined, however, doing +this requires resolving <tt>#include</tt> issues with the +<tt>task_struct</tt> structure. + +<p> +The Linux kernel supports hardware configurations with up to +4096 CPUs, which means that RCU must be extremely scalable. +Algorithms that involve frequent acquisitions of global locks or +frequent atomic operations on global variables simply cannot be +tolerated within the RCU implementation. +RCU therefore makes heavy use of a combining tree based on the +<tt>rcu_node</tt> structure. +RCU is required to tolerate all CPUs continuously invoking any +combination of RCU's runtime primitives with minimal per-operation +overhead. +In fact, in many cases, increasing load must <i>decrease</i> the +per-operation overhead, witness the batching optimizations for +<tt>synchronize_rcu()</tt>, <tt>call_rcu()</tt>, +<tt>synchronize_rcu_expedited()</tt>, and <tt>rcu_barrier()</tt>. +As a general rule, RCU must cheerfully accept whatever the +rest of the Linux kernel decides to throw at it. + +<p> +The Linux kernel is used for real-time workloads, especially +in conjunction with the +<a href="https://rt.wiki.kernel.org/index.php/Main_Page">-rt patchset</a>. +The real-time-latency response requirements are such that the +traditional approach of disabling preemption across RCU +read-side critical sections is inappropriate. +Kernels built with <tt>CONFIG_PREEMPT=y</tt> therefore +use an RCU implementation that allows RCU read-side critical +sections to be preempted. +This requirement made its presence known after users made it +clear that an earlier +<a href="http://lwn.net/Articles/107930/">real-time patch</a> +did not meet their needs, in conjunction with some +<a href="https://lkml.org/lkml/2005/3/17/199">RCU issues</a> +encountered by a very early version of the -rt patchset. + +<p> +In addition, RCU must make do with a sub-100-microsecond real-time latency +budget. +In fact, on smaller systems with the -rt patchset, the Linux kernel +provides sub-20-microsecond real-time latencies for the whole kernel, +including RCU. +RCU's scalability and latency must therefore be sufficient for +these sorts of configurations. +To my surprise, the sub-100-microsecond real-time latency budget +<a href="http://www.rdrop.com/users/paulmck/realtime/paper/bigrt.2013.01.31a.LCA.pdf"> +applies to even the largest systems [PDF]</a>, +up to and including systems with 4096 CPUs. +This real-time requirement motivated the grace-period kthread, which +also simplified handling of a number of race conditions. + +<p> +Finally, RCU's status as a synchronization primitive means that +any RCU failure can result in arbitrary memory corruption that can be +extremely difficult to debug. +This means that RCU must be extremely reliable, which in +practice also means that RCU must have an aggressive stress-test +suite. +This stress-test suite is called <tt>rcutorture</tt>. + +<p> +Although the need for <tt>rcutorture</tt> was no surprise, +the current immense popularity of the Linux kernel is posing +interesting—and perhaps unprecedented—validation +challenges. +To see this, keep in mind that there are well over one billion +instances of the Linux kernel running today, given Android +smartphones, Linux-powered televisions, and servers. +This number can be expected to increase sharply with the advent of +the celebrated Internet of Things. + +<p> +Suppose that RCU contains a race condition that manifests on average +once per million years of runtime. +This bug will be occurring about three times per <i>day</i> across +the installed base. +RCU could simply hide behind hardware error rates, given that no one +should really expect their smartphone to last for a million years. +However, anyone taking too much comfort from this thought should +consider the fact that in most jurisdictions, a successful multi-year +test of a given mechanism, which might include a Linux kernel, +suffices for a number of types of safety-critical certifications. +In fact, rumor has it that the Linux kernel is already being used +in production for safety-critical applications. +I don't know about you, but I would feel quite bad if a bug in RCU +killed someone. +Which might explain my recent focus on validation and verification. + +<h2><a name="Other RCU Flavors">Other RCU Flavors</a></h2> + +<p> +One of the more surprising things about RCU is that there are now +no fewer than five <i>flavors</i>, or API families. +In addition, the primary flavor that has been the sole focus up to +this point has two different implementations, non-preemptible and +preemptible. +The other four flavors are listed below, with requirements for each +described in a separate section. + +<ol> +<li> <a href="#Bottom-Half Flavor">Bottom-Half Flavor</a> +<li> <a href="#Sched Flavor">Sched Flavor</a> +<li> <a href="#Sleepable RCU">Sleepable RCU</a> +<li> <a href="#Tasks RCU">Tasks RCU</a> +</ol> + +<h3><a name="Bottom-Half Flavor">Bottom-Half Flavor</a></h3> + +<p> +The softirq-disable (AKA “bottom-half”, +hence the “_bh” abbreviations) +flavor of RCU, or <i>RCU-bh</i>, was developed by +Dipankar Sarma to provide a flavor of RCU that could withstand the +network-based denial-of-service attacks researched by Robert +Olsson. +These attacks placed so much networking load on the system +that some of the CPUs never exited softirq execution, +which in turn prevented those CPUs from ever executing a context switch, +which, in the RCU implementation of that time, prevented grace periods +from ever ending. +The result was an out-of-memory condition and a system hang. + +<p> +The solution was the creation of RCU-bh, which does +<tt>local_bh_disable()</tt> +across its read-side critical sections, and which uses the transition +from one type of softirq processing to another as a quiescent state +in addition to context switch, idle, user mode, and offline. +This means that RCU-bh grace periods can complete even when some of +the CPUs execute in softirq indefinitely, thus allowing algorithms +based on RCU-bh to withstand network-based denial-of-service attacks. + +<p> +Because +<tt>rcu_read_lock_bh()</tt> and <tt>rcu_read_unlock_bh()</tt> +disable and re-enable softirq handlers, any attempt to start a softirq +handlers during the +RCU-bh read-side critical section will be deferred. +In this case, <tt>rcu_read_unlock_bh()</tt> +will invoke softirq processing, which can take considerable time. +One can of course argue that this softirq overhead should be associated +with the code following the RCU-bh read-side critical section rather +than <tt>rcu_read_unlock_bh()</tt>, but the fact +is that most profiling tools cannot be expected to make this sort +of fine distinction. +For example, suppose that a three-millisecond-long RCU-bh read-side +critical section executes during a time of heavy networking load. +There will very likely be an attempt to invoke at least one softirq +handler during that three milliseconds, but any such invocation will +be delayed until the time of the <tt>rcu_read_unlock_bh()</tt>. +This can of course make it appear at first glance as if +<tt>rcu_read_unlock_bh()</tt> was executing very slowly. + +<p> +The +<a href="http://lwn.net/Articles/609973/#RCU Per-Flavor API Table">RCU-bh API</a> +includes +<tt>rcu_read_lock_bh()</tt>, +<tt>rcu_read_unlock_bh()</tt>, +<tt>rcu_dereference_bh()</tt>, +<tt>rcu_dereference_bh_check()</tt>, +<tt>synchronize_rcu_bh()</tt>, +<tt>synchronize_rcu_bh_expedited()</tt>, +<tt>call_rcu_bh()</tt>, +<tt>rcu_barrier_bh()</tt>, and +<tt>rcu_read_lock_bh_held()</tt>. + +<h3><a name="Sched Flavor">Sched Flavor</a></h3> + +<p> +Before preemptible RCU, waiting for an RCU grace period had the +side effect of also waiting for all pre-existing interrupt +and NMI handlers. +However, there are legitimate preemptible-RCU implementations that +do not have this property, given that any point in the code outside +of an RCU read-side critical section can be a quiescent state. +Therefore, <i>RCU-sched</i> was created, which follows “classic” +RCU in that an RCU-sched grace period waits for for pre-existing +interrupt and NMI handlers. +In kernels built with <tt>CONFIG_PREEMPT=n</tt>, the RCU and RCU-sched +APIs have identical implementations, while kernels built with +<tt>CONFIG_PREEMPT=y</tt> provide a separate implementation for each. + +<p> +Note well that in <tt>CONFIG_PREEMPT=y</tt> kernels, +<tt>rcu_read_lock_sched()</tt> and <tt>rcu_read_unlock_sched()</tt> +disable and re-enable preemption, respectively. +This means that if there was a preemption attempt during the +RCU-sched read-side critical section, <tt>rcu_read_unlock_sched()</tt> +will enter the scheduler, with all the latency and overhead entailed. +Just as with <tt>rcu_read_unlock_bh()</tt>, this can make it look +as if <tt>rcu_read_unlock_sched()</tt> was executing very slowly. +However, the highest-priority task won't be preempted, so that task +will enjoy low-overhead <tt>rcu_read_unlock_sched()</tt> invocations. + +<p> +The +<a href="http://lwn.net/Articles/609973/#RCU Per-Flavor API Table">RCU-sched API</a> +includes +<tt>rcu_read_lock_sched()</tt>, +<tt>rcu_read_unlock_sched()</tt>, +<tt>rcu_read_lock_sched_notrace()</tt>, +<tt>rcu_read_unlock_sched_notrace()</tt>, +<tt>rcu_dereference_sched()</tt>, +<tt>rcu_dereference_sched_check()</tt>, +<tt>synchronize_sched()</tt>, +<tt>synchronize_rcu_sched_expedited()</tt>, +<tt>call_rcu_sched()</tt>, +<tt>rcu_barrier_sched()</tt>, and +<tt>rcu_read_lock_sched_held()</tt>. +However, anything that disables preemption also marks an RCU-sched +read-side critical section, including +<tt>preempt_disable()</tt> and <tt>preempt_enable()</tt>, +<tt>local_irq_save()</tt> and <tt>local_irq_restore()</tt>, +and so on. + +<h3><a name="Sleepable RCU">Sleepable RCU</a></h3> + +<p> +For well over a decade, someone saying “I need to block within +an RCU read-side critical section” was a reliable indication +that this someone did not understand RCU. +After all, if you are always blocking in an RCU read-side critical +section, you can probably afford to use a higher-overhead synchronization +mechanism. +However, that changed with the advent of the Linux kernel's notifiers, +whose RCU read-side critical +sections almost never sleep, but sometimes need to. +This resulted in the introduction of +<a href="https://lwn.net/Articles/202847/">sleepable RCU</a>, +or <i>SRCU</i>. + +<p> +SRCU allows different domains to be defined, with each such domain +defined by an instance of an <tt>srcu_struct</tt> structure. +A pointer to this structure must be passed in to each SRCU function, +for example, <tt>synchronize_srcu(&ss)</tt>, where +<tt>ss</tt> is the <tt>srcu_struct</tt> structure. +The key benefit of these domains is that a slow SRCU reader in one +domain does not delay an SRCU grace period in some other domain. +That said, one consequence of these domains is that read-side code +must pass a “cookie” from <tt>srcu_read_lock()</tt> +to <tt>srcu_read_unlock()</tt>, for example, as follows: + +<blockquote> +<pre> + 1 int idx; + 2 + 3 idx = srcu_read_lock(&ss); + 4 do_something(); + 5 srcu_read_unlock(&ss, idx); +</pre> +</blockquote> + +<p> +As noted above, it is legal to block within SRCU read-side critical sections, +however, with great power comes great responsibility. +If you block forever in one of a given domain's SRCU read-side critical +sections, then that domain's grace periods will also be blocked forever. +Of course, one good way to block forever is to deadlock, which can +happen if any operation in a given domain's SRCU read-side critical +section can block waiting, either directly or indirectly, for that domain's +grace period to elapse. +For example, this results in a self-deadlock: + +<blockquote> +<pre> + 1 int idx; + 2 + 3 idx = srcu_read_lock(&ss); + 4 do_something(); + 5 synchronize_srcu(&ss); + 6 srcu_read_unlock(&ss, idx); +</pre> +</blockquote> + +<p> +However, if line 5 acquired a mutex that was held across +a <tt>synchronize_srcu()</tt> for domain <tt>ss</tt>, +deadlock would still be possible. +Furthermore, if line 5 acquired a mutex that was held across +a <tt>synchronize_srcu()</tt> for some other domain <tt>ss1</tt>, +and if an <tt>ss1</tt>-domain SRCU read-side critical section +acquired another mutex that was held across as <tt>ss</tt>-domain +<tt>synchronize_srcu()</tt>, +deadlock would again be possible. +Such a deadlock cycle could extend across an arbitrarily large number +of different SRCU domains. +Again, with great power comes great responsibility. + +<p> +Unlike the other RCU flavors, SRCU read-side critical sections can +run on idle and even offline CPUs. +This ability requires that <tt>srcu_read_lock()</tt> and +<tt>srcu_read_unlock()</tt> contain memory barriers, which means +that SRCU readers will run a bit slower than would RCU readers. +It also motivates the <tt>smp_mb__after_srcu_read_unlock()</tt> +API, which, in combination with <tt>srcu_read_unlock()</tt>, +guarantees a full memory barrier. + +<p> +The +<a href="http://lwn.net/Articles/609973/#RCU Per-Flavor API Table">SRCU API</a> +includes +<tt>srcu_read_lock()</tt>, +<tt>srcu_read_unlock()</tt>, +<tt>srcu_dereference()</tt>, +<tt>srcu_dereference_check()</tt>, +<tt>synchronize_srcu()</tt>, +<tt>synchronize_srcu_expedited()</tt>, +<tt>call_srcu()</tt>, +<tt>srcu_barrier()</tt>, and +<tt>srcu_read_lock_held()</tt>. +It also includes +<tt>DEFINE_SRCU()</tt>, +<tt>DEFINE_STATIC_SRCU()</tt>, and +<tt>init_srcu_struct()</tt> +APIs for defining and initializing <tt>srcu_struct</tt> structures. + +<h3><a name="Tasks RCU">Tasks RCU</a></h3> + +<p> +Some forms of tracing use “tramopolines” to handle the +binary rewriting required to install different types of probes. +It would be good to be able to free old trampolines, which sounds +like a job for some form of RCU. +However, because it is necessary to be able to install a trace +anywhere in the code, it is not possible to use read-side markers +such as <tt>rcu_read_lock()</tt> and <tt>rcu_read_unlock()</tt>. +In addition, it does not work to have these markers in the trampoline +itself, because there would need to be instructions following +<tt>rcu_read_unlock()</tt>. +Although <tt>synchronize_rcu()</tt> would guarantee that execution +reached the <tt>rcu_read_unlock()</tt>, it would not be able to +guarantee that execution had completely left the trampoline. + +<p> +The solution, in the form of +<a href="http://lwn.net/Articles/607117/"><i>Tasks RCU</i></a>, +is to have implicit +read-side critical sections that are delimited by voluntary context +switches, that is, calls to <tt>schedule()</tt>, +<tt>cond_resched_rcu_qs()</tt>, and +<tt>synchronize_rcu_tasks()</tt>. +In addition, transitions to and from userspace execution also delimit +tasks-RCU read-side critical sections. + +<p> +The tasks-RCU API is quite compact, consisting only of +<tt>call_rcu_tasks()</tt>, +<tt>synchronize_rcu_tasks()</tt>, and +<tt>rcu_barrier_tasks()</tt>. + +<h2><a name="Possible Future Changes">Possible Future Changes</a></h2> + +<p> +One of the tricks that RCU uses to attain update-side scalability is +to increase grace-period latency with increasing numbers of CPUs. +If this becomes a serious problem, it will be necessary to rework the +grace-period state machine so as to avoid the need for the additional +latency. + +<p> +Expedited grace periods scan the CPUs, so their latency and overhead +increases with increasing numbers of CPUs. +If this becomes a serious problem on large systems, it will be necessary +to do some redesign to avoid this scalability problem. + +<p> +RCU disables CPU hotplug in a few places, perhaps most notably in the +expedited grace-period and <tt>rcu_barrier()</tt> operations. +If there is a strong reason to use expedited grace periods in CPU-hotplug +notifiers, it will be necessary to avoid disabling CPU hotplug. +This would introduce some complexity, so there had better be a <i>very</i> +good reason. + +<p> +The tradeoff between grace-period latency on the one hand and interruptions +of other CPUs on the other hand may need to be re-examined. +The desire is of course for zero grace-period latency as well as zero +interprocessor interrupts undertaken during an expedited grace period +operation. +While this ideal is unlikely to be achievable, it is quite possible that +further improvements can be made. + +<p> +The multiprocessor implementations of RCU use a combining tree that +groups CPUs so as to reduce lock contention and increase cache locality. +However, this combining tree does not spread its memory across NUMA +nodes nor does it align the CPU groups with hardware features such +as sockets or cores. +Such spreading and alignment is currently believed to be unnecessary +because the hotpath read-side primitives do not access the combining +tree, nor does <tt>call_rcu()</tt> in the common case. +If you believe that your architecture needs such spreading and alignment, +then your architecture should also benefit from the +<tt>rcutree.rcu_fanout_leaf</tt> boot parameter, which can be set +to the number of CPUs in a socket, NUMA node, or whatever. +If the number of CPUs is too large, use a fraction of the number of +CPUs. +If the number of CPUs is a large prime number, well, that certainly +is an “interesting” architectural choice! +More flexible arrangements might be considered, but only if +<tt>rcutree.rcu_fanout_leaf</tt> has proven inadequate, and only +if the inadequacy has been demonstrated by a carefully run and +realistic system-level workload. + +<p> +Please note that arrangements that require RCU to remap CPU numbers will +require extremely good demonstration of need and full exploration of +alternatives. + +<p> +There is an embarrassingly large number of flavors of RCU, and this +number has been increasing over time. +Perhaps it will be possible to combine some at some future date. + +<p> +RCU's various kthreads are reasonably recent additions. +It is quite likely that adjustments will be required to more gracefully +handle extreme loads. +It might also be necessary to be able to relate CPU utilization by +RCU's kthreads and softirq handlers to the code that instigated this +CPU utilization. +For example, RCU callback overhead might be charged back to the +originating <tt>call_rcu()</tt> instance, though probably not +in production kernels. + +<h2><a name="Summary">Summary</a></h2> + +<p> +This document has presented more than two decade's worth of RCU +requirements. +Given that the requirements keep changing, this will not be the last +word on this subject, but at least it serves to get an important +subset of the requirements set forth. + +<h2><a name="Acknowledgments">Acknowledgments</a></h2> + +I am grateful to Steven Rostedt, Lai Jiangshan, Ingo Molnar, +Oleg Nesterov, Borislav Petkov, Peter Zijlstra, Boqun Feng, and +Andy Lutomirski for their help in rendering +this article human readable, and to Michelle Rankin for her support +of this effort. +Other contributions are acknowledged in the Linux kernel's git archive. +The cartoon is copyright (c) 2013 by Melissa Broussard, +and is provided +under the terms of the Creative Commons Attribution-Share Alike 3.0 +United States license. + +<p>@@QQAL@@ + +</body></html> diff --git a/Documentation/RCU/Design/htmlqqz.sh b/Documentation/RCU/Design/htmlqqz.sh new file mode 100755 index 000000000000..d354f069559b --- /dev/null +++ b/Documentation/RCU/Design/htmlqqz.sh @@ -0,0 +1,108 @@ +#!/bin/sh +# +# Usage: sh htmlqqz.sh file +# +# Extracts and converts quick quizzes in a proto-HTML document file.htmlx. +# Commands, all of which must be on a line by themselves: +# +# "<p>@@QQ@@": Start of a quick quiz. +# "<p>@@QQA@@": Start of a quick-quiz answer. +# "<p>@@QQE@@": End of a quick-quiz answer, and thus of the quick quiz. +# "<p>@@QQAL@@": Place to put quick-quiz answer list. +# +# Places the result in file.html. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, you can access it online at +# http://www.gnu.org/licenses/gpl-2.0.html. +# +# Copyright (c) 2013 Paul E. McKenney, IBM Corporation. + +fn=$1 +if test ! -r $fn.htmlx +then + echo "Error: $fn.htmlx unreadable." + exit 1 +fi + +echo "<!-- DO NOT HAND EDIT. -->" > $fn.html +echo "<!-- Instead, edit $fn.htmlx and run 'sh htmlqqz.sh $fn' -->" >> $fn.html +awk < $fn.htmlx >> $fn.html ' + +state == "" && $1 != "<p>@@QQ@@" && $1 != "<p>@@QQAL@@" { + print $0; + if ($0 ~ /^<p>@@QQ/) + print "Bad Quick Quiz command: " NR " (expected <p>@@QQ@@ or <p>@@QQAL@@)." > "/dev/stderr" + next; +} + +state == "" && $1 == "<p>@@QQ@@" { + qqn++; + qqlineno = NR; + haveqq = 1; + state = "qq"; + print "<p><a name=\"Quick Quiz " qqn "\"><b>Quick Quiz " qqn "</b>:</a>" + next; +} + +state == "qq" && $1 != "<p>@@QQA@@" { + qq[qqn] = qq[qqn] $0 "\n"; + print $0 + if ($0 ~ /^<p>@@QQ/) + print "Bad Quick Quiz command: " NR ". (expected <p>@@QQA@@)" > "/dev/stderr" + next; +} + +state == "qq" && $1 == "<p>@@QQA@@" { + state = "qqa"; + print "<br><a href=\"#qq" qqn "answer\">Answer</a>" + next; +} + +state == "qqa" && $1 != "<p>@@QQE@@" { + qqa[qqn] = qqa[qqn] $0 "\n"; + if ($0 ~ /^<p>@@QQ/) + print "Bad Quick Quiz command: " NR " (expected <p>@@QQE@@)." > "/dev/stderr" + next; +} + +state == "qqa" && $1 == "<p>@@QQE@@" { + state = ""; + next; +} + +state == "" && $1 == "<p>@@QQAL@@" { + haveqq = ""; + print "<h3><a name=\"Answers to Quick Quizzes\">" + print "Answers to Quick Quizzes</a></h3>" + print ""; + for (i = 1; i <= qqn; i++) { + print "<a name=\"qq" i "answer\"></a>" + print "<p><b>Quick Quiz " i "</b>:" + print qq[i]; + print ""; + print "</p><p><b>Answer</b>:" + print qqa[i]; + print ""; + print "</p><p><a href=\"#Quick%20Quiz%20" i "\"><b>Back to Quick Quiz " i "</b>.</a>" + print ""; + } + next; +} + +END { + if (state != "") + print "Unterminated Quick Quiz: " qqlineno "." > "/dev/stderr" + else if (haveqq) + print "Missing \"<p>@@QQAL@@\", no Quick Quiz." > "/dev/stderr" +}' -- 2.5.2
| |