Merge branch 'for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu into core/rcu
Pull RCU changes from Paul E. McKenney:
- Convert RCU's BUG_ON() and similar calls to WARN_ON() and similar.
- Replace calls of RCU-bh and RCU-sched update-side functions
to their vanilla RCU counterparts. This series is a step
towards complete removal of the RCU-bh and RCU-sched update-side
functions.
( Note that some of these conversions are going upstream via their
respective maintainers. )
- Documentation updates, including a number of flavor-consolidation
updates from Joel Fernandes.
- Miscellaneous fixes.
- Automate generation of the initrd filesystem used for
rcutorture testing.
- Convert spin_is_locked() assertions to instead use lockdep.
( Note that some of these conversions are going upstream via their
respective maintainers. )
- SRCU updates, especially including a fix from Dennis Krein
for a bag-on-head-class bug.
- RCU torture-test updates.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
@@ -1,499 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Creator: fig2dev Version 3.2 Patchlevel 5e -->
|
||||
|
||||
<!-- CreationDate: Wed Dec 9 17:26:09 2015 -->
|
||||
|
||||
<!-- Magnification: 2.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="5.7in"
|
||||
height="6.6in"
|
||||
viewBox="-44 -44 6838 7888"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="BigTreeClassicRCUBH.fig">
|
||||
<metadata
|
||||
id="metadata110">
|
||||
<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>
|
||||
<defs
|
||||
id="defs108">
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Mend"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path3868"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;"
|
||||
transform="scale(0.4) rotate(180) translate(10,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Mend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Mend"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path3886"
|
||||
style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.6) rotate(180) translate(0,0)" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="878"
|
||||
inkscape:window-height="1148"
|
||||
id="namedview106"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.3547758"
|
||||
inkscape:cx="256.5"
|
||||
inkscape:cy="297"
|
||||
inkscape:window-x="45"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="g4" />
|
||||
<g
|
||||
style="stroke-width:.025in; fill:none"
|
||||
id="g4">
|
||||
<!-- Line: box -->
|
||||
<rect
|
||||
x="450"
|
||||
y="0"
|
||||
width="6300"
|
||||
height="7350"
|
||||
rx="0"
|
||||
style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffffff; "
|
||||
id="rect6" />
|
||||
<!-- Line: box -->
|
||||
<rect
|
||||
x="4950"
|
||||
y="4950"
|
||||
width="1500"
|
||||
height="900"
|
||||
rx="0"
|
||||
style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; "
|
||||
id="rect8" />
|
||||
<!-- Line: box -->
|
||||
<rect
|
||||
x="750"
|
||||
y="600"
|
||||
width="5700"
|
||||
height="3750"
|
||||
rx="0"
|
||||
style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffff00; "
|
||||
id="rect10" />
|
||||
<!-- Line: box -->
|
||||
<rect
|
||||
x="0"
|
||||
y="450"
|
||||
width="6300"
|
||||
height="7350"
|
||||
rx="0"
|
||||
style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffffff; "
|
||||
id="rect12" />
|
||||
<!-- Line: box -->
|
||||
<rect
|
||||
x="300"
|
||||
y="1050"
|
||||
width="5700"
|
||||
height="3750"
|
||||
rx="0"
|
||||
style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffff00; "
|
||||
id="rect14" />
|
||||
<!-- Circle -->
|
||||
<circle
|
||||
cx="2850"
|
||||
cy="3900"
|
||||
r="76"
|
||||
style="fill:#000000;stroke:#000000;stroke-width:14;"
|
||||
id="circle16" />
|
||||
<!-- Circle -->
|
||||
<circle
|
||||
cx="3150"
|
||||
cy="3900"
|
||||
r="76"
|
||||
style="fill:#000000;stroke:#000000;stroke-width:14;"
|
||||
id="circle18" />
|
||||
<!-- Circle -->
|
||||
<circle
|
||||
cx="3450"
|
||||
cy="3900"
|
||||
r="76"
|
||||
style="fill:#000000;stroke:#000000;stroke-width:14;"
|
||||
id="circle20" />
|
||||
<!-- Circle -->
|
||||
<circle
|
||||
cx="1350"
|
||||
cy="5100"
|
||||
r="76"
|
||||
style="fill:#000000;stroke:#000000;stroke-width:14;"
|
||||
id="circle22" />
|
||||
<!-- Circle -->
|
||||
<circle
|
||||
cx="1650"
|
||||
cy="5100"
|
||||
r="76"
|
||||
style="fill:#000000;stroke:#000000;stroke-width:14;"
|
||||
id="circle24" />
|
||||
<!-- Circle -->
|
||||
<circle
|
||||
cx="1950"
|
||||
cy="5100"
|
||||
r="76"
|
||||
style="fill:#000000;stroke:#000000;stroke-width:14;"
|
||||
id="circle26" />
|
||||
<!-- Circle -->
|
||||
<circle
|
||||
cx="4350"
|
||||
cy="5100"
|
||||
r="76"
|
||||
style="fill:#000000;stroke:#000000;stroke-width:14;"
|
||||
id="circle28" />
|
||||
<!-- Circle -->
|
||||
<circle
|
||||
cx="4650"
|
||||
cy="5100"
|
||||
r="76"
|
||||
style="fill:#000000;stroke:#000000;stroke-width:14;"
|
||||
id="circle30" />
|
||||
<!-- Circle -->
|
||||
<circle
|
||||
cx="4950"
|
||||
cy="5100"
|
||||
r="76"
|
||||
style="fill:#000000;stroke:#000000;stroke-width:14;"
|
||||
id="circle32" />
|
||||
<!-- Line -->
|
||||
<polyline
|
||||
points="1350,3450 2350,2590 "
|
||||
style="stroke:#00d1d1;stroke-width:30.0045575;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)"
|
||||
id="polyline34" />
|
||||
<!-- Arrowhead on XXXpoint 1350 3450 - 2444 2510-->
|
||||
<!-- Line -->
|
||||
<polyline
|
||||
points="4950,3450 3948,2590 "
|
||||
style="stroke:#00d1d1;stroke-width:30.0045575;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)"
|
||||
id="polyline38" />
|
||||
<!-- Arrowhead on XXXpoint 4950 3450 - 3854 2510-->
|
||||
<!-- Line: box -->
|
||||
<rect
|
||||
x="750"
|
||||
y="3450"
|
||||
width="1800"
|
||||
height="900"
|
||||
rx="0"
|
||||
style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; "
|
||||
id="rect42" />
|
||||
<!-- Line -->
|
||||
<polyline
|
||||
points="2250,5400 2250,4414 "
|
||||
style="stroke:#00d1d1;stroke-width:30.0045575;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)"
|
||||
id="polyline44" />
|
||||
<!-- Arrowhead on XXXpoint 2250 5400 - 2250 4290-->
|
||||
<!-- Line: box -->
|
||||
<rect
|
||||
x="1500"
|
||||
y="5400"
|
||||
width="1500"
|
||||
height="900"
|
||||
rx="0"
|
||||
style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; "
|
||||
id="rect48" />
|
||||
<!-- Line: box -->
|
||||
<rect
|
||||
x="300"
|
||||
y="6600"
|
||||
width="1500"
|
||||
height="900"
|
||||
rx="0"
|
||||
style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; "
|
||||
id="rect50" />
|
||||
<!-- Line: box -->
|
||||
<rect
|
||||
x="3750"
|
||||
y="3450"
|
||||
width="1800"
|
||||
height="900"
|
||||
rx="0"
|
||||
style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; "
|
||||
id="rect52" />
|
||||
<!-- Line: box -->
|
||||
<rect
|
||||
x="4500"
|
||||
y="5400"
|
||||
width="1500"
|
||||
height="900"
|
||||
rx="0"
|
||||
style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; "
|
||||
id="rect54" />
|
||||
<!-- Line: box -->
|
||||
<rect
|
||||
x="3300"
|
||||
y="6600"
|
||||
width="1500"
|
||||
height="900"
|
||||
rx="0"
|
||||
style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; "
|
||||
id="rect56" />
|
||||
<!-- Line: box -->
|
||||
<rect
|
||||
x="2250"
|
||||
y="1650"
|
||||
width="1800"
|
||||
height="900"
|
||||
rx="0"
|
||||
style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; "
|
||||
id="rect58" />
|
||||
<!-- Text -->
|
||||
<text
|
||||
xml:space="preserve"
|
||||
x="6450"
|
||||
y="300"
|
||||
fill="#000000"
|
||||
font-family="Helvetica"
|
||||
font-style="normal"
|
||||
font-weight="normal"
|
||||
font-size="192"
|
||||
text-anchor="end"
|
||||
id="text60">rcu_bh</text>
|
||||
<!-- Text -->
|
||||
<text
|
||||
xml:space="preserve"
|
||||
x="3150"
|
||||
y="1950"
|
||||
fill="#000000"
|
||||
font-family="Courier"
|
||||
font-style="normal"
|
||||
font-weight="bold"
|
||||
font-size="192"
|
||||
text-anchor="middle"
|
||||
id="text62">struct</text>
|
||||
<!-- Text -->
|
||||
<text
|
||||
xml:space="preserve"
|
||||
x="3150"
|
||||
y="2250"
|
||||
fill="#000000"
|
||||
font-family="Courier"
|
||||
font-style="normal"
|
||||
font-weight="bold"
|
||||
font-size="192"
|
||||
text-anchor="middle"
|
||||
id="text64">rcu_node</text>
|
||||
<!-- Text -->
|
||||
<text
|
||||
xml:space="preserve"
|
||||
x="1650"
|
||||
y="3750"
|
||||
fill="#000000"
|
||||
font-family="Courier"
|
||||
font-style="normal"
|
||||
font-weight="bold"
|
||||
font-size="192"
|
||||
text-anchor="middle"
|
||||
id="text66">struct</text>
|
||||
<!-- Text -->
|
||||
<text
|
||||
xml:space="preserve"
|
||||
x="1650"
|
||||
y="4050"
|
||||
fill="#000000"
|
||||
font-family="Courier"
|
||||
font-style="normal"
|
||||
font-weight="bold"
|
||||
font-size="192"
|
||||
text-anchor="middle"
|
||||
id="text68">rcu_node</text>
|
||||
<!-- Text -->
|
||||
<text
|
||||
xml:space="preserve"
|
||||
x="4650"
|
||||
y="4050"
|
||||
fill="#000000"
|
||||
font-family="Courier"
|
||||
font-style="normal"
|
||||
font-weight="bold"
|
||||
font-size="192"
|
||||
text-anchor="middle"
|
||||
id="text70">rcu_node</text>
|
||||
<!-- Text -->
|
||||
<text
|
||||
xml:space="preserve"
|
||||
x="4650"
|
||||
y="3750"
|
||||
fill="#000000"
|
||||
font-family="Courier"
|
||||
font-style="normal"
|
||||
font-weight="bold"
|
||||
font-size="192"
|
||||
text-anchor="middle"
|
||||
id="text72">struct</text>
|
||||
<!-- Text -->
|
||||
<text
|
||||
xml:space="preserve"
|
||||
x="2250"
|
||||
y="5700"
|
||||
fill="#000000"
|
||||
font-family="Courier"
|
||||
font-style="normal"
|
||||
font-weight="bold"
|
||||
font-size="192"
|
||||
text-anchor="middle"
|
||||
id="text74">struct</text>
|
||||
<!-- Text -->
|
||||
<text
|
||||
xml:space="preserve"
|
||||
x="2250"
|
||||
y="6000"
|
||||
fill="#000000"
|
||||
font-family="Courier"
|
||||
font-style="normal"
|
||||
font-weight="bold"
|
||||
font-size="192"
|
||||
text-anchor="middle"
|
||||
id="text76">rcu_data</text>
|
||||
<!-- Text -->
|
||||
<text
|
||||
xml:space="preserve"
|
||||
x="1050"
|
||||
y="6900"
|
||||
fill="#000000"
|
||||
font-family="Courier"
|
||||
font-style="normal"
|
||||
font-weight="bold"
|
||||
font-size="192"
|
||||
text-anchor="middle"
|
||||
id="text78">struct</text>
|
||||
<!-- Text -->
|
||||
<text
|
||||
xml:space="preserve"
|
||||
x="1050"
|
||||
y="7200"
|
||||
fill="#000000"
|
||||
font-family="Courier"
|
||||
font-style="normal"
|
||||
font-weight="bold"
|
||||
font-size="192"
|
||||
text-anchor="middle"
|
||||
id="text80">rcu_data</text>
|
||||
<!-- Text -->
|
||||
<text
|
||||
xml:space="preserve"
|
||||
x="5250"
|
||||
y="5700"
|
||||
fill="#000000"
|
||||
font-family="Courier"
|
||||
font-style="normal"
|
||||
font-weight="bold"
|
||||
font-size="192"
|
||||
text-anchor="middle"
|
||||
id="text82">struct</text>
|
||||
<!-- Text -->
|
||||
<text
|
||||
xml:space="preserve"
|
||||
x="5250"
|
||||
y="6000"
|
||||
fill="#000000"
|
||||
font-family="Courier"
|
||||
font-style="normal"
|
||||
font-weight="bold"
|
||||
font-size="192"
|
||||
text-anchor="middle"
|
||||
id="text84">rcu_data</text>
|
||||
<!-- Text -->
|
||||
<text
|
||||
xml:space="preserve"
|
||||
x="4050"
|
||||
y="6900"
|
||||
fill="#000000"
|
||||
font-family="Courier"
|
||||
font-style="normal"
|
||||
font-weight="bold"
|
||||
font-size="192"
|
||||
text-anchor="middle"
|
||||
id="text86">struct</text>
|
||||
<!-- Text -->
|
||||
<text
|
||||
xml:space="preserve"
|
||||
x="4050"
|
||||
y="7200"
|
||||
fill="#000000"
|
||||
font-family="Courier"
|
||||
font-style="normal"
|
||||
font-weight="bold"
|
||||
font-size="192"
|
||||
text-anchor="middle"
|
||||
id="text88">rcu_data</text>
|
||||
<!-- Text -->
|
||||
<text
|
||||
xml:space="preserve"
|
||||
x="450"
|
||||
y="1350"
|
||||
fill="#000000"
|
||||
font-family="Courier"
|
||||
font-style="normal"
|
||||
font-weight="bold"
|
||||
font-size="192"
|
||||
text-anchor="start"
|
||||
id="text90">struct rcu_state</text>
|
||||
<!-- Text -->
|
||||
<text
|
||||
xml:space="preserve"
|
||||
x="6000"
|
||||
y="750"
|
||||
fill="#000000"
|
||||
font-family="Helvetica"
|
||||
font-style="normal"
|
||||
font-weight="normal"
|
||||
font-size="192"
|
||||
text-anchor="end"
|
||||
id="text92">rcu_sched</text>
|
||||
<!-- Line -->
|
||||
<polyline
|
||||
points="5250,5400 5250,4414 "
|
||||
style="stroke:#00d1d1;stroke-width:30.0045575;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)"
|
||||
id="polyline94" />
|
||||
<!-- Arrowhead on XXXpoint 5250 5400 - 5250 4290-->
|
||||
<!-- Line -->
|
||||
<polyline
|
||||
points="4050,6600 4050,4414 "
|
||||
style="stroke:#00d1d1;stroke-width:30.0045575;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)"
|
||||
id="polyline98" />
|
||||
<!-- Arrowhead on XXXpoint 4050 6600 - 4050 4290-->
|
||||
<!-- Line -->
|
||||
<polyline
|
||||
points="1050,6600 1050,4414 "
|
||||
style="stroke:#00d1d1;stroke-width:30.0045575;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)"
|
||||
id="polyline102" />
|
||||
<!-- Arrowhead on XXXpoint 1050 6600 - 1050 4290-->
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 22 KiB |
@@ -23,8 +23,6 @@ to each other.
|
||||
The <tt>rcu_segcblist</tt> Structure</a>
|
||||
<li> <a href="#The rcu_data Structure">
|
||||
The <tt>rcu_data</tt> Structure</a>
|
||||
<li> <a href="#The rcu_dynticks Structure">
|
||||
The <tt>rcu_dynticks</tt> Structure</a>
|
||||
<li> <a href="#The rcu_head Structure">
|
||||
The <tt>rcu_head</tt> Structure</a>
|
||||
<li> <a href="#RCU-Specific Fields in the task_struct Structure">
|
||||
@@ -127,9 +125,11 @@ CPUs, RCU would configure the <tt>rcu_node</tt> tree as follows:
|
||||
</p><p>RCU currently permits up to a four-level tree, which on a 64-bit system
|
||||
accommodates up to 4,194,304 CPUs, though only a mere 524,288 CPUs for
|
||||
32-bit systems.
|
||||
On the other hand, you can set <tt>CONFIG_RCU_FANOUT</tt> to be
|
||||
as small as 2 if you wish, which would permit only 16 CPUs, which
|
||||
is useful for testing.
|
||||
On the other hand, you can set both <tt>CONFIG_RCU_FANOUT</tt> and
|
||||
<tt>CONFIG_RCU_FANOUT_LEAF</tt> to be as small as 2, which would result
|
||||
in a 16-CPU test using a 4-level tree.
|
||||
This can be useful for testing large-system capabilities on small test
|
||||
machines.
|
||||
|
||||
</p><p>This multi-level combining tree allows us to get most of the
|
||||
performance and scalability
|
||||
@@ -154,44 +154,9 @@ on that root <tt>rcu_node</tt> structure remains acceptably low.
|
||||
keeping lock contention under control at all tree levels regardless
|
||||
of the level of loading on the system.
|
||||
|
||||
</p><p>The Linux kernel actually supports multiple flavors of RCU
|
||||
running concurrently, so RCU builds separate data structures for each
|
||||
flavor.
|
||||
For example, for <tt>CONFIG_TREE_RCU=y</tt> kernels, RCU provides
|
||||
rcu_sched and rcu_bh, as shown below:
|
||||
|
||||
</p><p><img src="BigTreeClassicRCUBH.svg" alt="BigTreeClassicRCUBH.svg" width="33%">
|
||||
|
||||
</p><p>Energy efficiency is increasingly important, and for that
|
||||
reason the Linux kernel provides <tt>CONFIG_NO_HZ_IDLE</tt>, which
|
||||
turns off the scheduling-clock interrupts on idle CPUs, which in
|
||||
turn allows those CPUs to attain deeper sleep states and to consume
|
||||
less energy.
|
||||
CPUs whose scheduling-clock interrupts have been turned off are
|
||||
said to be in <i>dyntick-idle mode</i>.
|
||||
RCU must handle dyntick-idle CPUs specially
|
||||
because RCU would otherwise wake up each CPU on every grace period,
|
||||
which would defeat the whole purpose of <tt>CONFIG_NO_HZ_IDLE</tt>.
|
||||
RCU uses the <tt>rcu_dynticks</tt> structure to track
|
||||
which CPUs are in dyntick idle mode, as shown below:
|
||||
|
||||
</p><p><img src="BigTreeClassicRCUBHdyntick.svg" alt="BigTreeClassicRCUBHdyntick.svg" width="33%">
|
||||
|
||||
</p><p>However, if a CPU is in dyntick-idle mode, it is in that mode
|
||||
for all flavors of RCU.
|
||||
Therefore, a single <tt>rcu_dynticks</tt> structure is allocated per
|
||||
CPU, and all of a given CPU's <tt>rcu_data</tt> structures share
|
||||
that <tt>rcu_dynticks</tt>, as shown in the figure.
|
||||
|
||||
</p><p>Kernels built with <tt>CONFIG_PREEMPT_RCU</tt> support
|
||||
rcu_preempt in addition to rcu_sched and rcu_bh, as shown below:
|
||||
|
||||
</p><p><img src="BigTreePreemptRCUBHdyntick.svg" alt="BigTreePreemptRCUBHdyntick.svg" width="35%">
|
||||
|
||||
</p><p>RCU updaters wait for normal grace periods by registering
|
||||
RCU callbacks, either directly via <tt>call_rcu()</tt> and
|
||||
friends (namely <tt>call_rcu_bh()</tt> and <tt>call_rcu_sched()</tt>),
|
||||
there being a separate interface per flavor of RCU)
|
||||
or indirectly via <tt>synchronize_rcu()</tt> and friends.
|
||||
RCU callbacks are represented by <tt>rcu_head</tt> structures,
|
||||
which are queued on <tt>rcu_data</tt> structures while they are
|
||||
@@ -214,9 +179,6 @@ its own synchronization:
|
||||
<li> Each <tt>rcu_node</tt> structure has a spinlock.
|
||||
<li> The fields in <tt>rcu_data</tt> are private to the corresponding
|
||||
CPU, although a few can be read and written by other CPUs.
|
||||
<li> Similarly, the fields in <tt>rcu_dynticks</tt> are private
|
||||
to the corresponding CPU, although a few can be read by
|
||||
other CPUs.
|
||||
</ol>
|
||||
|
||||
<p>It is important to note that different data structures can have
|
||||
@@ -272,11 +234,6 @@ follows:
|
||||
access to this information from the corresponding CPU.
|
||||
Finally, this structure records past dyntick-idle state
|
||||
for the corresponding CPU and also tracks statistics.
|
||||
<li> <tt>rcu_dynticks</tt>:
|
||||
This per-CPU structure tracks the current dyntick-idle
|
||||
state for the corresponding CPU.
|
||||
Unlike the other three structures, the <tt>rcu_dynticks</tt>
|
||||
structure is not replicated per RCU flavor.
|
||||
<li> <tt>rcu_head</tt>:
|
||||
This structure represents RCU callbacks, and is the
|
||||
only structure allocated and managed by RCU users.
|
||||
@@ -287,14 +244,14 @@ follows:
|
||||
<p>If all you wanted from this article was a general notion of how
|
||||
RCU's data structures are related, you are done.
|
||||
Otherwise, each of the following sections give more details on
|
||||
the <tt>rcu_state</tt>, <tt>rcu_node</tt>, <tt>rcu_data</tt>,
|
||||
and <tt>rcu_dynticks</tt> data structures.
|
||||
the <tt>rcu_state</tt>, <tt>rcu_node</tt> and <tt>rcu_data</tt> data
|
||||
structures.
|
||||
|
||||
<h3><a name="The rcu_state Structure">
|
||||
The <tt>rcu_state</tt> Structure</a></h3>
|
||||
|
||||
<p>The <tt>rcu_state</tt> structure is the base structure that
|
||||
represents a flavor of RCU.
|
||||
represents the state of RCU in the system.
|
||||
This structure forms the interconnection between the
|
||||
<tt>rcu_node</tt> and <tt>rcu_data</tt> structures,
|
||||
tracks grace periods, contains the lock used to
|
||||
@@ -389,7 +346,7 @@ sequence number.
|
||||
The bottom two bits are the state of the current grace period,
|
||||
which can be zero for not yet started or one for in progress.
|
||||
In other words, if the bottom two bits of <tt>->gp_seq</tt> are
|
||||
zero, the corresponding flavor of RCU is idle.
|
||||
zero, then RCU is idle.
|
||||
Any other value in the bottom two bits indicates that something is broken.
|
||||
This field is protected by the root <tt>rcu_node</tt> structure's
|
||||
<tt>->lock</tt> field.
|
||||
@@ -419,10 +376,10 @@ as follows:
|
||||
grace period in jiffies.
|
||||
It is protected by the root <tt>rcu_node</tt>'s <tt>->lock</tt>.
|
||||
|
||||
<p>The <tt>->name</tt> field points to the name of the RCU flavor
|
||||
(for example, “rcu_sched”), and is constant.
|
||||
The <tt>->abbr</tt> field contains a one-character abbreviation,
|
||||
for example, “s” for RCU-sched.
|
||||
<p>The <tt>->name</tt> and <tt>->abbr</tt> fields distinguish
|
||||
between preemptible RCU (“rcu_preempt” and “p”)
|
||||
and non-preemptible RCU (“rcu_sched” and “s”).
|
||||
These fields are used for diagnostic and tracing purposes.
|
||||
|
||||
<h3><a name="The rcu_node Structure">
|
||||
The <tt>rcu_node</tt> Structure</a></h3>
|
||||
@@ -971,25 +928,31 @@ this <tt>rcu_segcblist</tt> structure, <i>not</i> the <tt>->head</tt>
|
||||
pointer.
|
||||
The reason for this is that all the ready-to-invoke callbacks
|
||||
(that is, those in the <tt>RCU_DONE_TAIL</tt> segment) are extracted
|
||||
all at once at callback-invocation time.
|
||||
all at once at callback-invocation time (<tt>rcu_do_batch</tt>), due
|
||||
to which <tt>->head</tt> may be set to NULL if there are no not-done
|
||||
callbacks remaining in the <tt>rcu_segcblist</tt>.
|
||||
If callback invocation must be postponed, for example, because a
|
||||
high-priority process just woke up on this CPU, then the remaining
|
||||
callbacks are placed back on the <tt>RCU_DONE_TAIL</tt> segment.
|
||||
Either way, the <tt>->len</tt> and <tt>->len_lazy</tt> counts
|
||||
are adjusted after the corresponding callbacks have been invoked, and so
|
||||
again it is the <tt>->len</tt> count that accurately reflects whether
|
||||
or not there are callbacks associated with this <tt>rcu_segcblist</tt>
|
||||
structure.
|
||||
callbacks are placed back on the <tt>RCU_DONE_TAIL</tt> segment and
|
||||
<tt>->head</tt> once again points to the start of the segment.
|
||||
In short, the head field can briefly be <tt>NULL</tt> even though the
|
||||
CPU has callbacks present the entire time.
|
||||
Therefore, it is not appropriate to test the <tt>->head</tt> pointer
|
||||
for <tt>NULL</tt>.
|
||||
|
||||
<p>In contrast, the <tt>->len</tt> and <tt>->len_lazy</tt> counts
|
||||
are adjusted only after the corresponding callbacks have been invoked.
|
||||
This means that the <tt>->len</tt> count is zero only if
|
||||
the <tt>rcu_segcblist</tt> structure really is devoid of callbacks.
|
||||
Of course, off-CPU sampling of the <tt>->len</tt> count requires
|
||||
the use of appropriate synchronization, for example, memory barriers.
|
||||
careful use of appropriate synchronization, for example, memory barriers.
|
||||
This synchronization can be a bit subtle, particularly in the case
|
||||
of <tt>rcu_barrier()</tt>.
|
||||
|
||||
<h3><a name="The rcu_data Structure">
|
||||
The <tt>rcu_data</tt> Structure</a></h3>
|
||||
|
||||
<p>The <tt>rcu_data</tt> maintains the per-CPU state for the
|
||||
corresponding flavor of RCU.
|
||||
<p>The <tt>rcu_data</tt> maintains the per-CPU state for the RCU subsystem.
|
||||
The fields in this structure may be accessed only from the corresponding
|
||||
CPU (and from tracing) unless otherwise stated.
|
||||
This structure is the
|
||||
@@ -1015,30 +978,19 @@ as follows:
|
||||
|
||||
<pre>
|
||||
1 int cpu;
|
||||
2 struct rcu_state *rsp;
|
||||
3 struct rcu_node *mynode;
|
||||
4 struct rcu_dynticks *dynticks;
|
||||
5 unsigned long grpmask;
|
||||
6 bool beenonline;
|
||||
2 struct rcu_node *mynode;
|
||||
3 unsigned long grpmask;
|
||||
4 bool beenonline;
|
||||
</pre>
|
||||
|
||||
<p>The <tt>->cpu</tt> field contains the number of the
|
||||
corresponding CPU, the <tt>->rsp</tt> pointer references
|
||||
the corresponding <tt>rcu_state</tt> structure (and is most frequently
|
||||
used to locate the name of the corresponding flavor of RCU for tracing),
|
||||
and the <tt>->mynode</tt> field references the corresponding
|
||||
<tt>rcu_node</tt> structure.
|
||||
corresponding CPU and the <tt>->mynode</tt> field references the
|
||||
corresponding <tt>rcu_node</tt> structure.
|
||||
The <tt>->mynode</tt> is used to propagate quiescent states
|
||||
up the combining tree.
|
||||
<p>The <tt>->dynticks</tt> pointer references the
|
||||
<tt>rcu_dynticks</tt> structure corresponding to this
|
||||
CPU.
|
||||
Recall that a single per-CPU instance of the <tt>rcu_dynticks</tt>
|
||||
structure is shared among all flavors of RCU.
|
||||
These first four fields are constant and therefore require not
|
||||
synchronization.
|
||||
These two fields are constant and therefore do not require synchronization.
|
||||
|
||||
</p><p>The <tt>->grpmask</tt> field indicates the bit in
|
||||
<p>The <tt>->grpmask</tt> field indicates the bit in
|
||||
the <tt>->mynode->qsmask</tt> corresponding to this
|
||||
<tt>rcu_data</tt> structure, and is also used when propagating
|
||||
quiescent states.
|
||||
@@ -1057,12 +1009,12 @@ as follows:
|
||||
3 bool cpu_no_qs;
|
||||
4 bool core_needs_qs;
|
||||
5 bool gpwrap;
|
||||
6 unsigned long rcu_qs_ctr_snap;
|
||||
</pre>
|
||||
|
||||
<p>The <tt>->gp_seq</tt> and <tt>->gp_seq_needed</tt>
|
||||
fields are the counterparts of the fields of the same name
|
||||
in the <tt>rcu_state</tt> and <tt>rcu_node</tt> structures.
|
||||
<p>The <tt>->gp_seq</tt> field is the counterpart of the field of the same
|
||||
name in the <tt>rcu_state</tt> and <tt>rcu_node</tt> structures. The
|
||||
<tt>->gp_seq_needed</tt> field is the counterpart of the field of the same
|
||||
name in the rcu_node</tt> structure.
|
||||
They may each lag up to one behind their <tt>rcu_node</tt>
|
||||
counterparts, but in <tt>CONFIG_NO_HZ_IDLE</tt> and
|
||||
<tt>CONFIG_NO_HZ_FULL</tt> kernels can lag
|
||||
@@ -1103,10 +1055,6 @@ CPU has remained idle for so long that the
|
||||
<tt>gp_seq</tt> counter is in danger of overflow, which
|
||||
will cause the CPU to disregard the values of its counters on
|
||||
its next exit from idle.
|
||||
Finally, the <tt>rcu_qs_ctr_snap</tt> field is used to detect
|
||||
cases where a given operation has resulted in a quiescent state
|
||||
for all flavors of RCU, for example, <tt>cond_resched()</tt>
|
||||
when RCU has indicated a need for quiescent states.
|
||||
|
||||
<h5>RCU Callback Handling</h5>
|
||||
|
||||
@@ -1179,26 +1127,22 @@ Finally, the <tt>->dynticks_fqs</tt> field is used to
|
||||
count the number of times this CPU is determined to be in
|
||||
dyntick-idle state, and is used for tracing and debugging purposes.
|
||||
|
||||
<h3><a name="The rcu_dynticks Structure">
|
||||
The <tt>rcu_dynticks</tt> Structure</a></h3>
|
||||
|
||||
<p>The <tt>rcu_dynticks</tt> maintains the per-CPU dyntick-idle state
|
||||
for the corresponding CPU.
|
||||
Unlike the other structures, <tt>rcu_dynticks</tt> is not
|
||||
replicated over the different flavors of RCU.
|
||||
The fields in this structure may be accessed only from the corresponding
|
||||
CPU (and from tracing) unless otherwise stated.
|
||||
Its fields are as follows:
|
||||
<p>
|
||||
This portion of the rcu_data structure is declared as follows:
|
||||
|
||||
<pre>
|
||||
1 long dynticks_nesting;
|
||||
2 long dynticks_nmi_nesting;
|
||||
3 atomic_t dynticks;
|
||||
4 bool rcu_need_heavy_qs;
|
||||
5 unsigned long rcu_qs_ctr;
|
||||
6 bool rcu_urgent_qs;
|
||||
5 bool rcu_urgent_qs;
|
||||
</pre>
|
||||
|
||||
<p>These fields in the rcu_data structure maintain the per-CPU dyntick-idle
|
||||
state for the corresponding CPU.
|
||||
The fields may be accessed only from the corresponding CPU (and from tracing)
|
||||
unless otherwise stated.
|
||||
|
||||
<p>The <tt>->dynticks_nesting</tt> field counts the
|
||||
nesting depth of process execution, so that in normal circumstances
|
||||
this counter has value zero or one.
|
||||
@@ -1240,19 +1184,12 @@ it is willing to call for heavy-weight dyntick-counter operations.
|
||||
This flag is checked by RCU's context-switch and <tt>cond_resched()</tt>
|
||||
code, which provide a momentary idle sojourn in response.
|
||||
|
||||
</p><p>The <tt>->rcu_qs_ctr</tt> field is used to record
|
||||
quiescent states from <tt>cond_resched()</tt>.
|
||||
Because <tt>cond_resched()</tt> can execute quite frequently, this
|
||||
must be quite lightweight, as in a non-atomic increment of this
|
||||
per-CPU field.
|
||||
|
||||
</p><p>Finally, the <tt>->rcu_urgent_qs</tt> field is used to record
|
||||
the fact that the RCU core code would really like to see a quiescent
|
||||
state from the corresponding CPU, with the various other fields indicating
|
||||
just how badly RCU wants this quiescent state.
|
||||
This flag is checked by RCU's context-switch and <tt>cond_resched()</tt>
|
||||
code, which, if nothing else, non-atomically increment <tt>->rcu_qs_ctr</tt>
|
||||
in response.
|
||||
the fact that the RCU core code would really like to see a quiescent state from
|
||||
the corresponding CPU, with the various other fields indicating just how badly
|
||||
RCU wants this quiescent state.
|
||||
This flag is checked by RCU's context-switch path
|
||||
(<tt>rcu_note_context_switch</tt>) and the cond_resched code.
|
||||
|
||||
<table>
|
||||
<tr><th> </th></tr>
|
||||
@@ -1425,11 +1362,11 @@ the last part of the array, thus traversing only the leaf
|
||||
<h3><a name="Summary">
|
||||
Summary</a></h3>
|
||||
|
||||
So each flavor of RCU is represented by an <tt>rcu_state</tt> structure,
|
||||
So the state of RCU is represented by an <tt>rcu_state</tt> structure,
|
||||
which contains a combining tree of <tt>rcu_node</tt> and
|
||||
<tt>rcu_data</tt> structures.
|
||||
Finally, in <tt>CONFIG_NO_HZ_IDLE</tt> kernels, each CPU's dyntick-idle
|
||||
state is tracked by an <tt>rcu_dynticks</tt> structure.
|
||||
state is tracked by dynticks-related fields in the <tt>rcu_data</tt> structure.
|
||||
|
||||
If you made it this far, you are well prepared to read the code
|
||||
walkthroughs in the other articles in this series.
|
||||
|
||||
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 20 KiB |
@@ -160,9 +160,9 @@ was in flight.
|
||||
If the CPU is idle, then <tt>sync_sched_exp_handler()</tt> reports
|
||||
the quiescent state.
|
||||
|
||||
<p>
|
||||
Otherwise, the handler invokes <tt>resched_cpu()</tt>, which forces
|
||||
a future context switch.
|
||||
<p> Otherwise, the handler forces a future context switch by setting the
|
||||
NEED_RESCHED flag of the current task's thread flag and the CPU preempt
|
||||
counter.
|
||||
At the time of the context switch, the CPU reports the quiescent state.
|
||||
Should the CPU go offline first, it will report the quiescent state
|
||||
at that time.
|
||||
|
||||
@@ -77,7 +77,7 @@ The key point is that the lock-acquisition functions, including
|
||||
<tt>smp_mb__after_unlock_lock()</tt> immediately after successful
|
||||
acquisition of the lock.
|
||||
|
||||
<p>Therefore, for any given <tt>rcu_node</tt> struction, any access
|
||||
<p>Therefore, for any given <tt>rcu_node</tt> structure, any access
|
||||
happening before one of the above lock-release functions will be seen
|
||||
by all CPUs as happening before any access happening after a later
|
||||
one of the above lock-acquisition functions.
|
||||
|
||||
@@ -900,8 +900,6 @@ Except where otherwise noted, these non-guarantees were premeditated.
|
||||
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>
|
||||
@@ -1259,54 +1257,6 @@ of RCU grace periods.
|
||||
<tr><td> </td></tr>
|
||||
</table>
|
||||
|
||||
<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="https://lkml.kernel.org/g/20150614193825.GA19582@redhat.com">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.
|
||||
|
||||
<h2><a name="Parallelism Facts of Life">Parallelism Facts of Life</a></h2>
|
||||
|
||||
<p>
|
||||
@@ -1381,6 +1331,7 @@ 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="#Forward Progress">Forward Progress</a>
|
||||
<li> <a href="#Composability">Composability</a>
|
||||
<li> <a href="#Corner Cases">Corner Cases</a>
|
||||
</ol>
|
||||
@@ -1645,7 +1596,7 @@ used in place of <tt>synchronize_rcu()</tt> as follows:
|
||||
16 struct foo *p;
|
||||
17
|
||||
18 spin_lock(&gp_lock);
|
||||
19 p = rcu_dereference(gp);
|
||||
19 p = rcu_access_pointer(gp);
|
||||
20 if (!p) {
|
||||
21 spin_unlock(&gp_lock);
|
||||
22 return false;
|
||||
@@ -1822,6 +1773,106 @@ so it is too early to tell whether they will stand the test of time.
|
||||
RCU thus provides a range of tools to allow updaters to strike the
|
||||
required tradeoff between latency, flexibility and CPU overhead.
|
||||
|
||||
<h3><a name="Forward Progress">Forward Progress</a></h3>
|
||||
|
||||
<p>
|
||||
In theory, delaying grace-period completion and callback invocation
|
||||
is harmless.
|
||||
In practice, not only are memory sizes finite but also callbacks sometimes
|
||||
do wakeups, and sufficiently deferred wakeups can be difficult
|
||||
to distinguish from system hangs.
|
||||
Therefore, RCU must provide a number of mechanisms to promote forward
|
||||
progress.
|
||||
|
||||
<p>
|
||||
These mechanisms are not foolproof, nor can they be.
|
||||
For one simple example, an infinite loop in an RCU read-side critical
|
||||
section must by definition prevent later grace periods from ever completing.
|
||||
For a more involved example, consider a 64-CPU system built with
|
||||
<tt>CONFIG_RCU_NOCB_CPU=y</tt> and booted with <tt>rcu_nocbs=1-63</tt>,
|
||||
where CPUs 1 through 63 spin in tight loops that invoke
|
||||
<tt>call_rcu()</tt>.
|
||||
Even if these tight loops also contain calls to <tt>cond_resched()</tt>
|
||||
(thus allowing grace periods to complete), CPU 0 simply will
|
||||
not be able to invoke callbacks as fast as the other 63 CPUs can
|
||||
register them, at least not until the system runs out of memory.
|
||||
In both of these examples, the Spiderman principle applies: With great
|
||||
power comes great responsibility.
|
||||
However, short of this level of abuse, RCU is required to
|
||||
ensure timely completion of grace periods and timely invocation of
|
||||
callbacks.
|
||||
|
||||
<p>
|
||||
RCU takes the following steps to encourage timely completion of
|
||||
grace periods:
|
||||
|
||||
<ol>
|
||||
<li> If a grace period fails to complete within 100 milliseconds,
|
||||
RCU causes future invocations of <tt>cond_resched()</tt> on
|
||||
the holdout CPUs to provide an RCU quiescent state.
|
||||
RCU also causes those CPUs' <tt>need_resched()</tt> invocations
|
||||
to return <tt>true</tt>, but only after the corresponding CPU's
|
||||
next scheduling-clock.
|
||||
<li> CPUs mentioned in the <tt>nohz_full</tt> kernel boot parameter
|
||||
can run indefinitely in the kernel without scheduling-clock
|
||||
interrupts, which defeats the above <tt>need_resched()</tt>
|
||||
strategem.
|
||||
RCU will therefore invoke <tt>resched_cpu()</tt> on any
|
||||
<tt>nohz_full</tt> CPUs still holding out after
|
||||
109 milliseconds.
|
||||
<li> In kernels built with <tt>CONFIG_RCU_BOOST=y</tt>, if a given
|
||||
task that has been preempted within an RCU read-side critical
|
||||
section is holding out for more than 500 milliseconds,
|
||||
RCU will resort to priority boosting.
|
||||
<li> If a CPU is still holding out 10 seconds into the grace
|
||||
period, RCU will invoke <tt>resched_cpu()</tt> on it regardless
|
||||
of its <tt>nohz_full</tt> state.
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
The above values are defaults for systems running with <tt>HZ=1000</tt>.
|
||||
They will vary as the value of <tt>HZ</tt> varies, and can also be
|
||||
changed using the relevant Kconfig options and kernel boot parameters.
|
||||
RCU currently does not do much sanity checking of these
|
||||
parameters, so please use caution when changing them.
|
||||
Note that these forward-progress measures are provided only for RCU,
|
||||
not for
|
||||
<a href="#Sleepable RCU">SRCU</a> or
|
||||
<a href="#Tasks RCU">Tasks RCU</a>.
|
||||
|
||||
<p>
|
||||
RCU takes the following steps in <tt>call_rcu()</tt> to encourage timely
|
||||
invocation of callbacks when any given non-<tt>rcu_nocbs</tt> CPU has
|
||||
10,000 callbacks, or has 10,000 more callbacks than it had the last time
|
||||
encouragement was provided:
|
||||
|
||||
<ol>
|
||||
<li> Starts a grace period, if one is not already in progress.
|
||||
<li> Forces immediate checking for quiescent states, rather than
|
||||
waiting for three milliseconds to have elapsed since the
|
||||
beginning of the grace period.
|
||||
<li> Immediately tags the CPU's callbacks with their grace period
|
||||
completion numbers, rather than waiting for the <tt>RCU_SOFTIRQ</tt>
|
||||
handler to get around to it.
|
||||
<li> Lifts callback-execution batch limits, which speeds up callback
|
||||
invocation at the expense of degrading realtime response.
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
Again, these are default values when running at <tt>HZ=1000</tt>,
|
||||
and can be overridden.
|
||||
Again, these forward-progress measures are provided only for RCU,
|
||||
not for
|
||||
<a href="#Sleepable RCU">SRCU</a> or
|
||||
<a href="#Tasks RCU">Tasks RCU</a>.
|
||||
Even for RCU, callback-invocation forward progress for <tt>rcu_nocbs</tt>
|
||||
CPUs is much less well-developed, in part because workloads benefiting
|
||||
from <tt>rcu_nocbs</tt> CPUs tend to invoke <tt>call_rcu()</tt>
|
||||
relatively infrequently.
|
||||
If workloads emerge that need both <tt>rcu_nocbs</tt> CPUs and high
|
||||
<tt>call_rcu()</tt> invocation rates, then additional forward-progress
|
||||
work will be required.
|
||||
|
||||
<h3><a name="Composability">Composability</a></h3>
|
||||
|
||||
<p>
|
||||
@@ -2272,7 +2323,7 @@ that meets this requirement.
|
||||
Furthermore, NMI handlers can be interrupted by what appear to RCU
|
||||
to be normal interrupts.
|
||||
One way that this can happen is for code that directly invokes
|
||||
<tt>rcu_irq_enter()</tt> and </tt>rcu_irq_exit()</tt> to be called
|
||||
<tt>rcu_irq_enter()</tt> and <tt>rcu_irq_exit()</tt> to be called
|
||||
from an NMI handler.
|
||||
This astonishing fact of life prompted the current code structure,
|
||||
which has <tt>rcu_irq_enter()</tt> invoking <tt>rcu_nmi_enter()</tt>
|
||||
@@ -2294,7 +2345,7 @@ 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.
|
||||
eventually going to 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.
|
||||
@@ -2424,23 +2475,37 @@ for context-switch-heavy <tt>CONFIG_NO_HZ_FULL=y</tt> workloads,
|
||||
but there is room for further improvement.
|
||||
|
||||
<p>
|
||||
In the past, it was forbidden to disable interrupts across an
|
||||
<tt>rcu_read_unlock()</tt> unless that interrupt-disabled region
|
||||
of code also included the matching <tt>rcu_read_lock()</tt>.
|
||||
Violating this restriction could result in deadlocks involving the
|
||||
scheduler's runqueue and priority-inheritance spinlocks.
|
||||
This restriction was lifted when interrupt-disabled calls to
|
||||
<tt>rcu_read_unlock()</tt> started deferring the reporting of
|
||||
the resulting RCU-preempt quiescent state until the end of that
|
||||
It is forbidden to hold any of scheduler's runqueue or priority-inheritance
|
||||
spinlocks across an <tt>rcu_read_unlock()</tt> unless interrupts have been
|
||||
disabled across the entire RCU read-side critical section, that is,
|
||||
up to and including the matching <tt>rcu_read_lock()</tt>.
|
||||
Violating this restriction can result in deadlocks involving these
|
||||
scheduler spinlocks.
|
||||
There was hope that this restriction might be lifted when interrupt-disabled
|
||||
calls to <tt>rcu_read_unlock()</tt> started deferring the reporting of
|
||||
the resulting RCU-preempt quiescent state until the end of the corresponding
|
||||
interrupts-disabled region.
|
||||
This deferred reporting means that the scheduler's runqueue and
|
||||
priority-inheritance locks cannot be held while reporting an RCU-preempt
|
||||
quiescent state, which lifts the earlier restriction, at least from
|
||||
a deadlock perspective.
|
||||
Unfortunately, real-time systems using RCU priority boosting may
|
||||
Unfortunately, timely reporting of the corresponding quiescent state
|
||||
to expedited grace periods requires a call to <tt>raise_softirq()</tt>,
|
||||
which can acquire these scheduler spinlocks.
|
||||
In addition, real-time systems using RCU priority boosting
|
||||
need this restriction to remain in effect because deferred
|
||||
quiescent-state reporting also defers deboosting, which in turn
|
||||
degrades real-time latencies.
|
||||
quiescent-state reporting would also defer deboosting, which in turn
|
||||
would degrade real-time latencies.
|
||||
|
||||
<p>
|
||||
In theory, if a given RCU read-side critical section could be
|
||||
guaranteed to be less than one second in duration, holding a scheduler
|
||||
spinlock across that critical section's <tt>rcu_read_unlock()</tt>
|
||||
would require only that preemption be disabled across the entire
|
||||
RCU read-side critical section, not interrupts.
|
||||
Unfortunately, given the possibility of vCPU preemption, long-running
|
||||
interrupts, and so on, it is not possible in practice to guarantee
|
||||
that a given RCU read-side critical section will complete in less than
|
||||
one second.
|
||||
Therefore, as noted above, if scheduler spinlocks are held across
|
||||
a given call to <tt>rcu_read_unlock()</tt>, interrupts must be
|
||||
disabled across the entire RCU read-side critical section.
|
||||
|
||||
<h3><a name="Tracing and RCU">Tracing and RCU</a></h3>
|
||||
|
||||
@@ -3233,6 +3298,11 @@ For example, RCU callback overhead might be charged back to the
|
||||
originating <tt>call_rcu()</tt> instance, though probably not
|
||||
in production kernels.
|
||||
|
||||
<p>
|
||||
Additional work may be required to provide reasonable forward-progress
|
||||
guarantees under heavy load for grace periods and for callback
|
||||
invocation.
|
||||
|
||||
<h2><a name="Summary">Summary</a></h2>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -63,7 +63,7 @@ over a rather long period of time, but improvements are always welcome!
|
||||
pointer must be covered by rcu_read_lock(), rcu_read_lock_bh(),
|
||||
rcu_read_lock_sched(), or by the appropriate update-side lock.
|
||||
Disabling of preemption can serve as rcu_read_lock_sched(), but
|
||||
is less readable.
|
||||
is less readable and prevents lockdep from detecting locking issues.
|
||||
|
||||
Letting RCU-protected pointers "leak" out of an RCU read-side
|
||||
critical section is every bid as bad as letting them leak out
|
||||
@@ -285,11 +285,7 @@ over a rather long period of time, but improvements are always welcome!
|
||||
here is that superuser already has lots of ways to crash
|
||||
the machine.
|
||||
|
||||
d. Use call_rcu_bh() rather than call_rcu(), in order to take
|
||||
advantage of call_rcu_bh()'s faster grace periods. (This
|
||||
is only a partial solution, though.)
|
||||
|
||||
e. Periodically invoke synchronize_rcu(), permitting a limited
|
||||
d. Periodically invoke synchronize_rcu(), permitting a limited
|
||||
number of updates per grace period.
|
||||
|
||||
The same cautions apply to call_rcu_bh(), call_rcu_sched(),
|
||||
@@ -324,37 +320,14 @@ over a rather long period of time, but improvements are always welcome!
|
||||
will break Alpha, cause aggressive compilers to generate bad code,
|
||||
and confuse people trying to read your code.
|
||||
|
||||
11. Note that synchronize_rcu() -only- guarantees to wait until
|
||||
all currently executing rcu_read_lock()-protected RCU read-side
|
||||
critical sections complete. It does -not- necessarily guarantee
|
||||
that all currently running interrupts, NMIs, preempt_disable()
|
||||
code, or idle loops will complete. Therefore, if your
|
||||
read-side critical sections are protected by something other
|
||||
than rcu_read_lock(), do -not- use synchronize_rcu().
|
||||
|
||||
Similarly, disabling preemption is not an acceptable substitute
|
||||
for rcu_read_lock(). Code that attempts to use preemption
|
||||
disabling where it should be using rcu_read_lock() will break
|
||||
in CONFIG_PREEMPT=y kernel builds.
|
||||
|
||||
If you want to wait for interrupt handlers, NMI handlers, and
|
||||
code under the influence of preempt_disable(), you instead
|
||||
need to use synchronize_irq() or synchronize_sched().
|
||||
|
||||
This same limitation also applies to synchronize_rcu_bh()
|
||||
and synchronize_srcu(), as well as to the asynchronous and
|
||||
expedited forms of the three primitives, namely call_rcu(),
|
||||
call_rcu_bh(), call_srcu(), synchronize_rcu_expedited(),
|
||||
synchronize_rcu_bh_expedited(), and synchronize_srcu_expedited().
|
||||
|
||||
12. Any lock acquired by an RCU callback must be acquired elsewhere
|
||||
11. Any lock acquired by an RCU callback must be acquired elsewhere
|
||||
with softirq disabled, e.g., via spin_lock_irqsave(),
|
||||
spin_lock_bh(), etc. Failing to disable irq on a given
|
||||
acquisition of that lock will result in deadlock as soon as
|
||||
the RCU softirq handler happens to run your RCU callback while
|
||||
interrupting that acquisition's critical section.
|
||||
|
||||
13. RCU callbacks can be and are executed in parallel. In many cases,
|
||||
12. RCU callbacks can be and are executed in parallel. In many cases,
|
||||
the callback code simply wrappers around kfree(), so that this
|
||||
is not an issue (or, more accurately, to the extent that it is
|
||||
an issue, the memory-allocator locking handles it). However,
|
||||
@@ -370,7 +343,7 @@ over a rather long period of time, but improvements are always welcome!
|
||||
not the case, a self-spawning RCU callback would prevent the
|
||||
victim CPU from ever going offline.)
|
||||
|
||||
14. Unlike other forms of RCU, it -is- permissible to block in an
|
||||
13. Unlike other forms of RCU, it -is- permissible to block in an
|
||||
SRCU read-side critical section (demarked by srcu_read_lock()
|
||||
and srcu_read_unlock()), hence the "SRCU": "sleepable RCU".
|
||||
Please note that if you don't need to sleep in read-side critical
|
||||
@@ -414,7 +387,7 @@ over a rather long period of time, but improvements are always welcome!
|
||||
Note that rcu_dereference() and rcu_assign_pointer() relate to
|
||||
SRCU just as they do to other forms of RCU.
|
||||
|
||||
15. The whole point of call_rcu(), synchronize_rcu(), and friends
|
||||
14. The whole point of call_rcu(), synchronize_rcu(), and friends
|
||||
is to wait until all pre-existing readers have finished before
|
||||
carrying out some otherwise-destructive operation. It is
|
||||
therefore critically important to -first- remove any path
|
||||
@@ -426,13 +399,13 @@ over a rather long period of time, but improvements are always welcome!
|
||||
is the caller's responsibility to guarantee that any subsequent
|
||||
readers will execute safely.
|
||||
|
||||
16. The various RCU read-side primitives do -not- necessarily contain
|
||||
15. The various RCU read-side primitives do -not- necessarily contain
|
||||
memory barriers. You should therefore plan for the CPU
|
||||
and the compiler to freely reorder code into and out of RCU
|
||||
read-side critical sections. It is the responsibility of the
|
||||
RCU update-side primitives to deal with this.
|
||||
|
||||
17. Use CONFIG_PROVE_LOCKING, CONFIG_DEBUG_OBJECTS_RCU_HEAD, and the
|
||||
16. Use CONFIG_PROVE_LOCKING, CONFIG_DEBUG_OBJECTS_RCU_HEAD, and the
|
||||
__rcu sparse checks to validate your RCU code. These can help
|
||||
find problems as follows:
|
||||
|
||||
@@ -455,7 +428,7 @@ over a rather long period of time, but improvements are always welcome!
|
||||
These debugging aids can help you find problems that are
|
||||
otherwise extremely difficult to spot.
|
||||
|
||||
18. If you register a callback using call_rcu(), call_rcu_bh(),
|
||||
17. If you register a callback using call_rcu(), call_rcu_bh(),
|
||||
call_rcu_sched(), or call_srcu(), and pass in a function defined
|
||||
within a loadable module, then it in necessary to wait for
|
||||
all pending callbacks to be invoked after the last invocation
|
||||
@@ -469,8 +442,8 @@ over a rather long period of time, but improvements are always welcome!
|
||||
You instead need to use one of the barrier functions:
|
||||
|
||||
o call_rcu() -> rcu_barrier()
|
||||
o call_rcu_bh() -> rcu_barrier_bh()
|
||||
o call_rcu_sched() -> rcu_barrier_sched()
|
||||
o call_rcu_bh() -> rcu_barrier()
|
||||
o call_rcu_sched() -> rcu_barrier()
|
||||
o call_srcu() -> srcu_barrier()
|
||||
|
||||
However, these barrier functions are absolutely -not- guaranteed
|
||||
|
||||
@@ -176,9 +176,8 @@ causing stalls, and that the stall was affecting RCU-sched. This message
|
||||
will normally be followed by stack dumps for each CPU. Please note that
|
||||
PREEMPT_RCU builds can be stalled by tasks as well as by CPUs, and that
|
||||
the tasks will be indicated by PID, for example, "P3421". It is even
|
||||
possible for a rcu_preempt_state stall to be caused by both CPUs -and-
|
||||
tasks, in which case the offending CPUs and tasks will all be called
|
||||
out in the list.
|
||||
possible for an rcu_state stall to be caused by both CPUs -and- tasks,
|
||||
in which case the offending CPUs and tasks will all be called out in the list.
|
||||
|
||||
CPU 2's "(3 GPs behind)" indicates that this CPU has not interacted with
|
||||
the RCU core for the past three grace periods. In contrast, CPU 16's "(0
|
||||
@@ -206,7 +205,7 @@ handlers are no longer able to execute on this CPU. This can happen if
|
||||
the stalled CPU is spinning with interrupts are disabled, or, in -rt
|
||||
kernels, if a high-priority process is starving RCU's softirq handler.
|
||||
|
||||
The "fps=" shows the number of force-quiescent-state idle/offline
|
||||
The "fqs=" shows the number of force-quiescent-state idle/offline
|
||||
detection passes that the grace-period kthread has made across this
|
||||
CPU since the last time that this CPU noted the beginning of a grace
|
||||
period.
|
||||
|
||||
@@ -266,7 +266,7 @@ rcu_dereference()
|
||||
unnecessary overhead on Alpha CPUs.
|
||||
|
||||
Note that the value returned by rcu_dereference() is valid
|
||||
only within the enclosing RCU read-side critical section.
|
||||
only within the enclosing RCU read-side critical section [1].
|
||||
For example, the following is -not- legal:
|
||||
|
||||
rcu_read_lock();
|
||||
@@ -292,6 +292,19 @@ rcu_dereference()
|
||||
typically used indirectly, via the _rcu list-manipulation
|
||||
primitives, such as list_for_each_entry_rcu().
|
||||
|
||||
[1] The variant rcu_dereference_protected() can be used outside
|
||||
of an RCU read-side critical section as long as the usage is
|
||||
protected by locks acquired by the update-side code. This variant
|
||||
avoids the lockdep warning that would happen when using (for
|
||||
example) rcu_dereference() without rcu_read_lock() protection.
|
||||
Using rcu_dereference_protected() also has the advantage
|
||||
of permitting compiler optimizations that rcu_dereference()
|
||||
must prohibit. The rcu_dereference_protected() variant takes
|
||||
a lockdep expression to indicate which locks must be acquired
|
||||
by the caller. If the indicated protection is not provided,
|
||||
a lockdep splat is emitted. See RCU/Design/Requirements.html
|
||||
and the API's code comments for more details and example usage.
|
||||
|
||||
The following diagram shows how each API communicates among the
|
||||
reader, updater, and reclaimer.
|
||||
|
||||
@@ -322,28 +335,27 @@ to their callers and (2) call_rcu() callbacks may be invoked. Efficient
|
||||
implementations of the RCU infrastructure make heavy use of batching in
|
||||
order to amortize their overhead over many uses of the corresponding APIs.
|
||||
|
||||
There are no fewer than three RCU mechanisms in the Linux kernel; the
|
||||
diagram above shows the first one, which is by far the most commonly used.
|
||||
The rcu_dereference() and rcu_assign_pointer() primitives are used for
|
||||
all three mechanisms, but different defer and protect primitives are
|
||||
used as follows:
|
||||
There are at least three flavors of RCU usage in the Linux kernel. The diagram
|
||||
above shows the most common one. On the updater side, the rcu_assign_pointer(),
|
||||
sychronize_rcu() and call_rcu() primitives used are the same for all three
|
||||
flavors. However for protection (on the reader side), the primitives used vary
|
||||
depending on the flavor:
|
||||
|
||||
Defer Protect
|
||||
a. rcu_read_lock() / rcu_read_unlock()
|
||||
rcu_dereference()
|
||||
|
||||
a. synchronize_rcu() rcu_read_lock() / rcu_read_unlock()
|
||||
call_rcu() rcu_dereference()
|
||||
b. rcu_read_lock_bh() / rcu_read_unlock_bh()
|
||||
local_bh_disable() / local_bh_enable()
|
||||
rcu_dereference_bh()
|
||||
|
||||
b. synchronize_rcu_bh() rcu_read_lock_bh() / rcu_read_unlock_bh()
|
||||
call_rcu_bh() rcu_dereference_bh()
|
||||
c. rcu_read_lock_sched() / rcu_read_unlock_sched()
|
||||
preempt_disable() / preempt_enable()
|
||||
local_irq_save() / local_irq_restore()
|
||||
hardirq enter / hardirq exit
|
||||
NMI enter / NMI exit
|
||||
rcu_dereference_sched()
|
||||
|
||||
c. synchronize_sched() rcu_read_lock_sched() / rcu_read_unlock_sched()
|
||||
call_rcu_sched() preempt_disable() / preempt_enable()
|
||||
local_irq_save() / local_irq_restore()
|
||||
hardirq enter / hardirq exit
|
||||
NMI enter / NMI exit
|
||||
rcu_dereference_sched()
|
||||
|
||||
These three mechanisms are used as follows:
|
||||
These three flavors are used as follows:
|
||||
|
||||
a. RCU applied to normal data structures.
|
||||
|
||||
@@ -867,18 +879,20 @@ RCU: Critical sections Grace period Barrier
|
||||
|
||||
bh: Critical sections Grace period Barrier
|
||||
|
||||
rcu_read_lock_bh call_rcu_bh rcu_barrier_bh
|
||||
rcu_read_unlock_bh synchronize_rcu_bh
|
||||
rcu_dereference_bh synchronize_rcu_bh_expedited
|
||||
rcu_read_lock_bh call_rcu rcu_barrier
|
||||
rcu_read_unlock_bh synchronize_rcu
|
||||
[local_bh_disable] synchronize_rcu_expedited
|
||||
[and friends]
|
||||
rcu_dereference_bh
|
||||
rcu_dereference_bh_check
|
||||
rcu_dereference_bh_protected
|
||||
rcu_read_lock_bh_held
|
||||
|
||||
sched: Critical sections Grace period Barrier
|
||||
|
||||
rcu_read_lock_sched synchronize_sched rcu_barrier_sched
|
||||
rcu_read_unlock_sched call_rcu_sched
|
||||
[preempt_disable] synchronize_sched_expedited
|
||||
rcu_read_lock_sched call_rcu rcu_barrier
|
||||
rcu_read_unlock_sched synchronize_rcu
|
||||
[preempt_disable] synchronize_rcu_expedited
|
||||
[and friends]
|
||||
rcu_read_lock_sched_notrace
|
||||
rcu_read_unlock_sched_notrace
|
||||
@@ -890,8 +904,8 @@ sched: Critical sections Grace period Barrier
|
||||
|
||||
SRCU: Critical sections Grace period Barrier
|
||||
|
||||
srcu_read_lock synchronize_srcu srcu_barrier
|
||||
srcu_read_unlock call_srcu
|
||||
srcu_read_lock call_srcu srcu_barrier
|
||||
srcu_read_unlock synchronize_srcu
|
||||
srcu_dereference synchronize_srcu_expedited
|
||||
srcu_dereference_check
|
||||
srcu_read_lock_held
|
||||
@@ -1034,7 +1048,7 @@ Answer: Just as PREEMPT_RT permits preemption of spinlock
|
||||
spinlocks blocking while in RCU read-side critical
|
||||
sections.
|
||||
|
||||
Why the apparent inconsistency? Because it is it
|
||||
Why the apparent inconsistency? Because it is
|
||||
possible to use priority boosting to keep the RCU
|
||||
grace periods short if need be (for example, if running
|
||||
short of memory). In contrast, if blocking waiting
|
||||
|
||||
@@ -3748,24 +3748,6 @@
|
||||
in microseconds. The default of zero says
|
||||
no holdoff.
|
||||
|
||||
rcutorture.cbflood_inter_holdoff= [KNL]
|
||||
Set holdoff time (jiffies) between successive
|
||||
callback-flood tests.
|
||||
|
||||
rcutorture.cbflood_intra_holdoff= [KNL]
|
||||
Set holdoff time (jiffies) between successive
|
||||
bursts of callbacks within a given callback-flood
|
||||
test.
|
||||
|
||||
rcutorture.cbflood_n_burst= [KNL]
|
||||
Set the number of bursts making up a given
|
||||
callback-flood test. Set this to zero to
|
||||
disable callback-flood testing.
|
||||
|
||||
rcutorture.cbflood_n_per_burst= [KNL]
|
||||
Set the number of callbacks to be registered
|
||||
in a given burst of a callback-flood test.
|
||||
|
||||
rcutorture.fqs_duration= [KNL]
|
||||
Set duration of force_quiescent_state bursts
|
||||
in microseconds.
|
||||
@@ -3778,6 +3760,23 @@
|
||||
Set wait time between force_quiescent_state bursts
|
||||
in seconds.
|
||||
|
||||
rcutorture.fwd_progress= [KNL]
|
||||
Enable RCU grace-period forward-progress testing
|
||||
for the types of RCU supporting this notion.
|
||||
|
||||
rcutorture.fwd_progress_div= [KNL]
|
||||
Specify the fraction of a CPU-stall-warning
|
||||
period to do tight-loop forward-progress testing.
|
||||
|
||||
rcutorture.fwd_progress_holdoff= [KNL]
|
||||
Number of seconds to wait between successive
|
||||
forward-progress tests.
|
||||
|
||||
rcutorture.fwd_progress_need_resched= [KNL]
|
||||
Enclose cond_resched() calls within checks for
|
||||
need_resched() during tight-loop forward-progress
|
||||
testing.
|
||||
|
||||
rcutorture.gp_cond= [KNL]
|
||||
Use conditional/asynchronous update-side
|
||||
primitives, if available.
|
||||
|
||||
@@ -4098,7 +4098,7 @@ S: Supported
|
||||
F: drivers/net/ethernet/chelsio/cxgb4vf/
|
||||
|
||||
CXL (IBM Coherent Accelerator Processor Interface CAPI) DRIVER
|
||||
M: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
|
||||
M: Frederic Barrat <fbarrat@linux.ibm.com>
|
||||
M: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
|
||||
L: linuxppc-dev@lists.ozlabs.org
|
||||
S: Supported
|
||||
@@ -4110,9 +4110,9 @@ F: Documentation/powerpc/cxl.txt
|
||||
F: Documentation/ABI/testing/sysfs-class-cxl
|
||||
|
||||
CXLFLASH (IBM Coherent Accelerator Processor Interface CAPI Flash) SCSI DRIVER
|
||||
M: Manoj N. Kumar <manoj@linux.vnet.ibm.com>
|
||||
M: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
|
||||
M: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
|
||||
M: Manoj N. Kumar <manoj@linux.ibm.com>
|
||||
M: Matthew R. Ochs <mrochs@linux.ibm.com>
|
||||
M: Uma Krishnan <ukrishn@linux.ibm.com>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/scsi/cxlflash/
|
||||
@@ -5493,7 +5493,7 @@ S: Orphan
|
||||
F: fs/efs/
|
||||
|
||||
EHEA (IBM pSeries eHEA 10Gb ethernet adapter) DRIVER
|
||||
M: Douglas Miller <dougmill@linux.vnet.ibm.com>
|
||||
M: Douglas Miller <dougmill@linux.ibm.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/ibm/ehea/
|
||||
@@ -5631,7 +5631,7 @@ F: Documentation/filesystems/ext4/ext4.rst
|
||||
F: fs/ext4/
|
||||
|
||||
Extended Verification Module (EVM)
|
||||
M: Mimi Zohar <zohar@linux.vnet.ibm.com>
|
||||
M: Mimi Zohar <zohar@linux.ibm.com>
|
||||
L: linux-integrity@vger.kernel.org
|
||||
S: Supported
|
||||
F: security/integrity/evm/
|
||||
@@ -5841,7 +5841,7 @@ F: include/linux/firmware.h
|
||||
|
||||
FLASH ADAPTER DRIVER (IBM Flash Adapter 900GB Full Height PCI Flash Card)
|
||||
M: Joshua Morris <josh.h.morris@us.ibm.com>
|
||||
M: Philip Kelleher <pjk1939@linux.vnet.ibm.com>
|
||||
M: Philip Kelleher <pjk1939@linux.ibm.com>
|
||||
S: Maintained
|
||||
F: drivers/block/rsxx/
|
||||
|
||||
@@ -6108,7 +6108,7 @@ F: include/linux/fscrypt*.h
|
||||
F: Documentation/filesystems/fscrypt.rst
|
||||
|
||||
FSI-ATTACHED I2C DRIVER
|
||||
M: Eddie James <eajames@linux.vnet.ibm.com>
|
||||
M: Eddie James <eajames@linux.ibm.com>
|
||||
L: linux-i2c@vger.kernel.org
|
||||
L: openbmc@lists.ozlabs.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
@@ -6284,8 +6284,7 @@ S: Supported
|
||||
F: drivers/uio/uio_pci_generic.c
|
||||
|
||||
GENWQE (IBM Generic Workqueue Card)
|
||||
M: Frank Haverkamp <haver@linux.vnet.ibm.com>
|
||||
M: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
|
||||
M: Frank Haverkamp <haver@linux.ibm.com>
|
||||
S: Supported
|
||||
F: drivers/misc/genwqe/
|
||||
|
||||
@@ -7075,8 +7074,7 @@ F: crypto/842.c
|
||||
F: lib/842/
|
||||
|
||||
IBM Power in-Nest Crypto Acceleration
|
||||
M: Leonidas S. Barbosa <leosilva@linux.vnet.ibm.com>
|
||||
M: Paulo Flabiano Smorigo <pfsmorigo@linux.vnet.ibm.com>
|
||||
M: Paulo Flabiano Smorigo <pfsmorigo@linux.ibm.com>
|
||||
L: linux-crypto@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/crypto/nx/Makefile
|
||||
@@ -7093,8 +7091,8 @@ S: Supported
|
||||
F: drivers/scsi/ipr.*
|
||||
|
||||
IBM Power SRIOV Virtual NIC Device Driver
|
||||
M: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
|
||||
M: John Allen <jallen@linux.vnet.ibm.com>
|
||||
M: Thomas Falcon <tlfalcon@linux.ibm.com>
|
||||
M: John Allen <jallen@linux.ibm.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/net/ethernet/ibm/ibmvnic.*
|
||||
@@ -7109,41 +7107,38 @@ F: arch/powerpc/include/asm/vas.h
|
||||
F: arch/powerpc/include/uapi/asm/vas.h
|
||||
|
||||
IBM Power Virtual Ethernet Device Driver
|
||||
M: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
|
||||
M: Thomas Falcon <tlfalcon@linux.ibm.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/net/ethernet/ibm/ibmveth.*
|
||||
|
||||
IBM Power Virtual FC Device Drivers
|
||||
M: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
|
||||
M: Tyrel Datwyler <tyreld@linux.ibm.com>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/scsi/ibmvscsi/ibmvfc*
|
||||
|
||||
IBM Power Virtual Management Channel Driver
|
||||
M: Bryant G. Ly <bryantly@linux.vnet.ibm.com>
|
||||
M: Steven Royer <seroyer@linux.vnet.ibm.com>
|
||||
M: Steven Royer <seroyer@linux.ibm.com>
|
||||
S: Supported
|
||||
F: drivers/misc/ibmvmc.*
|
||||
|
||||
IBM Power Virtual SCSI Device Drivers
|
||||
M: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
|
||||
M: Tyrel Datwyler <tyreld@linux.ibm.com>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/scsi/ibmvscsi/ibmvscsi*
|
||||
F: include/scsi/viosrp.h
|
||||
|
||||
IBM Power Virtual SCSI Device Target Driver
|
||||
M: Bryant G. Ly <bryantly@linux.vnet.ibm.com>
|
||||
M: Michael Cyr <mikecyr@linux.vnet.ibm.com>
|
||||
M: Michael Cyr <mikecyr@linux.ibm.com>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
L: target-devel@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/scsi/ibmvscsi_tgt/
|
||||
|
||||
IBM Power VMX Cryptographic instructions
|
||||
M: Leonidas S. Barbosa <leosilva@linux.vnet.ibm.com>
|
||||
M: Paulo Flabiano Smorigo <pfsmorigo@linux.vnet.ibm.com>
|
||||
M: Paulo Flabiano Smorigo <pfsmorigo@linux.ibm.com>
|
||||
L: linux-crypto@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/crypto/vmx/Makefile
|
||||
@@ -7420,7 +7415,7 @@ S: Maintained
|
||||
L: linux-crypto@vger.kernel.org
|
||||
|
||||
INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
|
||||
M: Mimi Zohar <zohar@linux.vnet.ibm.com>
|
||||
M: Mimi Zohar <zohar@linux.ibm.com>
|
||||
M: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
|
||||
L: linux-integrity@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git
|
||||
@@ -8021,9 +8016,8 @@ S: Maintained
|
||||
F: drivers/media/platform/rcar_jpu.c
|
||||
|
||||
JSM Neo PCI based serial card
|
||||
M: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
|
||||
L: linux-serial@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: drivers/tty/serial/jsm/
|
||||
|
||||
K10TEMP HARDWARE MONITORING DRIVER
|
||||
@@ -8253,7 +8247,7 @@ F: include/uapi/linux/kexec.h
|
||||
F: kernel/kexec*
|
||||
|
||||
KEYS-ENCRYPTED
|
||||
M: Mimi Zohar <zohar@linux.vnet.ibm.com>
|
||||
M: Mimi Zohar <zohar@linux.ibm.com>
|
||||
L: linux-integrity@vger.kernel.org
|
||||
L: keyrings@vger.kernel.org
|
||||
S: Supported
|
||||
@@ -8262,9 +8256,9 @@ F: include/keys/encrypted-type.h
|
||||
F: security/keys/encrypted-keys/
|
||||
|
||||
KEYS-TRUSTED
|
||||
M: James Bottomley <jejb@linux.vnet.ibm.com>
|
||||
M: James Bottomley <jejb@linux.ibm.com>
|
||||
M: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
|
||||
M: Mimi Zohar <zohar@linux.vnet.ibm.com>
|
||||
M: Mimi Zohar <zohar@linuxibm.com>
|
||||
L: linux-integrity@vger.kernel.org
|
||||
L: keyrings@vger.kernel.org
|
||||
S: Supported
|
||||
@@ -8317,7 +8311,7 @@ F: lib/test_kmod.c
|
||||
F: tools/testing/selftests/kmod/
|
||||
|
||||
KPROBES
|
||||
M: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
|
||||
M: Naveen N. Rao <naveen.n.rao@linux.ibm.com>
|
||||
M: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
|
||||
M: "David S. Miller" <davem@davemloft.net>
|
||||
M: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
@@ -8673,7 +8667,7 @@ M: Nicholas Piggin <npiggin@gmail.com>
|
||||
M: David Howells <dhowells@redhat.com>
|
||||
M: Jade Alglave <j.alglave@ucl.ac.uk>
|
||||
M: Luc Maranget <luc.maranget@inria.fr>
|
||||
M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
|
||||
M: "Paul E. McKenney" <paulmck@linux.ibm.com>
|
||||
R: Akira Yokosawa <akiyks@gmail.com>
|
||||
R: Daniel Lustig <dlustig@nvidia.com>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
@@ -9631,7 +9625,7 @@ F: drivers/platform/x86/mlx-platform.c
|
||||
|
||||
MEMBARRIER SUPPORT
|
||||
M: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
|
||||
M: "Paul E. McKenney" <paulmck@linux.ibm.com>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Supported
|
||||
F: kernel/sched/membarrier.c
|
||||
@@ -10769,7 +10763,7 @@ S: Supported
|
||||
F: tools/objtool/
|
||||
|
||||
OCXL (Open Coherent Accelerator Processor Interface OpenCAPI) DRIVER
|
||||
M: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
|
||||
M: Frederic Barrat <fbarrat@linux.ibm.com>
|
||||
M: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
|
||||
L: linuxppc-dev@lists.ozlabs.org
|
||||
S: Supported
|
||||
@@ -12580,7 +12574,7 @@ S: Orphan
|
||||
F: drivers/net/wireless/ray*
|
||||
|
||||
RCUTORTURE TEST FRAMEWORK
|
||||
M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
|
||||
M: "Paul E. McKenney" <paulmck@linux.ibm.com>
|
||||
M: Josh Triplett <josh@joshtriplett.org>
|
||||
R: Steven Rostedt <rostedt@goodmis.org>
|
||||
R: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
@@ -12627,11 +12621,12 @@ F: arch/x86/include/asm/intel_rdt_sched.h
|
||||
F: Documentation/x86/intel_rdt*
|
||||
|
||||
READ-COPY UPDATE (RCU)
|
||||
M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
|
||||
M: "Paul E. McKenney" <paulmck@linux.ibm.com>
|
||||
M: Josh Triplett <josh@joshtriplett.org>
|
||||
R: Steven Rostedt <rostedt@goodmis.org>
|
||||
R: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
R: Lai Jiangshan <jiangshanlai@gmail.com>
|
||||
R: Joel Fernandes <joel@joelfernandes.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
W: http://www.rdrop.com/users/paulmck/RCU/
|
||||
S: Supported
|
||||
@@ -12767,7 +12762,7 @@ F: include/linux/reset-controller.h
|
||||
RESTARTABLE SEQUENCES SUPPORT
|
||||
M: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
M: Peter Zijlstra <peterz@infradead.org>
|
||||
M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
|
||||
M: "Paul E. McKenney" <paulmck@linux.ibm.com>
|
||||
M: Boqun Feng <boqun.feng@gmail.com>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Supported
|
||||
@@ -13292,7 +13287,7 @@ F: drivers/scsi/sg.c
|
||||
F: include/scsi/sg.h
|
||||
|
||||
SCSI SUBSYSTEM
|
||||
M: "James E.J. Bottomley" <jejb@linux.vnet.ibm.com>
|
||||
M: "James E.J. Bottomley" <jejb@linux.ibm.com>
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
|
||||
M: "Martin K. Petersen" <martin.petersen@oracle.com>
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git
|
||||
@@ -13727,7 +13722,7 @@ F: mm/sl?b*
|
||||
|
||||
SLEEPABLE READ-COPY UPDATE (SRCU)
|
||||
M: Lai Jiangshan <jiangshanlai@gmail.com>
|
||||
M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
|
||||
M: "Paul E. McKenney" <paulmck@linux.ibm.com>
|
||||
M: Josh Triplett <josh@joshtriplett.org>
|
||||
R: Steven Rostedt <rostedt@goodmis.org>
|
||||
R: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
@@ -15151,7 +15146,7 @@ F: drivers/platform/x86/topstar-laptop.c
|
||||
|
||||
TORTURE-TEST MODULES
|
||||
M: Davidlohr Bueso <dave@stgolabs.net>
|
||||
M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
|
||||
M: "Paul E. McKenney" <paulmck@linux.ibm.com>
|
||||
M: Josh Triplett <josh@joshtriplett.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Supported
|
||||
|
||||
@@ -289,7 +289,7 @@ static void hugepd_free(struct mmu_gather *tlb, void *hugepte)
|
||||
|
||||
(*batchp)->ptes[(*batchp)->index++] = hugepte;
|
||||
if ((*batchp)->index == HUGEPD_FREELIST_SIZE) {
|
||||
call_rcu_sched(&(*batchp)->rcu, hugepd_free_rcu_callback);
|
||||
call_rcu(&(*batchp)->rcu, hugepd_free_rcu_callback);
|
||||
*batchp = NULL;
|
||||
}
|
||||
put_cpu_var(hugepd_freelist_cur);
|
||||
|
||||
@@ -352,7 +352,7 @@ void tlb_table_flush(struct mmu_gather *tlb)
|
||||
struct mmu_table_batch **batch = &tlb->batch;
|
||||
|
||||
if (*batch) {
|
||||
call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu);
|
||||
call_rcu(&(*batch)->rcu, tlb_remove_table_rcu);
|
||||
*batch = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ static void timer_stop(void)
|
||||
{
|
||||
nmi_adjust_hz(1);
|
||||
unregister_die_notifier(&profile_timer_exceptions_nb);
|
||||
synchronize_sched(); /* Allow already-started NMIs to complete. */
|
||||
synchronize_rcu(); /* Allow already-started NMIs to complete. */
|
||||
}
|
||||
|
||||
static int op_nmi_timer_init(struct oprofile_operations *ops)
|
||||
|
||||
@@ -59,7 +59,7 @@ static struct pcibios_fwaddrmap *pcibios_fwaddrmap_lookup(struct pci_dev *dev)
|
||||
{
|
||||
struct pcibios_fwaddrmap *map;
|
||||
|
||||
WARN_ON_SMP(!spin_is_locked(&pcibios_fwaddrmap_lock));
|
||||
lockdep_assert_held(&pcibios_fwaddrmap_lock);
|
||||
|
||||
list_for_each_entry(map, &pcibios_fwaddrmappings, list)
|
||||
if (map->dev == dev)
|
||||
|
||||
@@ -382,7 +382,7 @@ static int pcrypt_cpumask_change_notify(struct notifier_block *self,
|
||||
|
||||
cpumask_copy(new_mask->mask, cpumask->cbcpu);
|
||||
rcu_assign_pointer(pcrypt->cb_cpumask, new_mask);
|
||||
synchronize_rcu_bh();
|
||||
synchronize_rcu();
|
||||
|
||||
free_cpumask_var(old_mask->mask);
|
||||
kfree(old_mask);
|
||||
|
||||
@@ -2187,7 +2187,7 @@ static void shutdown_smi(void *send_info)
|
||||
* handlers might have been running before we freed the
|
||||
* interrupt.
|
||||
*/
|
||||
synchronize_sched();
|
||||
synchronize_rcu();
|
||||
|
||||
/*
|
||||
* Timeouts are stopped, now make sure the interrupts are off
|
||||
|
||||