Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branches 'bug.2018.11.12a', 'consolidate.2018.12.01a', 'doc.2018.11.12a', 'fixes.2018.11.12a', 'initrd.2018.11.08b', 'sil.2018.11.12a' and 'srcu.2018.11.27a' into HEAD

bug.2018.11.12a: Get rid of BUG_ON() and friends
consolidate.2018.12.01a: Continued RCU flavor-consolidation cleanup
doc.2018.11.12a: Documentation updates
fixes.2018.11.12a: Miscellaneous fixes
initrd.2018.11.08b: Automate creation of rcutorture initrd
sil.2018.11.12a: Remove more spin_unlock_wait() calls

+3887 -3925
-499
Documentation/RCU/Design/Data-Structures/BigTreeClassicRCUBH.svg
··· 1 - <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 - <!-- Creator: fig2dev Version 3.2 Patchlevel 5e --> 3 - 4 - <!-- CreationDate: Wed Dec 9 17:26:09 2015 --> 5 - 6 - <!-- Magnification: 2.000 --> 7 - 8 - <svg 9 - xmlns:dc="http://purl.org/dc/elements/1.1/" 10 - xmlns:cc="http://creativecommons.org/ns#" 11 - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 12 - xmlns:svg="http://www.w3.org/2000/svg" 13 - xmlns="http://www.w3.org/2000/svg" 14 - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 15 - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 16 - width="5.7in" 17 - height="6.6in" 18 - viewBox="-44 -44 6838 7888" 19 - id="svg2" 20 - version="1.1" 21 - inkscape:version="0.48.4 r9939" 22 - sodipodi:docname="BigTreeClassicRCUBH.fig"> 23 - <metadata 24 - id="metadata110"> 25 - <rdf:RDF> 26 - <cc:Work 27 - rdf:about=""> 28 - <dc:format>image/svg+xml</dc:format> 29 - <dc:type 30 - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 31 - <dc:title></dc:title> 32 - </cc:Work> 33 - </rdf:RDF> 34 - </metadata> 35 - <defs 36 - id="defs108"> 37 - <marker 38 - inkscape:stockid="Arrow1Mend" 39 - orient="auto" 40 - refY="0.0" 41 - refX="0.0" 42 - id="Arrow1Mend" 43 - style="overflow:visible;"> 44 - <path 45 - id="path3868" 46 - 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 " 47 - style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;" 48 - transform="scale(0.4) rotate(180) translate(10,0)" /> 49 - </marker> 50 - <marker 51 - inkscape:stockid="Arrow2Mend" 52 - orient="auto" 53 - refY="0.0" 54 - refX="0.0" 55 - id="Arrow2Mend" 56 - style="overflow:visible;"> 57 - <path 58 - id="path3886" 59 - style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;" 60 - 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 " 61 - transform="scale(0.6) rotate(180) translate(0,0)" /> 62 - </marker> 63 - </defs> 64 - <sodipodi:namedview 65 - pagecolor="#ffffff" 66 - bordercolor="#666666" 67 - borderopacity="1" 68 - objecttolerance="10" 69 - gridtolerance="10" 70 - guidetolerance="10" 71 - inkscape:pageopacity="0" 72 - inkscape:pageshadow="2" 73 - inkscape:window-width="878" 74 - inkscape:window-height="1148" 75 - id="namedview106" 76 - showgrid="false" 77 - inkscape:zoom="1.3547758" 78 - inkscape:cx="256.5" 79 - inkscape:cy="297" 80 - inkscape:window-x="45" 81 - inkscape:window-y="24" 82 - inkscape:window-maximized="0" 83 - inkscape:current-layer="g4" /> 84 - <g 85 - style="stroke-width:.025in; fill:none" 86 - id="g4"> 87 - <!-- Line: box --> 88 - <rect 89 - x="450" 90 - y="0" 91 - width="6300" 92 - height="7350" 93 - rx="0" 94 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffffff; " 95 - id="rect6" /> 96 - <!-- Line: box --> 97 - <rect 98 - x="4950" 99 - y="4950" 100 - width="1500" 101 - height="900" 102 - rx="0" 103 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 104 - id="rect8" /> 105 - <!-- Line: box --> 106 - <rect 107 - x="750" 108 - y="600" 109 - width="5700" 110 - height="3750" 111 - rx="0" 112 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffff00; " 113 - id="rect10" /> 114 - <!-- Line: box --> 115 - <rect 116 - x="0" 117 - y="450" 118 - width="6300" 119 - height="7350" 120 - rx="0" 121 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffffff; " 122 - id="rect12" /> 123 - <!-- Line: box --> 124 - <rect 125 - x="300" 126 - y="1050" 127 - width="5700" 128 - height="3750" 129 - rx="0" 130 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffff00; " 131 - id="rect14" /> 132 - <!-- Circle --> 133 - <circle 134 - cx="2850" 135 - cy="3900" 136 - r="76" 137 - style="fill:#000000;stroke:#000000;stroke-width:14;" 138 - id="circle16" /> 139 - <!-- Circle --> 140 - <circle 141 - cx="3150" 142 - cy="3900" 143 - r="76" 144 - style="fill:#000000;stroke:#000000;stroke-width:14;" 145 - id="circle18" /> 146 - <!-- Circle --> 147 - <circle 148 - cx="3450" 149 - cy="3900" 150 - r="76" 151 - style="fill:#000000;stroke:#000000;stroke-width:14;" 152 - id="circle20" /> 153 - <!-- Circle --> 154 - <circle 155 - cx="1350" 156 - cy="5100" 157 - r="76" 158 - style="fill:#000000;stroke:#000000;stroke-width:14;" 159 - id="circle22" /> 160 - <!-- Circle --> 161 - <circle 162 - cx="1650" 163 - cy="5100" 164 - r="76" 165 - style="fill:#000000;stroke:#000000;stroke-width:14;" 166 - id="circle24" /> 167 - <!-- Circle --> 168 - <circle 169 - cx="1950" 170 - cy="5100" 171 - r="76" 172 - style="fill:#000000;stroke:#000000;stroke-width:14;" 173 - id="circle26" /> 174 - <!-- Circle --> 175 - <circle 176 - cx="4350" 177 - cy="5100" 178 - r="76" 179 - style="fill:#000000;stroke:#000000;stroke-width:14;" 180 - id="circle28" /> 181 - <!-- Circle --> 182 - <circle 183 - cx="4650" 184 - cy="5100" 185 - r="76" 186 - style="fill:#000000;stroke:#000000;stroke-width:14;" 187 - id="circle30" /> 188 - <!-- Circle --> 189 - <circle 190 - cx="4950" 191 - cy="5100" 192 - r="76" 193 - style="fill:#000000;stroke:#000000;stroke-width:14;" 194 - id="circle32" /> 195 - <!-- Line --> 196 - <polyline 197 - points="1350,3450 2350,2590 " 198 - style="stroke:#00d1d1;stroke-width:30.0045575;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 199 - id="polyline34" /> 200 - <!-- Arrowhead on XXXpoint 1350 3450 - 2444 2510--> 201 - <!-- Line --> 202 - <polyline 203 - points="4950,3450 3948,2590 " 204 - style="stroke:#00d1d1;stroke-width:30.0045575;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 205 - id="polyline38" /> 206 - <!-- Arrowhead on XXXpoint 4950 3450 - 3854 2510--> 207 - <!-- Line: box --> 208 - <rect 209 - x="750" 210 - y="3450" 211 - width="1800" 212 - height="900" 213 - rx="0" 214 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 215 - id="rect42" /> 216 - <!-- Line --> 217 - <polyline 218 - points="2250,5400 2250,4414 " 219 - style="stroke:#00d1d1;stroke-width:30.0045575;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 220 - id="polyline44" /> 221 - <!-- Arrowhead on XXXpoint 2250 5400 - 2250 4290--> 222 - <!-- Line: box --> 223 - <rect 224 - x="1500" 225 - y="5400" 226 - width="1500" 227 - height="900" 228 - rx="0" 229 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 230 - id="rect48" /> 231 - <!-- Line: box --> 232 - <rect 233 - x="300" 234 - y="6600" 235 - width="1500" 236 - height="900" 237 - rx="0" 238 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 239 - id="rect50" /> 240 - <!-- Line: box --> 241 - <rect 242 - x="3750" 243 - y="3450" 244 - width="1800" 245 - height="900" 246 - rx="0" 247 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 248 - id="rect52" /> 249 - <!-- Line: box --> 250 - <rect 251 - x="4500" 252 - y="5400" 253 - width="1500" 254 - height="900" 255 - rx="0" 256 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 257 - id="rect54" /> 258 - <!-- Line: box --> 259 - <rect 260 - x="3300" 261 - y="6600" 262 - width="1500" 263 - height="900" 264 - rx="0" 265 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 266 - id="rect56" /> 267 - <!-- Line: box --> 268 - <rect 269 - x="2250" 270 - y="1650" 271 - width="1800" 272 - height="900" 273 - rx="0" 274 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 275 - id="rect58" /> 276 - <!-- Text --> 277 - <text 278 - xml:space="preserve" 279 - x="6450" 280 - y="300" 281 - fill="#000000" 282 - font-family="Helvetica" 283 - font-style="normal" 284 - font-weight="normal" 285 - font-size="192" 286 - text-anchor="end" 287 - id="text60">rcu_bh</text> 288 - <!-- Text --> 289 - <text 290 - xml:space="preserve" 291 - x="3150" 292 - y="1950" 293 - fill="#000000" 294 - font-family="Courier" 295 - font-style="normal" 296 - font-weight="bold" 297 - font-size="192" 298 - text-anchor="middle" 299 - id="text62">struct</text> 300 - <!-- Text --> 301 - <text 302 - xml:space="preserve" 303 - x="3150" 304 - y="2250" 305 - fill="#000000" 306 - font-family="Courier" 307 - font-style="normal" 308 - font-weight="bold" 309 - font-size="192" 310 - text-anchor="middle" 311 - id="text64">rcu_node</text> 312 - <!-- Text --> 313 - <text 314 - xml:space="preserve" 315 - x="1650" 316 - y="3750" 317 - fill="#000000" 318 - font-family="Courier" 319 - font-style="normal" 320 - font-weight="bold" 321 - font-size="192" 322 - text-anchor="middle" 323 - id="text66">struct</text> 324 - <!-- Text --> 325 - <text 326 - xml:space="preserve" 327 - x="1650" 328 - y="4050" 329 - fill="#000000" 330 - font-family="Courier" 331 - font-style="normal" 332 - font-weight="bold" 333 - font-size="192" 334 - text-anchor="middle" 335 - id="text68">rcu_node</text> 336 - <!-- Text --> 337 - <text 338 - xml:space="preserve" 339 - x="4650" 340 - y="4050" 341 - fill="#000000" 342 - font-family="Courier" 343 - font-style="normal" 344 - font-weight="bold" 345 - font-size="192" 346 - text-anchor="middle" 347 - id="text70">rcu_node</text> 348 - <!-- Text --> 349 - <text 350 - xml:space="preserve" 351 - x="4650" 352 - y="3750" 353 - fill="#000000" 354 - font-family="Courier" 355 - font-style="normal" 356 - font-weight="bold" 357 - font-size="192" 358 - text-anchor="middle" 359 - id="text72">struct</text> 360 - <!-- Text --> 361 - <text 362 - xml:space="preserve" 363 - x="2250" 364 - y="5700" 365 - fill="#000000" 366 - font-family="Courier" 367 - font-style="normal" 368 - font-weight="bold" 369 - font-size="192" 370 - text-anchor="middle" 371 - id="text74">struct</text> 372 - <!-- Text --> 373 - <text 374 - xml:space="preserve" 375 - x="2250" 376 - y="6000" 377 - fill="#000000" 378 - font-family="Courier" 379 - font-style="normal" 380 - font-weight="bold" 381 - font-size="192" 382 - text-anchor="middle" 383 - id="text76">rcu_data</text> 384 - <!-- Text --> 385 - <text 386 - xml:space="preserve" 387 - x="1050" 388 - y="6900" 389 - fill="#000000" 390 - font-family="Courier" 391 - font-style="normal" 392 - font-weight="bold" 393 - font-size="192" 394 - text-anchor="middle" 395 - id="text78">struct</text> 396 - <!-- Text --> 397 - <text 398 - xml:space="preserve" 399 - x="1050" 400 - y="7200" 401 - fill="#000000" 402 - font-family="Courier" 403 - font-style="normal" 404 - font-weight="bold" 405 - font-size="192" 406 - text-anchor="middle" 407 - id="text80">rcu_data</text> 408 - <!-- Text --> 409 - <text 410 - xml:space="preserve" 411 - x="5250" 412 - y="5700" 413 - fill="#000000" 414 - font-family="Courier" 415 - font-style="normal" 416 - font-weight="bold" 417 - font-size="192" 418 - text-anchor="middle" 419 - id="text82">struct</text> 420 - <!-- Text --> 421 - <text 422 - xml:space="preserve" 423 - x="5250" 424 - y="6000" 425 - fill="#000000" 426 - font-family="Courier" 427 - font-style="normal" 428 - font-weight="bold" 429 - font-size="192" 430 - text-anchor="middle" 431 - id="text84">rcu_data</text> 432 - <!-- Text --> 433 - <text 434 - xml:space="preserve" 435 - x="4050" 436 - y="6900" 437 - fill="#000000" 438 - font-family="Courier" 439 - font-style="normal" 440 - font-weight="bold" 441 - font-size="192" 442 - text-anchor="middle" 443 - id="text86">struct</text> 444 - <!-- Text --> 445 - <text 446 - xml:space="preserve" 447 - x="4050" 448 - y="7200" 449 - fill="#000000" 450 - font-family="Courier" 451 - font-style="normal" 452 - font-weight="bold" 453 - font-size="192" 454 - text-anchor="middle" 455 - id="text88">rcu_data</text> 456 - <!-- Text --> 457 - <text 458 - xml:space="preserve" 459 - x="450" 460 - y="1350" 461 - fill="#000000" 462 - font-family="Courier" 463 - font-style="normal" 464 - font-weight="bold" 465 - font-size="192" 466 - text-anchor="start" 467 - id="text90">struct rcu_state</text> 468 - <!-- Text --> 469 - <text 470 - xml:space="preserve" 471 - x="6000" 472 - y="750" 473 - fill="#000000" 474 - font-family="Helvetica" 475 - font-style="normal" 476 - font-weight="normal" 477 - font-size="192" 478 - text-anchor="end" 479 - id="text92">rcu_sched</text> 480 - <!-- Line --> 481 - <polyline 482 - points="5250,5400 5250,4414 " 483 - style="stroke:#00d1d1;stroke-width:30.0045575;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 484 - id="polyline94" /> 485 - <!-- Arrowhead on XXXpoint 5250 5400 - 5250 4290--> 486 - <!-- Line --> 487 - <polyline 488 - points="4050,6600 4050,4414 " 489 - style="stroke:#00d1d1;stroke-width:30.0045575;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 490 - id="polyline98" /> 491 - <!-- Arrowhead on XXXpoint 4050 6600 - 4050 4290--> 492 - <!-- Line --> 493 - <polyline 494 - points="1050,6600 1050,4414 " 495 - style="stroke:#00d1d1;stroke-width:30.0045575;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 496 - id="polyline102" /> 497 - <!-- Arrowhead on XXXpoint 1050 6600 - 1050 4290--> 498 - </g> 499 - </svg>
-695
Documentation/RCU/Design/Data-Structures/BigTreeClassicRCUBHdyntick.svg
··· 1 - <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 - <!-- Creator: fig2dev Version 3.2 Patchlevel 5e --> 3 - 4 - <!-- CreationDate: Wed Dec 9 17:20:02 2015 --> 5 - 6 - <!-- Magnification: 2.000 --> 7 - 8 - <svg 9 - xmlns:dc="http://purl.org/dc/elements/1.1/" 10 - xmlns:cc="http://creativecommons.org/ns#" 11 - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 12 - xmlns:svg="http://www.w3.org/2000/svg" 13 - xmlns="http://www.w3.org/2000/svg" 14 - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 15 - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 16 - width="5.7in" 17 - height="8.6in" 18 - viewBox="-44 -44 6838 10288" 19 - id="svg2" 20 - version="1.1" 21 - inkscape:version="0.48.4 r9939" 22 - sodipodi:docname="BigTreeClassicRCUBHdyntick.fig"> 23 - <metadata 24 - id="metadata166"> 25 - <rdf:RDF> 26 - <cc:Work 27 - rdf:about=""> 28 - <dc:format>image/svg+xml</dc:format> 29 - <dc:type 30 - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 31 - <dc:title></dc:title> 32 - </cc:Work> 33 - </rdf:RDF> 34 - </metadata> 35 - <defs 36 - id="defs164"> 37 - <marker 38 - inkscape:stockid="Arrow1Mend" 39 - orient="auto" 40 - refY="0.0" 41 - refX="0.0" 42 - id="Arrow1Mend" 43 - style="overflow:visible;"> 44 - <path 45 - id="path3924" 46 - 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 " 47 - style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;" 48 - transform="scale(0.4) rotate(180) translate(10,0)" /> 49 - </marker> 50 - <marker 51 - inkscape:stockid="Arrow2Lend" 52 - orient="auto" 53 - refY="0.0" 54 - refX="0.0" 55 - id="Arrow2Lend" 56 - style="overflow:visible;"> 57 - <path 58 - id="path3936" 59 - style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;" 60 - 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 " 61 - transform="scale(1.1) rotate(180) translate(1,0)" /> 62 - </marker> 63 - </defs> 64 - <sodipodi:namedview 65 - pagecolor="#ffffff" 66 - bordercolor="#666666" 67 - borderopacity="1" 68 - objecttolerance="10" 69 - gridtolerance="10" 70 - guidetolerance="10" 71 - inkscape:pageopacity="0" 72 - inkscape:pageshadow="2" 73 - inkscape:window-width="845" 74 - inkscape:window-height="988" 75 - id="namedview162" 76 - showgrid="false" 77 - inkscape:zoom="1.0452196" 78 - inkscape:cx="256.5" 79 - inkscape:cy="387.00003" 80 - inkscape:window-x="356" 81 - inkscape:window-y="61" 82 - inkscape:window-maximized="0" 83 - inkscape:current-layer="g4" /> 84 - <g 85 - style="stroke-width:.025in; fill:none" 86 - id="g4"> 87 - <!-- Line: box --> 88 - <rect 89 - x="450" 90 - y="0" 91 - width="6300" 92 - height="7350" 93 - rx="0" 94 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffffff; " 95 - id="rect6" /> 96 - <!-- Line: box --> 97 - <rect 98 - x="4950" 99 - y="4950" 100 - width="1500" 101 - height="900" 102 - rx="0" 103 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 104 - id="rect8" /> 105 - <!-- Line: box --> 106 - <rect 107 - x="750" 108 - y="600" 109 - width="5700" 110 - height="3750" 111 - rx="0" 112 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffff00; " 113 - id="rect10" /> 114 - <!-- Line --> 115 - <polyline 116 - points="5250,8100 5688,5912 " 117 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 118 - id="polyline12" /> 119 - <!-- Arrowhead on XXXpoint 5250 8100 - 5710 5790--> 120 - <polyline 121 - points="5714 6068 5704 5822 5598 6044 " 122 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 123 - id="polyline14" /> 124 - <!-- Line --> 125 - <polyline 126 - points="4050,9300 4486,7262 " 127 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 128 - id="polyline16" /> 129 - <!-- Arrowhead on XXXpoint 4050 9300 - 4512 7140--> 130 - <polyline 131 - points="4514 7418 4506 7172 4396 7394 " 132 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 133 - id="polyline18" /> 134 - <!-- Line --> 135 - <polyline 136 - points="1040,9300 1476,7262 " 137 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 138 - id="polyline20" /> 139 - <!-- Arrowhead on XXXpoint 1040 9300 - 1502 7140--> 140 - <polyline 141 - points="1504 7418 1496 7172 1386 7394 " 142 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 143 - id="polyline22" /> 144 - <!-- Line --> 145 - <polyline 146 - points="2240,8100 2676,6062 " 147 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 148 - id="polyline24" /> 149 - <!-- Arrowhead on XXXpoint 2240 8100 - 2702 5940--> 150 - <polyline 151 - points="2704 6218 2696 5972 2586 6194 " 152 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 153 - id="polyline26" /> 154 - <!-- Line: box --> 155 - <rect 156 - x="0" 157 - y="450" 158 - width="6300" 159 - height="7350" 160 - rx="0" 161 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffffff; " 162 - id="rect28" /> 163 - <!-- Line: box --> 164 - <rect 165 - x="300" 166 - y="1050" 167 - width="5700" 168 - height="3750" 169 - rx="0" 170 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffff00; " 171 - id="rect30" /> 172 - <!-- Line --> 173 - <polyline 174 - points="1350,3450 2350,2590 " 175 - style="stroke:#00d1d1;stroke-width:30.0045575;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 176 - id="polyline32" /> 177 - <!-- Arrowhead on XXXpoint 1350 3450 - 2444 2510--> 178 - <!-- Line --> 179 - <polyline 180 - points="4950,3450 3948,2590 " 181 - style="stroke:#00d1d1;stroke-width:30.0045575;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 182 - id="polyline36" /> 183 - <!-- Arrowhead on XXXpoint 4950 3450 - 3854 2510--> 184 - <!-- Line --> 185 - <polyline 186 - points="4050,6600 4050,4414 " 187 - style="stroke:#00d1d1;stroke-width:30.00455750000000066;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 188 - id="polyline40" /> 189 - <!-- Arrowhead on XXXpoint 4050 6600 - 4050 4290--> 190 - <!-- Line --> 191 - <polyline 192 - points="1050,6600 1050,4414 " 193 - style="stroke:#00d1d1;stroke-width:30.00455750000000066;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 194 - id="polyline44" /> 195 - <!-- Arrowhead on XXXpoint 1050 6600 - 1050 4290--> 196 - <!-- Line --> 197 - <polyline 198 - points="2250,5400 2250,4414 " 199 - style="stroke:#00d1d1;stroke-width:30.00455750000000066;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 200 - id="polyline48" /> 201 - <!-- Arrowhead on XXXpoint 2250 5400 - 2250 4290--> 202 - <!-- Line --> 203 - <polyline 204 - points="2250,8100 2250,6364 " 205 - style="stroke:#00ff00;stroke-width:30;stroke-linejoin:miter;stroke-linecap:butt;marker-end:url(#Arrow1Mend)" 206 - id="polyline52" /> 207 - <!-- Arrowhead on XXXpoint 2250 8100 - 2250 6240--> 208 - <!-- Line --> 209 - <polyline 210 - points="1050,9300 1050,7564 " 211 - style="stroke:#00ff00;stroke-width:30;stroke-linejoin:miter;stroke-linecap:butt;marker-end:url(#Arrow1Mend)" 212 - id="polyline56" /> 213 - <!-- Arrowhead on XXXpoint 1050 9300 - 1050 7440--> 214 - <!-- Line --> 215 - <polyline 216 - points="4050,9300 4050,7564 " 217 - style="stroke:#00ff00;stroke-width:30;stroke-linejoin:miter;stroke-linecap:butt;marker-end:url(#Arrow1Mend)" 218 - id="polyline60" /> 219 - <!-- Arrowhead on XXXpoint 4050 9300 - 4050 7440--> 220 - <!-- Line --> 221 - <polyline 222 - points="5250,8100 5250,6364 " 223 - style="stroke:#00ff00;stroke-width:30;stroke-linejoin:miter;stroke-linecap:butt;marker-end:url(#Arrow1Mend)" 224 - id="polyline64" /> 225 - <!-- Arrowhead on XXXpoint 5250 8100 - 5250 6240--> 226 - <!-- Circle --> 227 - <circle 228 - cx="2850" 229 - cy="3900" 230 - r="76" 231 - style="fill:#000000;stroke:#000000;stroke-width:14;" 232 - id="circle68" /> 233 - <!-- Circle --> 234 - <circle 235 - cx="3150" 236 - cy="3900" 237 - r="76" 238 - style="fill:#000000;stroke:#000000;stroke-width:14;" 239 - id="circle70" /> 240 - <!-- Circle --> 241 - <circle 242 - cx="3450" 243 - cy="3900" 244 - r="76" 245 - style="fill:#000000;stroke:#000000;stroke-width:14;" 246 - id="circle72" /> 247 - <!-- Circle --> 248 - <circle 249 - cx="1350" 250 - cy="5100" 251 - r="76" 252 - style="fill:#000000;stroke:#000000;stroke-width:14;" 253 - id="circle74" /> 254 - <!-- Circle --> 255 - <circle 256 - cx="1650" 257 - cy="5100" 258 - r="76" 259 - style="fill:#000000;stroke:#000000;stroke-width:14;" 260 - id="circle76" /> 261 - <!-- Circle --> 262 - <circle 263 - cx="1950" 264 - cy="5100" 265 - r="76" 266 - style="fill:#000000;stroke:#000000;stroke-width:14;" 267 - id="circle78" /> 268 - <!-- Circle --> 269 - <circle 270 - cx="4350" 271 - cy="5100" 272 - r="76" 273 - style="fill:#000000;stroke:#000000;stroke-width:14;" 274 - id="circle80" /> 275 - <!-- Circle --> 276 - <circle 277 - cx="4650" 278 - cy="5100" 279 - r="76" 280 - style="fill:#000000;stroke:#000000;stroke-width:14;" 281 - id="circle82" /> 282 - <!-- Circle --> 283 - <circle 284 - cx="4950" 285 - cy="5100" 286 - r="76" 287 - style="fill:#000000;stroke:#000000;stroke-width:14;" 288 - id="circle84" /> 289 - <!-- Line: box --> 290 - <rect 291 - x="750" 292 - y="3450" 293 - width="1800" 294 - height="900" 295 - rx="0" 296 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 297 - id="rect86" /> 298 - <!-- Line: box --> 299 - <rect 300 - x="300" 301 - y="6600" 302 - width="1500" 303 - height="900" 304 - rx="0" 305 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 306 - id="rect88" /> 307 - <!-- Line: box --> 308 - <rect 309 - x="3750" 310 - y="3450" 311 - width="1800" 312 - height="900" 313 - rx="0" 314 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 315 - id="rect90" /> 316 - <!-- Line: box --> 317 - <rect 318 - x="4500" 319 - y="5400" 320 - width="1500" 321 - height="900" 322 - rx="0" 323 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 324 - id="rect92" /> 325 - <!-- Line: box --> 326 - <rect 327 - x="3300" 328 - y="6600" 329 - width="1500" 330 - height="900" 331 - rx="0" 332 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 333 - id="rect94" /> 334 - <!-- Line: box --> 335 - <rect 336 - x="2250" 337 - y="1650" 338 - width="1800" 339 - height="900" 340 - rx="0" 341 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 342 - id="rect96" /> 343 - <!-- Line: box --> 344 - <rect 345 - x="0" 346 - y="9300" 347 - width="2100" 348 - height="900" 349 - rx="0" 350 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#00ff00; " 351 - id="rect98" /> 352 - <!-- Line: box --> 353 - <rect 354 - x="1350" 355 - y="8100" 356 - width="2100" 357 - height="900" 358 - rx="0" 359 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#00ff00; " 360 - id="rect100" /> 361 - <!-- Line: box --> 362 - <rect 363 - x="3000" 364 - y="9300" 365 - width="2100" 366 - height="900" 367 - rx="0" 368 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#00ff00; " 369 - id="rect102" /> 370 - <!-- Line: box --> 371 - <rect 372 - x="4350" 373 - y="8100" 374 - width="2100" 375 - height="900" 376 - rx="0" 377 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#00ff00; " 378 - id="rect104" /> 379 - <!-- Line: box --> 380 - <rect 381 - x="1500" 382 - y="5400" 383 - width="1500" 384 - height="900" 385 - rx="0" 386 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 387 - id="rect106" /> 388 - <!-- Text --> 389 - <text 390 - xml:space="preserve" 391 - x="6450" 392 - y="300" 393 - fill="#000000" 394 - font-family="Helvetica" 395 - font-style="normal" 396 - font-weight="normal" 397 - font-size="192" 398 - text-anchor="end" 399 - id="text108">rcu_bh</text> 400 - <!-- Text --> 401 - <text 402 - xml:space="preserve" 403 - x="3150" 404 - y="1950" 405 - fill="#000000" 406 - font-family="Courier" 407 - font-style="normal" 408 - font-weight="bold" 409 - font-size="192" 410 - text-anchor="middle" 411 - id="text110">struct</text> 412 - <!-- Text --> 413 - <text 414 - xml:space="preserve" 415 - x="3150" 416 - y="2250" 417 - fill="#000000" 418 - font-family="Courier" 419 - font-style="normal" 420 - font-weight="bold" 421 - font-size="192" 422 - text-anchor="middle" 423 - id="text112">rcu_node</text> 424 - <!-- Text --> 425 - <text 426 - xml:space="preserve" 427 - x="1650" 428 - y="3750" 429 - fill="#000000" 430 - font-family="Courier" 431 - font-style="normal" 432 - font-weight="bold" 433 - font-size="192" 434 - text-anchor="middle" 435 - id="text114">struct</text> 436 - <!-- Text --> 437 - <text 438 - xml:space="preserve" 439 - x="1650" 440 - y="4050" 441 - fill="#000000" 442 - font-family="Courier" 443 - font-style="normal" 444 - font-weight="bold" 445 - font-size="192" 446 - text-anchor="middle" 447 - id="text116">rcu_node</text> 448 - <!-- Text --> 449 - <text 450 - xml:space="preserve" 451 - x="4650" 452 - y="4050" 453 - fill="#000000" 454 - font-family="Courier" 455 - font-style="normal" 456 - font-weight="bold" 457 - font-size="192" 458 - text-anchor="middle" 459 - id="text118">rcu_node</text> 460 - <!-- Text --> 461 - <text 462 - xml:space="preserve" 463 - x="4650" 464 - y="3750" 465 - fill="#000000" 466 - font-family="Courier" 467 - font-style="normal" 468 - font-weight="bold" 469 - font-size="192" 470 - text-anchor="middle" 471 - id="text120">struct</text> 472 - <!-- Text --> 473 - <text 474 - xml:space="preserve" 475 - x="2250" 476 - y="5700" 477 - fill="#000000" 478 - font-family="Courier" 479 - font-style="normal" 480 - font-weight="bold" 481 - font-size="192" 482 - text-anchor="middle" 483 - id="text122">struct</text> 484 - <!-- Text --> 485 - <text 486 - xml:space="preserve" 487 - x="2250" 488 - y="6000" 489 - fill="#000000" 490 - font-family="Courier" 491 - font-style="normal" 492 - font-weight="bold" 493 - font-size="192" 494 - text-anchor="middle" 495 - id="text124">rcu_data</text> 496 - <!-- Text --> 497 - <text 498 - xml:space="preserve" 499 - x="1050" 500 - y="6900" 501 - fill="#000000" 502 - font-family="Courier" 503 - font-style="normal" 504 - font-weight="bold" 505 - font-size="192" 506 - text-anchor="middle" 507 - id="text126">struct</text> 508 - <!-- Text --> 509 - <text 510 - xml:space="preserve" 511 - x="1050" 512 - y="7200" 513 - fill="#000000" 514 - font-family="Courier" 515 - font-style="normal" 516 - font-weight="bold" 517 - font-size="192" 518 - text-anchor="middle" 519 - id="text128">rcu_data</text> 520 - <!-- Text --> 521 - <text 522 - xml:space="preserve" 523 - x="5250" 524 - y="5700" 525 - fill="#000000" 526 - font-family="Courier" 527 - font-style="normal" 528 - font-weight="bold" 529 - font-size="192" 530 - text-anchor="middle" 531 - id="text130">struct</text> 532 - <!-- Text --> 533 - <text 534 - xml:space="preserve" 535 - x="5250" 536 - y="6000" 537 - fill="#000000" 538 - font-family="Courier" 539 - font-style="normal" 540 - font-weight="bold" 541 - font-size="192" 542 - text-anchor="middle" 543 - id="text132">rcu_data</text> 544 - <!-- Text --> 545 - <text 546 - xml:space="preserve" 547 - x="4050" 548 - y="6900" 549 - fill="#000000" 550 - font-family="Courier" 551 - font-style="normal" 552 - font-weight="bold" 553 - font-size="192" 554 - text-anchor="middle" 555 - id="text134">struct</text> 556 - <!-- Text --> 557 - <text 558 - xml:space="preserve" 559 - x="4050" 560 - y="7200" 561 - fill="#000000" 562 - font-family="Courier" 563 - font-style="normal" 564 - font-weight="bold" 565 - font-size="192" 566 - text-anchor="middle" 567 - id="text136">rcu_data</text> 568 - <!-- Text --> 569 - <text 570 - xml:space="preserve" 571 - x="450" 572 - y="1350" 573 - fill="#000000" 574 - font-family="Courier" 575 - font-style="normal" 576 - font-weight="bold" 577 - font-size="192" 578 - text-anchor="start" 579 - id="text138">struct rcu_state</text> 580 - <!-- Text --> 581 - <text 582 - xml:space="preserve" 583 - x="1050" 584 - y="9600" 585 - fill="#000000" 586 - font-family="Courier" 587 - font-style="normal" 588 - font-weight="bold" 589 - font-size="192" 590 - text-anchor="middle" 591 - id="text140">struct</text> 592 - <!-- Text --> 593 - <text 594 - xml:space="preserve" 595 - x="1050" 596 - y="9900" 597 - fill="#000000" 598 - font-family="Courier" 599 - font-style="normal" 600 - font-weight="bold" 601 - font-size="192" 602 - text-anchor="middle" 603 - id="text142">rcu_dynticks</text> 604 - <!-- Text --> 605 - <text 606 - xml:space="preserve" 607 - x="4050" 608 - y="9600" 609 - fill="#000000" 610 - font-family="Courier" 611 - font-style="normal" 612 - font-weight="bold" 613 - font-size="192" 614 - text-anchor="middle" 615 - id="text144">struct</text> 616 - <!-- Text --> 617 - <text 618 - xml:space="preserve" 619 - x="4050" 620 - y="9900" 621 - fill="#000000" 622 - font-family="Courier" 623 - font-style="normal" 624 - font-weight="bold" 625 - font-size="192" 626 - text-anchor="middle" 627 - id="text146">rcu_dynticks</text> 628 - <!-- Text --> 629 - <text 630 - xml:space="preserve" 631 - x="2400" 632 - y="8400" 633 - fill="#000000" 634 - font-family="Courier" 635 - font-style="normal" 636 - font-weight="bold" 637 - font-size="192" 638 - text-anchor="middle" 639 - id="text148">struct</text> 640 - <!-- Text --> 641 - <text 642 - xml:space="preserve" 643 - x="2400" 644 - y="8700" 645 - fill="#000000" 646 - font-family="Courier" 647 - font-style="normal" 648 - font-weight="bold" 649 - font-size="192" 650 - text-anchor="middle" 651 - id="text150">rcu_dynticks</text> 652 - <!-- Text --> 653 - <text 654 - xml:space="preserve" 655 - x="5400" 656 - y="8400" 657 - fill="#000000" 658 - font-family="Courier" 659 - font-style="normal" 660 - font-weight="bold" 661 - font-size="192" 662 - text-anchor="middle" 663 - id="text152">struct</text> 664 - <!-- Text --> 665 - <text 666 - xml:space="preserve" 667 - x="5400" 668 - y="8700" 669 - fill="#000000" 670 - font-family="Courier" 671 - font-style="normal" 672 - font-weight="bold" 673 - font-size="192" 674 - text-anchor="middle" 675 - id="text154">rcu_dynticks</text> 676 - <!-- Text --> 677 - <text 678 - xml:space="preserve" 679 - x="6000" 680 - y="750" 681 - fill="#000000" 682 - font-family="Helvetica" 683 - font-style="normal" 684 - font-weight="normal" 685 - font-size="192" 686 - text-anchor="end" 687 - id="text156">rcu_sched</text> 688 - <!-- Line --> 689 - <polyline 690 - points="5250,5400 5250,4414 " 691 - style="stroke:#00d1d1;stroke-width:30.00455750000000066;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 692 - id="polyline158" /> 693 - <!-- Arrowhead on XXXpoint 5250 5400 - 5250 4290--> 694 - </g> 695 - </svg>
-741
Documentation/RCU/Design/Data-Structures/BigTreePreemptRCUBHdyntick.svg
··· 1 - <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 - <!-- Creator: fig2dev Version 3.2 Patchlevel 5e --> 3 - 4 - <!-- CreationDate: Wed Dec 9 17:32:59 2015 --> 5 - 6 - <!-- Magnification: 2.000 --> 7 - 8 - <svg 9 - xmlns:dc="http://purl.org/dc/elements/1.1/" 10 - xmlns:cc="http://creativecommons.org/ns#" 11 - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 12 - xmlns:svg="http://www.w3.org/2000/svg" 13 - xmlns="http://www.w3.org/2000/svg" 14 - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 15 - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 16 - width="6.1in" 17 - height="8.9in" 18 - viewBox="-44 -44 7288 10738" 19 - id="svg2" 20 - version="1.1" 21 - inkscape:version="0.48.4 r9939" 22 - sodipodi:docname="BigTreePreemptRCUBHdyntick.fig"> 23 - <metadata 24 - id="metadata182"> 25 - <rdf:RDF> 26 - <cc:Work 27 - rdf:about=""> 28 - <dc:format>image/svg+xml</dc:format> 29 - <dc:type 30 - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> 31 - <dc:title></dc:title> 32 - </cc:Work> 33 - </rdf:RDF> 34 - </metadata> 35 - <defs 36 - id="defs180"> 37 - <marker 38 - inkscape:stockid="Arrow1Mend" 39 - orient="auto" 40 - refY="0.0" 41 - refX="0.0" 42 - id="Arrow1Mend" 43 - style="overflow:visible;"> 44 - <path 45 - id="path3940" 46 - 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 " 47 - style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;" 48 - transform="scale(0.4) rotate(180) translate(10,0)" /> 49 - </marker> 50 - </defs> 51 - <sodipodi:namedview 52 - pagecolor="#ffffff" 53 - bordercolor="#666666" 54 - borderopacity="1" 55 - objecttolerance="10" 56 - gridtolerance="10" 57 - guidetolerance="10" 58 - inkscape:pageopacity="0" 59 - inkscape:pageshadow="2" 60 - inkscape:window-width="874" 61 - inkscape:window-height="1148" 62 - id="namedview178" 63 - showgrid="false" 64 - inkscape:zoom="1.2097379" 65 - inkscape:cx="274.5" 66 - inkscape:cy="400.49997" 67 - inkscape:window-x="946" 68 - inkscape:window-y="24" 69 - inkscape:window-maximized="0" 70 - inkscape:current-layer="g4" /> 71 - <g 72 - style="stroke-width:.025in; fill:none" 73 - id="g4"> 74 - <!-- Line: box --> 75 - <rect 76 - x="900" 77 - y="0" 78 - width="6300" 79 - height="7350" 80 - rx="0" 81 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffffff; " 82 - id="rect6" /> 83 - <!-- Line: box --> 84 - <rect 85 - x="1200" 86 - y="600" 87 - width="5700" 88 - height="3750" 89 - rx="0" 90 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffff00; " 91 - id="rect8" /> 92 - <!-- Line: box --> 93 - <rect 94 - x="5400" 95 - y="4950" 96 - width="1500" 97 - height="900" 98 - rx="0" 99 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 100 - id="rect10" /> 101 - <!-- Line: box --> 102 - <rect 103 - x="450" 104 - y="450" 105 - width="6300" 106 - height="7350" 107 - rx="0" 108 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffffff; " 109 - id="rect12" /> 110 - <!-- Line: box --> 111 - <rect 112 - x="750" 113 - y="1050" 114 - width="5700" 115 - height="3750" 116 - rx="0" 117 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffff00; " 118 - id="rect14" /> 119 - <!-- Line: box --> 120 - <rect 121 - x="4950" 122 - y="5400" 123 - width="1500" 124 - height="900" 125 - rx="0" 126 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 127 - id="rect16" /> 128 - <!-- Line --> 129 - <polyline 130 - points="5250,8550 5688,6362 " 131 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 132 - id="polyline18" /> 133 - <!-- Arrowhead on XXXpoint 5250 8550 - 5710 6240--> 134 - <polyline 135 - points="5714 6518 5704 6272 5598 6494 " 136 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 137 - id="polyline20" /> 138 - <!-- Line --> 139 - <polyline 140 - points="4050,9750 4486,7712 " 141 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 142 - id="polyline22" /> 143 - <!-- Arrowhead on XXXpoint 4050 9750 - 4512 7590--> 144 - <polyline 145 - points="4514 7868 4506 7622 4396 7844 " 146 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 147 - id="polyline24" /> 148 - <!-- Line --> 149 - <polyline 150 - points="1040,9750 1476,7712 " 151 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 152 - id="polyline26" /> 153 - <!-- Arrowhead on XXXpoint 1040 9750 - 1502 7590--> 154 - <polyline 155 - points="1504 7868 1496 7622 1386 7844 " 156 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 157 - id="polyline28" /> 158 - <!-- Line --> 159 - <polyline 160 - points="2240,8550 2676,6512 " 161 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 162 - id="polyline30" /> 163 - <!-- Arrowhead on XXXpoint 2240 8550 - 2702 6390--> 164 - <polyline 165 - points="2704 6668 2696 6422 2586 6644 " 166 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 167 - id="polyline32" /> 168 - <!-- Line --> 169 - <polyline 170 - points="4050,9750 5682,6360 " 171 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 172 - id="polyline34" /> 173 - <!-- Arrowhead on XXXpoint 4050 9750 - 5736 6246--> 174 - <polyline 175 - points="5672 6518 5722 6276 5562 6466 " 176 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 177 - id="polyline36" /> 178 - <!-- Line --> 179 - <polyline 180 - points="1010,9750 2642,6360 " 181 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 182 - id="polyline38" /> 183 - <!-- Arrowhead on XXXpoint 1010 9750 - 2696 6246--> 184 - <polyline 185 - points="2632 6518 2682 6276 2522 6466 " 186 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 187 - id="polyline40" /> 188 - <!-- Line: box --> 189 - <rect 190 - x="0" 191 - y="900" 192 - width="6300" 193 - height="7350" 194 - rx="0" 195 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffffff; " 196 - id="rect42" /> 197 - <!-- Line: box --> 198 - <rect 199 - x="300" 200 - y="1500" 201 - width="5700" 202 - height="3750" 203 - rx="0" 204 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffff00; " 205 - id="rect44" /> 206 - <!-- Line --> 207 - <polyline 208 - points="1350,3900 2350,3040 " 209 - style="stroke:#00d1d1;stroke-width:30.00205472;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 210 - id="polyline46" /> 211 - <!-- Arrowhead on XXXpoint 1350 3900 - 2444 2960--> 212 - <!-- Line --> 213 - <polyline 214 - points="4950,3900 3948,3040 " 215 - style="stroke:#00d1d1;stroke-width:30.00205472;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 216 - id="polyline50" /> 217 - <!-- Arrowhead on XXXpoint 4950 3900 - 3854 2960--> 218 - <!-- Line --> 219 - <polyline 220 - points="4050,7050 4050,4864 " 221 - style="stroke:#00d1d1;stroke-width:30.00205472;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 222 - id="polyline54" /> 223 - <!-- Arrowhead on XXXpoint 4050 7050 - 4050 4740--> 224 - <!-- Line --> 225 - <polyline 226 - points="1050,7050 1050,4864 " 227 - style="stroke:#00d1d1;stroke-width:30.00205472;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 228 - id="polyline58" /> 229 - <!-- Arrowhead on XXXpoint 1050 7050 - 1050 4740--> 230 - <!-- Line --> 231 - <polyline 232 - points="2250,5850 2250,4864 " 233 - style="stroke:#00d1d1;stroke-width:30.00205472;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 234 - id="polyline62" /> 235 - <!-- Arrowhead on XXXpoint 2250 5850 - 2250 4740--> 236 - <!-- Line --> 237 - <polyline 238 - points="2250,8550 2250,6814 " 239 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 240 - id="polyline66" /> 241 - <!-- Arrowhead on XXXpoint 2250 8550 - 2250 6690--> 242 - <!-- Line --> 243 - <polyline 244 - points="1050,9750 1050,8014 " 245 - style="stroke:#00ff00;stroke-width:30.00205472;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 246 - id="polyline70" /> 247 - <!-- Arrowhead on XXXpoint 1050 9750 - 1050 7890--> 248 - <!-- Line --> 249 - <polyline 250 - points="4050,9750 4050,8014 " 251 - style="stroke:#00ff00;stroke-width:30.00205472;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 252 - id="polyline74" /> 253 - <!-- Arrowhead on XXXpoint 4050 9750 - 4050 7890--> 254 - <!-- Line --> 255 - <polyline 256 - points="5250,8550 5250,6814 " 257 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 258 - id="polyline78" /> 259 - <!-- Arrowhead on XXXpoint 5250 8550 - 5250 6690--> 260 - <!-- Circle --> 261 - <circle 262 - cx="2850" 263 - cy="4350" 264 - r="76" 265 - style="fill:#000000;stroke:#000000;stroke-width:14;" 266 - id="circle82" /> 267 - <!-- Circle --> 268 - <circle 269 - cx="3150" 270 - cy="4350" 271 - r="76" 272 - style="fill:#000000;stroke:#000000;stroke-width:14;" 273 - id="circle84" /> 274 - <!-- Circle --> 275 - <circle 276 - cx="3450" 277 - cy="4350" 278 - r="76" 279 - style="fill:#000000;stroke:#000000;stroke-width:14;" 280 - id="circle86" /> 281 - <!-- Circle --> 282 - <circle 283 - cx="1350" 284 - cy="5550" 285 - r="76" 286 - style="fill:#000000;stroke:#000000;stroke-width:14;" 287 - id="circle88" /> 288 - <!-- Circle --> 289 - <circle 290 - cx="1650" 291 - cy="5550" 292 - r="76" 293 - style="fill:#000000;stroke:#000000;stroke-width:14;" 294 - id="circle90" /> 295 - <!-- Circle --> 296 - <circle 297 - cx="1950" 298 - cy="5550" 299 - r="76" 300 - style="fill:#000000;stroke:#000000;stroke-width:14;" 301 - id="circle92" /> 302 - <!-- Circle --> 303 - <circle 304 - cx="4350" 305 - cy="5550" 306 - r="76" 307 - style="fill:#000000;stroke:#000000;stroke-width:14;" 308 - id="circle94" /> 309 - <!-- Circle --> 310 - <circle 311 - cx="4650" 312 - cy="5550" 313 - r="76" 314 - style="fill:#000000;stroke:#000000;stroke-width:14;" 315 - id="circle96" /> 316 - <!-- Circle --> 317 - <circle 318 - cx="4950" 319 - cy="5550" 320 - r="76" 321 - style="fill:#000000;stroke:#000000;stroke-width:14;" 322 - id="circle98" /> 323 - <!-- Line: box --> 324 - <rect 325 - x="750" 326 - y="3900" 327 - width="1800" 328 - height="900" 329 - rx="0" 330 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 331 - id="rect100" /> 332 - <!-- Line: box --> 333 - <rect 334 - x="300" 335 - y="7050" 336 - width="1500" 337 - height="900" 338 - rx="0" 339 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 340 - id="rect102" /> 341 - <!-- Line: box --> 342 - <rect 343 - x="3750" 344 - y="3900" 345 - width="1800" 346 - height="900" 347 - rx="0" 348 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 349 - id="rect104" /> 350 - <!-- Line: box --> 351 - <rect 352 - x="4500" 353 - y="5850" 354 - width="1500" 355 - height="900" 356 - rx="0" 357 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 358 - id="rect106" /> 359 - <!-- Line: box --> 360 - <rect 361 - x="3300" 362 - y="7050" 363 - width="1500" 364 - height="900" 365 - rx="0" 366 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 367 - id="rect108" /> 368 - <!-- Line: box --> 369 - <rect 370 - x="2250" 371 - y="2100" 372 - width="1800" 373 - height="900" 374 - rx="0" 375 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 376 - id="rect110" /> 377 - <!-- Line: box --> 378 - <rect 379 - x="0" 380 - y="9750" 381 - width="2100" 382 - height="900" 383 - rx="0" 384 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#00ff00; " 385 - id="rect112" /> 386 - <!-- Line: box --> 387 - <rect 388 - x="1350" 389 - y="8550" 390 - width="2100" 391 - height="900" 392 - rx="0" 393 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#00ff00; " 394 - id="rect114" /> 395 - <!-- Line: box --> 396 - <rect 397 - x="3000" 398 - y="9750" 399 - width="2100" 400 - height="900" 401 - rx="0" 402 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#00ff00; " 403 - id="rect116" /> 404 - <!-- Line: box --> 405 - <rect 406 - x="4350" 407 - y="8550" 408 - width="2100" 409 - height="900" 410 - rx="0" 411 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#00ff00; " 412 - id="rect118" /> 413 - <!-- Line: box --> 414 - <rect 415 - x="1500" 416 - y="5850" 417 - width="1500" 418 - height="900" 419 - rx="0" 420 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 421 - id="rect120" /> 422 - <!-- Text --> 423 - <text 424 - xml:space="preserve" 425 - x="6450" 426 - y="750" 427 - fill="#000000" 428 - font-family="Helvetica" 429 - font-style="normal" 430 - font-weight="normal" 431 - font-size="192" 432 - text-anchor="end" 433 - id="text122">rcu_bh</text> 434 - <!-- Text --> 435 - <text 436 - xml:space="preserve" 437 - x="3150" 438 - y="2400" 439 - fill="#000000" 440 - font-family="Courier" 441 - font-style="normal" 442 - font-weight="bold" 443 - font-size="192" 444 - text-anchor="middle" 445 - id="text124">struct</text> 446 - <!-- Text --> 447 - <text 448 - xml:space="preserve" 449 - x="3150" 450 - y="2700" 451 - fill="#000000" 452 - font-family="Courier" 453 - font-style="normal" 454 - font-weight="bold" 455 - font-size="192" 456 - text-anchor="middle" 457 - id="text126">rcu_node</text> 458 - <!-- Text --> 459 - <text 460 - xml:space="preserve" 461 - x="1650" 462 - y="4200" 463 - fill="#000000" 464 - font-family="Courier" 465 - font-style="normal" 466 - font-weight="bold" 467 - font-size="192" 468 - text-anchor="middle" 469 - id="text128">struct</text> 470 - <!-- Text --> 471 - <text 472 - xml:space="preserve" 473 - x="1650" 474 - y="4500" 475 - fill="#000000" 476 - font-family="Courier" 477 - font-style="normal" 478 - font-weight="bold" 479 - font-size="192" 480 - text-anchor="middle" 481 - id="text130">rcu_node</text> 482 - <!-- Text --> 483 - <text 484 - xml:space="preserve" 485 - x="4650" 486 - y="4500" 487 - fill="#000000" 488 - font-family="Courier" 489 - font-style="normal" 490 - font-weight="bold" 491 - font-size="192" 492 - text-anchor="middle" 493 - id="text132">rcu_node</text> 494 - <!-- Text --> 495 - <text 496 - xml:space="preserve" 497 - x="4650" 498 - y="4200" 499 - fill="#000000" 500 - font-family="Courier" 501 - font-style="normal" 502 - font-weight="bold" 503 - font-size="192" 504 - text-anchor="middle" 505 - id="text134">struct</text> 506 - <!-- Text --> 507 - <text 508 - xml:space="preserve" 509 - x="2250" 510 - y="6150" 511 - fill="#000000" 512 - font-family="Courier" 513 - font-style="normal" 514 - font-weight="bold" 515 - font-size="192" 516 - text-anchor="middle" 517 - id="text136">struct</text> 518 - <!-- Text --> 519 - <text 520 - xml:space="preserve" 521 - x="2250" 522 - y="6450" 523 - fill="#000000" 524 - font-family="Courier" 525 - font-style="normal" 526 - font-weight="bold" 527 - font-size="192" 528 - text-anchor="middle" 529 - id="text138">rcu_data</text> 530 - <!-- Text --> 531 - <text 532 - xml:space="preserve" 533 - x="1050" 534 - y="7350" 535 - fill="#000000" 536 - font-family="Courier" 537 - font-style="normal" 538 - font-weight="bold" 539 - font-size="192" 540 - text-anchor="middle" 541 - id="text140">struct</text> 542 - <!-- Text --> 543 - <text 544 - xml:space="preserve" 545 - x="1050" 546 - y="7650" 547 - fill="#000000" 548 - font-family="Courier" 549 - font-style="normal" 550 - font-weight="bold" 551 - font-size="192" 552 - text-anchor="middle" 553 - id="text142">rcu_data</text> 554 - <!-- Text --> 555 - <text 556 - xml:space="preserve" 557 - x="5250" 558 - y="6150" 559 - fill="#000000" 560 - font-family="Courier" 561 - font-style="normal" 562 - font-weight="bold" 563 - font-size="192" 564 - text-anchor="middle" 565 - id="text144">struct</text> 566 - <!-- Text --> 567 - <text 568 - xml:space="preserve" 569 - x="5250" 570 - y="6450" 571 - fill="#000000" 572 - font-family="Courier" 573 - font-style="normal" 574 - font-weight="bold" 575 - font-size="192" 576 - text-anchor="middle" 577 - id="text146">rcu_data</text> 578 - <!-- Text --> 579 - <text 580 - xml:space="preserve" 581 - x="4050" 582 - y="7350" 583 - fill="#000000" 584 - font-family="Courier" 585 - font-style="normal" 586 - font-weight="bold" 587 - font-size="192" 588 - text-anchor="middle" 589 - id="text148">struct</text> 590 - <!-- Text --> 591 - <text 592 - xml:space="preserve" 593 - x="4050" 594 - y="7650" 595 - fill="#000000" 596 - font-family="Courier" 597 - font-style="normal" 598 - font-weight="bold" 599 - font-size="192" 600 - text-anchor="middle" 601 - id="text150">rcu_data</text> 602 - <!-- Text --> 603 - <text 604 - xml:space="preserve" 605 - x="450" 606 - y="1800" 607 - fill="#000000" 608 - font-family="Courier" 609 - font-style="normal" 610 - font-weight="bold" 611 - font-size="192" 612 - text-anchor="start" 613 - id="text152">struct rcu_state</text> 614 - <!-- Text --> 615 - <text 616 - xml:space="preserve" 617 - x="1050" 618 - y="10050" 619 - fill="#000000" 620 - font-family="Courier" 621 - font-style="normal" 622 - font-weight="bold" 623 - font-size="192" 624 - text-anchor="middle" 625 - id="text154">struct</text> 626 - <!-- Text --> 627 - <text 628 - xml:space="preserve" 629 - x="1050" 630 - y="10350" 631 - fill="#000000" 632 - font-family="Courier" 633 - font-style="normal" 634 - font-weight="bold" 635 - font-size="192" 636 - text-anchor="middle" 637 - id="text156">rcu_dynticks</text> 638 - <!-- Text --> 639 - <text 640 - xml:space="preserve" 641 - x="4050" 642 - y="10050" 643 - fill="#000000" 644 - font-family="Courier" 645 - font-style="normal" 646 - font-weight="bold" 647 - font-size="192" 648 - text-anchor="middle" 649 - id="text158">struct</text> 650 - <!-- Text --> 651 - <text 652 - xml:space="preserve" 653 - x="4050" 654 - y="10350" 655 - fill="#000000" 656 - font-family="Courier" 657 - font-style="normal" 658 - font-weight="bold" 659 - font-size="192" 660 - text-anchor="middle" 661 - id="text160">rcu_dynticks</text> 662 - <!-- Text --> 663 - <text 664 - xml:space="preserve" 665 - x="2400" 666 - y="8850" 667 - fill="#000000" 668 - font-family="Courier" 669 - font-style="normal" 670 - font-weight="bold" 671 - font-size="192" 672 - text-anchor="middle" 673 - id="text162">struct</text> 674 - <!-- Text --> 675 - <text 676 - xml:space="preserve" 677 - x="2400" 678 - y="9150" 679 - fill="#000000" 680 - font-family="Courier" 681 - font-style="normal" 682 - font-weight="bold" 683 - font-size="192" 684 - text-anchor="middle" 685 - id="text164">rcu_dynticks</text> 686 - <!-- Text --> 687 - <text 688 - xml:space="preserve" 689 - x="5400" 690 - y="8850" 691 - fill="#000000" 692 - font-family="Courier" 693 - font-style="normal" 694 - font-weight="bold" 695 - font-size="192" 696 - text-anchor="middle" 697 - id="text166">struct</text> 698 - <!-- Text --> 699 - <text 700 - xml:space="preserve" 701 - x="5400" 702 - y="9150" 703 - fill="#000000" 704 - font-family="Courier" 705 - font-style="normal" 706 - font-weight="bold" 707 - font-size="192" 708 - text-anchor="middle" 709 - id="text168">rcu_dynticks</text> 710 - <!-- Text --> 711 - <text 712 - xml:space="preserve" 713 - x="6900" 714 - y="300" 715 - fill="#000000" 716 - font-family="Helvetica" 717 - font-style="normal" 718 - font-weight="normal" 719 - font-size="192" 720 - text-anchor="end" 721 - id="text170">rcu_preempt</text> 722 - <!-- Text --> 723 - <text 724 - xml:space="preserve" 725 - x="6000" 726 - y="1200" 727 - fill="#000000" 728 - font-family="Helvetica" 729 - font-style="normal" 730 - font-weight="normal" 731 - font-size="192" 732 - text-anchor="end" 733 - id="text172">rcu_sched</text> 734 - <!-- Line --> 735 - <polyline 736 - points="5250,5850 5250,4864 " 737 - style="stroke:#00d1d1;stroke-width:30.00205472;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 738 - id="polyline174" /> 739 - <!-- Arrowhead on XXXpoint 5250 5850 - 5250 4740--> 740 - </g> 741 - </svg>
+323 -519
Documentation/RCU/Design/Data-Structures/BigTreePreemptRCUBHdyntickCB.svg
··· 13 13 xmlns="http://www.w3.org/2000/svg" 14 14 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 15 15 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 16 - width="7.4in" 17 - height="9.9in" 18 - viewBox="-44 -44 8938 11938" 16 + width="7.4000001in" 17 + height="7.9000001in" 18 + viewBox="-44 -44 8938 9526.283" 19 19 id="svg2" 20 20 version="1.1" 21 - inkscape:version="0.48.4 r9939" 21 + inkscape:version="0.92.2pre0 (973e216, 2017-07-25)" 22 22 sodipodi:docname="BigTreePreemptRCUBHdyntickCB.svg"> 23 23 <metadata 24 24 id="metadata212"> ··· 37 37 <marker 38 38 inkscape:stockid="Arrow1Mend" 39 39 orient="auto" 40 - refY="0.0" 41 - refX="0.0" 40 + refY="0" 41 + refX="0" 42 + id="marker1177" 43 + style="overflow:visible" 44 + inkscape:isstock="true"> 45 + <path 46 + id="path897" 47 + d="M 0,0 5,-5 -12.5,0 5,5 Z" 48 + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" 49 + transform="matrix(-0.4,0,0,-0.4,-4,0)" 50 + inkscape:connector-curvature="0" /> 51 + </marker> 52 + <marker 53 + inkscape:stockid="Arrow1Lend" 54 + orient="auto" 55 + refY="0" 56 + refX="0" 57 + id="Arrow1Lend" 58 + style="overflow:visible" 59 + inkscape:isstock="true"> 60 + <path 61 + id="path891" 62 + d="M 0,0 5,-5 -12.5,0 5,5 Z" 63 + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" 64 + transform="matrix(-0.8,0,0,-0.8,-10,0)" 65 + inkscape:connector-curvature="0" /> 66 + </marker> 67 + <marker 68 + inkscape:stockid="Arrow1Mend" 69 + orient="auto" 70 + refY="0" 71 + refX="0" 42 72 id="Arrow1Mend" 43 - style="overflow:visible;"> 73 + style="overflow:visible"> 44 74 <path 45 75 id="path3970" 46 - 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 " 47 - style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;" 48 - transform="scale(0.4) rotate(180) translate(10,0)" /> 76 + d="M 0,0 5,-5 -12.5,0 5,5 Z" 77 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt" 78 + transform="matrix(-0.4,0,0,-0.4,-4,0)" 79 + inkscape:connector-curvature="0" /> 49 80 </marker> 50 81 </defs> 51 82 <sodipodi:namedview ··· 88 57 guidetolerance="10" 89 58 inkscape:pageopacity="0" 90 59 inkscape:pageshadow="2" 91 - inkscape:window-width="881" 92 - inkscape:window-height="1128" 60 + inkscape:window-width="1920" 61 + inkscape:window-height="1019" 93 62 id="namedview208" 94 63 showgrid="false" 95 64 inkscape:zoom="1.0195195" 96 - inkscape:cx="333" 97 - inkscape:cy="445.49997" 98 - inkscape:window-x="936" 99 - inkscape:window-y="24" 100 - inkscape:window-maximized="0" 65 + inkscape:cx="166.25478" 66 + inkscape:cy="362.18693" 67 + inkscape:window-x="0" 68 + inkscape:window-y="0" 69 + inkscape:window-maximized="1" 101 70 inkscape:current-layer="g4" /> 102 71 <g 103 - style="stroke-width:.025in; fill:none" 104 - id="g4"> 72 + style="fill:none;stroke-width:0.025in" 73 + id="g4" 74 + transform="translate(0,-2415.6743)"> 105 75 <!-- Line: box --> 106 - <rect 107 - x="900" 108 - y="0" 109 - width="6300" 110 - height="7350" 111 - rx="0" 112 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffffff; " 113 - id="rect6" /> 114 76 <!-- Line: box --> 115 - <rect 116 - x="1200" 117 - y="600" 118 - width="5700" 119 - height="3750" 120 - rx="0" 121 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffff00; " 122 - id="rect8" /> 123 77 <!-- Line: box --> 124 - <rect 125 - x="5400" 126 - y="4950" 127 - width="1500" 128 - height="900" 129 - rx="0" 130 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 131 - id="rect10" /> 132 78 <!-- Line: box --> 133 - <rect 134 - x="450" 135 - y="450" 136 - width="6300" 137 - height="7350" 138 - rx="0" 139 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffffff; " 140 - id="rect12" /> 141 79 <!-- Line: box --> 142 - <rect 143 - x="750" 144 - y="1050" 145 - width="5700" 146 - height="3750" 147 - rx="0" 148 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffff00; " 149 - id="rect14" /> 150 80 <!-- Line: box --> 151 - <rect 152 - x="4950" 153 - y="5400" 154 - width="1500" 155 - height="900" 156 - rx="0" 157 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 158 - id="rect16" /> 159 81 <!-- Line --> 160 - <polyline 161 - points="5250,8550 5688,6362 " 162 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 163 - id="polyline18" /> 164 82 <!-- Arrowhead on XXXpoint 5250 8550 - 5710 6240--> 165 83 <polyline 166 84 points="5714 6518 5704 6272 5598 6494 " 167 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 168 - id="polyline20" /> 85 + style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8" 86 + id="polyline20" 87 + transform="matrix(1,0,0,0.95854605,12.340758,1579.9033)" /> 169 88 <!-- Line --> 170 - <polyline 171 - points="4050,9750 4486,7712 " 172 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 173 - id="polyline22" /> 174 89 <!-- Arrowhead on XXXpoint 4050 9750 - 4512 7590--> 175 90 <polyline 176 91 points="4514 7868 4506 7622 4396 7844 " 177 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 178 - id="polyline24" /> 92 + style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8" 93 + id="polyline24" 94 + transform="matrix(1,0,0,0.95854605,12.340758,1579.9033)" /> 179 95 <!-- Line --> 180 - <polyline 181 - points="1040,9750 1476,7712 " 182 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 183 - id="polyline26" /> 184 96 <!-- Arrowhead on XXXpoint 1040 9750 - 1502 7590--> 185 97 <polyline 186 98 points="1504 7868 1496 7622 1386 7844 " 187 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 188 - id="polyline28" /> 99 + style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8" 100 + id="polyline28" 101 + transform="matrix(1,0,0,0.95854605,12.340758,1579.9033)" /> 189 102 <!-- Line --> 190 - <polyline 191 - points="2240,8550 2676,6512 " 192 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 193 - id="polyline30" /> 194 103 <!-- Arrowhead on XXXpoint 2240 8550 - 2702 6390--> 195 104 <polyline 196 105 points="2704 6668 2696 6422 2586 6644 " 197 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 198 - id="polyline32" /> 106 + style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8" 107 + id="polyline32" 108 + transform="matrix(1,0,0,0.95854605,12.340758,1579.9033)" /> 199 109 <!-- Line --> 200 - <polyline 201 - points="4050,9600 5692,6062 " 202 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 203 - id="polyline34" /> 204 110 <!-- Arrowhead on XXXpoint 4050 9600 - 5744 5948--> 205 111 <polyline 206 112 points="5682 6220 5730 5978 5574 6170 " 207 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 208 - id="polyline36" /> 113 + style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8" 114 + id="polyline36" 115 + transform="matrix(1,0,0,0.95854605,12.340758,1579.9033)" /> 209 116 <!-- Line --> 210 - <polyline 211 - points="1086,9600 2728,6062 " 212 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 213 - id="polyline38" /> 214 117 <!-- Arrowhead on XXXpoint 1086 9600 - 2780 5948--> 215 118 <polyline 216 119 points="2718 6220 2766 5978 2610 6170 " 217 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 218 - id="polyline40" /> 120 + style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8" 121 + id="polyline40" 122 + transform="matrix(1,0,0,0.95854605,12.340758,1579.9033)" /> 219 123 <!-- Line: box --> 220 124 <rect 221 - x="0" 222 - y="900" 125 + x="12.340758" 126 + y="2442.5947" 223 127 width="6300" 224 - height="7350" 128 + height="7045.3135" 225 129 rx="0" 226 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffffff; " 130 + style="fill:#ffffff;stroke:#000000;stroke-width:29.37160873;stroke-linecap:butt;stroke-linejoin:miter" 227 131 id="rect42" /> 228 132 <!-- Line: box --> 229 133 <rect 230 - x="300" 231 - y="1500" 134 + x="312.34076" 135 + y="3017.7224" 232 136 width="5700" 233 - height="3750" 137 + height="3594.5476" 234 138 rx="0" 235 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffff00; " 139 + style="fill:#ffff00;stroke:#000000;stroke-width:29.37160873;stroke-linecap:butt;stroke-linejoin:miter" 236 140 id="rect44" /> 237 141 <!-- Line --> 238 142 <polyline 239 143 points="1350,3900 2350,3040 " 240 - style="stroke:#00d1d1;stroke-width:29.99463964;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 241 - id="polyline46" /> 144 + style="stroke:#00d1d1;stroke-width:29.99464035;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 145 + id="polyline46" 146 + transform="matrix(1,0,0,0.95854605,12.340758,1579.9033)" /> 242 147 <!-- Arrowhead on XXXpoint 1350 3900 - 2444 2960--> 243 148 <!-- Line --> 244 149 <polyline 245 150 points="4950,3900 3948,3040 " 246 - style="stroke:#00d1d1;stroke-width:29.99463964;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 247 - id="polyline50" /> 151 + style="stroke:#00d1d1;stroke-width:29.99464035;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 152 + id="polyline50" 153 + transform="matrix(1,0,0,0.95854605,12.340758,1579.9033)" /> 248 154 <!-- Arrowhead on XXXpoint 4950 3900 - 3854 2960--> 249 155 <!-- Line --> 250 156 <polyline 251 157 points="4050,7050 4050,4864 " 252 - style="stroke:#00d1d1;stroke-width:29.99463964;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 253 - id="polyline54" /> 158 + style="stroke:#00d1d1;stroke-width:29.99464035;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 159 + id="polyline54" 160 + transform="matrix(1,0,0,0.95854605,12.340758,1579.9033)" /> 254 161 <!-- Arrowhead on XXXpoint 4050 7050 - 4050 4740--> 255 162 <!-- Line --> 256 163 <polyline 257 164 points="1050,7050 1050,4864 " 258 - style="stroke:#00d1d1;stroke-width:29.99463964;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 259 - id="polyline58" /> 165 + style="stroke:#00d1d1;stroke-width:29.99464035;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 166 + id="polyline58" 167 + transform="matrix(1,0,0,0.95854605,12.340758,1579.9033)" /> 260 168 <!-- Arrowhead on XXXpoint 1050 7050 - 1050 4740--> 261 169 <!-- Line --> 262 170 <polyline 263 171 points="2250,5850 2250,4864 " 264 - style="stroke:#00d1d1;stroke-width:29.99463964;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 265 - id="polyline62" /> 172 + style="stroke:#00d1d1;stroke-width:29.99464035;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 173 + id="polyline62" 174 + transform="matrix(1,0,0,0.95854605,12.340758,1579.9033)" /> 266 175 <!-- Arrowhead on XXXpoint 2250 5850 - 2250 4740--> 267 176 <!-- Line --> 268 - <polyline 269 - points="2250,8550 2250,6814 " 270 - style="stroke:#00ff00;stroke-width:29.99463964;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 271 - id="polyline66" /> 272 177 <!-- Arrowhead on XXXpoint 2250 8550 - 2250 6690--> 273 178 <!-- Line --> 274 - <polyline 275 - points="1050,9750 1050,8014 " 276 - style="stroke:#00ff00;stroke-width:29.99463964;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 277 - id="polyline70" /> 278 179 <!-- Arrowhead on XXXpoint 1050 9750 - 1050 7890--> 279 180 <!-- Line --> 280 - <polyline 281 - points="4050,9750 4050,8014 " 282 - style="stroke:#00ff00;stroke-width:29.99463964;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 283 - id="polyline74" /> 284 181 <!-- Arrowhead on XXXpoint 4050 9750 - 4050 7890--> 285 182 <!-- Line --> 286 - <polyline 287 - points="5250,8550 5250,6814 " 288 - style="stroke:#00ff00;stroke-width:29.99463964;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 289 - id="polyline78" /> 290 183 <!-- Arrowhead on XXXpoint 5250 8550 - 5250 6690--> 291 184 <!-- Line --> 292 - <polyline 293 - points="6000,6300 8048,7910 " 294 - style="stroke:#87cfff;stroke-width:30;stroke-linejoin:miter;stroke-linecap:butt;marker-end:url(#Arrow1Mend)" 295 - id="polyline82" /> 296 185 <!-- Arrowhead on XXXpoint 6000 6300 - 8146 7986--> 297 186 <!-- Circle --> 298 - <circle 299 - cx="2850" 300 - cy="4350" 301 - r="76" 302 - style="fill:#000000;stroke:#000000;stroke-width:14;" 303 - id="circle86" /> 187 + <ellipse 188 + cx="2862.3408" 189 + cy="5749.5786" 190 + style="fill:#000000;stroke:#000000;stroke-width:13.70675087" 191 + id="circle86" 192 + rx="76" 193 + ry="72.849495" /> 304 194 <!-- Circle --> 305 - <circle 306 - cx="3150" 307 - cy="4350" 308 - r="76" 309 - style="fill:#000000;stroke:#000000;stroke-width:14;" 310 - id="circle88" /> 195 + <ellipse 196 + cx="3162.3408" 197 + cy="5749.5786" 198 + style="fill:#000000;stroke:#000000;stroke-width:13.70675087" 199 + id="circle88" 200 + rx="76" 201 + ry="72.849495" /> 311 202 <!-- Circle --> 312 - <circle 313 - cx="3450" 314 - cy="4350" 315 - r="76" 316 - style="fill:#000000;stroke:#000000;stroke-width:14;" 317 - id="circle90" /> 203 + <ellipse 204 + cx="3462.3408" 205 + cy="5749.5786" 206 + style="fill:#000000;stroke:#000000;stroke-width:13.70675087" 207 + id="circle90" 208 + rx="76" 209 + ry="72.849495" /> 318 210 <!-- Circle --> 319 - <circle 320 - cx="1350" 321 - cy="5550" 322 - r="76" 323 - style="fill:#000000;stroke:#000000;stroke-width:14;" 324 - id="circle92" /> 211 + <ellipse 212 + cx="1362.3407" 213 + cy="6899.834" 214 + style="fill:#000000;stroke:#000000;stroke-width:13.70675087" 215 + id="circle92" 216 + rx="76" 217 + ry="72.849495" /> 325 218 <!-- Circle --> 326 - <circle 327 - cx="1650" 328 - cy="5550" 329 - r="76" 330 - style="fill:#000000;stroke:#000000;stroke-width:14;" 331 - id="circle94" /> 219 + <ellipse 220 + cx="1662.3407" 221 + cy="6899.834" 222 + style="fill:#000000;stroke:#000000;stroke-width:13.70675087" 223 + id="circle94" 224 + rx="76" 225 + ry="72.849495" /> 332 226 <!-- Circle --> 333 - <circle 334 - cx="1950" 335 - cy="5550" 336 - r="76" 337 - style="fill:#000000;stroke:#000000;stroke-width:14;" 338 - id="circle96" /> 227 + <ellipse 228 + cx="1962.3407" 229 + cy="6899.834" 230 + style="fill:#000000;stroke:#000000;stroke-width:13.70675087" 231 + id="circle96" 232 + rx="76" 233 + ry="72.849495" /> 339 234 <!-- Circle --> 340 - <circle 341 - cx="4350" 342 - cy="5550" 343 - r="76" 344 - style="fill:#000000;stroke:#000000;stroke-width:14;" 345 - id="circle98" /> 235 + <ellipse 236 + cx="4362.3408" 237 + cy="6899.834" 238 + style="fill:#000000;stroke:#000000;stroke-width:13.70675087" 239 + id="circle98" 240 + rx="76" 241 + ry="72.849495" /> 346 242 <!-- Circle --> 347 - <circle 348 - cx="4650" 349 - cy="5550" 350 - r="76" 351 - style="fill:#000000;stroke:#000000;stroke-width:14;" 352 - id="circle100" /> 243 + <ellipse 244 + cx="4662.3408" 245 + cy="6899.834" 246 + style="fill:#000000;stroke:#000000;stroke-width:13.70675087" 247 + id="circle100" 248 + rx="76" 249 + ry="72.849495" /> 353 250 <!-- Circle --> 354 - <circle 355 - cx="4950" 356 - cy="5550" 357 - r="76" 358 - style="fill:#000000;stroke:#000000;stroke-width:14;" 359 - id="circle102" /> 251 + <ellipse 252 + cx="4962.3408" 253 + cy="6899.834" 254 + style="fill:#000000;stroke:#000000;stroke-width:13.70675087" 255 + id="circle102" 256 + rx="76" 257 + ry="72.849495" /> 360 258 <!-- Line: box --> 361 259 <rect 362 - x="7350" 363 - y="7950" 260 + x="6745.3027" 261 + y="8146.0654" 364 262 width="1500" 365 - height="900" 263 + height="862.69141" 366 264 rx="0" 367 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 265 + style="stroke:#000000;stroke-width:29.37160873;stroke-linecap:butt;stroke-linejoin:miter" 368 266 id="rect104" /> 369 267 <!-- Line: box --> 370 268 <rect 371 - x="7350" 372 - y="9450" 269 + x="6745.3027" 270 + y="9583.8857" 373 271 width="1500" 374 - height="900" 272 + height="862.69141" 375 273 rx="0" 376 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 274 + style="stroke:#000000;stroke-width:29.37160873;stroke-linecap:butt;stroke-linejoin:miter" 377 275 id="rect106" /> 378 276 <!-- Line --> 379 277 <polyline 380 278 points="8100,8850 8100,9384 " 381 - style="stroke:#000000;stroke-width:30;stroke-linejoin:miter;stroke-linecap:butt;marker-end:url(#Arrow1Mend)" 382 - id="polyline108" /> 279 + style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend)" 280 + id="polyline108" 281 + transform="matrix(1,0,0,0.95854605,-604.69715,525.62477)" /> 383 282 <!-- Arrowhead on XXXpoint 8100 8850 - 8100 9510--> 384 283 <!-- Line: box --> 385 284 <rect 386 - x="7350" 387 - y="10950" 285 + x="6745.3027" 286 + y="11021.704" 388 287 width="1500" 389 - height="900" 288 + height="862.69141" 390 289 rx="0" 391 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 290 + style="stroke:#000000;stroke-width:29.37160873;stroke-linecap:butt;stroke-linejoin:miter" 392 291 id="rect112" /> 393 292 <!-- Line --> 394 293 <polyline 395 294 points="8100,10350 8100,10884 " 396 - style="stroke:#000000;stroke-width:30;stroke-linejoin:miter;stroke-linecap:butt;marker-end:url(#Arrow1Mend)" 397 - id="polyline114" /> 295 + style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Mend)" 296 + id="polyline114" 297 + transform="matrix(1,0,0,0.95854605,-604.69715,525.62477)" /> 398 298 <!-- Arrowhead on XXXpoint 8100 10350 - 8100 11010--> 399 299 <!-- Line: box --> 400 300 <rect 401 - x="750" 402 - y="3900" 301 + x="762.34076" 302 + y="5318.2324" 403 303 width="1800" 404 - height="900" 304 + height="862.69141" 405 305 rx="0" 406 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 306 + style="fill:#ffbfbf;stroke:#000000;stroke-width:29.37160873;stroke-linecap:butt;stroke-linejoin:miter" 407 307 id="rect118" /> 408 308 <!-- Line: box --> 409 309 <rect 410 - x="300" 411 - y="7050" 310 + x="312.34076" 311 + y="8337.6533" 412 312 width="1500" 413 - height="900" 313 + height="862.69141" 414 314 rx="0" 415 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 315 + style="fill:#87cfff;stroke:#000000;stroke-width:29.37160873;stroke-linecap:butt;stroke-linejoin:miter" 416 316 id="rect120" /> 417 317 <!-- Line: box --> 418 318 <rect 419 - x="3750" 420 - y="3900" 319 + x="3762.3408" 320 + y="5318.2324" 421 321 width="1800" 422 - height="900" 322 + height="862.69141" 423 323 rx="0" 424 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 324 + style="fill:#ffbfbf;stroke:#000000;stroke-width:29.37160873;stroke-linecap:butt;stroke-linejoin:miter" 425 325 id="rect122" /> 426 326 <!-- Line: box --> 427 327 <rect 428 - x="4500" 429 - y="5850" 328 + x="4512.3408" 329 + y="7187.3975" 430 330 width="1500" 431 - height="900" 331 + height="862.69141" 432 332 rx="0" 433 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 333 + style="fill:#87cfff;stroke:#000000;stroke-width:29.37160873;stroke-linecap:butt;stroke-linejoin:miter" 434 334 id="rect124" /> 435 335 <!-- Line: box --> 436 336 <rect 437 - x="3300" 438 - y="7050" 337 + x="3312.3408" 338 + y="8337.6533" 439 339 width="1500" 440 - height="900" 340 + height="862.69141" 441 341 rx="0" 442 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 342 + style="fill:#87cfff;stroke:#000000;stroke-width:29.37160873;stroke-linecap:butt;stroke-linejoin:miter" 443 343 id="rect126" /> 444 344 <!-- Line: box --> 445 345 <rect 446 - x="2250" 447 - y="2100" 346 + x="2262.3408" 347 + y="3592.8503" 448 348 width="1800" 449 - height="900" 349 + height="862.69141" 450 350 rx="0" 451 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 351 + style="fill:#ffbfbf;stroke:#000000;stroke-width:29.37160873;stroke-linecap:butt;stroke-linejoin:miter" 452 352 id="rect128" /> 453 353 <!-- Line: box --> 454 - <rect 455 - x="0" 456 - y="9750" 457 - width="2100" 458 - height="900" 459 - rx="0" 460 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#00ff00; " 461 - id="rect130" /> 354 + <!-- Line: box --> 355 + <!-- Line: box --> 356 + <!-- Line: box --> 462 357 <!-- Line: box --> 463 358 <rect 464 - x="1350" 465 - y="8550" 466 - width="2100" 467 - height="900" 468 - rx="0" 469 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#00ff00; " 470 - id="rect132" /> 471 - <!-- Line: box --> 472 - <rect 473 - x="3000" 474 - y="9750" 475 - width="2100" 476 - height="900" 477 - rx="0" 478 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#00ff00; " 479 - id="rect134" /> 480 - <!-- Line: box --> 481 - <rect 482 - x="4350" 483 - y="8550" 484 - width="2100" 485 - height="900" 486 - rx="0" 487 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#00ff00; " 488 - id="rect136" /> 489 - <!-- Line: box --> 490 - <rect 491 - x="1500" 492 - y="5850" 359 + x="1512.3407" 360 + y="7187.3975" 493 361 width="1500" 494 - height="900" 362 + height="862.69141" 495 363 rx="0" 496 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 364 + style="fill:#87cfff;stroke:#000000;stroke-width:29.37160873;stroke-linecap:butt;stroke-linejoin:miter" 497 365 id="rect138" /> 498 366 <!-- Text --> 499 367 <text 500 368 xml:space="preserve" 501 - x="8100" 502 - y="8250" 503 - fill="#000000" 504 - font-family="Courier" 369 + x="7338.3037" 370 + y="8614.0625" 505 371 font-style="normal" 506 372 font-weight="bold" 507 373 font-size="192" 508 - text-anchor="middle" 509 - id="text140">struct</text> 374 + id="text140" 375 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 376 + transform="scale(1.0213945,0.97905363)">struct</text> 510 377 <!-- Text --> 511 378 <text 512 379 xml:space="preserve" 513 - x="8100" 514 - y="8550" 515 - fill="#000000" 516 - font-family="Courier" 380 + x="7338.3037" 381 + y="8907.7783" 517 382 font-style="normal" 518 383 font-weight="bold" 519 384 font-size="192" 520 - text-anchor="middle" 521 - id="text142">rcu_head</text> 385 + id="text142" 386 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 387 + transform="scale(1.0213945,0.97905363)">rcu_head</text> 522 388 <!-- Text --> 523 389 <text 524 390 xml:space="preserve" 525 - x="8100" 526 - y="9750" 527 - fill="#000000" 528 - font-family="Courier" 391 + x="7338.3037" 392 + y="10082.644" 529 393 font-style="normal" 530 394 font-weight="bold" 531 395 font-size="192" 532 - text-anchor="middle" 533 - id="text144">struct</text> 396 + id="text144" 397 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 398 + transform="scale(1.0213945,0.97905363)">struct</text> 534 399 <!-- Text --> 535 400 <text 536 401 xml:space="preserve" 537 - x="8100" 538 - y="10050" 539 - fill="#000000" 540 - font-family="Courier" 402 + x="7338.3037" 403 + y="10376.36" 541 404 font-style="normal" 542 405 font-weight="bold" 543 406 font-size="192" 544 - text-anchor="middle" 545 - id="text146">rcu_head</text> 407 + id="text146" 408 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 409 + transform="scale(1.0213945,0.97905363)">rcu_head</text> 546 410 <!-- Text --> 547 411 <text 548 412 xml:space="preserve" 549 - x="8100" 550 - y="11250" 551 - fill="#000000" 552 - font-family="Courier" 413 + x="7338.3037" 414 + y="11551.224" 553 415 font-style="normal" 554 416 font-weight="bold" 555 417 font-size="192" 556 - text-anchor="middle" 557 - id="text148">struct</text> 418 + id="text148" 419 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 420 + transform="scale(1.0213945,0.97905363)">struct</text> 558 421 <!-- Text --> 559 422 <text 560 423 xml:space="preserve" 561 - x="8100" 562 - y="11550" 563 - fill="#000000" 564 - font-family="Courier" 424 + x="7338.3037" 425 + y="11844.94" 565 426 font-style="normal" 566 427 font-weight="bold" 567 428 font-size="192" 568 - text-anchor="middle" 569 - id="text150">rcu_head</text> 429 + id="text150" 430 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 431 + transform="scale(1.0213945,0.97905363)">rcu_head</text> 570 432 <!-- Text --> 571 433 <text 572 434 xml:space="preserve" 573 - x="6000" 574 - y="1200" 575 - fill="#000000" 576 - font-family="Helvetica" 435 + x="5886.4043" 436 + y="2788.5688" 577 437 font-style="normal" 578 438 font-weight="normal" 579 439 font-size="192" 580 - text-anchor="end" 581 - id="text152">rcu_sched</text> 440 + id="text152" 441 + style="font-style:normal;font-weight:normal;font-size:187.978302px;font-family:Helvetica;text-anchor:end;fill:#000000;stroke-width:0.02447634in" 442 + transform="scale(1.0213945,0.97905363)">rcu_state</text> 443 + <!-- Text --> 582 444 <!-- Text --> 583 445 <text 584 446 xml:space="preserve" 585 - x="6450" 586 - y="750" 587 - fill="#000000" 588 - font-family="Helvetica" 589 - font-style="normal" 590 - font-weight="normal" 591 - font-size="192" 592 - text-anchor="end" 593 - id="text154">rcu_bh</text> 594 - <!-- Text --> 595 - <text 596 - xml:space="preserve" 597 - x="3150" 598 - y="2400" 599 - fill="#000000" 600 - font-family="Courier" 447 + x="3096.1016" 448 + y="3963.4336" 601 449 font-style="normal" 602 450 font-weight="bold" 603 451 font-size="192" 604 - text-anchor="middle" 605 - id="text156">struct</text> 452 + id="text156" 453 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 454 + transform="scale(1.0213945,0.97905363)">struct</text> 606 455 <!-- Text --> 607 456 <text 608 457 xml:space="preserve" 609 - x="3150" 610 - y="2700" 611 - fill="#000000" 612 - font-family="Courier" 458 + x="3096.1016" 459 + y="4257.1494" 613 460 font-style="normal" 614 461 font-weight="bold" 615 462 font-size="192" 616 - text-anchor="middle" 617 - id="text158">rcu_node</text> 463 + id="text158" 464 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 465 + transform="scale(1.0213945,0.97905363)">rcu_node</text> 618 466 <!-- Text --> 619 467 <text 620 468 xml:space="preserve" 621 - x="1650" 622 - y="4200" 623 - fill="#000000" 624 - font-family="Courier" 469 + x="1627.5209" 470 + y="5725.7305" 625 471 font-style="normal" 626 472 font-weight="bold" 627 473 font-size="192" 628 - text-anchor="middle" 629 - id="text160">struct</text> 474 + id="text160" 475 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 476 + transform="scale(1.0213945,0.97905363)">struct</text> 630 477 <!-- Text --> 631 478 <text 632 479 xml:space="preserve" 633 - x="1650" 634 - y="4500" 635 - fill="#000000" 636 - font-family="Courier" 480 + x="1627.5209" 481 + y="6019.4463" 637 482 font-style="normal" 638 483 font-weight="bold" 639 484 font-size="192" 640 - text-anchor="middle" 641 - id="text162">rcu_node</text> 485 + id="text162" 486 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 487 + transform="scale(1.0213945,0.97905363)">rcu_node</text> 642 488 <!-- Text --> 643 489 <text 644 490 xml:space="preserve" 645 - x="4650" 646 - y="4500" 647 - fill="#000000" 648 - font-family="Courier" 491 + x="4564.6821" 492 + y="6019.4463" 649 493 font-style="normal" 650 494 font-weight="bold" 651 495 font-size="192" 652 - text-anchor="middle" 653 - id="text164">rcu_node</text> 496 + id="text164" 497 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 498 + transform="scale(1.0213945,0.97905363)">rcu_node</text> 654 499 <!-- Text --> 655 500 <text 656 501 xml:space="preserve" 657 - x="4650" 658 - y="4200" 659 - fill="#000000" 660 - font-family="Courier" 502 + x="4564.6821" 503 + y="5725.7305" 661 504 font-style="normal" 662 505 font-weight="bold" 663 506 font-size="192" 664 - text-anchor="middle" 665 - id="text166">struct</text> 507 + id="text166" 508 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 509 + transform="scale(1.0213945,0.97905363)">struct</text> 666 510 <!-- Text --> 667 511 <text 668 512 xml:space="preserve" 669 - x="2250" 670 - y="6150" 671 - fill="#000000" 672 - font-family="Courier" 513 + x="2214.9531" 514 + y="7634.8848" 673 515 font-style="normal" 674 516 font-weight="bold" 675 517 font-size="192" 676 - text-anchor="middle" 677 - id="text168">struct</text> 518 + id="text168" 519 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 520 + transform="scale(1.0213945,0.97905363)">struct</text> 678 521 <!-- Text --> 679 522 <text 680 523 xml:space="preserve" 681 - x="2250" 682 - y="6450" 683 - fill="#000000" 684 - font-family="Courier" 524 + x="2214.9531" 525 + y="7928.6011" 685 526 font-style="normal" 686 527 font-weight="bold" 687 528 font-size="192" 688 - text-anchor="middle" 689 - id="text170">rcu_data</text> 529 + id="text170" 530 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 531 + transform="scale(1.0213945,0.97905363)">rcu_data</text> 690 532 <!-- Text --> 691 533 <text 692 534 xml:space="preserve" 693 - x="1050" 694 - y="7350" 695 - fill="#000000" 696 - font-family="Courier" 535 + x="1040.0886" 536 + y="8809.749" 697 537 font-style="normal" 698 538 font-weight="bold" 699 539 font-size="192" 700 - text-anchor="middle" 701 - id="text172">struct</text> 540 + id="text172" 541 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 542 + transform="scale(1.0213945,0.97905363)">struct</text> 702 543 <!-- Text --> 703 544 <text 704 545 xml:space="preserve" 705 - x="1050" 706 - y="7650" 707 - fill="#000000" 708 - font-family="Courier" 546 + x="1040.0886" 547 + y="9103.4648" 709 548 font-style="normal" 710 549 font-weight="bold" 711 550 font-size="192" 712 - text-anchor="middle" 713 - id="text174">rcu_data</text> 551 + id="text174" 552 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 553 + transform="scale(1.0213945,0.97905363)">rcu_data</text> 714 554 <!-- Text --> 715 555 <text 716 556 xml:space="preserve" 717 - x="5250" 718 - y="6150" 719 - fill="#000000" 720 - font-family="Courier" 557 + x="5152.1138" 558 + y="7634.8848" 721 559 font-style="normal" 722 560 font-weight="bold" 723 561 font-size="192" 724 - text-anchor="middle" 725 - id="text176">struct</text> 562 + id="text176" 563 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 564 + transform="scale(1.0213945,0.97905363)">struct</text> 726 565 <!-- Text --> 727 566 <text 728 567 xml:space="preserve" 729 - x="5250" 730 - y="6450" 731 - fill="#000000" 732 - font-family="Courier" 568 + x="5152.1138" 569 + y="7928.6011" 733 570 font-style="normal" 734 571 font-weight="bold" 735 572 font-size="192" 736 - text-anchor="middle" 737 - id="text178">rcu_data</text> 573 + id="text178" 574 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 575 + transform="scale(1.0213945,0.97905363)">rcu_data</text> 738 576 <!-- Text --> 739 577 <text 740 578 xml:space="preserve" 741 - x="4050" 742 - y="7350" 743 - fill="#000000" 744 - font-family="Courier" 579 + x="3977.2495" 580 + y="8809.749" 745 581 font-style="normal" 746 582 font-weight="bold" 747 583 font-size="192" 748 - text-anchor="middle" 749 - id="text180">struct</text> 584 + id="text180" 585 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 586 + transform="scale(1.0213945,0.97905363)">struct</text> 750 587 <!-- Text --> 751 588 <text 752 589 xml:space="preserve" 753 - x="4050" 754 - y="7650" 755 - fill="#000000" 756 - font-family="Courier" 590 + x="3977.2495" 591 + y="9103.4648" 757 592 font-style="normal" 758 593 font-weight="bold" 759 594 font-size="192" 760 - text-anchor="middle" 761 - id="text182">rcu_data</text> 595 + id="text182" 596 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:middle;fill:#000000;stroke-width:0.02447634in" 597 + transform="scale(1.0213945,0.97905363)">rcu_data</text> 762 598 <!-- Text --> 763 599 <text 764 600 xml:space="preserve" 765 - x="450" 766 - y="1800" 767 - fill="#000000" 768 - font-family="Courier" 601 + x="452.6564" 602 + y="3376.0012" 769 603 font-style="normal" 770 604 font-weight="bold" 771 605 font-size="192" 772 - text-anchor="start" 773 - id="text184">struct rcu_state</text> 606 + id="text184" 607 + style="font-style:normal;font-weight:bold;font-size:187.978302px;font-family:Courier;text-anchor:start;fill:#000000;stroke-width:0.02447634in" 608 + transform="scale(1.0213945,0.97905363)">struct rcu_state</text> 774 609 <!-- Text --> 775 - <text 776 - xml:space="preserve" 777 - x="1050" 778 - y="10050" 779 - fill="#000000" 780 - font-family="Courier" 781 - font-style="normal" 782 - font-weight="bold" 783 - font-size="192" 784 - text-anchor="middle" 785 - id="text186">struct</text> 786 610 <!-- Text --> 787 - <text 788 - xml:space="preserve" 789 - x="1050" 790 - y="10350" 791 - fill="#000000" 792 - font-family="Courier" 793 - font-style="normal" 794 - font-weight="bold" 795 - font-size="192" 796 - text-anchor="middle" 797 - id="text188">rcu_dynticks</text> 798 611 <!-- Text --> 799 - <text 800 - xml:space="preserve" 801 - x="4050" 802 - y="10050" 803 - fill="#000000" 804 - font-family="Courier" 805 - font-style="normal" 806 - font-weight="bold" 807 - font-size="192" 808 - text-anchor="middle" 809 - id="text190">struct</text> 810 612 <!-- Text --> 811 - <text 812 - xml:space="preserve" 813 - x="4050" 814 - y="10350" 815 - fill="#000000" 816 - font-family="Courier" 817 - font-style="normal" 818 - font-weight="bold" 819 - font-size="192" 820 - text-anchor="middle" 821 - id="text192">rcu_dynticks</text> 822 613 <!-- Text --> 823 - <text 824 - xml:space="preserve" 825 - x="2400" 826 - y="8850" 827 - fill="#000000" 828 - font-family="Courier" 829 - font-style="normal" 830 - font-weight="bold" 831 - font-size="192" 832 - text-anchor="middle" 833 - id="text194">struct</text> 834 614 <!-- Text --> 835 - <text 836 - xml:space="preserve" 837 - x="2400" 838 - y="9150" 839 - fill="#000000" 840 - font-family="Courier" 841 - font-style="normal" 842 - font-weight="bold" 843 - font-size="192" 844 - text-anchor="middle" 845 - id="text196">rcu_dynticks</text> 846 615 <!-- Text --> 847 - <text 848 - xml:space="preserve" 849 - x="5400" 850 - y="8850" 851 - fill="#000000" 852 - font-family="Courier" 853 - font-style="normal" 854 - font-weight="bold" 855 - font-size="192" 856 - text-anchor="middle" 857 - id="text198">struct</text> 858 616 <!-- Text --> 859 - <text 860 - xml:space="preserve" 861 - x="5400" 862 - y="9150" 863 - fill="#000000" 864 - font-family="Courier" 865 - font-style="normal" 866 - font-weight="bold" 867 - font-size="192" 868 - text-anchor="middle" 869 - id="text200">rcu_dynticks</text> 870 617 <!-- Text --> 871 - <text 872 - xml:space="preserve" 873 - x="6900" 874 - y="300" 875 - fill="#000000" 876 - font-family="Helvetica" 877 - font-style="normal" 878 - font-weight="normal" 879 - font-size="192" 880 - text-anchor="end" 881 - id="text202">rcu_preempt</text> 882 618 <!-- Line --> 883 619 <polyline 884 620 points="5250,5850 5250,4864 " 885 - style="stroke:#00d1d1;stroke-width:29.99463964;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 886 - id="polyline204" /> 621 + style="stroke:#00d1d1;stroke-width:29.99464035;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 622 + id="polyline204" 623 + transform="matrix(1,0,0,0.95854605,12.340758,1579.9033)" /> 887 624 <!-- Arrowhead on XXXpoint 5250 5850 - 5250 4740--> 625 + <path 626 + style="fill:none;stroke:#000000;stroke-width:34.24744034;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker1177)" 627 + d="m 6000.1472,7564.2558 c 1498.5508,0 1498.5508,0 1498.5508,0 v 520.0252" 628 + id="path886" 629 + inkscape:connector-curvature="0" /> 888 630 </g> 889 631 </svg>
+55 -118
Documentation/RCU/Design/Data-Structures/Data-Structures.html
··· 23 23 The <tt>rcu_segcblist</tt> Structure</a> 24 24 <li> <a href="#The rcu_data Structure"> 25 25 The <tt>rcu_data</tt> Structure</a> 26 - <li> <a href="#The rcu_dynticks Structure"> 27 - The <tt>rcu_dynticks</tt> Structure</a> 28 26 <li> <a href="#The rcu_head Structure"> 29 27 The <tt>rcu_head</tt> Structure</a> 30 28 <li> <a href="#RCU-Specific Fields in the task_struct Structure"> ··· 125 127 </p><p>RCU currently permits up to a four-level tree, which on a 64-bit system 126 128 accommodates up to 4,194,304 CPUs, though only a mere 524,288 CPUs for 127 129 32-bit systems. 128 - On the other hand, you can set <tt>CONFIG_RCU_FANOUT</tt> to be 129 - as small as 2 if you wish, which would permit only 16 CPUs, which 130 - is useful for testing. 130 + On the other hand, you can set both <tt>CONFIG_RCU_FANOUT</tt> and 131 + <tt>CONFIG_RCU_FANOUT_LEAF</tt> to be as small as 2, which would result 132 + in a 16-CPU test using a 4-level tree. 133 + This can be useful for testing large-system capabilities on small test 134 + machines. 131 135 132 136 </p><p>This multi-level combining tree allows us to get most of the 133 137 performance and scalability ··· 154 154 keeping lock contention under control at all tree levels regardless 155 155 of the level of loading on the system. 156 156 157 - </p><p>The Linux kernel actually supports multiple flavors of RCU 158 - running concurrently, so RCU builds separate data structures for each 159 - flavor. 160 - For example, for <tt>CONFIG_TREE_RCU=y</tt> kernels, RCU provides 161 - rcu_sched and rcu_bh, as shown below: 162 - 163 - </p><p><img src="BigTreeClassicRCUBH.svg" alt="BigTreeClassicRCUBH.svg" width="33%"> 164 - 165 - </p><p>Energy efficiency is increasingly important, and for that 166 - reason the Linux kernel provides <tt>CONFIG_NO_HZ_IDLE</tt>, which 167 - turns off the scheduling-clock interrupts on idle CPUs, which in 168 - turn allows those CPUs to attain deeper sleep states and to consume 169 - less energy. 170 - CPUs whose scheduling-clock interrupts have been turned off are 171 - said to be in <i>dyntick-idle mode</i>. 172 - RCU must handle dyntick-idle CPUs specially 173 - because RCU would otherwise wake up each CPU on every grace period, 174 - which would defeat the whole purpose of <tt>CONFIG_NO_HZ_IDLE</tt>. 175 - RCU uses the <tt>rcu_dynticks</tt> structure to track 176 - which CPUs are in dyntick idle mode, as shown below: 177 - 178 - </p><p><img src="BigTreeClassicRCUBHdyntick.svg" alt="BigTreeClassicRCUBHdyntick.svg" width="33%"> 179 - 180 - </p><p>However, if a CPU is in dyntick-idle mode, it is in that mode 181 - for all flavors of RCU. 182 - Therefore, a single <tt>rcu_dynticks</tt> structure is allocated per 183 - CPU, and all of a given CPU's <tt>rcu_data</tt> structures share 184 - that <tt>rcu_dynticks</tt>, as shown in the figure. 185 - 186 - </p><p>Kernels built with <tt>CONFIG_PREEMPT_RCU</tt> support 187 - rcu_preempt in addition to rcu_sched and rcu_bh, as shown below: 188 - 189 - </p><p><img src="BigTreePreemptRCUBHdyntick.svg" alt="BigTreePreemptRCUBHdyntick.svg" width="35%"> 190 - 191 157 </p><p>RCU updaters wait for normal grace periods by registering 192 158 RCU callbacks, either directly via <tt>call_rcu()</tt> and 193 159 friends (namely <tt>call_rcu_bh()</tt> and <tt>call_rcu_sched()</tt>), 194 - there being a separate interface per flavor of RCU) 195 160 or indirectly via <tt>synchronize_rcu()</tt> and friends. 196 161 RCU callbacks are represented by <tt>rcu_head</tt> structures, 197 162 which are queued on <tt>rcu_data</tt> structures while they are ··· 179 214 <li> Each <tt>rcu_node</tt> structure has a spinlock. 180 215 <li> The fields in <tt>rcu_data</tt> are private to the corresponding 181 216 CPU, although a few can be read and written by other CPUs. 182 - <li> Similarly, the fields in <tt>rcu_dynticks</tt> are private 183 - to the corresponding CPU, although a few can be read by 184 - other CPUs. 185 217 </ol> 186 218 187 219 <p>It is important to note that different data structures can have ··· 234 272 access to this information from the corresponding CPU. 235 273 Finally, this structure records past dyntick-idle state 236 274 for the corresponding CPU and also tracks statistics. 237 - <li> <tt>rcu_dynticks</tt>: 238 - This per-CPU structure tracks the current dyntick-idle 239 - state for the corresponding CPU. 240 - Unlike the other three structures, the <tt>rcu_dynticks</tt> 241 - structure is not replicated per RCU flavor. 242 275 <li> <tt>rcu_head</tt>: 243 276 This structure represents RCU callbacks, and is the 244 277 only structure allocated and managed by RCU users. ··· 244 287 <p>If all you wanted from this article was a general notion of how 245 288 RCU's data structures are related, you are done. 246 289 Otherwise, each of the following sections give more details on 247 - the <tt>rcu_state</tt>, <tt>rcu_node</tt>, <tt>rcu_data</tt>, 248 - and <tt>rcu_dynticks</tt> data structures. 290 + the <tt>rcu_state</tt>, <tt>rcu_node</tt> and <tt>rcu_data</tt> data 291 + structures. 249 292 250 293 <h3><a name="The rcu_state Structure"> 251 294 The <tt>rcu_state</tt> Structure</a></h3> 252 295 253 296 <p>The <tt>rcu_state</tt> structure is the base structure that 254 - represents a flavor of RCU. 297 + represents the state of RCU in the system. 255 298 This structure forms the interconnection between the 256 299 <tt>rcu_node</tt> and <tt>rcu_data</tt> structures, 257 300 tracks grace periods, contains the lock used to ··· 346 389 The bottom two bits are the state of the current grace period, 347 390 which can be zero for not yet started or one for in progress. 348 391 In other words, if the bottom two bits of <tt>-&gt;gp_seq</tt> are 349 - zero, the corresponding flavor of RCU is idle. 392 + zero, then RCU is idle. 350 393 Any other value in the bottom two bits indicates that something is broken. 351 394 This field is protected by the root <tt>rcu_node</tt> structure's 352 395 <tt>-&gt;lock</tt> field. ··· 376 419 grace period in jiffies. 377 420 It is protected by the root <tt>rcu_node</tt>'s <tt>-&gt;lock</tt>. 378 421 379 - <p>The <tt>-&gt;name</tt> field points to the name of the RCU flavor 380 - (for example, &ldquo;rcu_sched&rdquo;), and is constant. 381 - The <tt>-&gt;abbr</tt> field contains a one-character abbreviation, 382 - for example, &ldquo;s&rdquo; for RCU-sched. 422 + <p>The <tt>-&gt;name</tt> and <tt>-&gt;abbr</tt> fields distinguish 423 + between preemptible RCU (&ldquo;rcu_preempt&rdquo; and &ldquo;p&rdquo;) 424 + and non-preemptible RCU (&ldquo;rcu_sched&rdquo; and &ldquo;s&rdquo;). 425 + These fields are used for diagnostic and tracing purposes. 383 426 384 427 <h3><a name="The rcu_node Structure"> 385 428 The <tt>rcu_node</tt> Structure</a></h3> ··· 928 971 pointer. 929 972 The reason for this is that all the ready-to-invoke callbacks 930 973 (that is, those in the <tt>RCU_DONE_TAIL</tt> segment) are extracted 931 - all at once at callback-invocation time. 974 + all at once at callback-invocation time (<tt>rcu_do_batch</tt>), due 975 + to which <tt>-&gt;head</tt> may be set to NULL if there are no not-done 976 + callbacks remaining in the <tt>rcu_segcblist</tt>. 932 977 If callback invocation must be postponed, for example, because a 933 978 high-priority process just woke up on this CPU, then the remaining 934 - callbacks are placed back on the <tt>RCU_DONE_TAIL</tt> segment. 935 - Either way, the <tt>-&gt;len</tt> and <tt>-&gt;len_lazy</tt> counts 936 - are adjusted after the corresponding callbacks have been invoked, and so 937 - again it is the <tt>-&gt;len</tt> count that accurately reflects whether 938 - or not there are callbacks associated with this <tt>rcu_segcblist</tt> 939 - structure. 979 + callbacks are placed back on the <tt>RCU_DONE_TAIL</tt> segment and 980 + <tt>-&gt;head</tt> once again points to the start of the segment. 981 + In short, the head field can briefly be <tt>NULL</tt> even though the 982 + CPU has callbacks present the entire time. 983 + Therefore, it is not appropriate to test the <tt>-&gt;head</tt> pointer 984 + for <tt>NULL</tt>. 985 + 986 + <p>In contrast, the <tt>-&gt;len</tt> and <tt>-&gt;len_lazy</tt> counts 987 + are adjusted only after the corresponding callbacks have been invoked. 988 + This means that the <tt>-&gt;len</tt> count is zero only if 989 + the <tt>rcu_segcblist</tt> structure really is devoid of callbacks. 940 990 Of course, off-CPU sampling of the <tt>-&gt;len</tt> count requires 941 - the use of appropriate synchronization, for example, memory barriers. 991 + careful use of appropriate synchronization, for example, memory barriers. 942 992 This synchronization can be a bit subtle, particularly in the case 943 993 of <tt>rcu_barrier()</tt>. 944 994 945 995 <h3><a name="The rcu_data Structure"> 946 996 The <tt>rcu_data</tt> Structure</a></h3> 947 997 948 - <p>The <tt>rcu_data</tt> maintains the per-CPU state for the 949 - corresponding flavor of RCU. 998 + <p>The <tt>rcu_data</tt> maintains the per-CPU state for the RCU subsystem. 950 999 The fields in this structure may be accessed only from the corresponding 951 1000 CPU (and from tracing) unless otherwise stated. 952 1001 This structure is the ··· 978 1015 979 1016 <pre> 980 1017 1 int cpu; 981 - 2 struct rcu_state *rsp; 982 - 3 struct rcu_node *mynode; 983 - 4 struct rcu_dynticks *dynticks; 984 - 5 unsigned long grpmask; 985 - 6 bool beenonline; 1018 + 2 struct rcu_node *mynode; 1019 + 3 unsigned long grpmask; 1020 + 4 bool beenonline; 986 1021 </pre> 987 1022 988 1023 <p>The <tt>-&gt;cpu</tt> field contains the number of the 989 - corresponding CPU, the <tt>-&gt;rsp</tt> pointer references 990 - the corresponding <tt>rcu_state</tt> structure (and is most frequently 991 - used to locate the name of the corresponding flavor of RCU for tracing), 992 - and the <tt>-&gt;mynode</tt> field references the corresponding 993 - <tt>rcu_node</tt> structure. 1024 + corresponding CPU and the <tt>-&gt;mynode</tt> field references the 1025 + corresponding <tt>rcu_node</tt> structure. 994 1026 The <tt>-&gt;mynode</tt> is used to propagate quiescent states 995 1027 up the combining tree. 996 - <p>The <tt>-&gt;dynticks</tt> pointer references the 997 - <tt>rcu_dynticks</tt> structure corresponding to this 998 - CPU. 999 - Recall that a single per-CPU instance of the <tt>rcu_dynticks</tt> 1000 - structure is shared among all flavors of RCU. 1001 - These first four fields are constant and therefore require not 1002 - synchronization. 1028 + These two fields are constant and therefore do not require synchronization. 1003 1029 1004 - </p><p>The <tt>-&gt;grpmask</tt> field indicates the bit in 1030 + <p>The <tt>-&gt;grpmask</tt> field indicates the bit in 1005 1031 the <tt>-&gt;mynode-&gt;qsmask</tt> corresponding to this 1006 1032 <tt>rcu_data</tt> structure, and is also used when propagating 1007 1033 quiescent states. ··· 1009 1057 3 bool cpu_no_qs; 1010 1058 4 bool core_needs_qs; 1011 1059 5 bool gpwrap; 1012 - 6 unsigned long rcu_qs_ctr_snap; 1013 1060 </pre> 1014 1061 1015 - <p>The <tt>-&gt;gp_seq</tt> and <tt>-&gt;gp_seq_needed</tt> 1016 - fields are the counterparts of the fields of the same name 1017 - in the <tt>rcu_state</tt> and <tt>rcu_node</tt> structures. 1062 + <p>The <tt>-&gt;gp_seq</tt> field is the counterpart of the field of the same 1063 + name in the <tt>rcu_state</tt> and <tt>rcu_node</tt> structures. The 1064 + <tt>-&gt;gp_seq_needed</tt> field is the counterpart of the field of the same 1065 + name in the rcu_node</tt> structure. 1018 1066 They may each lag up to one behind their <tt>rcu_node</tt> 1019 1067 counterparts, but in <tt>CONFIG_NO_HZ_IDLE</tt> and 1020 1068 <tt>CONFIG_NO_HZ_FULL</tt> kernels can lag ··· 1055 1103 <tt>gp_seq</tt> counter is in danger of overflow, which 1056 1104 will cause the CPU to disregard the values of its counters on 1057 1105 its next exit from idle. 1058 - Finally, the <tt>rcu_qs_ctr_snap</tt> field is used to detect 1059 - cases where a given operation has resulted in a quiescent state 1060 - for all flavors of RCU, for example, <tt>cond_resched()</tt> 1061 - when RCU has indicated a need for quiescent states. 1062 1106 1063 1107 <h5>RCU Callback Handling</h5> 1064 1108 ··· 1127 1179 count the number of times this CPU is determined to be in 1128 1180 dyntick-idle state, and is used for tracing and debugging purposes. 1129 1181 1130 - <h3><a name="The rcu_dynticks Structure"> 1131 - The <tt>rcu_dynticks</tt> Structure</a></h3> 1132 - 1133 - <p>The <tt>rcu_dynticks</tt> maintains the per-CPU dyntick-idle state 1134 - for the corresponding CPU. 1135 - Unlike the other structures, <tt>rcu_dynticks</tt> is not 1136 - replicated over the different flavors of RCU. 1137 - The fields in this structure may be accessed only from the corresponding 1138 - CPU (and from tracing) unless otherwise stated. 1139 - Its fields are as follows: 1182 + <p> 1183 + This portion of the rcu_data structure is declared as follows: 1140 1184 1141 1185 <pre> 1142 1186 1 long dynticks_nesting; 1143 1187 2 long dynticks_nmi_nesting; 1144 1188 3 atomic_t dynticks; 1145 1189 4 bool rcu_need_heavy_qs; 1146 - 5 unsigned long rcu_qs_ctr; 1147 - 6 bool rcu_urgent_qs; 1190 + 5 bool rcu_urgent_qs; 1148 1191 </pre> 1192 + 1193 + <p>These fields in the rcu_data structure maintain the per-CPU dyntick-idle 1194 + state for the corresponding CPU. 1195 + The fields may be accessed only from the corresponding CPU (and from tracing) 1196 + unless otherwise stated. 1149 1197 1150 1198 <p>The <tt>-&gt;dynticks_nesting</tt> field counts the 1151 1199 nesting depth of process execution, so that in normal circumstances ··· 1184 1240 This flag is checked by RCU's context-switch and <tt>cond_resched()</tt> 1185 1241 code, which provide a momentary idle sojourn in response. 1186 1242 1187 - </p><p>The <tt>-&gt;rcu_qs_ctr</tt> field is used to record 1188 - quiescent states from <tt>cond_resched()</tt>. 1189 - Because <tt>cond_resched()</tt> can execute quite frequently, this 1190 - must be quite lightweight, as in a non-atomic increment of this 1191 - per-CPU field. 1192 - 1193 1243 </p><p>Finally, the <tt>-&gt;rcu_urgent_qs</tt> field is used to record 1194 - the fact that the RCU core code would really like to see a quiescent 1195 - state from the corresponding CPU, with the various other fields indicating 1196 - just how badly RCU wants this quiescent state. 1197 - This flag is checked by RCU's context-switch and <tt>cond_resched()</tt> 1198 - code, which, if nothing else, non-atomically increment <tt>-&gt;rcu_qs_ctr</tt> 1199 - in response. 1244 + the fact that the RCU core code would really like to see a quiescent state from 1245 + the corresponding CPU, with the various other fields indicating just how badly 1246 + RCU wants this quiescent state. 1247 + This flag is checked by RCU's context-switch path 1248 + (<tt>rcu_note_context_switch</tt>) and the cond_resched code. 1200 1249 1201 1250 <table> 1202 1251 <tr><th>&nbsp;</th></tr> ··· 1362 1425 <h3><a name="Summary"> 1363 1426 Summary</a></h3> 1364 1427 1365 - So each flavor of RCU is represented by an <tt>rcu_state</tt> structure, 1428 + So the state of RCU is represented by an <tt>rcu_state</tt> structure, 1366 1429 which contains a combining tree of <tt>rcu_node</tt> and 1367 1430 <tt>rcu_data</tt> structures. 1368 1431 Finally, in <tt>CONFIG_NO_HZ_IDLE</tt> kernels, each CPU's dyntick-idle 1369 - state is tracked by an <tt>rcu_dynticks</tt> structure. 1432 + state is tracked by dynticks-related fields in the <tt>rcu_data</tt> structure. 1370 1433 1371 1434 If you made it this far, you are well prepared to read the code 1372 1435 walkthroughs in the other articles in this series.
+322 -534
Documentation/RCU/Design/Data-Structures/blkd_task.svg
··· 14 14 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 15 15 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 16 16 width="10.1in" 17 - height="8.6in" 18 - viewBox="-44 -44 12088 10288" 17 + height="6.5999999in" 18 + viewBox="-44 -44 12088 7895.4414" 19 19 id="svg2" 20 20 version="1.1" 21 - inkscape:version="0.48.4 r9939" 22 - sodipodi:docname="blkd_task.fig"> 21 + inkscape:version="0.92.2pre0 (973e216, 2017-07-25)" 22 + sodipodi:docname="blkd_task.svg"> 23 23 <metadata 24 24 id="metadata212"> 25 25 <rdf:RDF> ··· 37 37 <marker 38 38 inkscape:stockid="Arrow1Mend" 39 39 orient="auto" 40 - refY="0.0" 41 - refX="0.0" 40 + refY="0" 41 + refX="0" 42 42 id="Arrow1Mend" 43 - style="overflow:visible;"> 43 + style="overflow:visible"> 44 44 <path 45 45 id="path3970" 46 - 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 " 47 - style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;" 48 - transform="scale(0.4) rotate(180) translate(10,0)" /> 46 + d="M 0,0 5,-5 -12.5,0 5,5 Z" 47 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt" 48 + transform="matrix(-0.4,0,0,-0.4,-4,0)" 49 + inkscape:connector-curvature="0" /> 49 50 </marker> 50 51 </defs> 51 52 <sodipodi:namedview ··· 58 57 guidetolerance="10" 59 58 inkscape:pageopacity="0" 60 59 inkscape:pageshadow="2" 61 - inkscape:window-width="1087" 62 - inkscape:window-height="1144" 60 + inkscape:window-width="1920" 61 + inkscape:window-height="1019" 63 62 id="namedview208" 64 63 showgrid="false" 65 64 inkscape:zoom="1.0495049" 66 - inkscape:cx="454.50003" 67 - inkscape:cy="387.00003" 68 - inkscape:window-x="833" 69 - inkscape:window-y="28" 70 - inkscape:window-maximized="0" 71 - inkscape:current-layer="g4" /> 65 + inkscape:cx="456.40569" 66 + inkscape:cy="348.88682" 67 + inkscape:window-x="0" 68 + inkscape:window-y="0" 69 + inkscape:window-maximized="1" 70 + inkscape:current-layer="g4" 71 + showguides="false" /> 72 72 <g 73 - style="stroke-width:.025in; fill:none" 74 - id="g4"> 73 + style="fill:none;stroke-width:0.025in" 74 + id="g4" 75 + transform="translate(0,-2393.6637)"> 75 76 <!-- Line: box --> 76 - <rect 77 - x="450" 78 - y="0" 79 - width="6300" 80 - height="7350" 81 - rx="0" 82 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffffff; " 83 - id="rect6" /> 84 77 <!-- Line: box --> 85 - <rect 86 - x="4950" 87 - y="4950" 88 - width="1500" 89 - height="900" 90 - rx="0" 91 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 92 - id="rect8" /> 93 78 <!-- Line: box --> 94 - <rect 95 - x="750" 96 - y="600" 97 - width="5700" 98 - height="3750" 99 - rx="0" 100 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffff00; " 101 - id="rect10" /> 102 79 <!-- Line --> 103 - <polyline 104 - points="5250,8100 5688,5912 " 105 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 106 - id="polyline12" /> 107 80 <!-- Arrowhead on XXXpoint 5250 8100 - 5710 5790--> 108 81 <polyline 109 82 points="5714 6068 5704 5822 5598 6044 " 110 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 111 - id="polyline14" /> 83 + style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8" 84 + id="polyline14" 85 + transform="translate(23.757862,2185.7233)" /> 112 86 <!-- Line --> 113 - <polyline 114 - points="4050,9300 4486,7262 " 115 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 116 - id="polyline16" /> 117 87 <!-- Arrowhead on XXXpoint 4050 9300 - 4512 7140--> 118 88 <polyline 119 89 points="4514 7418 4506 7172 4396 7394 " 120 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 121 - id="polyline18" /> 90 + style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8" 91 + id="polyline18" 92 + transform="translate(23.757862,2185.7233)" /> 122 93 <!-- Line --> 123 - <polyline 124 - points="1040,9300 1476,7262 " 125 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 126 - id="polyline20" /> 127 94 <!-- Arrowhead on XXXpoint 1040 9300 - 1502 7140--> 128 95 <polyline 129 96 points="1504 7418 1496 7172 1386 7394 " 130 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 131 - id="polyline22" /> 97 + style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8" 98 + id="polyline22" 99 + transform="translate(23.757862,2185.7233)" /> 132 100 <!-- Line --> 133 - <polyline 134 - points="2240,8100 2676,6062 " 135 - style="stroke:#00ff00;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 136 - id="polyline24" /> 137 101 <!-- Arrowhead on XXXpoint 2240 8100 - 2702 5940--> 138 102 <polyline 139 103 points="2704 6218 2696 5972 2586 6194 " 140 - style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8; " 141 - id="polyline26" /> 104 + style="stroke:#00ff00;stroke-width:14;stroke-miterlimit:8" 105 + id="polyline26" 106 + transform="translate(23.757862,2185.7233)" /> 142 107 <!-- Line: box --> 143 108 <rect 144 - x="0" 145 - y="450" 109 + x="23.757858" 110 + y="2635.7231" 146 111 width="6300" 147 112 height="7350" 148 113 rx="0" 149 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffffff; " 114 + style="fill:#ffffff;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter" 150 115 id="rect28" /> 151 116 <!-- Line: box --> 152 117 <rect 153 - x="300" 154 - y="1050" 118 + x="323.75787" 119 + y="3235.7231" 155 120 width="5700" 156 121 height="3750" 157 122 rx="0" 158 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffff00; " 123 + style="fill:#ffff00;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter" 159 124 id="rect30" /> 160 125 <!-- Line --> 161 126 <polyline 162 127 points="1350,3450 2350,2590 " 163 - style="stroke:#00d1d1;stroke-width:30.00057884;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 164 - id="polyline32" /> 128 + style="stroke:#00d1d1;stroke-width:30.00057793;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 129 + id="polyline32" 130 + transform="translate(23.757862,2185.7233)" /> 165 131 <!-- Arrowhead on XXXpoint 1350 3450 - 2444 2510--> 166 132 <!-- Line --> 167 133 <polyline 168 134 points="4950,3450 3948,2590 " 169 - style="stroke:#00d1d1;stroke-width:30.00057884;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 170 - id="polyline36" /> 135 + style="stroke:#00d1d1;stroke-width:30.00057793;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 136 + id="polyline36" 137 + transform="translate(23.757862,2185.7233)" /> 171 138 <!-- Arrowhead on XXXpoint 4950 3450 - 3854 2510--> 172 139 <!-- Line --> 173 140 <polyline 174 141 points="4050,6600 4050,4414 " 175 - style="stroke:#00d1d1;stroke-width:30.00057884;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 176 - id="polyline40" /> 142 + style="stroke:#00d1d1;stroke-width:30.00057793;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 143 + id="polyline40" 144 + transform="translate(23.757862,2185.7233)" /> 177 145 <!-- Arrowhead on XXXpoint 4050 6600 - 4050 4290--> 178 146 <!-- Line --> 179 147 <polyline 180 148 points="1050,6600 1050,4414 " 181 - style="stroke:#00d1d1;stroke-width:30.00057884;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 182 - id="polyline44" /> 149 + style="stroke:#00d1d1;stroke-width:30.00057793;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 150 + id="polyline44" 151 + transform="translate(23.757862,2185.7233)" /> 183 152 <!-- Arrowhead on XXXpoint 1050 6600 - 1050 4290--> 184 153 <!-- Line --> 185 154 <polyline 186 155 points="2250,5400 2250,4414 " 187 - style="stroke:#00d1d1;stroke-width:30.00057884;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 188 - id="polyline48" /> 156 + style="stroke:#00d1d1;stroke-width:30.00057793;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 157 + id="polyline48" 158 + transform="translate(23.757862,2185.7233)" /> 189 159 <!-- Arrowhead on XXXpoint 2250 5400 - 2250 4290--> 190 160 <!-- Line --> 191 - <polyline 192 - points="2250,8100 2250,6364 " 193 - style="stroke:#00ff00;stroke-width:30.00057884;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 194 - id="polyline52" /> 195 161 <!-- Arrowhead on XXXpoint 2250 8100 - 2250 6240--> 196 162 <!-- Line --> 197 - <polyline 198 - points="1050,9300 1050,7564 " 199 - style="stroke:#00ff00;stroke-width:30.00057884;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 200 - id="polyline56" /> 201 163 <!-- Arrowhead on XXXpoint 1050 9300 - 1050 7440--> 202 164 <!-- Line --> 203 - <polyline 204 - points="4050,9300 4050,7564 " 205 - style="stroke:#00ff00;stroke-width:30.00057884;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 206 - id="polyline60" /> 207 165 <!-- Arrowhead on XXXpoint 4050 9300 - 4050 7440--> 208 166 <!-- Line --> 209 - <polyline 210 - points="5250,8100 5250,6364 " 211 - style="stroke:#00ff00;stroke-width:30.00057884;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 212 - id="polyline64" /> 213 167 <!-- Arrowhead on XXXpoint 5250 8100 - 5250 6240--> 214 168 <!-- Circle --> 215 169 <circle 216 - cx="2850" 217 - cy="3900" 170 + cx="2873.7581" 171 + cy="6085.7236" 218 172 r="76" 219 - style="fill:#000000;stroke:#000000;stroke-width:14;" 173 + style="fill:#000000;stroke:#000000;stroke-width:14" 220 174 id="circle68" /> 221 175 <!-- Circle --> 222 176 <circle 223 - cx="3150" 224 - cy="3900" 177 + cx="3173.7581" 178 + cy="6085.7236" 225 179 r="76" 226 - style="fill:#000000;stroke:#000000;stroke-width:14;" 180 + style="fill:#000000;stroke:#000000;stroke-width:14" 227 181 id="circle70" /> 228 182 <!-- Circle --> 229 183 <circle 230 - cx="3450" 231 - cy="3900" 184 + cx="3473.7581" 185 + cy="6085.7236" 232 186 r="76" 233 - style="fill:#000000;stroke:#000000;stroke-width:14;" 187 + style="fill:#000000;stroke:#000000;stroke-width:14" 234 188 id="circle72" /> 235 189 <!-- Circle --> 236 190 <circle 237 - cx="1350" 238 - cy="5100" 191 + cx="1373.7578" 192 + cy="7285.7236" 239 193 r="76" 240 - style="fill:#000000;stroke:#000000;stroke-width:14;" 194 + style="fill:#000000;stroke:#000000;stroke-width:14" 241 195 id="circle74" /> 242 196 <!-- Circle --> 243 197 <circle 244 - cx="1650" 245 - cy="5100" 198 + cx="1673.7578" 199 + cy="7285.7236" 246 200 r="76" 247 - style="fill:#000000;stroke:#000000;stroke-width:14;" 201 + style="fill:#000000;stroke:#000000;stroke-width:14" 248 202 id="circle76" /> 249 203 <!-- Circle --> 250 204 <circle 251 - cx="1950" 252 - cy="5100" 205 + cx="1973.7578" 206 + cy="7285.7236" 253 207 r="76" 254 - style="fill:#000000;stroke:#000000;stroke-width:14;" 208 + style="fill:#000000;stroke:#000000;stroke-width:14" 255 209 id="circle78" /> 256 210 <!-- Circle --> 257 211 <circle 258 - cx="4350" 259 - cy="5100" 212 + cx="4373.7578" 213 + cy="7285.7236" 260 214 r="76" 261 - style="fill:#000000;stroke:#000000;stroke-width:14;" 215 + style="fill:#000000;stroke:#000000;stroke-width:14" 262 216 id="circle80" /> 263 217 <!-- Circle --> 264 218 <circle 265 - cx="4650" 266 - cy="5100" 219 + cx="4673.7578" 220 + cy="7285.7236" 267 221 r="76" 268 - style="fill:#000000;stroke:#000000;stroke-width:14;" 222 + style="fill:#000000;stroke:#000000;stroke-width:14" 269 223 id="circle82" /> 270 224 <!-- Circle --> 271 225 <circle 272 - cx="4950" 273 - cy="5100" 226 + cx="4973.7578" 227 + cy="7285.7236" 274 228 r="76" 275 - style="fill:#000000;stroke:#000000;stroke-width:14;" 229 + style="fill:#000000;stroke:#000000;stroke-width:14" 276 230 id="circle84" /> 277 231 <!-- Line: box --> 278 232 <rect 279 - x="750" 280 - y="3450" 233 + x="773.75781" 234 + y="5635.7236" 281 235 width="1800" 282 236 height="900" 283 237 rx="0" 284 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 238 + style="fill:#ffbfbf;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter" 285 239 id="rect86" /> 286 240 <!-- Line: box --> 287 241 <rect 288 - x="300" 289 - y="6600" 242 + x="323.75787" 243 + y="8785.7227" 290 244 width="1500" 291 245 height="900" 292 246 rx="0" 293 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 247 + style="fill:#87cfff;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter" 294 248 id="rect88" /> 295 249 <!-- Line: box --> 296 250 <rect 297 - x="4500" 298 - y="5400" 251 + x="4523.7578" 252 + y="7585.7236" 299 253 width="1500" 300 254 height="900" 301 255 rx="0" 302 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 256 + style="fill:#87cfff;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter" 303 257 id="rect90" /> 304 258 <!-- Line: box --> 305 259 <rect 306 - x="3300" 307 - y="6600" 260 + x="3323.7581" 261 + y="8785.7227" 308 262 width="1500" 309 263 height="900" 310 264 rx="0" 311 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 265 + style="fill:#87cfff;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter" 312 266 id="rect92" /> 313 267 <!-- Line: box --> 314 268 <rect 315 - x="2250" 316 - y="1650" 269 + x="2273.7581" 270 + y="3835.7231" 317 271 width="1800" 318 272 height="900" 319 273 rx="0" 320 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 274 + style="fill:#ffbfbf;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter" 321 275 id="rect94" /> 322 276 <!-- Line: box --> 323 - <rect 324 - x="0" 325 - y="9300" 326 - width="2100" 327 - height="900" 328 - rx="0" 329 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#00ff00; " 330 - id="rect96" /> 277 + <!-- Line: box --> 278 + <!-- Line: box --> 279 + <!-- Line: box --> 331 280 <!-- Line: box --> 332 281 <rect 333 - x="1350" 334 - y="8100" 335 - width="2100" 336 - height="900" 337 - rx="0" 338 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#00ff00; " 339 - id="rect98" /> 340 - <!-- Line: box --> 341 - <rect 342 - x="3000" 343 - y="9300" 344 - width="2100" 345 - height="900" 346 - rx="0" 347 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#00ff00; " 348 - id="rect100" /> 349 - <!-- Line: box --> 350 - <rect 351 - x="4350" 352 - y="8100" 353 - width="2100" 354 - height="900" 355 - rx="0" 356 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#00ff00; " 357 - id="rect102" /> 358 - <!-- Line: box --> 359 - <rect 360 - x="1500" 361 - y="5400" 282 + x="1523.7578" 283 + y="7585.7236" 362 284 width="1500" 363 285 height="900" 364 286 rx="0" 365 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#87cfff; " 287 + style="fill:#87cfff;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter" 366 288 id="rect104" /> 367 289 <!-- Line --> 368 290 <polygon 369 - points="5550,3450 7350,2850 7350,5100 5550,4350 5550,3450 " 370 - style="stroke:#000000;stroke-width:14; stroke-linejoin:miter; stroke-linecap:butt; stroke-dasharray:120 120;fill:#ffbfbf; " 371 - id="polygon106" /> 291 + points="7350,2850 7350,5100 5550,4350 5550,3450 " 292 + style="fill:#ffbfbf;stroke:#000000;stroke-width:14;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:120, 120" 293 + id="polygon106" 294 + transform="translate(23.757862,2185.7233)" /> 372 295 <!-- Line --> 373 296 <polyline 374 297 points="9300,3150 10734,3150 " 375 - style="stroke:#000000;stroke-width:30.00057884;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 376 - id="polyline108" /> 298 + style="stroke:#000000;stroke-width:30.00057793;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 299 + id="polyline108" 300 + transform="translate(23.757862,2185.7233)" /> 377 301 <!-- Arrowhead on XXXpoint 9300 3150 - 10860 3150--> 378 302 <!-- Line: box --> 379 303 <rect 380 - x="10800" 381 - y="2850" 304 + x="10823.758" 305 + y="5035.7236" 382 306 width="1200" 383 307 height="750" 384 308 rx="0" 385 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 309 + style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter" 386 310 id="rect112" /> 387 311 <!-- Line --> 388 312 <polyline 389 313 points="11400,3600 11400,4284 " 390 - style="stroke:#000000;stroke-width:30.00057884;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 391 - id="polyline114" /> 314 + style="stroke:#000000;stroke-width:30.00057793;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 315 + id="polyline114" 316 + transform="translate(23.757862,2185.7233)" /> 392 317 <!-- Arrowhead on XXXpoint 11400 3600 - 11400 4410--> 393 318 <!-- Line: box --> 394 319 <rect 395 - x="10800" 396 - y="4350" 320 + x="10823.758" 321 + y="6535.7236" 397 322 width="1200" 398 323 height="750" 399 324 rx="0" 400 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 325 + style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter" 401 326 id="rect118" /> 402 327 <!-- Line --> 403 328 <polyline 404 329 points="11400,5100 11400,5784 " 405 - style="stroke:#000000;stroke-width:30.00057884;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 406 - id="polyline120" /> 330 + style="stroke:#000000;stroke-width:30.00057793;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 331 + id="polyline120" 332 + transform="translate(23.757862,2185.7233)" /> 407 333 <!-- Arrowhead on XXXpoint 11400 5100 - 11400 5910--> 408 334 <!-- Line: box --> 409 335 <rect 410 - x="10800" 411 - y="5850" 336 + x="10823.758" 337 + y="8035.7236" 412 338 width="1200" 413 339 height="750" 414 340 rx="0" 415 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; " 341 + style="stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter" 416 342 id="rect124" /> 417 343 <!-- Line --> 418 344 <polyline 419 345 points="9300,3900 9900,3900 9900,4650 10734,4650 " 420 - style="stroke:#000000;stroke-width:30.00057884;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 421 - id="polyline126" /> 346 + style="stroke:#000000;stroke-width:30.00057793;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 347 + id="polyline126" 348 + transform="translate(23.757862,2185.7233)" /> 422 349 <!-- Arrowhead on XXXpoint 9900 4650 - 10860 4650--> 423 350 <!-- Line --> 424 351 <polyline 425 352 points="9300,4650 9600,4650 9600,6150 10734,6150 " 426 - style="stroke:#000000;stroke-width:30.00057884;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 427 - id="polyline130" /> 353 + style="stroke:#000000;stroke-width:30.00057793;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 354 + id="polyline130" 355 + transform="translate(23.757862,2185.7233)" /> 428 356 <!-- Arrowhead on XXXpoint 9600 6150 - 10860 6150--> 429 357 <!-- Text --> 358 + <!-- Text --> 430 359 <text 431 360 xml:space="preserve" 432 - x="6450" 433 - y="300" 434 - fill="#000000" 435 - font-family="Helvetica" 361 + x="3173.7581" 362 + y="4135.7231" 363 + font-style="normal" 364 + font-weight="bold" 365 + font-size="192" 366 + id="text136" 367 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:middle;fill:#000000">struct</text> 368 + <!-- Text --> 369 + <text 370 + xml:space="preserve" 371 + x="3173.7581" 372 + y="4435.7236" 373 + font-style="normal" 374 + font-weight="bold" 375 + font-size="192" 376 + id="text138" 377 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:middle;fill:#000000">rcu_node</text> 378 + <!-- Text --> 379 + <text 380 + xml:space="preserve" 381 + x="1673.7578" 382 + y="5935.7236" 383 + font-style="normal" 384 + font-weight="bold" 385 + font-size="192" 386 + id="text140" 387 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:middle;fill:#000000">struct</text> 388 + <!-- Text --> 389 + <text 390 + xml:space="preserve" 391 + x="1673.7578" 392 + y="6235.7236" 393 + font-style="normal" 394 + font-weight="bold" 395 + font-size="192" 396 + id="text142" 397 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:middle;fill:#000000">rcu_node</text> 398 + <!-- Text --> 399 + <text 400 + xml:space="preserve" 401 + x="2273.7581" 402 + y="7885.7236" 403 + font-style="normal" 404 + font-weight="bold" 405 + font-size="192" 406 + id="text144" 407 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:middle;fill:#000000">struct</text> 408 + <!-- Text --> 409 + <text 410 + xml:space="preserve" 411 + x="2273.7581" 412 + y="8185.7236" 413 + font-style="normal" 414 + font-weight="bold" 415 + font-size="192" 416 + id="text146" 417 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:middle;fill:#000000">rcu_data</text> 418 + <!-- Text --> 419 + <text 420 + xml:space="preserve" 421 + x="1073.7578" 422 + y="9085.7227" 423 + font-style="normal" 424 + font-weight="bold" 425 + font-size="192" 426 + id="text148" 427 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:middle;fill:#000000">struct</text> 428 + <!-- Text --> 429 + <text 430 + xml:space="preserve" 431 + x="1073.7578" 432 + y="9385.7227" 433 + font-style="normal" 434 + font-weight="bold" 435 + font-size="192" 436 + id="text150" 437 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:middle;fill:#000000">rcu_data</text> 438 + <!-- Text --> 439 + <text 440 + xml:space="preserve" 441 + x="5273.7578" 442 + y="7885.7236" 443 + font-style="normal" 444 + font-weight="bold" 445 + font-size="192" 446 + id="text152" 447 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:middle;fill:#000000">struct</text> 448 + <!-- Text --> 449 + <text 450 + xml:space="preserve" 451 + x="5273.7578" 452 + y="8185.7236" 453 + font-style="normal" 454 + font-weight="bold" 455 + font-size="192" 456 + id="text154" 457 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:middle;fill:#000000">rcu_data</text> 458 + <!-- Text --> 459 + <text 460 + xml:space="preserve" 461 + x="4073.7578" 462 + y="9085.7227" 463 + font-style="normal" 464 + font-weight="bold" 465 + font-size="192" 466 + id="text156" 467 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:middle;fill:#000000">struct</text> 468 + <!-- Text --> 469 + <text 470 + xml:space="preserve" 471 + x="4073.7578" 472 + y="9385.7227" 473 + font-style="normal" 474 + font-weight="bold" 475 + font-size="192" 476 + id="text158" 477 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:middle;fill:#000000">rcu_data</text> 478 + <!-- Text --> 479 + <text 480 + xml:space="preserve" 481 + x="473.75784" 482 + y="3535.7231" 483 + font-style="normal" 484 + font-weight="bold" 485 + font-size="192" 486 + id="text160" 487 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:start;fill:#000000">struct rcu_state</text> 488 + <!-- Text --> 489 + <!-- Text --> 490 + <!-- Text --> 491 + <!-- Text --> 492 + <!-- Text --> 493 + <!-- Text --> 494 + <!-- Text --> 495 + <!-- Text --> 496 + <!-- Text --> 497 + <text 498 + xml:space="preserve" 499 + x="6023.7578" 500 + y="2935.7231" 436 501 font-style="normal" 437 502 font-weight="normal" 438 503 font-size="192" 439 - text-anchor="end" 440 - id="text134">rcu_bh</text> 504 + id="text178" 505 + style="font-style:normal;font-weight:normal;font-size:192px;font-family:Helvetica;text-anchor:end;fill:#000000">rcu_state</text> 441 506 <!-- Text --> 442 507 <text 443 508 xml:space="preserve" 444 - x="3150" 445 - y="1950" 446 - fill="#000000" 447 - font-family="Courier" 448 - font-style="normal" 449 - font-weight="bold" 450 - font-size="192" 451 - text-anchor="middle" 452 - id="text136">struct</text> 453 - <!-- Text --> 454 - <text 455 - xml:space="preserve" 456 - x="3150" 457 - y="2250" 458 - fill="#000000" 459 - font-family="Courier" 460 - font-style="normal" 461 - font-weight="bold" 462 - font-size="192" 463 - text-anchor="middle" 464 - id="text138">rcu_node</text> 465 - <!-- Text --> 466 - <text 467 - xml:space="preserve" 468 - x="1650" 469 - y="3750" 470 - fill="#000000" 471 - font-family="Courier" 472 - font-style="normal" 473 - font-weight="bold" 474 - font-size="192" 475 - text-anchor="middle" 476 - id="text140">struct</text> 477 - <!-- Text --> 478 - <text 479 - xml:space="preserve" 480 - x="1650" 481 - y="4050" 482 - fill="#000000" 483 - font-family="Courier" 484 - font-style="normal" 485 - font-weight="bold" 486 - font-size="192" 487 - text-anchor="middle" 488 - id="text142">rcu_node</text> 489 - <!-- Text --> 490 - <text 491 - xml:space="preserve" 492 - x="2250" 493 - y="5700" 494 - fill="#000000" 495 - font-family="Courier" 496 - font-style="normal" 497 - font-weight="bold" 498 - font-size="192" 499 - text-anchor="middle" 500 - id="text144">struct</text> 501 - <!-- Text --> 502 - <text 503 - xml:space="preserve" 504 - x="2250" 505 - y="6000" 506 - fill="#000000" 507 - font-family="Courier" 508 - font-style="normal" 509 - font-weight="bold" 510 - font-size="192" 511 - text-anchor="middle" 512 - id="text146">rcu_data</text> 513 - <!-- Text --> 514 - <text 515 - xml:space="preserve" 516 - x="1050" 517 - y="6900" 518 - fill="#000000" 519 - font-family="Courier" 520 - font-style="normal" 521 - font-weight="bold" 522 - font-size="192" 523 - text-anchor="middle" 524 - id="text148">struct</text> 525 - <!-- Text --> 526 - <text 527 - xml:space="preserve" 528 - x="1050" 529 - y="7200" 530 - fill="#000000" 531 - font-family="Courier" 532 - font-style="normal" 533 - font-weight="bold" 534 - font-size="192" 535 - text-anchor="middle" 536 - id="text150">rcu_data</text> 537 - <!-- Text --> 538 - <text 539 - xml:space="preserve" 540 - x="5250" 541 - y="5700" 542 - fill="#000000" 543 - font-family="Courier" 544 - font-style="normal" 545 - font-weight="bold" 546 - font-size="192" 547 - text-anchor="middle" 548 - id="text152">struct</text> 549 - <!-- Text --> 550 - <text 551 - xml:space="preserve" 552 - x="5250" 553 - y="6000" 554 - fill="#000000" 555 - font-family="Courier" 556 - font-style="normal" 557 - font-weight="bold" 558 - font-size="192" 559 - text-anchor="middle" 560 - id="text154">rcu_data</text> 561 - <!-- Text --> 562 - <text 563 - xml:space="preserve" 564 - x="4050" 565 - y="6900" 566 - fill="#000000" 567 - font-family="Courier" 568 - font-style="normal" 569 - font-weight="bold" 570 - font-size="192" 571 - text-anchor="middle" 572 - id="text156">struct</text> 573 - <!-- Text --> 574 - <text 575 - xml:space="preserve" 576 - x="4050" 577 - y="7200" 578 - fill="#000000" 579 - font-family="Courier" 580 - font-style="normal" 581 - font-weight="bold" 582 - font-size="192" 583 - text-anchor="middle" 584 - id="text158">rcu_data</text> 585 - <!-- Text --> 586 - <text 587 - xml:space="preserve" 588 - x="450" 589 - y="1350" 590 - fill="#000000" 591 - font-family="Courier" 592 - font-style="normal" 593 - font-weight="bold" 594 - font-size="192" 595 - text-anchor="start" 596 - id="text160">struct rcu_state</text> 597 - <!-- Text --> 598 - <text 599 - xml:space="preserve" 600 - x="1050" 601 - y="9600" 602 - fill="#000000" 603 - font-family="Courier" 604 - font-style="normal" 605 - font-weight="bold" 606 - font-size="192" 607 - text-anchor="middle" 608 - id="text162">struct</text> 609 - <!-- Text --> 610 - <text 611 - xml:space="preserve" 612 - x="1050" 613 - y="9900" 614 - fill="#000000" 615 - font-family="Courier" 616 - font-style="normal" 617 - font-weight="bold" 618 - font-size="192" 619 - text-anchor="middle" 620 - id="text164">rcu_dynticks</text> 621 - <!-- Text --> 622 - <text 623 - xml:space="preserve" 624 - x="4050" 625 - y="9600" 626 - fill="#000000" 627 - font-family="Courier" 628 - font-style="normal" 629 - font-weight="bold" 630 - font-size="192" 631 - text-anchor="middle" 632 - id="text166">struct</text> 633 - <!-- Text --> 634 - <text 635 - xml:space="preserve" 636 - x="4050" 637 - y="9900" 638 - fill="#000000" 639 - font-family="Courier" 640 - font-style="normal" 641 - font-weight="bold" 642 - font-size="192" 643 - text-anchor="middle" 644 - id="text168">rcu_dynticks</text> 645 - <!-- Text --> 646 - <text 647 - xml:space="preserve" 648 - x="2400" 649 - y="8400" 650 - fill="#000000" 651 - font-family="Courier" 652 - font-style="normal" 653 - font-weight="bold" 654 - font-size="192" 655 - text-anchor="middle" 656 - id="text170">struct</text> 657 - <!-- Text --> 658 - <text 659 - xml:space="preserve" 660 - x="2400" 661 - y="8700" 662 - fill="#000000" 663 - font-family="Courier" 664 - font-style="normal" 665 - font-weight="bold" 666 - font-size="192" 667 - text-anchor="middle" 668 - id="text172">rcu_dynticks</text> 669 - <!-- Text --> 670 - <text 671 - xml:space="preserve" 672 - x="5400" 673 - y="8400" 674 - fill="#000000" 675 - font-family="Courier" 676 - font-style="normal" 677 - font-weight="bold" 678 - font-size="192" 679 - text-anchor="middle" 680 - id="text174">struct</text> 681 - <!-- Text --> 682 - <text 683 - xml:space="preserve" 684 - x="5400" 685 - y="8700" 686 - fill="#000000" 687 - font-family="Courier" 688 - font-style="normal" 689 - font-weight="bold" 690 - font-size="192" 691 - text-anchor="middle" 692 - id="text176">rcu_dynticks</text> 693 - <!-- Text --> 694 - <text 695 - xml:space="preserve" 696 - x="6000" 697 - y="750" 698 - fill="#000000" 699 - font-family="Helvetica" 700 - font-style="normal" 701 - font-weight="normal" 702 - font-size="192" 703 - text-anchor="end" 704 - id="text178">rcu_sched</text> 705 - <!-- Text --> 706 - <text 707 - xml:space="preserve" 708 - x="11400" 709 - y="3300" 710 - fill="#000000" 711 - font-family="Helvetica" 509 + x="11423.758" 510 + y="5485.7236" 712 511 font-style="normal" 713 512 font-weight="normal" 714 513 font-size="216" 715 - text-anchor="middle" 716 - id="text180">T3</text> 514 + id="text180" 515 + style="font-style:normal;font-weight:normal;font-size:216px;font-family:Helvetica;text-anchor:middle;fill:#000000">T3</text> 717 516 <!-- Text --> 718 517 <text 719 518 xml:space="preserve" 720 - x="11400" 721 - y="4800" 722 - fill="#000000" 723 - font-family="Helvetica" 519 + x="11423.758" 520 + y="6985.7236" 724 521 font-style="normal" 725 522 font-weight="normal" 726 523 font-size="216" 727 - text-anchor="middle" 728 - id="text182">T2</text> 524 + id="text182" 525 + style="font-style:normal;font-weight:normal;font-size:216px;font-family:Helvetica;text-anchor:middle;fill:#000000">T2</text> 729 526 <!-- Text --> 730 527 <text 731 528 xml:space="preserve" 732 - x="11400" 733 - y="6300" 734 - fill="#000000" 735 - font-family="Helvetica" 529 + x="11423.758" 530 + y="8485.7227" 736 531 font-style="normal" 737 532 font-weight="normal" 738 533 font-size="216" 739 - text-anchor="middle" 740 - id="text184">T1</text> 534 + id="text184" 535 + style="font-style:normal;font-weight:normal;font-size:216px;font-family:Helvetica;text-anchor:middle;fill:#000000">T1</text> 741 536 <!-- Line --> 742 537 <polyline 743 538 points="5250,5400 5250,4414 " 744 - style="stroke:#00d1d1;stroke-width:30.00057884;stroke-linejoin:miter;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 745 - id="polyline186" /> 539 + style="stroke:#00d1d1;stroke-width:30.00057793;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow1Mend)" 540 + id="polyline186" 541 + transform="translate(23.757862,2185.7233)" /> 746 542 <!-- Arrowhead on XXXpoint 5250 5400 - 5250 4290--> 747 543 <!-- Line: box --> 748 544 <rect 749 - x="3750" 750 - y="3450" 545 + x="3773.7581" 546 + y="5635.7236" 751 547 width="1800" 752 548 height="900" 753 549 rx="0" 754 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 550 + style="fill:#ffbfbf;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter" 755 551 id="rect190" /> 756 552 <!-- Line: box --> 757 553 <rect 758 - x="7350" 759 - y="2850" 554 + x="7373.7578" 555 + y="5035.7236" 760 556 width="1950" 761 557 height="750" 762 558 rx="0" 763 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 559 + style="fill:#ffbfbf;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter" 764 560 id="rect192" /> 765 561 <!-- Line: box --> 766 562 <rect 767 - x="7350" 768 - y="3600" 563 + x="7373.7578" 564 + y="5785.7236" 769 565 width="1950" 770 566 height="750" 771 567 rx="0" 772 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 568 + style="fill:#ffbfbf;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter" 773 569 id="rect194" /> 774 570 <!-- Line: box --> 775 571 <rect 776 - x="7350" 777 - y="4350" 572 + x="7373.7578" 573 + y="6535.7236" 778 574 width="1950" 779 575 height="750" 780 576 rx="0" 781 - style="stroke:#000000;stroke-width:30; stroke-linejoin:miter; stroke-linecap:butt; fill:#ffbfbf; " 577 + style="fill:#ffbfbf;stroke:#000000;stroke-width:30;stroke-linecap:butt;stroke-linejoin:miter" 782 578 id="rect196" /> 783 579 <!-- Text --> 784 580 <text 785 581 xml:space="preserve" 786 - x="4650" 787 - y="4050" 788 - fill="#000000" 789 - font-family="Courier" 582 + x="4673.7578" 583 + y="6235.7236" 790 584 font-style="normal" 791 585 font-weight="bold" 792 586 font-size="192" 793 - text-anchor="middle" 794 - id="text198">rcu_node</text> 587 + id="text198" 588 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:middle;fill:#000000">rcu_node</text> 795 589 <!-- Text --> 796 590 <text 797 591 xml:space="preserve" 798 - x="4650" 799 - y="3750" 800 - fill="#000000" 801 - font-family="Courier" 592 + x="4673.7578" 593 + y="5935.7236" 802 594 font-style="normal" 803 595 font-weight="bold" 804 596 font-size="192" 805 - text-anchor="middle" 806 - id="text200">struct</text> 597 + id="text200" 598 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:middle;fill:#000000">struct</text> 807 599 <!-- Text --> 808 600 <text 809 601 xml:space="preserve" 810 - x="7500" 811 - y="3300" 812 - fill="#000000" 813 - font-family="Courier" 602 + x="7523.7578" 603 + y="5485.7236" 814 604 font-style="normal" 815 605 font-weight="bold" 816 606 font-size="192" 817 - text-anchor="start" 818 - id="text202">blkd_tasks</text> 607 + id="text202" 608 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:start;fill:#000000">blkd_tasks</text> 819 609 <!-- Text --> 820 610 <text 821 611 xml:space="preserve" 822 - x="7500" 823 - y="4050" 824 - fill="#000000" 825 - font-family="Courier" 612 + x="7523.7578" 613 + y="6235.7236" 826 614 font-style="normal" 827 615 font-weight="bold" 828 616 font-size="192" 829 - text-anchor="start" 830 - id="text204">gp_tasks</text> 617 + id="text204" 618 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:start;fill:#000000">gp_tasks</text> 831 619 <!-- Text --> 832 620 <text 833 621 xml:space="preserve" 834 - x="7500" 835 - y="4800" 836 - fill="#000000" 837 - font-family="Courier" 622 + x="7523.7578" 623 + y="6985.7236" 838 624 font-style="normal" 839 625 font-weight="bold" 840 626 font-size="192" 841 - text-anchor="start" 842 - id="text206">exp_tasks</text> 627 + id="text206" 628 + style="font-style:normal;font-weight:bold;font-size:192px;font-family:Courier;text-anchor:start;fill:#000000">exp_tasks</text> 843 629 </g> 844 630 </svg>
+3 -3
Documentation/RCU/Design/Expedited-Grace-Periods/Expedited-Grace-Periods.html
··· 160 160 If the CPU is idle, then <tt>sync_sched_exp_handler()</tt> reports 161 161 the quiescent state. 162 162 163 - <p> 164 - Otherwise, the handler invokes <tt>resched_cpu()</tt>, which forces 165 - a future context switch. 163 + <p> Otherwise, the handler forces a future context switch by setting the 164 + NEED_RESCHED flag of the current task's thread flag and the CPU preempt 165 + counter. 166 166 At the time of the context switch, the CPU reports the quiescent state. 167 167 Should the CPU go offline first, it will report the quiescent state 168 168 at that time.
+1 -1
Documentation/RCU/Design/Memory-Ordering/Tree-RCU-Memory-Ordering.html
··· 77 77 <tt>smp_mb__after_unlock_lock()</tt> immediately after successful 78 78 acquisition of the lock. 79 79 80 - <p>Therefore, for any given <tt>rcu_node</tt> struction, any access 80 + <p>Therefore, for any given <tt>rcu_node</tt> structure, any access 81 81 happening before one of the above lock-release functions will be seen 82 82 by all CPUs as happening before any access happening after a later 83 83 one of the above lock-acquisition functions.
+138 -68
Documentation/RCU/Design/Requirements/Requirements.html
··· 900 900 Grace Periods Don't Partition Read-Side Critical Sections</a> 901 901 <li> <a href="#Read-Side Critical Sections Don't Partition Grace Periods"> 902 902 Read-Side Critical Sections Don't Partition Grace Periods</a> 903 - <li> <a href="#Disabling Preemption Does Not Block Grace Periods"> 904 - Disabling Preemption Does Not Block Grace Periods</a> 905 903 </ol> 906 904 907 905 <h3><a name="Readers Impose Minimal Ordering">Readers Impose Minimal Ordering</a></h3> ··· 1257 1259 <tr><td>&nbsp;</td></tr> 1258 1260 </table> 1259 1261 1260 - <h3><a name="Disabling Preemption Does Not Block Grace Periods"> 1261 - Disabling Preemption Does Not Block Grace Periods</a></h3> 1262 - 1263 - <p> 1264 - There was a time when disabling preemption on any given CPU would block 1265 - subsequent grace periods. 1266 - However, this was an accident of implementation and is not a requirement. 1267 - And in the current Linux-kernel implementation, disabling preemption 1268 - on a given CPU in fact does not block grace periods, as Oleg Nesterov 1269 - <a href="https://lkml.kernel.org/g/20150614193825.GA19582@redhat.com">demonstrated</a>. 1270 - 1271 - <p> 1272 - If you need a preempt-disable region to block grace periods, you need to add 1273 - <tt>rcu_read_lock()</tt> and <tt>rcu_read_unlock()</tt>, for example 1274 - as follows: 1275 - 1276 - <blockquote> 1277 - <pre> 1278 - 1 preempt_disable(); 1279 - 2 rcu_read_lock(); 1280 - 3 do_something(); 1281 - 4 rcu_read_unlock(); 1282 - 5 preempt_enable(); 1283 - 6 1284 - 7 /* Spinlocks implicitly disable preemption. */ 1285 - 8 spin_lock(&amp;mylock); 1286 - 9 rcu_read_lock(); 1287 - 10 do_something(); 1288 - 11 rcu_read_unlock(); 1289 - 12 spin_unlock(&amp;mylock); 1290 - </pre> 1291 - </blockquote> 1292 - 1293 - <p> 1294 - In theory, you could enter the RCU read-side critical section first, 1295 - but it is more efficient to keep the entire RCU read-side critical 1296 - section contained in the preempt-disable region as shown above. 1297 - Of course, RCU read-side critical sections that extend outside of 1298 - preempt-disable regions will work correctly, but such critical sections 1299 - can be preempted, which forces <tt>rcu_read_unlock()</tt> to do 1300 - more work. 1301 - And no, this is <i>not</i> an invitation to enclose all of your RCU 1302 - read-side critical sections within preempt-disable regions, because 1303 - doing so would degrade real-time response. 1304 - 1305 - <p> 1306 - This non-requirement appeared with preemptible RCU. 1307 - 1308 1262 <h2><a name="Parallelism Facts of Life">Parallelism Facts of Life</a></h2> 1309 1263 1310 1264 <p> ··· 1331 1381 <ol> 1332 1382 <li> <a href="#Specialization">Specialization</a> 1333 1383 <li> <a href="#Performance and Scalability">Performance and Scalability</a> 1384 + <li> <a href="#Forward Progress">Forward Progress</a> 1334 1385 <li> <a href="#Composability">Composability</a> 1335 1386 <li> <a href="#Corner Cases">Corner Cases</a> 1336 1387 </ol> ··· 1596 1645 16 struct foo *p; 1597 1646 17 1598 1647 18 spin_lock(&amp;gp_lock); 1599 - 19 p = rcu_dereference(gp); 1648 + 19 p = rcu_access_pointer(gp); 1600 1649 20 if (!p) { 1601 1650 21 spin_unlock(&amp;gp_lock); 1602 1651 22 return false; ··· 1772 1821 <p> 1773 1822 RCU thus provides a range of tools to allow updaters to strike the 1774 1823 required tradeoff between latency, flexibility and CPU overhead. 1824 + 1825 + <h3><a name="Forward Progress">Forward Progress</a></h3> 1826 + 1827 + <p> 1828 + In theory, delaying grace-period completion and callback invocation 1829 + is harmless. 1830 + In practice, not only are memory sizes finite but also callbacks sometimes 1831 + do wakeups, and sufficiently deferred wakeups can be difficult 1832 + to distinguish from system hangs. 1833 + Therefore, RCU must provide a number of mechanisms to promote forward 1834 + progress. 1835 + 1836 + <p> 1837 + These mechanisms are not foolproof, nor can they be. 1838 + For one simple example, an infinite loop in an RCU read-side critical 1839 + section must by definition prevent later grace periods from ever completing. 1840 + For a more involved example, consider a 64-CPU system built with 1841 + <tt>CONFIG_RCU_NOCB_CPU=y</tt> and booted with <tt>rcu_nocbs=1-63</tt>, 1842 + where CPUs&nbsp;1 through&nbsp;63 spin in tight loops that invoke 1843 + <tt>call_rcu()</tt>. 1844 + Even if these tight loops also contain calls to <tt>cond_resched()</tt> 1845 + (thus allowing grace periods to complete), CPU&nbsp;0 simply will 1846 + not be able to invoke callbacks as fast as the other 63 CPUs can 1847 + register them, at least not until the system runs out of memory. 1848 + In both of these examples, the Spiderman principle applies: With great 1849 + power comes great responsibility. 1850 + However, short of this level of abuse, RCU is required to 1851 + ensure timely completion of grace periods and timely invocation of 1852 + callbacks. 1853 + 1854 + <p> 1855 + RCU takes the following steps to encourage timely completion of 1856 + grace periods: 1857 + 1858 + <ol> 1859 + <li> If a grace period fails to complete within 100&nbsp;milliseconds, 1860 + RCU causes future invocations of <tt>cond_resched()</tt> on 1861 + the holdout CPUs to provide an RCU quiescent state. 1862 + RCU also causes those CPUs' <tt>need_resched()</tt> invocations 1863 + to return <tt>true</tt>, but only after the corresponding CPU's 1864 + next scheduling-clock. 1865 + <li> CPUs mentioned in the <tt>nohz_full</tt> kernel boot parameter 1866 + can run indefinitely in the kernel without scheduling-clock 1867 + interrupts, which defeats the above <tt>need_resched()</tt> 1868 + strategem. 1869 + RCU will therefore invoke <tt>resched_cpu()</tt> on any 1870 + <tt>nohz_full</tt> CPUs still holding out after 1871 + 109&nbsp;milliseconds. 1872 + <li> In kernels built with <tt>CONFIG_RCU_BOOST=y</tt>, if a given 1873 + task that has been preempted within an RCU read-side critical 1874 + section is holding out for more than 500&nbsp;milliseconds, 1875 + RCU will resort to priority boosting. 1876 + <li> If a CPU is still holding out 10&nbsp;seconds into the grace 1877 + period, RCU will invoke <tt>resched_cpu()</tt> on it regardless 1878 + of its <tt>nohz_full</tt> state. 1879 + </ol> 1880 + 1881 + <p> 1882 + The above values are defaults for systems running with <tt>HZ=1000</tt>. 1883 + They will vary as the value of <tt>HZ</tt> varies, and can also be 1884 + changed using the relevant Kconfig options and kernel boot parameters. 1885 + RCU currently does not do much sanity checking of these 1886 + parameters, so please use caution when changing them. 1887 + Note that these forward-progress measures are provided only for RCU, 1888 + not for 1889 + <a href="#Sleepable RCU">SRCU</a> or 1890 + <a href="#Tasks RCU">Tasks RCU</a>. 1891 + 1892 + <p> 1893 + RCU takes the following steps in <tt>call_rcu()</tt> to encourage timely 1894 + invocation of callbacks when any given non-<tt>rcu_nocbs</tt> CPU has 1895 + 10,000 callbacks, or has 10,000 more callbacks than it had the last time 1896 + encouragement was provided: 1897 + 1898 + <ol> 1899 + <li> Starts a grace period, if one is not already in progress. 1900 + <li> Forces immediate checking for quiescent states, rather than 1901 + waiting for three milliseconds to have elapsed since the 1902 + beginning of the grace period. 1903 + <li> Immediately tags the CPU's callbacks with their grace period 1904 + completion numbers, rather than waiting for the <tt>RCU_SOFTIRQ</tt> 1905 + handler to get around to it. 1906 + <li> Lifts callback-execution batch limits, which speeds up callback 1907 + invocation at the expense of degrading realtime response. 1908 + </ol> 1909 + 1910 + <p> 1911 + Again, these are default values when running at <tt>HZ=1000</tt>, 1912 + and can be overridden. 1913 + Again, these forward-progress measures are provided only for RCU, 1914 + not for 1915 + <a href="#Sleepable RCU">SRCU</a> or 1916 + <a href="#Tasks RCU">Tasks RCU</a>. 1917 + Even for RCU, callback-invocation forward progress for <tt>rcu_nocbs</tt> 1918 + CPUs is much less well-developed, in part because workloads benefiting 1919 + from <tt>rcu_nocbs</tt> CPUs tend to invoke <tt>call_rcu()</tt> 1920 + relatively infrequently. 1921 + If workloads emerge that need both <tt>rcu_nocbs</tt> CPUs and high 1922 + <tt>call_rcu()</tt> invocation rates, then additional forward-progress 1923 + work will be required. 1775 1924 1776 1925 <h3><a name="Composability">Composability</a></h3> 1777 1926 ··· 2323 2272 Furthermore, NMI handlers can be interrupted by what appear to RCU 2324 2273 to be normal interrupts. 2325 2274 One way that this can happen is for code that directly invokes 2326 - <tt>rcu_irq_enter()</tt> and </tt>rcu_irq_exit()</tt> to be called 2275 + <tt>rcu_irq_enter()</tt> and <tt>rcu_irq_exit()</tt> to be called 2327 2276 from an NMI handler. 2328 2277 This astonishing fact of life prompted the current code structure, 2329 2278 which has <tt>rcu_irq_enter()</tt> invoking <tt>rcu_nmi_enter()</tt> ··· 2345 2294 <p> 2346 2295 Unfortunately, there is no way to cancel an RCU callback; 2347 2296 once you invoke <tt>call_rcu()</tt>, the callback function is 2348 - going to eventually be invoked, unless the system goes down first. 2297 + eventually going to be invoked, unless the system goes down first. 2349 2298 Because it is normally considered socially irresponsible to crash the system 2350 2299 in response to a module unload request, we need some other way 2351 2300 to deal with in-flight RCU callbacks. ··· 2475 2424 but there is room for further improvement. 2476 2425 2477 2426 <p> 2478 - In the past, it was forbidden to disable interrupts across an 2479 - <tt>rcu_read_unlock()</tt> unless that interrupt-disabled region 2480 - of code also included the matching <tt>rcu_read_lock()</tt>. 2481 - Violating this restriction could result in deadlocks involving the 2482 - scheduler's runqueue and priority-inheritance spinlocks. 2483 - This restriction was lifted when interrupt-disabled calls to 2484 - <tt>rcu_read_unlock()</tt> started deferring the reporting of 2485 - the resulting RCU-preempt quiescent state until the end of that 2427 + It is forbidden to hold any of scheduler's runqueue or priority-inheritance 2428 + spinlocks across an <tt>rcu_read_unlock()</tt> unless interrupts have been 2429 + disabled across the entire RCU read-side critical section, that is, 2430 + up to and including the matching <tt>rcu_read_lock()</tt>. 2431 + Violating this restriction can result in deadlocks involving these 2432 + scheduler spinlocks. 2433 + There was hope that this restriction might be lifted when interrupt-disabled 2434 + calls to <tt>rcu_read_unlock()</tt> started deferring the reporting of 2435 + the resulting RCU-preempt quiescent state until the end of the corresponding 2486 2436 interrupts-disabled region. 2487 - This deferred reporting means that the scheduler's runqueue and 2488 - priority-inheritance locks cannot be held while reporting an RCU-preempt 2489 - quiescent state, which lifts the earlier restriction, at least from 2490 - a deadlock perspective. 2491 - Unfortunately, real-time systems using RCU priority boosting may 2437 + Unfortunately, timely reporting of the corresponding quiescent state 2438 + to expedited grace periods requires a call to <tt>raise_softirq()</tt>, 2439 + which can acquire these scheduler spinlocks. 2440 + In addition, real-time systems using RCU priority boosting 2492 2441 need this restriction to remain in effect because deferred 2493 - quiescent-state reporting also defers deboosting, which in turn 2494 - degrades real-time latencies. 2442 + quiescent-state reporting would also defer deboosting, which in turn 2443 + would degrade real-time latencies. 2444 + 2445 + <p> 2446 + In theory, if a given RCU read-side critical section could be 2447 + guaranteed to be less than one second in duration, holding a scheduler 2448 + spinlock across that critical section's <tt>rcu_read_unlock()</tt> 2449 + would require only that preemption be disabled across the entire 2450 + RCU read-side critical section, not interrupts. 2451 + Unfortunately, given the possibility of vCPU preemption, long-running 2452 + interrupts, and so on, it is not possible in practice to guarantee 2453 + that a given RCU read-side critical section will complete in less than 2454 + one second. 2455 + Therefore, as noted above, if scheduler spinlocks are held across 2456 + a given call to <tt>rcu_read_unlock()</tt>, interrupts must be 2457 + disabled across the entire RCU read-side critical section. 2495 2458 2496 2459 <h3><a name="Tracing and RCU">Tracing and RCU</a></h3> 2497 2460 ··· 3297 3232 For example, RCU callback overhead might be charged back to the 3298 3233 originating <tt>call_rcu()</tt> instance, though probably not 3299 3234 in production kernels. 3235 + 3236 + <p> 3237 + Additional work may be required to provide reasonable forward-progress 3238 + guarantees under heavy load for grace periods and for callback 3239 + invocation. 3300 3240 3301 3241 <h2><a name="Summary">Summary</a></h2> 3302 3242
+11 -38
Documentation/RCU/checklist.txt
··· 63 63 pointer must be covered by rcu_read_lock(), rcu_read_lock_bh(), 64 64 rcu_read_lock_sched(), or by the appropriate update-side lock. 65 65 Disabling of preemption can serve as rcu_read_lock_sched(), but 66 - is less readable. 66 + is less readable and prevents lockdep from detecting locking issues. 67 67 68 68 Letting RCU-protected pointers "leak" out of an RCU read-side 69 69 critical section is every bid as bad as letting them leak out ··· 285 285 here is that superuser already has lots of ways to crash 286 286 the machine. 287 287 288 - d. Use call_rcu_bh() rather than call_rcu(), in order to take 289 - advantage of call_rcu_bh()'s faster grace periods. (This 290 - is only a partial solution, though.) 291 - 292 - e. Periodically invoke synchronize_rcu(), permitting a limited 288 + d. Periodically invoke synchronize_rcu(), permitting a limited 293 289 number of updates per grace period. 294 290 295 291 The same cautions apply to call_rcu_bh(), call_rcu_sched(), ··· 320 324 will break Alpha, cause aggressive compilers to generate bad code, 321 325 and confuse people trying to read your code. 322 326 323 - 11. Note that synchronize_rcu() -only- guarantees to wait until 324 - all currently executing rcu_read_lock()-protected RCU read-side 325 - critical sections complete. It does -not- necessarily guarantee 326 - that all currently running interrupts, NMIs, preempt_disable() 327 - code, or idle loops will complete. Therefore, if your 328 - read-side critical sections are protected by something other 329 - than rcu_read_lock(), do -not- use synchronize_rcu(). 330 - 331 - Similarly, disabling preemption is not an acceptable substitute 332 - for rcu_read_lock(). Code that attempts to use preemption 333 - disabling where it should be using rcu_read_lock() will break 334 - in CONFIG_PREEMPT=y kernel builds. 335 - 336 - If you want to wait for interrupt handlers, NMI handlers, and 337 - code under the influence of preempt_disable(), you instead 338 - need to use synchronize_irq() or synchronize_sched(). 339 - 340 - This same limitation also applies to synchronize_rcu_bh() 341 - and synchronize_srcu(), as well as to the asynchronous and 342 - expedited forms of the three primitives, namely call_rcu(), 343 - call_rcu_bh(), call_srcu(), synchronize_rcu_expedited(), 344 - synchronize_rcu_bh_expedited(), and synchronize_srcu_expedited(). 345 - 346 - 12. Any lock acquired by an RCU callback must be acquired elsewhere 327 + 11. Any lock acquired by an RCU callback must be acquired elsewhere 347 328 with softirq disabled, e.g., via spin_lock_irqsave(), 348 329 spin_lock_bh(), etc. Failing to disable irq on a given 349 330 acquisition of that lock will result in deadlock as soon as 350 331 the RCU softirq handler happens to run your RCU callback while 351 332 interrupting that acquisition's critical section. 352 333 353 - 13. RCU callbacks can be and are executed in parallel. In many cases, 334 + 12. RCU callbacks can be and are executed in parallel. In many cases, 354 335 the callback code simply wrappers around kfree(), so that this 355 336 is not an issue (or, more accurately, to the extent that it is 356 337 an issue, the memory-allocator locking handles it). However, ··· 343 370 not the case, a self-spawning RCU callback would prevent the 344 371 victim CPU from ever going offline.) 345 372 346 - 14. Unlike other forms of RCU, it -is- permissible to block in an 373 + 13. Unlike other forms of RCU, it -is- permissible to block in an 347 374 SRCU read-side critical section (demarked by srcu_read_lock() 348 375 and srcu_read_unlock()), hence the "SRCU": "sleepable RCU". 349 376 Please note that if you don't need to sleep in read-side critical ··· 387 414 Note that rcu_dereference() and rcu_assign_pointer() relate to 388 415 SRCU just as they do to other forms of RCU. 389 416 390 - 15. The whole point of call_rcu(), synchronize_rcu(), and friends 417 + 14. The whole point of call_rcu(), synchronize_rcu(), and friends 391 418 is to wait until all pre-existing readers have finished before 392 419 carrying out some otherwise-destructive operation. It is 393 420 therefore critically important to -first- remove any path ··· 399 426 is the caller's responsibility to guarantee that any subsequent 400 427 readers will execute safely. 401 428 402 - 16. The various RCU read-side primitives do -not- necessarily contain 429 + 15. The various RCU read-side primitives do -not- necessarily contain 403 430 memory barriers. You should therefore plan for the CPU 404 431 and the compiler to freely reorder code into and out of RCU 405 432 read-side critical sections. It is the responsibility of the 406 433 RCU update-side primitives to deal with this. 407 434 408 - 17. Use CONFIG_PROVE_LOCKING, CONFIG_DEBUG_OBJECTS_RCU_HEAD, and the 435 + 16. Use CONFIG_PROVE_LOCKING, CONFIG_DEBUG_OBJECTS_RCU_HEAD, and the 409 436 __rcu sparse checks to validate your RCU code. These can help 410 437 find problems as follows: 411 438 ··· 428 455 These debugging aids can help you find problems that are 429 456 otherwise extremely difficult to spot. 430 457 431 - 18. If you register a callback using call_rcu(), call_rcu_bh(), 458 + 17. If you register a callback using call_rcu(), call_rcu_bh(), 432 459 call_rcu_sched(), or call_srcu(), and pass in a function defined 433 460 within a loadable module, then it in necessary to wait for 434 461 all pending callbacks to be invoked after the last invocation ··· 442 469 You instead need to use one of the barrier functions: 443 470 444 471 o call_rcu() -> rcu_barrier() 445 - o call_rcu_bh() -> rcu_barrier_bh() 446 - o call_rcu_sched() -> rcu_barrier_sched() 472 + o call_rcu_bh() -> rcu_barrier() 473 + o call_rcu_sched() -> rcu_barrier() 447 474 o call_srcu() -> srcu_barrier() 448 475 449 476 However, these barrier functions are absolutely -not- guaranteed
+3 -4
Documentation/RCU/stallwarn.txt
··· 176 176 will normally be followed by stack dumps for each CPU. Please note that 177 177 PREEMPT_RCU builds can be stalled by tasks as well as by CPUs, and that 178 178 the tasks will be indicated by PID, for example, "P3421". It is even 179 - possible for a rcu_preempt_state stall to be caused by both CPUs -and- 180 - tasks, in which case the offending CPUs and tasks will all be called 181 - out in the list. 179 + possible for an rcu_state stall to be caused by both CPUs -and- tasks, 180 + in which case the offending CPUs and tasks will all be called out in the list. 182 181 183 182 CPU 2's "(3 GPs behind)" indicates that this CPU has not interacted with 184 183 the RCU core for the past three grace periods. In contrast, CPU 16's "(0 ··· 205 206 the stalled CPU is spinning with interrupts are disabled, or, in -rt 206 207 kernels, if a high-priority process is starving RCU's softirq handler. 207 208 208 - The "fps=" shows the number of force-quiescent-state idle/offline 209 + The "fqs=" shows the number of force-quiescent-state idle/offline 209 210 detection passes that the grace-period kthread has made across this 210 211 CPU since the last time that this CPU noted the beginning of a grace 211 212 period.
+42 -28
Documentation/RCU/whatisRCU.txt
··· 266 266 unnecessary overhead on Alpha CPUs. 267 267 268 268 Note that the value returned by rcu_dereference() is valid 269 - only within the enclosing RCU read-side critical section. 269 + only within the enclosing RCU read-side critical section [1]. 270 270 For example, the following is -not- legal: 271 271 272 272 rcu_read_lock(); ··· 291 291 And, again like rcu_assign_pointer(), rcu_dereference() is 292 292 typically used indirectly, via the _rcu list-manipulation 293 293 primitives, such as list_for_each_entry_rcu(). 294 + 295 + [1] The variant rcu_dereference_protected() can be used outside 296 + of an RCU read-side critical section as long as the usage is 297 + protected by locks acquired by the update-side code. This variant 298 + avoids the lockdep warning that would happen when using (for 299 + example) rcu_dereference() without rcu_read_lock() protection. 300 + Using rcu_dereference_protected() also has the advantage 301 + of permitting compiler optimizations that rcu_dereference() 302 + must prohibit. The rcu_dereference_protected() variant takes 303 + a lockdep expression to indicate which locks must be acquired 304 + by the caller. If the indicated protection is not provided, 305 + a lockdep splat is emitted. See RCU/Design/Requirements.html 306 + and the API's code comments for more details and example usage. 294 307 295 308 The following diagram shows how each API communicates among the 296 309 reader, updater, and reclaimer. ··· 335 322 implementations of the RCU infrastructure make heavy use of batching in 336 323 order to amortize their overhead over many uses of the corresponding APIs. 337 324 338 - There are no fewer than three RCU mechanisms in the Linux kernel; the 339 - diagram above shows the first one, which is by far the most commonly used. 340 - The rcu_dereference() and rcu_assign_pointer() primitives are used for 341 - all three mechanisms, but different defer and protect primitives are 342 - used as follows: 325 + There are at least three flavors of RCU usage in the Linux kernel. The diagram 326 + above shows the most common one. On the updater side, the rcu_assign_pointer(), 327 + sychronize_rcu() and call_rcu() primitives used are the same for all three 328 + flavors. However for protection (on the reader side), the primitives used vary 329 + depending on the flavor: 343 330 344 - Defer Protect 331 + a. rcu_read_lock() / rcu_read_unlock() 332 + rcu_dereference() 345 333 346 - a. synchronize_rcu() rcu_read_lock() / rcu_read_unlock() 347 - call_rcu() rcu_dereference() 334 + b. rcu_read_lock_bh() / rcu_read_unlock_bh() 335 + local_bh_disable() / local_bh_enable() 336 + rcu_dereference_bh() 348 337 349 - b. synchronize_rcu_bh() rcu_read_lock_bh() / rcu_read_unlock_bh() 350 - call_rcu_bh() rcu_dereference_bh() 338 + c. rcu_read_lock_sched() / rcu_read_unlock_sched() 339 + preempt_disable() / preempt_enable() 340 + local_irq_save() / local_irq_restore() 341 + hardirq enter / hardirq exit 342 + NMI enter / NMI exit 343 + rcu_dereference_sched() 351 344 352 - c. synchronize_sched() rcu_read_lock_sched() / rcu_read_unlock_sched() 353 - call_rcu_sched() preempt_disable() / preempt_enable() 354 - local_irq_save() / local_irq_restore() 355 - hardirq enter / hardirq exit 356 - NMI enter / NMI exit 357 - rcu_dereference_sched() 358 - 359 - These three mechanisms are used as follows: 345 + These three flavors are used as follows: 360 346 361 347 a. RCU applied to normal data structures. 362 348 ··· 879 867 880 868 bh: Critical sections Grace period Barrier 881 869 882 - rcu_read_lock_bh call_rcu_bh rcu_barrier_bh 883 - rcu_read_unlock_bh synchronize_rcu_bh 884 - rcu_dereference_bh synchronize_rcu_bh_expedited 870 + rcu_read_lock_bh call_rcu rcu_barrier 871 + rcu_read_unlock_bh synchronize_rcu 872 + [local_bh_disable] synchronize_rcu_expedited 873 + [and friends] 874 + rcu_dereference_bh 885 875 rcu_dereference_bh_check 886 876 rcu_dereference_bh_protected 887 877 rcu_read_lock_bh_held 888 878 889 879 sched: Critical sections Grace period Barrier 890 880 891 - rcu_read_lock_sched synchronize_sched rcu_barrier_sched 892 - rcu_read_unlock_sched call_rcu_sched 893 - [preempt_disable] synchronize_sched_expedited 881 + rcu_read_lock_sched call_rcu rcu_barrier 882 + rcu_read_unlock_sched synchronize_rcu 883 + [preempt_disable] synchronize_rcu_expedited 894 884 [and friends] 895 885 rcu_read_lock_sched_notrace 896 886 rcu_read_unlock_sched_notrace ··· 904 890 905 891 SRCU: Critical sections Grace period Barrier 906 892 907 - srcu_read_lock synchronize_srcu srcu_barrier 908 - srcu_read_unlock call_srcu 893 + srcu_read_lock call_srcu srcu_barrier 894 + srcu_read_unlock synchronize_srcu 909 895 srcu_dereference synchronize_srcu_expedited 910 896 srcu_dereference_check 911 897 srcu_read_lock_held ··· 1048 1034 spinlocks blocking while in RCU read-side critical 1049 1035 sections. 1050 1036 1051 - Why the apparent inconsistency? Because it is it 1037 + Why the apparent inconsistency? Because it is 1052 1038 possible to use priority boosting to keep the RCU 1053 1039 grace periods short if need be (for example, if running 1054 1040 short of memory). In contrast, if blocking waiting
+17
Documentation/admin-guide/kernel-parameters.txt
··· 3773 3773 Set wait time between force_quiescent_state bursts 3774 3774 in seconds. 3775 3775 3776 + rcutorture.fwd_progress= [KNL] 3777 + Enable RCU grace-period forward-progress testing 3778 + for the types of RCU supporting this notion. 3779 + 3780 + rcutorture.fwd_progress_div= [KNL] 3781 + Specify the fraction of a CPU-stall-warning 3782 + period to do tight-loop forward-progress testing. 3783 + 3784 + rcutorture.fwd_progress_holdoff= [KNL] 3785 + Number of seconds to wait between successive 3786 + forward-progress tests. 3787 + 3788 + rcutorture.fwd_progress_need_resched= [KNL] 3789 + Enclose cond_resched() calls within checks for 3790 + need_resched() during tight-loop forward-progress 3791 + testing. 3792 + 3776 3793 rcutorture.gp_cond= [KNL] 3777 3794 Use conditional/asynchronous update-side 3778 3795 primitives, if available.
+34 -39
MAINTAINERS
··· 4033 4033 F: drivers/net/ethernet/chelsio/cxgb4vf/ 4034 4034 4035 4035 CXL (IBM Coherent Accelerator Processor Interface CAPI) DRIVER 4036 - M: Frederic Barrat <fbarrat@linux.vnet.ibm.com> 4036 + M: Frederic Barrat <fbarrat@linux.ibm.com> 4037 4037 M: Andrew Donnellan <andrew.donnellan@au1.ibm.com> 4038 4038 L: linuxppc-dev@lists.ozlabs.org 4039 4039 S: Supported ··· 4045 4045 F: Documentation/ABI/testing/sysfs-class-cxl 4046 4046 4047 4047 CXLFLASH (IBM Coherent Accelerator Processor Interface CAPI Flash) SCSI DRIVER 4048 - M: Manoj N. Kumar <manoj@linux.vnet.ibm.com> 4049 - M: Matthew R. Ochs <mrochs@linux.vnet.ibm.com> 4050 - M: Uma Krishnan <ukrishn@linux.vnet.ibm.com> 4048 + M: Manoj N. Kumar <manoj@linux.ibm.com> 4049 + M: Matthew R. Ochs <mrochs@linux.ibm.com> 4050 + M: Uma Krishnan <ukrishn@linux.ibm.com> 4051 4051 L: linux-scsi@vger.kernel.org 4052 4052 S: Supported 4053 4053 F: drivers/scsi/cxlflash/ ··· 5428 5428 F: fs/efs/ 5429 5429 5430 5430 EHEA (IBM pSeries eHEA 10Gb ethernet adapter) DRIVER 5431 - M: Douglas Miller <dougmill@linux.vnet.ibm.com> 5431 + M: Douglas Miller <dougmill@linux.ibm.com> 5432 5432 L: netdev@vger.kernel.org 5433 5433 S: Maintained 5434 5434 F: drivers/net/ethernet/ibm/ehea/ ··· 5565 5565 F: fs/ext4/ 5566 5566 5567 5567 Extended Verification Module (EVM) 5568 - M: Mimi Zohar <zohar@linux.vnet.ibm.com> 5568 + M: Mimi Zohar <zohar@linux.ibm.com> 5569 5569 L: linux-integrity@vger.kernel.org 5570 5570 S: Supported 5571 5571 F: security/integrity/evm/ ··· 5775 5775 5776 5776 FLASH ADAPTER DRIVER (IBM Flash Adapter 900GB Full Height PCI Flash Card) 5777 5777 M: Joshua Morris <josh.h.morris@us.ibm.com> 5778 - M: Philip Kelleher <pjk1939@linux.vnet.ibm.com> 5778 + M: Philip Kelleher <pjk1939@linux.ibm.com> 5779 5779 S: Maintained 5780 5780 F: drivers/block/rsxx/ 5781 5781 ··· 6042 6042 F: Documentation/filesystems/fscrypt.rst 6043 6043 6044 6044 FSI-ATTACHED I2C DRIVER 6045 - M: Eddie James <eajames@linux.vnet.ibm.com> 6045 + M: Eddie James <eajames@linux.ibm.com> 6046 6046 L: linux-i2c@vger.kernel.org 6047 6047 L: openbmc@lists.ozlabs.org (moderated for non-subscribers) 6048 6048 S: Maintained ··· 6218 6218 F: drivers/uio/uio_pci_generic.c 6219 6219 6220 6220 GENWQE (IBM Generic Workqueue Card) 6221 - M: Frank Haverkamp <haver@linux.vnet.ibm.com> 6222 - M: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com> 6221 + M: Frank Haverkamp <haver@linux.ibm.com> 6223 6222 S: Supported 6224 6223 F: drivers/misc/genwqe/ 6225 6224 ··· 7000 7001 F: lib/842/ 7001 7002 7002 7003 IBM Power in-Nest Crypto Acceleration 7003 - M: Leonidas S. Barbosa <leosilva@linux.vnet.ibm.com> 7004 - M: Paulo Flabiano Smorigo <pfsmorigo@linux.vnet.ibm.com> 7004 + M: Paulo Flabiano Smorigo <pfsmorigo@linux.ibm.com> 7005 7005 L: linux-crypto@vger.kernel.org 7006 7006 S: Supported 7007 7007 F: drivers/crypto/nx/Makefile ··· 7017 7019 F: drivers/scsi/ipr.* 7018 7020 7019 7021 IBM Power SRIOV Virtual NIC Device Driver 7020 - M: Thomas Falcon <tlfalcon@linux.vnet.ibm.com> 7021 - M: John Allen <jallen@linux.vnet.ibm.com> 7022 + M: Thomas Falcon <tlfalcon@linux.ibm.com> 7023 + M: John Allen <jallen@linux.ibm.com> 7022 7024 L: netdev@vger.kernel.org 7023 7025 S: Supported 7024 7026 F: drivers/net/ethernet/ibm/ibmvnic.* ··· 7033 7035 F: arch/powerpc/include/uapi/asm/vas.h 7034 7036 7035 7037 IBM Power Virtual Ethernet Device Driver 7036 - M: Thomas Falcon <tlfalcon@linux.vnet.ibm.com> 7038 + M: Thomas Falcon <tlfalcon@linux.ibm.com> 7037 7039 L: netdev@vger.kernel.org 7038 7040 S: Supported 7039 7041 F: drivers/net/ethernet/ibm/ibmveth.* 7040 7042 7041 7043 IBM Power Virtual FC Device Drivers 7042 - M: Tyrel Datwyler <tyreld@linux.vnet.ibm.com> 7044 + M: Tyrel Datwyler <tyreld@linux.ibm.com> 7043 7045 L: linux-scsi@vger.kernel.org 7044 7046 S: Supported 7045 7047 F: drivers/scsi/ibmvscsi/ibmvfc* 7046 7048 7047 7049 IBM Power Virtual Management Channel Driver 7048 - M: Bryant G. Ly <bryantly@linux.vnet.ibm.com> 7049 - M: Steven Royer <seroyer@linux.vnet.ibm.com> 7050 + M: Steven Royer <seroyer@linux.ibm.com> 7050 7051 S: Supported 7051 7052 F: drivers/misc/ibmvmc.* 7052 7053 7053 7054 IBM Power Virtual SCSI Device Drivers 7054 - M: Tyrel Datwyler <tyreld@linux.vnet.ibm.com> 7055 + M: Tyrel Datwyler <tyreld@linux.ibm.com> 7055 7056 L: linux-scsi@vger.kernel.org 7056 7057 S: Supported 7057 7058 F: drivers/scsi/ibmvscsi/ibmvscsi* 7058 7059 F: include/scsi/viosrp.h 7059 7060 7060 7061 IBM Power Virtual SCSI Device Target Driver 7061 - M: Bryant G. Ly <bryantly@linux.vnet.ibm.com> 7062 - M: Michael Cyr <mikecyr@linux.vnet.ibm.com> 7062 + M: Michael Cyr <mikecyr@linux.ibm.com> 7063 7063 L: linux-scsi@vger.kernel.org 7064 7064 L: target-devel@vger.kernel.org 7065 7065 S: Supported 7066 7066 F: drivers/scsi/ibmvscsi_tgt/ 7067 7067 7068 7068 IBM Power VMX Cryptographic instructions 7069 - M: Leonidas S. Barbosa <leosilva@linux.vnet.ibm.com> 7070 - M: Paulo Flabiano Smorigo <pfsmorigo@linux.vnet.ibm.com> 7069 + M: Paulo Flabiano Smorigo <pfsmorigo@linux.ibm.com> 7071 7070 L: linux-crypto@vger.kernel.org 7072 7071 S: Supported 7073 7072 F: drivers/crypto/vmx/Makefile ··· 7341 7346 L: linux-crypto@vger.kernel.org 7342 7347 7343 7348 INTEGRITY MEASUREMENT ARCHITECTURE (IMA) 7344 - M: Mimi Zohar <zohar@linux.vnet.ibm.com> 7349 + M: Mimi Zohar <zohar@linux.ibm.com> 7345 7350 M: Dmitry Kasatkin <dmitry.kasatkin@gmail.com> 7346 7351 L: linux-integrity@vger.kernel.org 7347 7352 T: git git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git ··· 7933 7938 F: drivers/media/platform/rcar_jpu.c 7934 7939 7935 7940 JSM Neo PCI based serial card 7936 - M: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com> 7937 7941 L: linux-serial@vger.kernel.org 7938 - S: Maintained 7942 + S: Orphan 7939 7943 F: drivers/tty/serial/jsm/ 7940 7944 7941 7945 K10TEMP HARDWARE MONITORING DRIVER ··· 8164 8170 F: kernel/kexec* 8165 8171 8166 8172 KEYS-ENCRYPTED 8167 - M: Mimi Zohar <zohar@linux.vnet.ibm.com> 8173 + M: Mimi Zohar <zohar@linux.ibm.com> 8168 8174 L: linux-integrity@vger.kernel.org 8169 8175 L: keyrings@vger.kernel.org 8170 8176 S: Supported ··· 8173 8179 F: security/keys/encrypted-keys/ 8174 8180 8175 8181 KEYS-TRUSTED 8176 - M: James Bottomley <jejb@linux.vnet.ibm.com> 8182 + M: James Bottomley <jejb@linux.ibm.com> 8177 8183 M: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> 8178 - M: Mimi Zohar <zohar@linux.vnet.ibm.com> 8184 + M: Mimi Zohar <zohar@linuxibm.com> 8179 8185 L: linux-integrity@vger.kernel.org 8180 8186 L: keyrings@vger.kernel.org 8181 8187 S: Supported ··· 8228 8234 F: tools/testing/selftests/kmod/ 8229 8235 8230 8236 KPROBES 8231 - M: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> 8237 + M: Naveen N. Rao <naveen.n.rao@linux.ibm.com> 8232 8238 M: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> 8233 8239 M: "David S. Miller" <davem@davemloft.net> 8234 8240 M: Masami Hiramatsu <mhiramat@kernel.org> ··· 8584 8590 M: David Howells <dhowells@redhat.com> 8585 8591 M: Jade Alglave <j.alglave@ucl.ac.uk> 8586 8592 M: Luc Maranget <luc.maranget@inria.fr> 8587 - M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> 8593 + M: "Paul E. McKenney" <paulmck@linux.ibm.com> 8588 8594 R: Akira Yokosawa <akiyks@gmail.com> 8589 8595 R: Daniel Lustig <dlustig@nvidia.com> 8590 8596 L: linux-kernel@vger.kernel.org ··· 9542 9548 9543 9549 MEMBARRIER SUPPORT 9544 9550 M: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> 9545 - M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> 9551 + M: "Paul E. McKenney" <paulmck@linux.ibm.com> 9546 9552 L: linux-kernel@vger.kernel.org 9547 9553 S: Supported 9548 9554 F: kernel/sched/membarrier.c ··· 10680 10686 F: tools/objtool/ 10681 10687 10682 10688 OCXL (Open Coherent Accelerator Processor Interface OpenCAPI) DRIVER 10683 - M: Frederic Barrat <fbarrat@linux.vnet.ibm.com> 10689 + M: Frederic Barrat <fbarrat@linux.ibm.com> 10684 10690 M: Andrew Donnellan <andrew.donnellan@au1.ibm.com> 10685 10691 L: linuxppc-dev@lists.ozlabs.org 10686 10692 S: Supported ··· 12481 12487 F: drivers/net/wireless/ray* 12482 12488 12483 12489 RCUTORTURE TEST FRAMEWORK 12484 - M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> 12490 + M: "Paul E. McKenney" <paulmck@linux.ibm.com> 12485 12491 M: Josh Triplett <josh@joshtriplett.org> 12486 12492 R: Steven Rostedt <rostedt@goodmis.org> 12487 12493 R: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> ··· 12528 12534 F: Documentation/x86/intel_rdt* 12529 12535 12530 12536 READ-COPY UPDATE (RCU) 12531 - M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> 12537 + M: "Paul E. McKenney" <paulmck@linux.ibm.com> 12532 12538 M: Josh Triplett <josh@joshtriplett.org> 12533 12539 R: Steven Rostedt <rostedt@goodmis.org> 12534 12540 R: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> 12535 12541 R: Lai Jiangshan <jiangshanlai@gmail.com> 12542 + R: Joel Fernandes <joel@joelfernandes.org> 12536 12543 L: linux-kernel@vger.kernel.org 12537 12544 W: http://www.rdrop.com/users/paulmck/RCU/ 12538 12545 S: Supported ··· 12669 12674 RESTARTABLE SEQUENCES SUPPORT 12670 12675 M: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> 12671 12676 M: Peter Zijlstra <peterz@infradead.org> 12672 - M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> 12677 + M: "Paul E. McKenney" <paulmck@linux.ibm.com> 12673 12678 M: Boqun Feng <boqun.feng@gmail.com> 12674 12679 L: linux-kernel@vger.kernel.org 12675 12680 S: Supported ··· 13194 13199 F: include/scsi/sg.h 13195 13200 13196 13201 SCSI SUBSYSTEM 13197 - M: "James E.J. Bottomley" <jejb@linux.vnet.ibm.com> 13202 + M: "James E.J. Bottomley" <jejb@linux.ibm.com> 13198 13203 T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git 13199 13204 M: "Martin K. Petersen" <martin.petersen@oracle.com> 13200 13205 T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git ··· 13629 13634 13630 13635 SLEEPABLE READ-COPY UPDATE (SRCU) 13631 13636 M: Lai Jiangshan <jiangshanlai@gmail.com> 13632 - M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> 13637 + M: "Paul E. McKenney" <paulmck@linux.ibm.com> 13633 13638 M: Josh Triplett <josh@joshtriplett.org> 13634 13639 R: Steven Rostedt <rostedt@goodmis.org> 13635 13640 R: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> ··· 15052 15057 15053 15058 TORTURE-TEST MODULES 15054 15059 M: Davidlohr Bueso <dave@stgolabs.net> 15055 - M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> 15060 + M: "Paul E. McKenney" <paulmck@linux.ibm.com> 15056 15061 M: Josh Triplett <josh@joshtriplett.org> 15057 15062 L: linux-kernel@vger.kernel.org 15058 15063 S: Supported
+1 -1
arch/powerpc/mm/hugetlbpage.c
··· 289 289 290 290 (*batchp)->ptes[(*batchp)->index++] = hugepte; 291 291 if ((*batchp)->index == HUGEPD_FREELIST_SIZE) { 292 - call_rcu_sched(&(*batchp)->rcu, hugepd_free_rcu_callback); 292 + call_rcu(&(*batchp)->rcu, hugepd_free_rcu_callback); 293 293 *batchp = NULL; 294 294 } 295 295 put_cpu_var(hugepd_freelist_cur);
+1 -1
arch/s390/mm/pgalloc.c
··· 350 350 struct mmu_table_batch **batch = &tlb->batch; 351 351 352 352 if (*batch) { 353 - call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu); 353 + call_rcu(&(*batch)->rcu, tlb_remove_table_rcu); 354 354 *batch = NULL; 355 355 } 356 356 }
+1 -1
arch/sparc/oprofile/init.c
··· 53 53 { 54 54 nmi_adjust_hz(1); 55 55 unregister_die_notifier(&profile_timer_exceptions_nb); 56 - synchronize_sched(); /* Allow already-started NMIs to complete. */ 56 + synchronize_rcu(); /* Allow already-started NMIs to complete. */ 57 57 } 58 58 59 59 static int op_nmi_timer_init(struct oprofile_operations *ops)
+1 -1
arch/x86/pci/i386.c
··· 59 59 { 60 60 struct pcibios_fwaddrmap *map; 61 61 62 - WARN_ON_SMP(!spin_is_locked(&pcibios_fwaddrmap_lock)); 62 + lockdep_assert_held(&pcibios_fwaddrmap_lock); 63 63 64 64 list_for_each_entry(map, &pcibios_fwaddrmappings, list) 65 65 if (map->dev == dev)
+1 -1
crypto/pcrypt.c
··· 382 382 383 383 cpumask_copy(new_mask->mask, cpumask->cbcpu); 384 384 rcu_assign_pointer(pcrypt->cb_cpumask, new_mask); 385 - synchronize_rcu_bh(); 385 + synchronize_rcu(); 386 386 387 387 free_cpumask_var(old_mask->mask); 388 388 kfree(old_mask);
+1 -1
drivers/char/ipmi/ipmi_si_intf.c
··· 2187 2187 * handlers might have been running before we freed the 2188 2188 * interrupt. 2189 2189 */ 2190 - synchronize_sched(); 2190 + synchronize_rcu(); 2191 2191 2192 2192 /* 2193 2193 * Timeouts are stopped, now make sure the interrupts are off
+1 -1
drivers/cpufreq/cpufreq_governor.c
··· 346 346 for_each_cpu(i, policy->cpus) 347 347 cpufreq_remove_update_util_hook(i); 348 348 349 - synchronize_sched(); 349 + synchronize_rcu(); 350 350 } 351 351 352 352 static struct policy_dbs_info *alloc_policy_dbs_info(struct cpufreq_policy *policy,
+1 -1
drivers/cpufreq/intel_pstate.c
··· 1930 1930 1931 1931 cpufreq_remove_update_util_hook(cpu); 1932 1932 cpu_data->update_util_set = false; 1933 - synchronize_sched(); 1933 + synchronize_rcu(); 1934 1934 } 1935 1935 1936 1936 static int intel_pstate_get_max_freq(struct cpudata *cpu)
+1 -1
drivers/net/ethernet/realtek/8139too.c
··· 1661 1661 1662 1662 napi_disable(&tp->napi); 1663 1663 netif_stop_queue(dev); 1664 - synchronize_sched(); 1664 + synchronize_rcu(); 1665 1665 1666 1666 netdev_dbg(dev, "Transmit timeout, status %02x %04x %04x media %02x\n", 1667 1667 RTL_R8(ChipCmd), RTL_R16(IntrStatus),
+2 -2
drivers/net/ethernet/realtek/r8169.c
··· 5866 5866 5867 5867 napi_disable(&tp->napi); 5868 5868 netif_stop_queue(dev); 5869 - synchronize_sched(); 5869 + synchronize_rcu(); 5870 5870 5871 5871 rtl8169_hw_reset(tp); 5872 5872 ··· 6609 6609 rtl8169_rx_missed(dev); 6610 6610 6611 6611 /* Give a racing hard_start_xmit a few cycles to complete. */ 6612 - synchronize_sched(); 6612 + synchronize_rcu(); 6613 6613 6614 6614 rtl8169_tx_clear(tp); 6615 6615
+1 -1
drivers/net/ethernet/sfc/efx.c
··· 3167 3167 { 3168 3168 u32 hash = efx_filter_spec_hash(spec); 3169 3169 3170 - WARN_ON(!spin_is_locked(&efx->rps_hash_lock)); 3170 + lockdep_assert_held(&efx->rps_hash_lock); 3171 3171 if (!efx->rps_hash_table) 3172 3172 return NULL; 3173 3173 return &efx->rps_hash_table[hash % EFX_ARFS_HASH_TABLE_SIZE];
+1 -1
drivers/net/ethernet/sis/sis190.c
··· 1142 1142 if (!poll_locked) 1143 1143 poll_locked++; 1144 1144 1145 - synchronize_sched(); 1145 + synchronize_rcu(); 1146 1146 1147 1147 } while (SIS_R32(IntrMask)); 1148 1148
+1 -1
drivers/net/ethernet/smsc/smsc911x.h
··· 67 67 68 68 #ifdef CONFIG_DEBUG_SPINLOCK 69 69 #define SMSC_ASSERT_MAC_LOCK(pdata) \ 70 - WARN_ON_SMP(!spin_is_locked(&pdata->mac_lock)) 70 + lockdep_assert_held(&pdata->mac_lock) 71 71 #else 72 72 #define SMSC_ASSERT_MAC_LOCK(pdata) do {} while (0) 73 73 #endif /* CONFIG_DEBUG_SPINLOCK */
+1 -1
drivers/vhost/net.c
··· 1359 1359 if (rx_sock) 1360 1360 sockfd_put(rx_sock); 1361 1361 /* Make sure no callbacks are outstanding */ 1362 - synchronize_rcu_bh(); 1362 + synchronize_rcu(); 1363 1363 /* We do an extra flush before freeing memory, 1364 1364 * since jobs can re-queue themselves. */ 1365 1365 vhost_net_flush(n);
+1 -1
fs/file.c
··· 158 158 * or have finished their rcu_read_lock_sched() section. 159 159 */ 160 160 if (atomic_read(&files->count) > 1) 161 - synchronize_sched(); 161 + synchronize_rcu(); 162 162 163 163 spin_lock(&files->file_lock); 164 164 if (!new_fdt)
+1 -1
fs/userfaultfd.c
··· 926 926 wait_queue_entry_t *wq; 927 927 struct userfaultfd_wait_queue *uwq; 928 928 929 - VM_BUG_ON(!spin_is_locked(&wqh->lock)); 929 + lockdep_assert_held(&wqh->lock); 930 930 931 931 uwq = NULL; 932 932 if (!waitqueue_active(wqh))
+1 -1
include/linux/percpu-rwsem.h
··· 41 41 * cannot both change sem->state from readers_fast and start checking 42 42 * counters while we are here. So if we see !sem->state, we know that 43 43 * the writer won't be checking until we're past the preempt_enable() 44 - * and that one the synchronize_sched() is done, the writer will see 44 + * and that once the synchronize_rcu() is done, the writer will see 45 45 * anything we did within this RCU-sched read-size critical section. 46 46 */ 47 47 __this_cpu_inc(*sem->read_count);
-17
include/linux/rcupdate_wait.h
··· 31 31 32 32 #define wait_rcu_gp(...) _wait_rcu_gp(false, __VA_ARGS__) 33 33 34 - /** 35 - * synchronize_rcu_mult - Wait concurrently for multiple grace periods 36 - * @...: List of call_rcu() functions for different grace periods to wait on 37 - * 38 - * This macro waits concurrently for multiple types of RCU grace periods. 39 - * For example, synchronize_rcu_mult(call_rcu, call_rcu_tasks) would wait 40 - * on concurrent RCU and RCU-tasks grace periods. Waiting on a give SRCU 41 - * domain requires you to write a wrapper function for that SRCU domain's 42 - * call_srcu() function, supplying the corresponding srcu_struct. 43 - * 44 - * If Tiny RCU, tell _wait_rcu_gp() does not bother waiting for RCU, 45 - * given that anywhere synchronize_rcu_mult() can be called is automatically 46 - * a grace period. 47 - */ 48 - #define synchronize_rcu_mult(...) \ 49 - _wait_rcu_gp(IS_ENABLED(CONFIG_TINY_RCU), __VA_ARGS__) 50 - 51 34 #endif /* _LINUX_SCHED_RCUPDATE_WAIT_H */
+3 -1
include/linux/sched.h
··· 572 572 struct { 573 573 u8 blocked; 574 574 u8 need_qs; 575 + u8 exp_hint; /* Hint for performance. */ 576 + u8 pad; /* No garbage from compiler! */ 575 577 } b; /* Bits. */ 576 - u16 s; /* Set of bits. */ 578 + u32 s; /* Set of bits. */ 577 579 }; 578 580 579 581 enum perf_event_task_context {
+41 -38
include/linux/srcu.h
··· 38 38 39 39 #ifdef CONFIG_DEBUG_LOCK_ALLOC 40 40 41 - int __init_srcu_struct(struct srcu_struct *sp, const char *name, 41 + int __init_srcu_struct(struct srcu_struct *ssp, const char *name, 42 42 struct lock_class_key *key); 43 43 44 - #define init_srcu_struct(sp) \ 44 + #define init_srcu_struct(ssp) \ 45 45 ({ \ 46 46 static struct lock_class_key __srcu_key; \ 47 47 \ 48 - __init_srcu_struct((sp), #sp, &__srcu_key); \ 48 + __init_srcu_struct((ssp), #ssp, &__srcu_key); \ 49 49 }) 50 50 51 51 #define __SRCU_DEP_MAP_INIT(srcu_name) .dep_map = { .name = #srcu_name }, 52 52 #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ 53 53 54 - int init_srcu_struct(struct srcu_struct *sp); 54 + int init_srcu_struct(struct srcu_struct *ssp); 55 55 56 56 #define __SRCU_DEP_MAP_INIT(srcu_name) 57 57 #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ ··· 67 67 struct srcu_struct { }; 68 68 #endif 69 69 70 - void call_srcu(struct srcu_struct *sp, struct rcu_head *head, 70 + void call_srcu(struct srcu_struct *ssp, struct rcu_head *head, 71 71 void (*func)(struct rcu_head *head)); 72 - void _cleanup_srcu_struct(struct srcu_struct *sp, bool quiesced); 73 - int __srcu_read_lock(struct srcu_struct *sp) __acquires(sp); 74 - void __srcu_read_unlock(struct srcu_struct *sp, int idx) __releases(sp); 75 - void synchronize_srcu(struct srcu_struct *sp); 72 + void _cleanup_srcu_struct(struct srcu_struct *ssp, bool quiesced); 73 + int __srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp); 74 + void __srcu_read_unlock(struct srcu_struct *ssp, int idx) __releases(ssp); 75 + void synchronize_srcu(struct srcu_struct *ssp); 76 76 77 77 /** 78 78 * cleanup_srcu_struct - deconstruct a sleep-RCU structure 79 - * @sp: structure to clean up. 79 + * @ssp: structure to clean up. 80 80 * 81 81 * Must invoke this after you are finished using a given srcu_struct that 82 82 * was initialized via init_srcu_struct(), else you leak memory. 83 83 */ 84 - static inline void cleanup_srcu_struct(struct srcu_struct *sp) 84 + static inline void cleanup_srcu_struct(struct srcu_struct *ssp) 85 85 { 86 - _cleanup_srcu_struct(sp, false); 86 + _cleanup_srcu_struct(ssp, false); 87 87 } 88 88 89 89 /** 90 90 * cleanup_srcu_struct_quiesced - deconstruct a quiesced sleep-RCU structure 91 - * @sp: structure to clean up. 91 + * @ssp: structure to clean up. 92 92 * 93 93 * Must invoke this after you are finished using a given srcu_struct that 94 94 * was initialized via init_srcu_struct(), else you leak memory. Also, ··· 103 103 * (with high probability, anyway), and will also cause the srcu_struct 104 104 * to be leaked. 105 105 */ 106 - static inline void cleanup_srcu_struct_quiesced(struct srcu_struct *sp) 106 + static inline void cleanup_srcu_struct_quiesced(struct srcu_struct *ssp) 107 107 { 108 - _cleanup_srcu_struct(sp, true); 108 + _cleanup_srcu_struct(ssp, true); 109 109 } 110 110 111 111 #ifdef CONFIG_DEBUG_LOCK_ALLOC 112 112 113 113 /** 114 114 * srcu_read_lock_held - might we be in SRCU read-side critical section? 115 - * @sp: The srcu_struct structure to check 115 + * @ssp: The srcu_struct structure to check 116 116 * 117 117 * If CONFIG_DEBUG_LOCK_ALLOC is selected, returns nonzero iff in an SRCU 118 118 * read-side critical section. In absence of CONFIG_DEBUG_LOCK_ALLOC, ··· 126 126 * relies on normal RCU, it can be called from the CPU which 127 127 * is in the idle loop from an RCU point of view or offline. 128 128 */ 129 - static inline int srcu_read_lock_held(const struct srcu_struct *sp) 129 + static inline int srcu_read_lock_held(const struct srcu_struct *ssp) 130 130 { 131 131 if (!debug_lockdep_rcu_enabled()) 132 132 return 1; 133 - return lock_is_held(&sp->dep_map); 133 + return lock_is_held(&ssp->dep_map); 134 134 } 135 135 136 136 #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ 137 137 138 - static inline int srcu_read_lock_held(const struct srcu_struct *sp) 138 + static inline int srcu_read_lock_held(const struct srcu_struct *ssp) 139 139 { 140 140 return 1; 141 141 } ··· 145 145 /** 146 146 * srcu_dereference_check - fetch SRCU-protected pointer for later dereferencing 147 147 * @p: the pointer to fetch and protect for later dereferencing 148 - * @sp: pointer to the srcu_struct, which is used to check that we 148 + * @ssp: pointer to the srcu_struct, which is used to check that we 149 149 * really are in an SRCU read-side critical section. 150 150 * @c: condition to check for update-side use 151 151 * ··· 154 154 * to 1. The @c argument will normally be a logical expression containing 155 155 * lockdep_is_held() calls. 156 156 */ 157 - #define srcu_dereference_check(p, sp, c) \ 158 - __rcu_dereference_check((p), (c) || srcu_read_lock_held(sp), __rcu) 157 + #define srcu_dereference_check(p, ssp, c) \ 158 + __rcu_dereference_check((p), (c) || srcu_read_lock_held(ssp), __rcu) 159 159 160 160 /** 161 161 * srcu_dereference - fetch SRCU-protected pointer for later dereferencing 162 162 * @p: the pointer to fetch and protect for later dereferencing 163 - * @sp: pointer to the srcu_struct, which is used to check that we 163 + * @ssp: pointer to the srcu_struct, which is used to check that we 164 164 * really are in an SRCU read-side critical section. 165 165 * 166 166 * Makes rcu_dereference_check() do the dirty work. If PROVE_RCU 167 167 * is enabled, invoking this outside of an RCU read-side critical 168 168 * section will result in an RCU-lockdep splat. 169 169 */ 170 - #define srcu_dereference(p, sp) srcu_dereference_check((p), (sp), 0) 170 + #define srcu_dereference(p, ssp) srcu_dereference_check((p), (ssp), 0) 171 171 172 172 /** 173 173 * srcu_dereference_notrace - no tracing and no lockdep calls from here 174 + * @p: the pointer to fetch and protect for later dereferencing 175 + * @ssp: pointer to the srcu_struct, which is used to check that we 176 + * really are in an SRCU read-side critical section. 174 177 */ 175 - #define srcu_dereference_notrace(p, sp) srcu_dereference_check((p), (sp), 1) 178 + #define srcu_dereference_notrace(p, ssp) srcu_dereference_check((p), (ssp), 1) 176 179 177 180 /** 178 181 * srcu_read_lock - register a new reader for an SRCU-protected structure. 179 - * @sp: srcu_struct in which to register the new reader. 182 + * @ssp: srcu_struct in which to register the new reader. 180 183 * 181 184 * Enter an SRCU read-side critical section. Note that SRCU read-side 182 185 * critical sections may be nested. However, it is illegal to ··· 194 191 * srcu_read_unlock() in an irq handler if the matching srcu_read_lock() 195 192 * was invoked in process context. 196 193 */ 197 - static inline int srcu_read_lock(struct srcu_struct *sp) __acquires(sp) 194 + static inline int srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp) 198 195 { 199 196 int retval; 200 197 201 - retval = __srcu_read_lock(sp); 202 - rcu_lock_acquire(&(sp)->dep_map); 198 + retval = __srcu_read_lock(ssp); 199 + rcu_lock_acquire(&(ssp)->dep_map); 203 200 return retval; 204 201 } 205 202 206 203 /* Used by tracing, cannot be traced and cannot invoke lockdep. */ 207 204 static inline notrace int 208 - srcu_read_lock_notrace(struct srcu_struct *sp) __acquires(sp) 205 + srcu_read_lock_notrace(struct srcu_struct *ssp) __acquires(ssp) 209 206 { 210 207 int retval; 211 208 212 - retval = __srcu_read_lock(sp); 209 + retval = __srcu_read_lock(ssp); 213 210 return retval; 214 211 } 215 212 216 213 /** 217 214 * srcu_read_unlock - unregister a old reader from an SRCU-protected structure. 218 - * @sp: srcu_struct in which to unregister the old reader. 215 + * @ssp: srcu_struct in which to unregister the old reader. 219 216 * @idx: return value from corresponding srcu_read_lock(). 220 217 * 221 218 * Exit an SRCU read-side critical section. 222 219 */ 223 - static inline void srcu_read_unlock(struct srcu_struct *sp, int idx) 224 - __releases(sp) 220 + static inline void srcu_read_unlock(struct srcu_struct *ssp, int idx) 221 + __releases(ssp) 225 222 { 226 - rcu_lock_release(&(sp)->dep_map); 227 - __srcu_read_unlock(sp, idx); 223 + rcu_lock_release(&(ssp)->dep_map); 224 + __srcu_read_unlock(ssp, idx); 228 225 } 229 226 230 227 /* Used by tracing, cannot be traced and cannot call lockdep. */ 231 228 static inline notrace void 232 - srcu_read_unlock_notrace(struct srcu_struct *sp, int idx) __releases(sp) 229 + srcu_read_unlock_notrace(struct srcu_struct *ssp, int idx) __releases(ssp) 233 230 { 234 - __srcu_read_unlock(sp, idx); 231 + __srcu_read_unlock(ssp, idx); 235 232 } 236 233 237 234 /**
+12 -12
include/linux/srcutiny.h
··· 60 60 #define DEFINE_STATIC_SRCU(name) \ 61 61 static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name) 62 62 63 - void synchronize_srcu(struct srcu_struct *sp); 63 + void synchronize_srcu(struct srcu_struct *ssp); 64 64 65 65 /* 66 66 * Counts the new reader in the appropriate per-CPU element of the ··· 68 68 * __srcu_read_unlock() must be in the same handler instance. Returns an 69 69 * index that must be passed to the matching srcu_read_unlock(). 70 70 */ 71 - static inline int __srcu_read_lock(struct srcu_struct *sp) 71 + static inline int __srcu_read_lock(struct srcu_struct *ssp) 72 72 { 73 73 int idx; 74 74 75 - idx = READ_ONCE(sp->srcu_idx); 76 - WRITE_ONCE(sp->srcu_lock_nesting[idx], sp->srcu_lock_nesting[idx] + 1); 75 + idx = READ_ONCE(ssp->srcu_idx); 76 + WRITE_ONCE(ssp->srcu_lock_nesting[idx], ssp->srcu_lock_nesting[idx] + 1); 77 77 return idx; 78 78 } 79 79 80 - static inline void synchronize_srcu_expedited(struct srcu_struct *sp) 80 + static inline void synchronize_srcu_expedited(struct srcu_struct *ssp) 81 81 { 82 - synchronize_srcu(sp); 82 + synchronize_srcu(ssp); 83 83 } 84 84 85 - static inline void srcu_barrier(struct srcu_struct *sp) 85 + static inline void srcu_barrier(struct srcu_struct *ssp) 86 86 { 87 - synchronize_srcu(sp); 87 + synchronize_srcu(ssp); 88 88 } 89 89 90 90 /* Defined here to avoid size increase for non-torture kernels. */ 91 - static inline void srcu_torture_stats_print(struct srcu_struct *sp, 91 + static inline void srcu_torture_stats_print(struct srcu_struct *ssp, 92 92 char *tt, char *tf) 93 93 { 94 94 int idx; 95 95 96 - idx = READ_ONCE(sp->srcu_idx) & 0x1; 96 + idx = READ_ONCE(ssp->srcu_idx) & 0x1; 97 97 pr_alert("%s%s Tiny SRCU per-CPU(idx=%d): (%hd,%hd)\n", 98 98 tt, tf, idx, 99 - READ_ONCE(sp->srcu_lock_nesting[!idx]), 100 - READ_ONCE(sp->srcu_lock_nesting[idx])); 99 + READ_ONCE(ssp->srcu_lock_nesting[!idx]), 100 + READ_ONCE(ssp->srcu_lock_nesting[idx])); 101 101 } 102 102 103 103 #endif
+4 -4
include/linux/srcutree.h
··· 51 51 unsigned long grpmask; /* Mask for leaf srcu_node */ 52 52 /* ->srcu_data_have_cbs[]. */ 53 53 int cpu; 54 - struct srcu_struct *sp; 54 + struct srcu_struct *ssp; 55 55 }; 56 56 57 57 /* ··· 138 138 #define DEFINE_SRCU(name) __DEFINE_SRCU(name, /* not static */) 139 139 #define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static) 140 140 141 - void synchronize_srcu_expedited(struct srcu_struct *sp); 142 - void srcu_barrier(struct srcu_struct *sp); 143 - void srcu_torture_stats_print(struct srcu_struct *sp, char *tt, char *tf); 141 + void synchronize_srcu_expedited(struct srcu_struct *ssp); 142 + void srcu_barrier(struct srcu_struct *ssp); 143 + void srcu_torture_stats_print(struct srcu_struct *ssp, char *tt, char *tf); 144 144 145 145 #endif
+1 -1
include/linux/tracepoint.h
··· 82 82 static inline void tracepoint_synchronize_unregister(void) 83 83 { 84 84 synchronize_srcu(&tracepoint_srcu); 85 - synchronize_sched(); 85 + synchronize_rcu(); 86 86 } 87 87 #else 88 88 static inline void tracepoint_synchronize_unregister(void)
+2 -2
include/linux/types.h
··· 212 212 * weird ABI and we need to ask it explicitly. 213 213 * 214 214 * The alignment is required to guarantee that bit 0 of @next will be 215 - * clear under normal conditions -- as long as we use call_rcu(), 216 - * call_rcu_bh(), call_rcu_sched(), or call_srcu() to queue callback. 215 + * clear under normal conditions -- as long as we use call_rcu() or 216 + * call_srcu() to queue the callback. 217 217 * 218 218 * This guarantee is important for few reasons: 219 219 * - future call_rcu_lazy() will make use of lower bits in the pointer;
+3 -3
init/main.c
··· 1046 1046 { 1047 1047 if (rodata_enabled) { 1048 1048 /* 1049 - * load_module() results in W+X mappings, which are cleaned up 1050 - * with call_rcu_sched(). Let's make sure that queued work is 1049 + * load_module() results in W+X mappings, which are cleaned 1050 + * up with call_rcu(). Let's make sure that queued work is 1051 1051 * flushed so that we don't hit false positives looking for 1052 1052 * insecure pages which are W+X. 1053 1053 */ 1054 - rcu_barrier_sched(); 1054 + rcu_barrier(); 1055 1055 mark_rodata_ro(); 1056 1056 rodata_test(); 1057 1057 } else
+1 -1
kernel/cgroup/cgroup.c
··· 5343 5343 cgroup_rstat_boot(); 5344 5344 5345 5345 /* 5346 - * The latency of the synchronize_sched() is too high for cgroups, 5346 + * The latency of the synchronize_rcu() is too high for cgroups, 5347 5347 * avoid it at the cost of forcing all readers into the slow path. 5348 5348 */ 5349 5349 rcu_sync_enter_start(&cgroup_threadgroup_rwsem.rss);
+1 -1
kernel/events/core.c
··· 9918 9918 * call the perf scheduling hooks before proceeding to 9919 9919 * install events that need them. 9920 9920 */ 9921 - synchronize_sched(); 9921 + synchronize_rcu(); 9922 9922 } 9923 9923 /* 9924 9924 * Now that we have waited for the sync_sched(), allow further
+5 -5
kernel/kprobes.c
··· 229 229 struct kprobe_insn_page *kip, *next; 230 230 231 231 /* Ensure no-one is interrupted on the garbages */ 232 - synchronize_sched(); 232 + synchronize_rcu(); 233 233 234 234 list_for_each_entry_safe(kip, next, &c->pages, list) { 235 235 int i; ··· 1382 1382 if (ret) { 1383 1383 ap->flags |= KPROBE_FLAG_DISABLED; 1384 1384 list_del_rcu(&p->list); 1385 - synchronize_sched(); 1385 + synchronize_rcu(); 1386 1386 } 1387 1387 } 1388 1388 } ··· 1597 1597 ret = arm_kprobe(p); 1598 1598 if (ret) { 1599 1599 hlist_del_rcu(&p->hlist); 1600 - synchronize_sched(); 1600 + synchronize_rcu(); 1601 1601 goto out; 1602 1602 } 1603 1603 } ··· 1776 1776 kps[i]->addr = NULL; 1777 1777 mutex_unlock(&kprobe_mutex); 1778 1778 1779 - synchronize_sched(); 1779 + synchronize_rcu(); 1780 1780 for (i = 0; i < num; i++) 1781 1781 if (kps[i]->addr) 1782 1782 __unregister_kprobe_bottom(kps[i]); ··· 1966 1966 rps[i]->kp.addr = NULL; 1967 1967 mutex_unlock(&kprobe_mutex); 1968 1968 1969 - synchronize_sched(); 1969 + synchronize_rcu(); 1970 1970 for (i = 0; i < num; i++) { 1971 1971 if (rps[i]->kp.addr) { 1972 1972 __unregister_kprobe_bottom(&rps[i]->kp);
+2 -2
kernel/livepatch/patch.c
··· 61 61 ops = container_of(fops, struct klp_ops, fops); 62 62 63 63 /* 64 - * A variant of synchronize_sched() is used to allow patching functions 64 + * A variant of synchronize_rcu() is used to allow patching functions 65 65 * where RCU is not watching, see klp_synchronize_transition(). 66 66 */ 67 67 preempt_disable_notrace(); ··· 72 72 /* 73 73 * func should never be NULL because preemption should be disabled here 74 74 * and unregister_ftrace_function() does the equivalent of a 75 - * synchronize_sched() before the func_stack removal. 75 + * synchronize_rcu() before the func_stack removal. 76 76 */ 77 77 if (WARN_ON_ONCE(!func)) 78 78 goto unlock;
+2 -2
kernel/livepatch/transition.c
··· 52 52 53 53 /* 54 54 * This function is just a stub to implement a hard force 55 - * of synchronize_sched(). This requires synchronizing 55 + * of synchronize_rcu(). This requires synchronizing 56 56 * tasks even in userspace and idle. 57 57 */ 58 58 static void klp_sync(struct work_struct *work) ··· 175 175 void klp_update_patch_state(struct task_struct *task) 176 176 { 177 177 /* 178 - * A variant of synchronize_sched() is used to allow patching functions 178 + * A variant of synchronize_rcu() is used to allow patching functions 179 179 * where RCU is not watching, see klp_synchronize_transition(). 180 180 */ 181 181 preempt_disable_notrace();
+1 -1
kernel/locking/lockdep.c
··· 4195 4195 * 4196 4196 * sync_sched() is sufficient because the read-side is IRQ disable. 4197 4197 */ 4198 - synchronize_sched(); 4198 + synchronize_rcu(); 4199 4199 4200 4200 /* 4201 4201 * XXX at this point we could return the resources to the pool;
+2 -2
kernel/locking/mutex-debug.c
··· 36 36 37 37 void debug_mutex_wake_waiter(struct mutex *lock, struct mutex_waiter *waiter) 38 38 { 39 - SMP_DEBUG_LOCKS_WARN_ON(!spin_is_locked(&lock->wait_lock)); 39 + lockdep_assert_held(&lock->wait_lock); 40 40 DEBUG_LOCKS_WARN_ON(list_empty(&lock->wait_list)); 41 41 DEBUG_LOCKS_WARN_ON(waiter->magic != waiter); 42 42 DEBUG_LOCKS_WARN_ON(list_empty(&waiter->list)); ··· 51 51 void debug_mutex_add_waiter(struct mutex *lock, struct mutex_waiter *waiter, 52 52 struct task_struct *task) 53 53 { 54 - SMP_DEBUG_LOCKS_WARN_ON(!spin_is_locked(&lock->wait_lock)); 54 + lockdep_assert_held(&lock->wait_lock); 55 55 56 56 /* Mark the current thread as blocked on the lock: */ 57 57 task->blocked_on = waiter;
+7 -7
kernel/module.c
··· 2159 2159 /* Remove this module from bug list, this uses list_del_rcu */ 2160 2160 module_bug_cleanup(mod); 2161 2161 /* Wait for RCU-sched synchronizing before releasing mod->list and buglist. */ 2162 - synchronize_sched(); 2162 + synchronize_rcu(); 2163 2163 mutex_unlock(&module_mutex); 2164 2164 2165 2165 /* This may be empty, but that's OK */ ··· 3507 3507 /* 3508 3508 * We want to free module_init, but be aware that kallsyms may be 3509 3509 * walking this with preempt disabled. In all the failure paths, we 3510 - * call synchronize_sched(), but we don't want to slow down the success 3510 + * call synchronize_rcu(), but we don't want to slow down the success 3511 3511 * path, so use actual RCU here. 3512 3512 * Note that module_alloc() on most architectures creates W+X page 3513 3513 * mappings which won't be cleaned up until do_free_init() runs. Any 3514 3514 * code such as mark_rodata_ro() which depends on those mappings to 3515 3515 * be cleaned up needs to sync with the queued work - ie 3516 - * rcu_barrier_sched() 3516 + * rcu_barrier() 3517 3517 */ 3518 - call_rcu_sched(&freeinit->rcu, do_free_init); 3518 + call_rcu(&freeinit->rcu, do_free_init); 3519 3519 mutex_unlock(&module_mutex); 3520 3520 wake_up_all(&module_wq); 3521 3521 ··· 3526 3526 fail: 3527 3527 /* Try to protect us from buggy refcounters. */ 3528 3528 mod->state = MODULE_STATE_GOING; 3529 - synchronize_sched(); 3529 + synchronize_rcu(); 3530 3530 module_put(mod); 3531 3531 blocking_notifier_call_chain(&module_notify_list, 3532 3532 MODULE_STATE_GOING, mod); ··· 3819 3819 ddebug_cleanup: 3820 3820 ftrace_release_mod(mod); 3821 3821 dynamic_debug_remove(mod, info->debug); 3822 - synchronize_sched(); 3822 + synchronize_rcu(); 3823 3823 kfree(mod->args); 3824 3824 free_arch_cleanup: 3825 3825 module_arch_cleanup(mod); ··· 3834 3834 mod_tree_remove(mod); 3835 3835 wake_up_all(&module_wq); 3836 3836 /* Wait for RCU-sched synchronizing before releasing mod->list. */ 3837 - synchronize_sched(); 3837 + synchronize_rcu(); 3838 3838 mutex_unlock(&module_mutex); 3839 3839 free_module: 3840 3840 /* Free lock-classes; relies on the preceding sync_rcu() */
+60 -60
kernel/rcu/srcutiny.c
··· 37 37 static LIST_HEAD(srcu_boot_list); 38 38 static bool srcu_init_done; 39 39 40 - static int init_srcu_struct_fields(struct srcu_struct *sp) 40 + static int init_srcu_struct_fields(struct srcu_struct *ssp) 41 41 { 42 - sp->srcu_lock_nesting[0] = 0; 43 - sp->srcu_lock_nesting[1] = 0; 44 - init_swait_queue_head(&sp->srcu_wq); 45 - sp->srcu_cb_head = NULL; 46 - sp->srcu_cb_tail = &sp->srcu_cb_head; 47 - sp->srcu_gp_running = false; 48 - sp->srcu_gp_waiting = false; 49 - sp->srcu_idx = 0; 50 - INIT_WORK(&sp->srcu_work, srcu_drive_gp); 51 - INIT_LIST_HEAD(&sp->srcu_work.entry); 42 + ssp->srcu_lock_nesting[0] = 0; 43 + ssp->srcu_lock_nesting[1] = 0; 44 + init_swait_queue_head(&ssp->srcu_wq); 45 + ssp->srcu_cb_head = NULL; 46 + ssp->srcu_cb_tail = &ssp->srcu_cb_head; 47 + ssp->srcu_gp_running = false; 48 + ssp->srcu_gp_waiting = false; 49 + ssp->srcu_idx = 0; 50 + INIT_WORK(&ssp->srcu_work, srcu_drive_gp); 51 + INIT_LIST_HEAD(&ssp->srcu_work.entry); 52 52 return 0; 53 53 } 54 54 55 55 #ifdef CONFIG_DEBUG_LOCK_ALLOC 56 56 57 - int __init_srcu_struct(struct srcu_struct *sp, const char *name, 57 + int __init_srcu_struct(struct srcu_struct *ssp, const char *name, 58 58 struct lock_class_key *key) 59 59 { 60 60 /* Don't re-initialize a lock while it is held. */ 61 - debug_check_no_locks_freed((void *)sp, sizeof(*sp)); 62 - lockdep_init_map(&sp->dep_map, name, key, 0); 63 - return init_srcu_struct_fields(sp); 61 + debug_check_no_locks_freed((void *)ssp, sizeof(*ssp)); 62 + lockdep_init_map(&ssp->dep_map, name, key, 0); 63 + return init_srcu_struct_fields(ssp); 64 64 } 65 65 EXPORT_SYMBOL_GPL(__init_srcu_struct); 66 66 ··· 68 68 69 69 /* 70 70 * init_srcu_struct - initialize a sleep-RCU structure 71 - * @sp: structure to initialize. 71 + * @ssp: structure to initialize. 72 72 * 73 73 * Must invoke this on a given srcu_struct before passing that srcu_struct 74 74 * to any other function. Each srcu_struct represents a separate domain 75 75 * of SRCU protection. 76 76 */ 77 - int init_srcu_struct(struct srcu_struct *sp) 77 + int init_srcu_struct(struct srcu_struct *ssp) 78 78 { 79 - return init_srcu_struct_fields(sp); 79 + return init_srcu_struct_fields(ssp); 80 80 } 81 81 EXPORT_SYMBOL_GPL(init_srcu_struct); 82 82 ··· 84 84 85 85 /* 86 86 * cleanup_srcu_struct - deconstruct a sleep-RCU structure 87 - * @sp: structure to clean up. 87 + * @ssp: structure to clean up. 88 88 * 89 89 * Must invoke this after you are finished using a given srcu_struct that 90 90 * was initialized via init_srcu_struct(), else you leak memory. 91 91 */ 92 - void _cleanup_srcu_struct(struct srcu_struct *sp, bool quiesced) 92 + void _cleanup_srcu_struct(struct srcu_struct *ssp, bool quiesced) 93 93 { 94 - WARN_ON(sp->srcu_lock_nesting[0] || sp->srcu_lock_nesting[1]); 94 + WARN_ON(ssp->srcu_lock_nesting[0] || ssp->srcu_lock_nesting[1]); 95 95 if (quiesced) 96 - WARN_ON(work_pending(&sp->srcu_work)); 96 + WARN_ON(work_pending(&ssp->srcu_work)); 97 97 else 98 - flush_work(&sp->srcu_work); 99 - WARN_ON(sp->srcu_gp_running); 100 - WARN_ON(sp->srcu_gp_waiting); 101 - WARN_ON(sp->srcu_cb_head); 102 - WARN_ON(&sp->srcu_cb_head != sp->srcu_cb_tail); 98 + flush_work(&ssp->srcu_work); 99 + WARN_ON(ssp->srcu_gp_running); 100 + WARN_ON(ssp->srcu_gp_waiting); 101 + WARN_ON(ssp->srcu_cb_head); 102 + WARN_ON(&ssp->srcu_cb_head != ssp->srcu_cb_tail); 103 103 } 104 104 EXPORT_SYMBOL_GPL(_cleanup_srcu_struct); 105 105 ··· 107 107 * Removes the count for the old reader from the appropriate element of 108 108 * the srcu_struct. 109 109 */ 110 - void __srcu_read_unlock(struct srcu_struct *sp, int idx) 110 + void __srcu_read_unlock(struct srcu_struct *ssp, int idx) 111 111 { 112 - int newval = sp->srcu_lock_nesting[idx] - 1; 112 + int newval = ssp->srcu_lock_nesting[idx] - 1; 113 113 114 - WRITE_ONCE(sp->srcu_lock_nesting[idx], newval); 115 - if (!newval && READ_ONCE(sp->srcu_gp_waiting)) 116 - swake_up_one(&sp->srcu_wq); 114 + WRITE_ONCE(ssp->srcu_lock_nesting[idx], newval); 115 + if (!newval && READ_ONCE(ssp->srcu_gp_waiting)) 116 + swake_up_one(&ssp->srcu_wq); 117 117 } 118 118 EXPORT_SYMBOL_GPL(__srcu_read_unlock); 119 119 ··· 127 127 int idx; 128 128 struct rcu_head *lh; 129 129 struct rcu_head *rhp; 130 - struct srcu_struct *sp; 130 + struct srcu_struct *ssp; 131 131 132 - sp = container_of(wp, struct srcu_struct, srcu_work); 133 - if (sp->srcu_gp_running || !READ_ONCE(sp->srcu_cb_head)) 132 + ssp = container_of(wp, struct srcu_struct, srcu_work); 133 + if (ssp->srcu_gp_running || !READ_ONCE(ssp->srcu_cb_head)) 134 134 return; /* Already running or nothing to do. */ 135 135 136 136 /* Remove recently arrived callbacks and wait for readers. */ 137 - WRITE_ONCE(sp->srcu_gp_running, true); 137 + WRITE_ONCE(ssp->srcu_gp_running, true); 138 138 local_irq_disable(); 139 - lh = sp->srcu_cb_head; 140 - sp->srcu_cb_head = NULL; 141 - sp->srcu_cb_tail = &sp->srcu_cb_head; 139 + lh = ssp->srcu_cb_head; 140 + ssp->srcu_cb_head = NULL; 141 + ssp->srcu_cb_tail = &ssp->srcu_cb_head; 142 142 local_irq_enable(); 143 - idx = sp->srcu_idx; 144 - WRITE_ONCE(sp->srcu_idx, !sp->srcu_idx); 145 - WRITE_ONCE(sp->srcu_gp_waiting, true); /* srcu_read_unlock() wakes! */ 146 - swait_event_exclusive(sp->srcu_wq, !READ_ONCE(sp->srcu_lock_nesting[idx])); 147 - WRITE_ONCE(sp->srcu_gp_waiting, false); /* srcu_read_unlock() cheap. */ 143 + idx = ssp->srcu_idx; 144 + WRITE_ONCE(ssp->srcu_idx, !ssp->srcu_idx); 145 + WRITE_ONCE(ssp->srcu_gp_waiting, true); /* srcu_read_unlock() wakes! */ 146 + swait_event_exclusive(ssp->srcu_wq, !READ_ONCE(ssp->srcu_lock_nesting[idx])); 147 + WRITE_ONCE(ssp->srcu_gp_waiting, false); /* srcu_read_unlock() cheap. */ 148 148 149 149 /* Invoke the callbacks we removed above. */ 150 150 while (lh) { ··· 161 161 * at interrupt level, but the ->srcu_gp_running checks will 162 162 * straighten that out. 163 163 */ 164 - WRITE_ONCE(sp->srcu_gp_running, false); 165 - if (READ_ONCE(sp->srcu_cb_head)) 166 - schedule_work(&sp->srcu_work); 164 + WRITE_ONCE(ssp->srcu_gp_running, false); 165 + if (READ_ONCE(ssp->srcu_cb_head)) 166 + schedule_work(&ssp->srcu_work); 167 167 } 168 168 EXPORT_SYMBOL_GPL(srcu_drive_gp); 169 169 ··· 171 171 * Enqueue an SRCU callback on the specified srcu_struct structure, 172 172 * initiating grace-period processing if it is not already running. 173 173 */ 174 - void call_srcu(struct srcu_struct *sp, struct rcu_head *rhp, 174 + void call_srcu(struct srcu_struct *ssp, struct rcu_head *rhp, 175 175 rcu_callback_t func) 176 176 { 177 177 unsigned long flags; ··· 179 179 rhp->func = func; 180 180 rhp->next = NULL; 181 181 local_irq_save(flags); 182 - *sp->srcu_cb_tail = rhp; 183 - sp->srcu_cb_tail = &rhp->next; 182 + *ssp->srcu_cb_tail = rhp; 183 + ssp->srcu_cb_tail = &rhp->next; 184 184 local_irq_restore(flags); 185 - if (!READ_ONCE(sp->srcu_gp_running)) { 185 + if (!READ_ONCE(ssp->srcu_gp_running)) { 186 186 if (likely(srcu_init_done)) 187 - schedule_work(&sp->srcu_work); 188 - else if (list_empty(&sp->srcu_work.entry)) 189 - list_add(&sp->srcu_work.entry, &srcu_boot_list); 187 + schedule_work(&ssp->srcu_work); 188 + else if (list_empty(&ssp->srcu_work.entry)) 189 + list_add(&ssp->srcu_work.entry, &srcu_boot_list); 190 190 } 191 191 } 192 192 EXPORT_SYMBOL_GPL(call_srcu); ··· 194 194 /* 195 195 * synchronize_srcu - wait for prior SRCU read-side critical-section completion 196 196 */ 197 - void synchronize_srcu(struct srcu_struct *sp) 197 + void synchronize_srcu(struct srcu_struct *ssp) 198 198 { 199 199 struct rcu_synchronize rs; 200 200 201 201 init_rcu_head_on_stack(&rs.head); 202 202 init_completion(&rs.completion); 203 - call_srcu(sp, &rs.head, wakeme_after_rcu); 203 + call_srcu(ssp, &rs.head, wakeme_after_rcu); 204 204 wait_for_completion(&rs.completion); 205 205 destroy_rcu_head_on_stack(&rs.head); 206 206 } ··· 219 219 */ 220 220 void __init srcu_init(void) 221 221 { 222 - struct srcu_struct *sp; 222 + struct srcu_struct *ssp; 223 223 224 224 srcu_init_done = true; 225 225 while (!list_empty(&srcu_boot_list)) { 226 - sp = list_first_entry(&srcu_boot_list, 226 + ssp = list_first_entry(&srcu_boot_list, 227 227 struct srcu_struct, srcu_work.entry); 228 - list_del_init(&sp->srcu_work.entry); 229 - schedule_work(&sp->srcu_work); 228 + list_del_init(&ssp->srcu_work.entry); 229 + schedule_work(&ssp->srcu_work); 230 230 } 231 231 }
+247 -242
kernel/rcu/srcutree.c
··· 56 56 static bool __read_mostly srcu_init_done; 57 57 58 58 static void srcu_invoke_callbacks(struct work_struct *work); 59 - static void srcu_reschedule(struct srcu_struct *sp, unsigned long delay); 59 + static void srcu_reschedule(struct srcu_struct *ssp, unsigned long delay); 60 60 static void process_srcu(struct work_struct *work); 61 61 62 62 /* Wrappers for lock acquisition and release, see raw_spin_lock_rcu_node(). */ ··· 92 92 * srcu_read_unlock() running against them. So if the is_static parameter 93 93 * is set, don't initialize ->srcu_lock_count[] and ->srcu_unlock_count[]. 94 94 */ 95 - static void init_srcu_struct_nodes(struct srcu_struct *sp, bool is_static) 95 + static void init_srcu_struct_nodes(struct srcu_struct *ssp, bool is_static) 96 96 { 97 97 int cpu; 98 98 int i; ··· 103 103 struct srcu_node *snp_first; 104 104 105 105 /* Work out the overall tree geometry. */ 106 - sp->level[0] = &sp->node[0]; 106 + ssp->level[0] = &ssp->node[0]; 107 107 for (i = 1; i < rcu_num_lvls; i++) 108 - sp->level[i] = sp->level[i - 1] + num_rcu_lvl[i - 1]; 108 + ssp->level[i] = ssp->level[i - 1] + num_rcu_lvl[i - 1]; 109 109 rcu_init_levelspread(levelspread, num_rcu_lvl); 110 110 111 111 /* Each pass through this loop initializes one srcu_node structure. */ 112 - srcu_for_each_node_breadth_first(sp, snp) { 112 + srcu_for_each_node_breadth_first(ssp, snp) { 113 113 spin_lock_init(&ACCESS_PRIVATE(snp, lock)); 114 114 WARN_ON_ONCE(ARRAY_SIZE(snp->srcu_have_cbs) != 115 115 ARRAY_SIZE(snp->srcu_data_have_cbs)); ··· 120 120 snp->srcu_gp_seq_needed_exp = 0; 121 121 snp->grplo = -1; 122 122 snp->grphi = -1; 123 - if (snp == &sp->node[0]) { 123 + if (snp == &ssp->node[0]) { 124 124 /* Root node, special case. */ 125 125 snp->srcu_parent = NULL; 126 126 continue; 127 127 } 128 128 129 129 /* Non-root node. */ 130 - if (snp == sp->level[level + 1]) 130 + if (snp == ssp->level[level + 1]) 131 131 level++; 132 - snp->srcu_parent = sp->level[level - 1] + 133 - (snp - sp->level[level]) / 132 + snp->srcu_parent = ssp->level[level - 1] + 133 + (snp - ssp->level[level]) / 134 134 levelspread[level - 1]; 135 135 } 136 136 ··· 141 141 WARN_ON_ONCE(ARRAY_SIZE(sdp->srcu_lock_count) != 142 142 ARRAY_SIZE(sdp->srcu_unlock_count)); 143 143 level = rcu_num_lvls - 1; 144 - snp_first = sp->level[level]; 144 + snp_first = ssp->level[level]; 145 145 for_each_possible_cpu(cpu) { 146 - sdp = per_cpu_ptr(sp->sda, cpu); 146 + sdp = per_cpu_ptr(ssp->sda, cpu); 147 147 spin_lock_init(&ACCESS_PRIVATE(sdp, lock)); 148 148 rcu_segcblist_init(&sdp->srcu_cblist); 149 149 sdp->srcu_cblist_invoking = false; 150 - sdp->srcu_gp_seq_needed = sp->srcu_gp_seq; 151 - sdp->srcu_gp_seq_needed_exp = sp->srcu_gp_seq; 150 + sdp->srcu_gp_seq_needed = ssp->srcu_gp_seq; 151 + sdp->srcu_gp_seq_needed_exp = ssp->srcu_gp_seq; 152 152 sdp->mynode = &snp_first[cpu / levelspread[level]]; 153 153 for (snp = sdp->mynode; snp != NULL; snp = snp->srcu_parent) { 154 154 if (snp->grplo < 0) ··· 157 157 } 158 158 sdp->cpu = cpu; 159 159 INIT_DELAYED_WORK(&sdp->work, srcu_invoke_callbacks); 160 - sdp->sp = sp; 160 + sdp->ssp = ssp; 161 161 sdp->grpmask = 1 << (cpu - sdp->mynode->grplo); 162 162 if (is_static) 163 163 continue; ··· 176 176 * parameter is passed through to init_srcu_struct_nodes(), and 177 177 * also tells us that ->sda has already been wired up to srcu_data. 178 178 */ 179 - static int init_srcu_struct_fields(struct srcu_struct *sp, bool is_static) 179 + static int init_srcu_struct_fields(struct srcu_struct *ssp, bool is_static) 180 180 { 181 - mutex_init(&sp->srcu_cb_mutex); 182 - mutex_init(&sp->srcu_gp_mutex); 183 - sp->srcu_idx = 0; 184 - sp->srcu_gp_seq = 0; 185 - sp->srcu_barrier_seq = 0; 186 - mutex_init(&sp->srcu_barrier_mutex); 187 - atomic_set(&sp->srcu_barrier_cpu_cnt, 0); 188 - INIT_DELAYED_WORK(&sp->work, process_srcu); 181 + mutex_init(&ssp->srcu_cb_mutex); 182 + mutex_init(&ssp->srcu_gp_mutex); 183 + ssp->srcu_idx = 0; 184 + ssp->srcu_gp_seq = 0; 185 + ssp->srcu_barrier_seq = 0; 186 + mutex_init(&ssp->srcu_barrier_mutex); 187 + atomic_set(&ssp->srcu_barrier_cpu_cnt, 0); 188 + INIT_DELAYED_WORK(&ssp->work, process_srcu); 189 189 if (!is_static) 190 - sp->sda = alloc_percpu(struct srcu_data); 191 - init_srcu_struct_nodes(sp, is_static); 192 - sp->srcu_gp_seq_needed_exp = 0; 193 - sp->srcu_last_gp_end = ktime_get_mono_fast_ns(); 194 - smp_store_release(&sp->srcu_gp_seq_needed, 0); /* Init done. */ 195 - return sp->sda ? 0 : -ENOMEM; 190 + ssp->sda = alloc_percpu(struct srcu_data); 191 + init_srcu_struct_nodes(ssp, is_static); 192 + ssp->srcu_gp_seq_needed_exp = 0; 193 + ssp->srcu_last_gp_end = ktime_get_mono_fast_ns(); 194 + smp_store_release(&ssp->srcu_gp_seq_needed, 0); /* Init done. */ 195 + return ssp->sda ? 0 : -ENOMEM; 196 196 } 197 197 198 198 #ifdef CONFIG_DEBUG_LOCK_ALLOC 199 199 200 - int __init_srcu_struct(struct srcu_struct *sp, const char *name, 200 + int __init_srcu_struct(struct srcu_struct *ssp, const char *name, 201 201 struct lock_class_key *key) 202 202 { 203 203 /* Don't re-initialize a lock while it is held. */ 204 - debug_check_no_locks_freed((void *)sp, sizeof(*sp)); 205 - lockdep_init_map(&sp->dep_map, name, key, 0); 206 - spin_lock_init(&ACCESS_PRIVATE(sp, lock)); 207 - return init_srcu_struct_fields(sp, false); 204 + debug_check_no_locks_freed((void *)ssp, sizeof(*ssp)); 205 + lockdep_init_map(&ssp->dep_map, name, key, 0); 206 + spin_lock_init(&ACCESS_PRIVATE(ssp, lock)); 207 + return init_srcu_struct_fields(ssp, false); 208 208 } 209 209 EXPORT_SYMBOL_GPL(__init_srcu_struct); 210 210 ··· 212 212 213 213 /** 214 214 * init_srcu_struct - initialize a sleep-RCU structure 215 - * @sp: structure to initialize. 215 + * @ssp: structure to initialize. 216 216 * 217 217 * Must invoke this on a given srcu_struct before passing that srcu_struct 218 218 * to any other function. Each srcu_struct represents a separate domain 219 219 * of SRCU protection. 220 220 */ 221 - int init_srcu_struct(struct srcu_struct *sp) 221 + int init_srcu_struct(struct srcu_struct *ssp) 222 222 { 223 - spin_lock_init(&ACCESS_PRIVATE(sp, lock)); 224 - return init_srcu_struct_fields(sp, false); 223 + spin_lock_init(&ACCESS_PRIVATE(ssp, lock)); 224 + return init_srcu_struct_fields(ssp, false); 225 225 } 226 226 EXPORT_SYMBOL_GPL(init_srcu_struct); 227 227 ··· 231 231 * First-use initialization of statically allocated srcu_struct 232 232 * structure. Wiring up the combining tree is more than can be 233 233 * done with compile-time initialization, so this check is added 234 - * to each update-side SRCU primitive. Use sp->lock, which -is- 234 + * to each update-side SRCU primitive. Use ssp->lock, which -is- 235 235 * compile-time initialized, to resolve races involving multiple 236 236 * CPUs trying to garner first-use privileges. 237 237 */ 238 - static void check_init_srcu_struct(struct srcu_struct *sp) 238 + static void check_init_srcu_struct(struct srcu_struct *ssp) 239 239 { 240 240 unsigned long flags; 241 241 242 242 /* The smp_load_acquire() pairs with the smp_store_release(). */ 243 - if (!rcu_seq_state(smp_load_acquire(&sp->srcu_gp_seq_needed))) /*^^^*/ 243 + if (!rcu_seq_state(smp_load_acquire(&ssp->srcu_gp_seq_needed))) /*^^^*/ 244 244 return; /* Already initialized. */ 245 - spin_lock_irqsave_rcu_node(sp, flags); 246 - if (!rcu_seq_state(sp->srcu_gp_seq_needed)) { 247 - spin_unlock_irqrestore_rcu_node(sp, flags); 245 + spin_lock_irqsave_rcu_node(ssp, flags); 246 + if (!rcu_seq_state(ssp->srcu_gp_seq_needed)) { 247 + spin_unlock_irqrestore_rcu_node(ssp, flags); 248 248 return; 249 249 } 250 - init_srcu_struct_fields(sp, true); 251 - spin_unlock_irqrestore_rcu_node(sp, flags); 250 + init_srcu_struct_fields(ssp, true); 251 + spin_unlock_irqrestore_rcu_node(ssp, flags); 252 252 } 253 253 254 254 /* 255 255 * Returns approximate total of the readers' ->srcu_lock_count[] values 256 256 * for the rank of per-CPU counters specified by idx. 257 257 */ 258 - static unsigned long srcu_readers_lock_idx(struct srcu_struct *sp, int idx) 258 + static unsigned long srcu_readers_lock_idx(struct srcu_struct *ssp, int idx) 259 259 { 260 260 int cpu; 261 261 unsigned long sum = 0; 262 262 263 263 for_each_possible_cpu(cpu) { 264 - struct srcu_data *cpuc = per_cpu_ptr(sp->sda, cpu); 264 + struct srcu_data *cpuc = per_cpu_ptr(ssp->sda, cpu); 265 265 266 266 sum += READ_ONCE(cpuc->srcu_lock_count[idx]); 267 267 } ··· 272 272 * Returns approximate total of the readers' ->srcu_unlock_count[] values 273 273 * for the rank of per-CPU counters specified by idx. 274 274 */ 275 - static unsigned long srcu_readers_unlock_idx(struct srcu_struct *sp, int idx) 275 + static unsigned long srcu_readers_unlock_idx(struct srcu_struct *ssp, int idx) 276 276 { 277 277 int cpu; 278 278 unsigned long sum = 0; 279 279 280 280 for_each_possible_cpu(cpu) { 281 - struct srcu_data *cpuc = per_cpu_ptr(sp->sda, cpu); 281 + struct srcu_data *cpuc = per_cpu_ptr(ssp->sda, cpu); 282 282 283 283 sum += READ_ONCE(cpuc->srcu_unlock_count[idx]); 284 284 } ··· 289 289 * Return true if the number of pre-existing readers is determined to 290 290 * be zero. 291 291 */ 292 - static bool srcu_readers_active_idx_check(struct srcu_struct *sp, int idx) 292 + static bool srcu_readers_active_idx_check(struct srcu_struct *ssp, int idx) 293 293 { 294 294 unsigned long unlocks; 295 295 296 - unlocks = srcu_readers_unlock_idx(sp, idx); 296 + unlocks = srcu_readers_unlock_idx(ssp, idx); 297 297 298 298 /* 299 299 * Make sure that a lock is always counted if the corresponding ··· 329 329 * of floor(ULONG_MAX/NR_CPUS/2), which should be sufficient, 330 330 * especially on 64-bit systems. 331 331 */ 332 - return srcu_readers_lock_idx(sp, idx) == unlocks; 332 + return srcu_readers_lock_idx(ssp, idx) == unlocks; 333 333 } 334 334 335 335 /** 336 336 * srcu_readers_active - returns true if there are readers. and false 337 337 * otherwise 338 - * @sp: which srcu_struct to count active readers (holding srcu_read_lock). 338 + * @ssp: which srcu_struct to count active readers (holding srcu_read_lock). 339 339 * 340 340 * Note that this is not an atomic primitive, and can therefore suffer 341 341 * severe errors when invoked on an active srcu_struct. That said, it 342 342 * can be useful as an error check at cleanup time. 343 343 */ 344 - static bool srcu_readers_active(struct srcu_struct *sp) 344 + static bool srcu_readers_active(struct srcu_struct *ssp) 345 345 { 346 346 int cpu; 347 347 unsigned long sum = 0; 348 348 349 349 for_each_possible_cpu(cpu) { 350 - struct srcu_data *cpuc = per_cpu_ptr(sp->sda, cpu); 350 + struct srcu_data *cpuc = per_cpu_ptr(ssp->sda, cpu); 351 351 352 352 sum += READ_ONCE(cpuc->srcu_lock_count[0]); 353 353 sum += READ_ONCE(cpuc->srcu_lock_count[1]); ··· 363 363 * Return grace-period delay, zero if there are expedited grace 364 364 * periods pending, SRCU_INTERVAL otherwise. 365 365 */ 366 - static unsigned long srcu_get_delay(struct srcu_struct *sp) 366 + static unsigned long srcu_get_delay(struct srcu_struct *ssp) 367 367 { 368 - if (ULONG_CMP_LT(READ_ONCE(sp->srcu_gp_seq), 369 - READ_ONCE(sp->srcu_gp_seq_needed_exp))) 368 + if (ULONG_CMP_LT(READ_ONCE(ssp->srcu_gp_seq), 369 + READ_ONCE(ssp->srcu_gp_seq_needed_exp))) 370 370 return 0; 371 371 return SRCU_INTERVAL; 372 372 } 373 373 374 374 /* Helper for cleanup_srcu_struct() and cleanup_srcu_struct_quiesced(). */ 375 - void _cleanup_srcu_struct(struct srcu_struct *sp, bool quiesced) 375 + void _cleanup_srcu_struct(struct srcu_struct *ssp, bool quiesced) 376 376 { 377 377 int cpu; 378 378 379 - if (WARN_ON(!srcu_get_delay(sp))) 379 + if (WARN_ON(!srcu_get_delay(ssp))) 380 380 return; /* Just leak it! */ 381 - if (WARN_ON(srcu_readers_active(sp))) 381 + if (WARN_ON(srcu_readers_active(ssp))) 382 382 return; /* Just leak it! */ 383 383 if (quiesced) { 384 - if (WARN_ON(delayed_work_pending(&sp->work))) 384 + if (WARN_ON(delayed_work_pending(&ssp->work))) 385 385 return; /* Just leak it! */ 386 386 } else { 387 - flush_delayed_work(&sp->work); 387 + flush_delayed_work(&ssp->work); 388 388 } 389 389 for_each_possible_cpu(cpu) 390 390 if (quiesced) { 391 - if (WARN_ON(delayed_work_pending(&per_cpu_ptr(sp->sda, cpu)->work))) 391 + if (WARN_ON(delayed_work_pending(&per_cpu_ptr(ssp->sda, cpu)->work))) 392 392 return; /* Just leak it! */ 393 393 } else { 394 - flush_delayed_work(&per_cpu_ptr(sp->sda, cpu)->work); 394 + flush_delayed_work(&per_cpu_ptr(ssp->sda, cpu)->work); 395 395 } 396 - if (WARN_ON(rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)) != SRCU_STATE_IDLE) || 397 - WARN_ON(srcu_readers_active(sp))) { 396 + if (WARN_ON(rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)) != SRCU_STATE_IDLE) || 397 + WARN_ON(srcu_readers_active(ssp))) { 398 398 pr_info("%s: Active srcu_struct %p state: %d\n", 399 - __func__, sp, rcu_seq_state(READ_ONCE(sp->srcu_gp_seq))); 399 + __func__, ssp, rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq))); 400 400 return; /* Caller forgot to stop doing call_srcu()? */ 401 401 } 402 - free_percpu(sp->sda); 403 - sp->sda = NULL; 402 + free_percpu(ssp->sda); 403 + ssp->sda = NULL; 404 404 } 405 405 EXPORT_SYMBOL_GPL(_cleanup_srcu_struct); 406 406 ··· 409 409 * srcu_struct. 410 410 * Returns an index that must be passed to the matching srcu_read_unlock(). 411 411 */ 412 - int __srcu_read_lock(struct srcu_struct *sp) 412 + int __srcu_read_lock(struct srcu_struct *ssp) 413 413 { 414 414 int idx; 415 415 416 - idx = READ_ONCE(sp->srcu_idx) & 0x1; 417 - this_cpu_inc(sp->sda->srcu_lock_count[idx]); 416 + idx = READ_ONCE(ssp->srcu_idx) & 0x1; 417 + this_cpu_inc(ssp->sda->srcu_lock_count[idx]); 418 418 smp_mb(); /* B */ /* Avoid leaking the critical section. */ 419 419 return idx; 420 420 } ··· 425 425 * element of the srcu_struct. Note that this may well be a different 426 426 * CPU than that which was incremented by the corresponding srcu_read_lock(). 427 427 */ 428 - void __srcu_read_unlock(struct srcu_struct *sp, int idx) 428 + void __srcu_read_unlock(struct srcu_struct *ssp, int idx) 429 429 { 430 430 smp_mb(); /* C */ /* Avoid leaking the critical section. */ 431 - this_cpu_inc(sp->sda->srcu_unlock_count[idx]); 431 + this_cpu_inc(ssp->sda->srcu_unlock_count[idx]); 432 432 } 433 433 EXPORT_SYMBOL_GPL(__srcu_read_unlock); 434 434 ··· 444 444 /* 445 445 * Start an SRCU grace period. 446 446 */ 447 - static void srcu_gp_start(struct srcu_struct *sp) 447 + static void srcu_gp_start(struct srcu_struct *ssp) 448 448 { 449 - struct srcu_data *sdp = this_cpu_ptr(sp->sda); 449 + struct srcu_data *sdp = this_cpu_ptr(ssp->sda); 450 450 int state; 451 451 452 - lockdep_assert_held(&ACCESS_PRIVATE(sp, lock)); 453 - WARN_ON_ONCE(ULONG_CMP_GE(sp->srcu_gp_seq, sp->srcu_gp_seq_needed)); 452 + lockdep_assert_held(&ACCESS_PRIVATE(ssp, lock)); 453 + WARN_ON_ONCE(ULONG_CMP_GE(ssp->srcu_gp_seq, ssp->srcu_gp_seq_needed)); 454 + spin_lock_rcu_node(sdp); /* Interrupts already disabled. */ 454 455 rcu_segcblist_advance(&sdp->srcu_cblist, 455 - rcu_seq_current(&sp->srcu_gp_seq)); 456 + rcu_seq_current(&ssp->srcu_gp_seq)); 456 457 (void)rcu_segcblist_accelerate(&sdp->srcu_cblist, 457 - rcu_seq_snap(&sp->srcu_gp_seq)); 458 + rcu_seq_snap(&ssp->srcu_gp_seq)); 459 + spin_unlock_rcu_node(sdp); /* Interrupts remain disabled. */ 458 460 smp_mb(); /* Order prior store to ->srcu_gp_seq_needed vs. GP start. */ 459 - rcu_seq_start(&sp->srcu_gp_seq); 460 - state = rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)); 461 + rcu_seq_start(&ssp->srcu_gp_seq); 462 + state = rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)); 461 463 WARN_ON_ONCE(state != SRCU_STATE_SCAN1); 462 464 } 463 465 ··· 513 511 * just-completed grace period, the one corresponding to idx. If possible, 514 512 * schedule this invocation on the corresponding CPUs. 515 513 */ 516 - static void srcu_schedule_cbs_snp(struct srcu_struct *sp, struct srcu_node *snp, 514 + static void srcu_schedule_cbs_snp(struct srcu_struct *ssp, struct srcu_node *snp, 517 515 unsigned long mask, unsigned long delay) 518 516 { 519 517 int cpu; ··· 521 519 for (cpu = snp->grplo; cpu <= snp->grphi; cpu++) { 522 520 if (!(mask & (1 << (cpu - snp->grplo)))) 523 521 continue; 524 - srcu_schedule_cbs_sdp(per_cpu_ptr(sp->sda, cpu), delay); 522 + srcu_schedule_cbs_sdp(per_cpu_ptr(ssp->sda, cpu), delay); 525 523 } 526 524 } 527 525 ··· 534 532 * are initiating callback invocation. This allows the ->srcu_have_cbs[] 535 533 * array to have a finite number of elements. 536 534 */ 537 - static void srcu_gp_end(struct srcu_struct *sp) 535 + static void srcu_gp_end(struct srcu_struct *ssp) 538 536 { 539 537 unsigned long cbdelay; 540 538 bool cbs; ··· 548 546 struct srcu_node *snp; 549 547 550 548 /* Prevent more than one additional grace period. */ 551 - mutex_lock(&sp->srcu_cb_mutex); 549 + mutex_lock(&ssp->srcu_cb_mutex); 552 550 553 551 /* End the current grace period. */ 554 - spin_lock_irq_rcu_node(sp); 555 - idx = rcu_seq_state(sp->srcu_gp_seq); 552 + spin_lock_irq_rcu_node(ssp); 553 + idx = rcu_seq_state(ssp->srcu_gp_seq); 556 554 WARN_ON_ONCE(idx != SRCU_STATE_SCAN2); 557 - cbdelay = srcu_get_delay(sp); 558 - sp->srcu_last_gp_end = ktime_get_mono_fast_ns(); 559 - rcu_seq_end(&sp->srcu_gp_seq); 560 - gpseq = rcu_seq_current(&sp->srcu_gp_seq); 561 - if (ULONG_CMP_LT(sp->srcu_gp_seq_needed_exp, gpseq)) 562 - sp->srcu_gp_seq_needed_exp = gpseq; 563 - spin_unlock_irq_rcu_node(sp); 564 - mutex_unlock(&sp->srcu_gp_mutex); 555 + cbdelay = srcu_get_delay(ssp); 556 + ssp->srcu_last_gp_end = ktime_get_mono_fast_ns(); 557 + rcu_seq_end(&ssp->srcu_gp_seq); 558 + gpseq = rcu_seq_current(&ssp->srcu_gp_seq); 559 + if (ULONG_CMP_LT(ssp->srcu_gp_seq_needed_exp, gpseq)) 560 + ssp->srcu_gp_seq_needed_exp = gpseq; 561 + spin_unlock_irq_rcu_node(ssp); 562 + mutex_unlock(&ssp->srcu_gp_mutex); 565 563 /* A new grace period can start at this point. But only one. */ 566 564 567 565 /* Initiate callback invocation as needed. */ 568 566 idx = rcu_seq_ctr(gpseq) % ARRAY_SIZE(snp->srcu_have_cbs); 569 - srcu_for_each_node_breadth_first(sp, snp) { 567 + srcu_for_each_node_breadth_first(ssp, snp) { 570 568 spin_lock_irq_rcu_node(snp); 571 569 cbs = false; 572 - last_lvl = snp >= sp->level[rcu_num_lvls - 1]; 570 + last_lvl = snp >= ssp->level[rcu_num_lvls - 1]; 573 571 if (last_lvl) 574 572 cbs = snp->srcu_have_cbs[idx] == gpseq; 575 573 snp->srcu_have_cbs[idx] = gpseq; ··· 580 578 snp->srcu_data_have_cbs[idx] = 0; 581 579 spin_unlock_irq_rcu_node(snp); 582 580 if (cbs) 583 - srcu_schedule_cbs_snp(sp, snp, mask, cbdelay); 581 + srcu_schedule_cbs_snp(ssp, snp, mask, cbdelay); 584 582 585 583 /* Occasionally prevent srcu_data counter wrap. */ 586 584 if (!(gpseq & counter_wrap_check) && last_lvl) 587 585 for (cpu = snp->grplo; cpu <= snp->grphi; cpu++) { 588 - sdp = per_cpu_ptr(sp->sda, cpu); 586 + sdp = per_cpu_ptr(ssp->sda, cpu); 589 587 spin_lock_irqsave_rcu_node(sdp, flags); 590 588 if (ULONG_CMP_GE(gpseq, 591 589 sdp->srcu_gp_seq_needed + 100)) ··· 598 596 } 599 597 600 598 /* Callback initiation done, allow grace periods after next. */ 601 - mutex_unlock(&sp->srcu_cb_mutex); 599 + mutex_unlock(&ssp->srcu_cb_mutex); 602 600 603 601 /* Start a new grace period if needed. */ 604 - spin_lock_irq_rcu_node(sp); 605 - gpseq = rcu_seq_current(&sp->srcu_gp_seq); 602 + spin_lock_irq_rcu_node(ssp); 603 + gpseq = rcu_seq_current(&ssp->srcu_gp_seq); 606 604 if (!rcu_seq_state(gpseq) && 607 - ULONG_CMP_LT(gpseq, sp->srcu_gp_seq_needed)) { 608 - srcu_gp_start(sp); 609 - spin_unlock_irq_rcu_node(sp); 610 - srcu_reschedule(sp, 0); 605 + ULONG_CMP_LT(gpseq, ssp->srcu_gp_seq_needed)) { 606 + srcu_gp_start(ssp); 607 + spin_unlock_irq_rcu_node(ssp); 608 + srcu_reschedule(ssp, 0); 611 609 } else { 612 - spin_unlock_irq_rcu_node(sp); 610 + spin_unlock_irq_rcu_node(ssp); 613 611 } 614 612 } 615 613 ··· 620 618 * but without expediting. To start a completely new grace period, 621 619 * whether expedited or not, use srcu_funnel_gp_start() instead. 622 620 */ 623 - static void srcu_funnel_exp_start(struct srcu_struct *sp, struct srcu_node *snp, 621 + static void srcu_funnel_exp_start(struct srcu_struct *ssp, struct srcu_node *snp, 624 622 unsigned long s) 625 623 { 626 624 unsigned long flags; 627 625 628 626 for (; snp != NULL; snp = snp->srcu_parent) { 629 - if (rcu_seq_done(&sp->srcu_gp_seq, s) || 627 + if (rcu_seq_done(&ssp->srcu_gp_seq, s) || 630 628 ULONG_CMP_GE(READ_ONCE(snp->srcu_gp_seq_needed_exp), s)) 631 629 return; 632 630 spin_lock_irqsave_rcu_node(snp, flags); ··· 637 635 WRITE_ONCE(snp->srcu_gp_seq_needed_exp, s); 638 636 spin_unlock_irqrestore_rcu_node(snp, flags); 639 637 } 640 - spin_lock_irqsave_rcu_node(sp, flags); 641 - if (ULONG_CMP_LT(sp->srcu_gp_seq_needed_exp, s)) 642 - sp->srcu_gp_seq_needed_exp = s; 643 - spin_unlock_irqrestore_rcu_node(sp, flags); 638 + spin_lock_irqsave_rcu_node(ssp, flags); 639 + if (ULONG_CMP_LT(ssp->srcu_gp_seq_needed_exp, s)) 640 + ssp->srcu_gp_seq_needed_exp = s; 641 + spin_unlock_irqrestore_rcu_node(ssp, flags); 644 642 } 645 643 646 644 /* ··· 653 651 * Note that this function also does the work of srcu_funnel_exp_start(), 654 652 * in some cases by directly invoking it. 655 653 */ 656 - static void srcu_funnel_gp_start(struct srcu_struct *sp, struct srcu_data *sdp, 654 + static void srcu_funnel_gp_start(struct srcu_struct *ssp, struct srcu_data *sdp, 657 655 unsigned long s, bool do_norm) 658 656 { 659 657 unsigned long flags; ··· 663 661 664 662 /* Each pass through the loop does one level of the srcu_node tree. */ 665 663 for (; snp != NULL; snp = snp->srcu_parent) { 666 - if (rcu_seq_done(&sp->srcu_gp_seq, s) && snp != sdp->mynode) 664 + if (rcu_seq_done(&ssp->srcu_gp_seq, s) && snp != sdp->mynode) 667 665 return; /* GP already done and CBs recorded. */ 668 666 spin_lock_irqsave_rcu_node(snp, flags); 669 667 if (ULONG_CMP_GE(snp->srcu_have_cbs[idx], s)) { ··· 678 676 return; 679 677 } 680 678 if (!do_norm) 681 - srcu_funnel_exp_start(sp, snp, s); 679 + srcu_funnel_exp_start(ssp, snp, s); 682 680 return; 683 681 } 684 682 snp->srcu_have_cbs[idx] = s; ··· 690 688 } 691 689 692 690 /* Top of tree, must ensure the grace period will be started. */ 693 - spin_lock_irqsave_rcu_node(sp, flags); 694 - if (ULONG_CMP_LT(sp->srcu_gp_seq_needed, s)) { 691 + spin_lock_irqsave_rcu_node(ssp, flags); 692 + if (ULONG_CMP_LT(ssp->srcu_gp_seq_needed, s)) { 695 693 /* 696 694 * Record need for grace period s. Pair with load 697 695 * acquire setting up for initialization. 698 696 */ 699 - smp_store_release(&sp->srcu_gp_seq_needed, s); /*^^^*/ 697 + smp_store_release(&ssp->srcu_gp_seq_needed, s); /*^^^*/ 700 698 } 701 - if (!do_norm && ULONG_CMP_LT(sp->srcu_gp_seq_needed_exp, s)) 702 - sp->srcu_gp_seq_needed_exp = s; 699 + if (!do_norm && ULONG_CMP_LT(ssp->srcu_gp_seq_needed_exp, s)) 700 + ssp->srcu_gp_seq_needed_exp = s; 703 701 704 702 /* If grace period not already done and none in progress, start it. */ 705 - if (!rcu_seq_done(&sp->srcu_gp_seq, s) && 706 - rcu_seq_state(sp->srcu_gp_seq) == SRCU_STATE_IDLE) { 707 - WARN_ON_ONCE(ULONG_CMP_GE(sp->srcu_gp_seq, sp->srcu_gp_seq_needed)); 708 - srcu_gp_start(sp); 703 + if (!rcu_seq_done(&ssp->srcu_gp_seq, s) && 704 + rcu_seq_state(ssp->srcu_gp_seq) == SRCU_STATE_IDLE) { 705 + WARN_ON_ONCE(ULONG_CMP_GE(ssp->srcu_gp_seq, ssp->srcu_gp_seq_needed)); 706 + srcu_gp_start(ssp); 709 707 if (likely(srcu_init_done)) 710 - queue_delayed_work(rcu_gp_wq, &sp->work, 711 - srcu_get_delay(sp)); 712 - else if (list_empty(&sp->work.work.entry)) 713 - list_add(&sp->work.work.entry, &srcu_boot_list); 708 + queue_delayed_work(rcu_gp_wq, &ssp->work, 709 + srcu_get_delay(ssp)); 710 + else if (list_empty(&ssp->work.work.entry)) 711 + list_add(&ssp->work.work.entry, &srcu_boot_list); 714 712 } 715 - spin_unlock_irqrestore_rcu_node(sp, flags); 713 + spin_unlock_irqrestore_rcu_node(ssp, flags); 716 714 } 717 715 718 716 /* ··· 720 718 * loop an additional time if there is an expedited grace period pending. 721 719 * The caller must ensure that ->srcu_idx is not changed while checking. 722 720 */ 723 - static bool try_check_zero(struct srcu_struct *sp, int idx, int trycount) 721 + static bool try_check_zero(struct srcu_struct *ssp, int idx, int trycount) 724 722 { 725 723 for (;;) { 726 - if (srcu_readers_active_idx_check(sp, idx)) 724 + if (srcu_readers_active_idx_check(ssp, idx)) 727 725 return true; 728 - if (--trycount + !srcu_get_delay(sp) <= 0) 726 + if (--trycount + !srcu_get_delay(ssp) <= 0) 729 727 return false; 730 728 udelay(SRCU_RETRY_CHECK_DELAY); 731 729 } ··· 736 734 * use the other rank of the ->srcu_(un)lock_count[] arrays. This allows 737 735 * us to wait for pre-existing readers in a starvation-free manner. 738 736 */ 739 - static void srcu_flip(struct srcu_struct *sp) 737 + static void srcu_flip(struct srcu_struct *ssp) 740 738 { 741 739 /* 742 740 * Ensure that if this updater saw a given reader's increment ··· 748 746 */ 749 747 smp_mb(); /* E */ /* Pairs with B and C. */ 750 748 751 - WRITE_ONCE(sp->srcu_idx, sp->srcu_idx + 1); 749 + WRITE_ONCE(ssp->srcu_idx, ssp->srcu_idx + 1); 752 750 753 751 /* 754 752 * Ensure that if the updater misses an __srcu_read_unlock() ··· 781 779 * negligible when amoritized over that time period, and the extra latency 782 780 * of a needlessly non-expedited grace period is similarly negligible. 783 781 */ 784 - static bool srcu_might_be_idle(struct srcu_struct *sp) 782 + static bool srcu_might_be_idle(struct srcu_struct *ssp) 785 783 { 786 784 unsigned long curseq; 787 785 unsigned long flags; ··· 790 788 791 789 /* If the local srcu_data structure has callbacks, not idle. */ 792 790 local_irq_save(flags); 793 - sdp = this_cpu_ptr(sp->sda); 791 + sdp = this_cpu_ptr(ssp->sda); 794 792 if (rcu_segcblist_pend_cbs(&sdp->srcu_cblist)) { 795 793 local_irq_restore(flags); 796 794 return false; /* Callbacks already present, so not idle. */ ··· 806 804 /* First, see if enough time has passed since the last GP. */ 807 805 t = ktime_get_mono_fast_ns(); 808 806 if (exp_holdoff == 0 || 809 - time_in_range_open(t, sp->srcu_last_gp_end, 810 - sp->srcu_last_gp_end + exp_holdoff)) 807 + time_in_range_open(t, ssp->srcu_last_gp_end, 808 + ssp->srcu_last_gp_end + exp_holdoff)) 811 809 return false; /* Too soon after last GP. */ 812 810 813 811 /* Next, check for probable idleness. */ 814 - curseq = rcu_seq_current(&sp->srcu_gp_seq); 812 + curseq = rcu_seq_current(&ssp->srcu_gp_seq); 815 813 smp_mb(); /* Order ->srcu_gp_seq with ->srcu_gp_seq_needed. */ 816 - if (ULONG_CMP_LT(curseq, READ_ONCE(sp->srcu_gp_seq_needed))) 814 + if (ULONG_CMP_LT(curseq, READ_ONCE(ssp->srcu_gp_seq_needed))) 817 815 return false; /* Grace period in progress, so not idle. */ 818 816 smp_mb(); /* Order ->srcu_gp_seq with prior access. */ 819 - if (curseq != rcu_seq_current(&sp->srcu_gp_seq)) 817 + if (curseq != rcu_seq_current(&ssp->srcu_gp_seq)) 820 818 return false; /* GP # changed, so not idle. */ 821 819 return true; /* With reasonable probability, idle! */ 822 820 } ··· 856 854 * srcu_read_lock(), and srcu_read_unlock() that are all passed the same 857 855 * srcu_struct structure. 858 856 */ 859 - void __call_srcu(struct srcu_struct *sp, struct rcu_head *rhp, 857 + void __call_srcu(struct srcu_struct *ssp, struct rcu_head *rhp, 860 858 rcu_callback_t func, bool do_norm) 861 859 { 862 860 unsigned long flags; 861 + int idx; 863 862 bool needexp = false; 864 863 bool needgp = false; 865 864 unsigned long s; 866 865 struct srcu_data *sdp; 867 866 868 - check_init_srcu_struct(sp); 867 + check_init_srcu_struct(ssp); 869 868 if (debug_rcu_head_queue(rhp)) { 870 869 /* Probable double call_srcu(), so leak the callback. */ 871 870 WRITE_ONCE(rhp->func, srcu_leak_callback); ··· 874 871 return; 875 872 } 876 873 rhp->func = func; 874 + idx = srcu_read_lock(ssp); 877 875 local_irq_save(flags); 878 - sdp = this_cpu_ptr(sp->sda); 876 + sdp = this_cpu_ptr(ssp->sda); 879 877 spin_lock_rcu_node(sdp); 880 878 rcu_segcblist_enqueue(&sdp->srcu_cblist, rhp, false); 881 879 rcu_segcblist_advance(&sdp->srcu_cblist, 882 - rcu_seq_current(&sp->srcu_gp_seq)); 883 - s = rcu_seq_snap(&sp->srcu_gp_seq); 880 + rcu_seq_current(&ssp->srcu_gp_seq)); 881 + s = rcu_seq_snap(&ssp->srcu_gp_seq); 884 882 (void)rcu_segcblist_accelerate(&sdp->srcu_cblist, s); 885 883 if (ULONG_CMP_LT(sdp->srcu_gp_seq_needed, s)) { 886 884 sdp->srcu_gp_seq_needed = s; ··· 893 889 } 894 890 spin_unlock_irqrestore_rcu_node(sdp, flags); 895 891 if (needgp) 896 - srcu_funnel_gp_start(sp, sdp, s, do_norm); 892 + srcu_funnel_gp_start(ssp, sdp, s, do_norm); 897 893 else if (needexp) 898 - srcu_funnel_exp_start(sp, sdp->mynode, s); 894 + srcu_funnel_exp_start(ssp, sdp->mynode, s); 895 + srcu_read_unlock(ssp, idx); 899 896 } 900 897 901 898 /** 902 899 * call_srcu() - Queue a callback for invocation after an SRCU grace period 903 - * @sp: srcu_struct in queue the callback 900 + * @ssp: srcu_struct in queue the callback 904 901 * @rhp: structure to be used for queueing the SRCU callback. 905 902 * @func: function to be invoked after the SRCU grace period 906 903 * ··· 916 911 * The callback will be invoked from process context, but must nevertheless 917 912 * be fast and must not block. 918 913 */ 919 - void call_srcu(struct srcu_struct *sp, struct rcu_head *rhp, 914 + void call_srcu(struct srcu_struct *ssp, struct rcu_head *rhp, 920 915 rcu_callback_t func) 921 916 { 922 - __call_srcu(sp, rhp, func, true); 917 + __call_srcu(ssp, rhp, func, true); 923 918 } 924 919 EXPORT_SYMBOL_GPL(call_srcu); 925 920 926 921 /* 927 922 * Helper function for synchronize_srcu() and synchronize_srcu_expedited(). 928 923 */ 929 - static void __synchronize_srcu(struct srcu_struct *sp, bool do_norm) 924 + static void __synchronize_srcu(struct srcu_struct *ssp, bool do_norm) 930 925 { 931 926 struct rcu_synchronize rcu; 932 927 933 - RCU_LOCKDEP_WARN(lock_is_held(&sp->dep_map) || 928 + RCU_LOCKDEP_WARN(lock_is_held(&ssp->dep_map) || 934 929 lock_is_held(&rcu_bh_lock_map) || 935 930 lock_is_held(&rcu_lock_map) || 936 931 lock_is_held(&rcu_sched_lock_map), ··· 939 934 if (rcu_scheduler_active == RCU_SCHEDULER_INACTIVE) 940 935 return; 941 936 might_sleep(); 942 - check_init_srcu_struct(sp); 937 + check_init_srcu_struct(ssp); 943 938 init_completion(&rcu.completion); 944 939 init_rcu_head_on_stack(&rcu.head); 945 - __call_srcu(sp, &rcu.head, wakeme_after_rcu, do_norm); 940 + __call_srcu(ssp, &rcu.head, wakeme_after_rcu, do_norm); 946 941 wait_for_completion(&rcu.completion); 947 942 destroy_rcu_head_on_stack(&rcu.head); 948 943 ··· 958 953 959 954 /** 960 955 * synchronize_srcu_expedited - Brute-force SRCU grace period 961 - * @sp: srcu_struct with which to synchronize. 956 + * @ssp: srcu_struct with which to synchronize. 962 957 * 963 958 * Wait for an SRCU grace period to elapse, but be more aggressive about 964 959 * spinning rather than blocking when waiting. ··· 966 961 * Note that synchronize_srcu_expedited() has the same deadlock and 967 962 * memory-ordering properties as does synchronize_srcu(). 968 963 */ 969 - void synchronize_srcu_expedited(struct srcu_struct *sp) 964 + void synchronize_srcu_expedited(struct srcu_struct *ssp) 970 965 { 971 - __synchronize_srcu(sp, rcu_gp_is_normal()); 966 + __synchronize_srcu(ssp, rcu_gp_is_normal()); 972 967 } 973 968 EXPORT_SYMBOL_GPL(synchronize_srcu_expedited); 974 969 975 970 /** 976 971 * synchronize_srcu - wait for prior SRCU read-side critical-section completion 977 - * @sp: srcu_struct with which to synchronize. 972 + * @ssp: srcu_struct with which to synchronize. 978 973 * 979 974 * Wait for the count to drain to zero of both indexes. To avoid the 980 975 * possible starvation of synchronize_srcu(), it waits for the count of ··· 1016 1011 * SRCU must also provide it. Note that detecting idleness is heuristic 1017 1012 * and subject to both false positives and negatives. 1018 1013 */ 1019 - void synchronize_srcu(struct srcu_struct *sp) 1014 + void synchronize_srcu(struct srcu_struct *ssp) 1020 1015 { 1021 - if (srcu_might_be_idle(sp) || rcu_gp_is_expedited()) 1022 - synchronize_srcu_expedited(sp); 1016 + if (srcu_might_be_idle(ssp) || rcu_gp_is_expedited()) 1017 + synchronize_srcu_expedited(ssp); 1023 1018 else 1024 - __synchronize_srcu(sp, true); 1019 + __synchronize_srcu(ssp, true); 1025 1020 } 1026 1021 EXPORT_SYMBOL_GPL(synchronize_srcu); 1027 1022 ··· 1031 1026 static void srcu_barrier_cb(struct rcu_head *rhp) 1032 1027 { 1033 1028 struct srcu_data *sdp; 1034 - struct srcu_struct *sp; 1029 + struct srcu_struct *ssp; 1035 1030 1036 1031 sdp = container_of(rhp, struct srcu_data, srcu_barrier_head); 1037 - sp = sdp->sp; 1038 - if (atomic_dec_and_test(&sp->srcu_barrier_cpu_cnt)) 1039 - complete(&sp->srcu_barrier_completion); 1032 + ssp = sdp->ssp; 1033 + if (atomic_dec_and_test(&ssp->srcu_barrier_cpu_cnt)) 1034 + complete(&ssp->srcu_barrier_completion); 1040 1035 } 1041 1036 1042 1037 /** 1043 1038 * srcu_barrier - Wait until all in-flight call_srcu() callbacks complete. 1044 - * @sp: srcu_struct on which to wait for in-flight callbacks. 1039 + * @ssp: srcu_struct on which to wait for in-flight callbacks. 1045 1040 */ 1046 - void srcu_barrier(struct srcu_struct *sp) 1041 + void srcu_barrier(struct srcu_struct *ssp) 1047 1042 { 1048 1043 int cpu; 1049 1044 struct srcu_data *sdp; 1050 - unsigned long s = rcu_seq_snap(&sp->srcu_barrier_seq); 1045 + unsigned long s = rcu_seq_snap(&ssp->srcu_barrier_seq); 1051 1046 1052 - check_init_srcu_struct(sp); 1053 - mutex_lock(&sp->srcu_barrier_mutex); 1054 - if (rcu_seq_done(&sp->srcu_barrier_seq, s)) { 1047 + check_init_srcu_struct(ssp); 1048 + mutex_lock(&ssp->srcu_barrier_mutex); 1049 + if (rcu_seq_done(&ssp->srcu_barrier_seq, s)) { 1055 1050 smp_mb(); /* Force ordering following return. */ 1056 - mutex_unlock(&sp->srcu_barrier_mutex); 1051 + mutex_unlock(&ssp->srcu_barrier_mutex); 1057 1052 return; /* Someone else did our work for us. */ 1058 1053 } 1059 - rcu_seq_start(&sp->srcu_barrier_seq); 1060 - init_completion(&sp->srcu_barrier_completion); 1054 + rcu_seq_start(&ssp->srcu_barrier_seq); 1055 + init_completion(&ssp->srcu_barrier_completion); 1061 1056 1062 1057 /* Initial count prevents reaching zero until all CBs are posted. */ 1063 - atomic_set(&sp->srcu_barrier_cpu_cnt, 1); 1058 + atomic_set(&ssp->srcu_barrier_cpu_cnt, 1); 1064 1059 1065 1060 /* 1066 1061 * Each pass through this loop enqueues a callback, but only ··· 1071 1066 * grace period as the last callback already in the queue. 1072 1067 */ 1073 1068 for_each_possible_cpu(cpu) { 1074 - sdp = per_cpu_ptr(sp->sda, cpu); 1069 + sdp = per_cpu_ptr(ssp->sda, cpu); 1075 1070 spin_lock_irq_rcu_node(sdp); 1076 - atomic_inc(&sp->srcu_barrier_cpu_cnt); 1071 + atomic_inc(&ssp->srcu_barrier_cpu_cnt); 1077 1072 sdp->srcu_barrier_head.func = srcu_barrier_cb; 1078 1073 debug_rcu_head_queue(&sdp->srcu_barrier_head); 1079 1074 if (!rcu_segcblist_entrain(&sdp->srcu_cblist, 1080 1075 &sdp->srcu_barrier_head, 0)) { 1081 1076 debug_rcu_head_unqueue(&sdp->srcu_barrier_head); 1082 - atomic_dec(&sp->srcu_barrier_cpu_cnt); 1077 + atomic_dec(&ssp->srcu_barrier_cpu_cnt); 1083 1078 } 1084 1079 spin_unlock_irq_rcu_node(sdp); 1085 1080 } 1086 1081 1087 1082 /* Remove the initial count, at which point reaching zero can happen. */ 1088 - if (atomic_dec_and_test(&sp->srcu_barrier_cpu_cnt)) 1089 - complete(&sp->srcu_barrier_completion); 1090 - wait_for_completion(&sp->srcu_barrier_completion); 1083 + if (atomic_dec_and_test(&ssp->srcu_barrier_cpu_cnt)) 1084 + complete(&ssp->srcu_barrier_completion); 1085 + wait_for_completion(&ssp->srcu_barrier_completion); 1091 1086 1092 - rcu_seq_end(&sp->srcu_barrier_seq); 1093 - mutex_unlock(&sp->srcu_barrier_mutex); 1087 + rcu_seq_end(&ssp->srcu_barrier_seq); 1088 + mutex_unlock(&ssp->srcu_barrier_mutex); 1094 1089 } 1095 1090 EXPORT_SYMBOL_GPL(srcu_barrier); 1096 1091 1097 1092 /** 1098 1093 * srcu_batches_completed - return batches completed. 1099 - * @sp: srcu_struct on which to report batch completion. 1094 + * @ssp: srcu_struct on which to report batch completion. 1100 1095 * 1101 1096 * Report the number of batches, correlated with, but not necessarily 1102 1097 * precisely the same as, the number of grace periods that have elapsed. 1103 1098 */ 1104 - unsigned long srcu_batches_completed(struct srcu_struct *sp) 1099 + unsigned long srcu_batches_completed(struct srcu_struct *ssp) 1105 1100 { 1106 - return sp->srcu_idx; 1101 + return ssp->srcu_idx; 1107 1102 } 1108 1103 EXPORT_SYMBOL_GPL(srcu_batches_completed); 1109 1104 ··· 1112 1107 * to SRCU_STATE_SCAN2, and invoke srcu_gp_end() when scan has 1113 1108 * completed in that state. 1114 1109 */ 1115 - static void srcu_advance_state(struct srcu_struct *sp) 1110 + static void srcu_advance_state(struct srcu_struct *ssp) 1116 1111 { 1117 1112 int idx; 1118 1113 1119 - mutex_lock(&sp->srcu_gp_mutex); 1114 + mutex_lock(&ssp->srcu_gp_mutex); 1120 1115 1121 1116 /* 1122 1117 * Because readers might be delayed for an extended period after ··· 1128 1123 * The load-acquire ensures that we see the accesses performed 1129 1124 * by the prior grace period. 1130 1125 */ 1131 - idx = rcu_seq_state(smp_load_acquire(&sp->srcu_gp_seq)); /* ^^^ */ 1126 + idx = rcu_seq_state(smp_load_acquire(&ssp->srcu_gp_seq)); /* ^^^ */ 1132 1127 if (idx == SRCU_STATE_IDLE) { 1133 - spin_lock_irq_rcu_node(sp); 1134 - if (ULONG_CMP_GE(sp->srcu_gp_seq, sp->srcu_gp_seq_needed)) { 1135 - WARN_ON_ONCE(rcu_seq_state(sp->srcu_gp_seq)); 1136 - spin_unlock_irq_rcu_node(sp); 1137 - mutex_unlock(&sp->srcu_gp_mutex); 1128 + spin_lock_irq_rcu_node(ssp); 1129 + if (ULONG_CMP_GE(ssp->srcu_gp_seq, ssp->srcu_gp_seq_needed)) { 1130 + WARN_ON_ONCE(rcu_seq_state(ssp->srcu_gp_seq)); 1131 + spin_unlock_irq_rcu_node(ssp); 1132 + mutex_unlock(&ssp->srcu_gp_mutex); 1138 1133 return; 1139 1134 } 1140 - idx = rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)); 1135 + idx = rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)); 1141 1136 if (idx == SRCU_STATE_IDLE) 1142 - srcu_gp_start(sp); 1143 - spin_unlock_irq_rcu_node(sp); 1137 + srcu_gp_start(ssp); 1138 + spin_unlock_irq_rcu_node(ssp); 1144 1139 if (idx != SRCU_STATE_IDLE) { 1145 - mutex_unlock(&sp->srcu_gp_mutex); 1140 + mutex_unlock(&ssp->srcu_gp_mutex); 1146 1141 return; /* Someone else started the grace period. */ 1147 1142 } 1148 1143 } 1149 1144 1150 - if (rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)) == SRCU_STATE_SCAN1) { 1151 - idx = 1 ^ (sp->srcu_idx & 1); 1152 - if (!try_check_zero(sp, idx, 1)) { 1153 - mutex_unlock(&sp->srcu_gp_mutex); 1145 + if (rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)) == SRCU_STATE_SCAN1) { 1146 + idx = 1 ^ (ssp->srcu_idx & 1); 1147 + if (!try_check_zero(ssp, idx, 1)) { 1148 + mutex_unlock(&ssp->srcu_gp_mutex); 1154 1149 return; /* readers present, retry later. */ 1155 1150 } 1156 - srcu_flip(sp); 1157 - rcu_seq_set_state(&sp->srcu_gp_seq, SRCU_STATE_SCAN2); 1151 + srcu_flip(ssp); 1152 + rcu_seq_set_state(&ssp->srcu_gp_seq, SRCU_STATE_SCAN2); 1158 1153 } 1159 1154 1160 - if (rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)) == SRCU_STATE_SCAN2) { 1155 + if (rcu_seq_state(READ_ONCE(ssp->srcu_gp_seq)) == SRCU_STATE_SCAN2) { 1161 1156 1162 1157 /* 1163 1158 * SRCU read-side critical sections are normally short, 1164 1159 * so check at least twice in quick succession after a flip. 1165 1160 */ 1166 - idx = 1 ^ (sp->srcu_idx & 1); 1167 - if (!try_check_zero(sp, idx, 2)) { 1168 - mutex_unlock(&sp->srcu_gp_mutex); 1161 + idx = 1 ^ (ssp->srcu_idx & 1); 1162 + if (!try_check_zero(ssp, idx, 2)) { 1163 + mutex_unlock(&ssp->srcu_gp_mutex); 1169 1164 return; /* readers present, retry later. */ 1170 1165 } 1171 - srcu_gp_end(sp); /* Releases ->srcu_gp_mutex. */ 1166 + srcu_gp_end(ssp); /* Releases ->srcu_gp_mutex. */ 1172 1167 } 1173 1168 } 1174 1169 ··· 1184 1179 struct rcu_cblist ready_cbs; 1185 1180 struct rcu_head *rhp; 1186 1181 struct srcu_data *sdp; 1187 - struct srcu_struct *sp; 1182 + struct srcu_struct *ssp; 1188 1183 1189 1184 sdp = container_of(work, struct srcu_data, work.work); 1190 - sp = sdp->sp; 1185 + ssp = sdp->ssp; 1191 1186 rcu_cblist_init(&ready_cbs); 1192 1187 spin_lock_irq_rcu_node(sdp); 1193 1188 rcu_segcblist_advance(&sdp->srcu_cblist, 1194 - rcu_seq_current(&sp->srcu_gp_seq)); 1189 + rcu_seq_current(&ssp->srcu_gp_seq)); 1195 1190 if (sdp->srcu_cblist_invoking || 1196 1191 !rcu_segcblist_ready_cbs(&sdp->srcu_cblist)) { 1197 1192 spin_unlock_irq_rcu_node(sdp); ··· 1217 1212 spin_lock_irq_rcu_node(sdp); 1218 1213 rcu_segcblist_insert_count(&sdp->srcu_cblist, &ready_cbs); 1219 1214 (void)rcu_segcblist_accelerate(&sdp->srcu_cblist, 1220 - rcu_seq_snap(&sp->srcu_gp_seq)); 1215 + rcu_seq_snap(&ssp->srcu_gp_seq)); 1221 1216 sdp->srcu_cblist_invoking = false; 1222 1217 more = rcu_segcblist_ready_cbs(&sdp->srcu_cblist); 1223 1218 spin_unlock_irq_rcu_node(sdp); ··· 1229 1224 * Finished one round of SRCU grace period. Start another if there are 1230 1225 * more SRCU callbacks queued, otherwise put SRCU into not-running state. 1231 1226 */ 1232 - static void srcu_reschedule(struct srcu_struct *sp, unsigned long delay) 1227 + static void srcu_reschedule(struct srcu_struct *ssp, unsigned long delay) 1233 1228 { 1234 1229 bool pushgp = true; 1235 1230 1236 - spin_lock_irq_rcu_node(sp); 1237 - if (ULONG_CMP_GE(sp->srcu_gp_seq, sp->srcu_gp_seq_needed)) { 1238 - if (!WARN_ON_ONCE(rcu_seq_state(sp->srcu_gp_seq))) { 1231 + spin_lock_irq_rcu_node(ssp); 1232 + if (ULONG_CMP_GE(ssp->srcu_gp_seq, ssp->srcu_gp_seq_needed)) { 1233 + if (!WARN_ON_ONCE(rcu_seq_state(ssp->srcu_gp_seq))) { 1239 1234 /* All requests fulfilled, time to go idle. */ 1240 1235 pushgp = false; 1241 1236 } 1242 - } else if (!rcu_seq_state(sp->srcu_gp_seq)) { 1237 + } else if (!rcu_seq_state(ssp->srcu_gp_seq)) { 1243 1238 /* Outstanding request and no GP. Start one. */ 1244 - srcu_gp_start(sp); 1239 + srcu_gp_start(ssp); 1245 1240 } 1246 - spin_unlock_irq_rcu_node(sp); 1241 + spin_unlock_irq_rcu_node(ssp); 1247 1242 1248 1243 if (pushgp) 1249 - queue_delayed_work(rcu_gp_wq, &sp->work, delay); 1244 + queue_delayed_work(rcu_gp_wq, &ssp->work, delay); 1250 1245 } 1251 1246 1252 1247 /* ··· 1254 1249 */ 1255 1250 static void process_srcu(struct work_struct *work) 1256 1251 { 1257 - struct srcu_struct *sp; 1252 + struct srcu_struct *ssp; 1258 1253 1259 - sp = container_of(work, struct srcu_struct, work.work); 1254 + ssp = container_of(work, struct srcu_struct, work.work); 1260 1255 1261 - srcu_advance_state(sp); 1262 - srcu_reschedule(sp, srcu_get_delay(sp)); 1256 + srcu_advance_state(ssp); 1257 + srcu_reschedule(ssp, srcu_get_delay(ssp)); 1263 1258 } 1264 1259 1265 1260 void srcutorture_get_gp_data(enum rcutorture_type test_type, 1266 - struct srcu_struct *sp, int *flags, 1261 + struct srcu_struct *ssp, int *flags, 1267 1262 unsigned long *gp_seq) 1268 1263 { 1269 1264 if (test_type != SRCU_FLAVOR) 1270 1265 return; 1271 1266 *flags = 0; 1272 - *gp_seq = rcu_seq_current(&sp->srcu_gp_seq); 1267 + *gp_seq = rcu_seq_current(&ssp->srcu_gp_seq); 1273 1268 } 1274 1269 EXPORT_SYMBOL_GPL(srcutorture_get_gp_data); 1275 1270 1276 - void srcu_torture_stats_print(struct srcu_struct *sp, char *tt, char *tf) 1271 + void srcu_torture_stats_print(struct srcu_struct *ssp, char *tt, char *tf) 1277 1272 { 1278 1273 int cpu; 1279 1274 int idx; 1280 1275 unsigned long s0 = 0, s1 = 0; 1281 1276 1282 - idx = sp->srcu_idx & 0x1; 1277 + idx = ssp->srcu_idx & 0x1; 1283 1278 pr_alert("%s%s Tree SRCU g%ld per-CPU(idx=%d):", 1284 - tt, tf, rcu_seq_current(&sp->srcu_gp_seq), idx); 1279 + tt, tf, rcu_seq_current(&ssp->srcu_gp_seq), idx); 1285 1280 for_each_possible_cpu(cpu) { 1286 1281 unsigned long l0, l1; 1287 1282 unsigned long u0, u1; 1288 1283 long c0, c1; 1289 1284 struct srcu_data *sdp; 1290 1285 1291 - sdp = per_cpu_ptr(sp->sda, cpu); 1286 + sdp = per_cpu_ptr(ssp->sda, cpu); 1292 1287 u0 = sdp->srcu_unlock_count[!idx]; 1293 1288 u1 = sdp->srcu_unlock_count[idx]; 1294 1289 ··· 1323 1318 1324 1319 void __init srcu_init(void) 1325 1320 { 1326 - struct srcu_struct *sp; 1321 + struct srcu_struct *ssp; 1327 1322 1328 1323 srcu_init_done = true; 1329 1324 while (!list_empty(&srcu_boot_list)) { 1330 - sp = list_first_entry(&srcu_boot_list, struct srcu_struct, 1325 + ssp = list_first_entry(&srcu_boot_list, struct srcu_struct, 1331 1326 work.work.entry); 1332 - check_init_srcu_struct(sp); 1333 - list_del_init(&sp->work.work.entry); 1334 - queue_work(rcu_gp_wq, &sp->work.work); 1327 + check_init_srcu_struct(ssp); 1328 + list_del_init(&ssp->work.work.entry); 1329 + queue_work(rcu_gp_wq, &ssp->work.work); 1335 1330 } 1336 1331 }
+6 -6
kernel/rcu/sync.c
··· 44 44 __INIT_HELD(rcu_read_lock_held) 45 45 }, 46 46 [RCU_SCHED_SYNC] = { 47 - .sync = synchronize_sched, 48 - .call = call_rcu_sched, 49 - .wait = rcu_barrier_sched, 47 + .sync = synchronize_rcu, 48 + .call = call_rcu, 49 + .wait = rcu_barrier, 50 50 __INIT_HELD(rcu_read_lock_sched_held) 51 51 }, 52 52 [RCU_BH_SYNC] = { 53 - .sync = synchronize_rcu_bh, 54 - .call = call_rcu_bh, 55 - .wait = rcu_barrier_bh, 53 + .sync = synchronize_rcu, 54 + .call = call_rcu, 55 + .wait = rcu_barrier, 56 56 __INIT_HELD(rcu_read_lock_bh_held) 57 57 }, 58 58 };
+24 -21
kernel/rcu/tree.c
··· 500 500 EXPORT_SYMBOL_GPL(rcu_force_quiescent_state); 501 501 502 502 /* 503 + * Convert a ->gp_state value to a character string. 504 + */ 505 + static const char *gp_state_getname(short gs) 506 + { 507 + if (gs < 0 || gs >= ARRAY_SIZE(gp_state_names)) 508 + return "???"; 509 + return gp_state_names[gs]; 510 + } 511 + 512 + /* 503 513 * Show the state of the grace-period kthreads. 504 514 */ 505 515 void show_rcu_gp_kthreads(void) 506 516 { 507 517 int cpu; 518 + unsigned long j; 508 519 struct rcu_data *rdp; 509 520 struct rcu_node *rnp; 510 521 511 - pr_info("%s: wait state: %d ->state: %#lx\n", rcu_state.name, 512 - rcu_state.gp_state, rcu_state.gp_kthread->state); 522 + j = jiffies - READ_ONCE(rcu_state.gp_activity); 523 + pr_info("%s: wait state: %s(%d) ->state: %#lx delta ->gp_activity %ld\n", 524 + rcu_state.name, gp_state_getname(rcu_state.gp_state), 525 + rcu_state.gp_state, rcu_state.gp_kthread->state, j); 513 526 rcu_for_each_node_breadth_first(rnp) { 514 527 if (ULONG_CMP_GE(rcu_state.gp_seq, rnp->gp_seq_needed)) 515 528 continue; ··· 904 891 } 905 892 906 893 /** 907 - * rcu_is_watching - see if RCU thinks that the current CPU is idle 894 + * rcu_is_watching - see if RCU thinks that the current CPU is not idle 908 895 * 909 896 * Return true if RCU is watching the running CPU, which means that this 910 897 * CPU can safely enter RCU read-side critical sections. In other words, 911 - * if the current CPU is in its idle loop and is neither in an interrupt 912 - * or NMI handler, return true. 898 + * if the current CPU is not in its idle loop or is in an interrupt or 899 + * NMI handler, return true. 913 900 */ 914 901 bool notrace rcu_is_watching(void) 915 902 { ··· 1153 1140 smp_store_release(&rcu_state.jiffies_stall, j + j1); /* ^^^ */ 1154 1141 rcu_state.jiffies_resched = j + j1 / 2; 1155 1142 rcu_state.n_force_qs_gpstart = READ_ONCE(rcu_state.n_force_qs); 1156 - } 1157 - 1158 - /* 1159 - * Convert a ->gp_state value to a character string. 1160 - */ 1161 - static const char *gp_state_getname(short gs) 1162 - { 1163 - if (gs < 0 || gs >= ARRAY_SIZE(gp_state_names)) 1164 - return "???"; 1165 - return gp_state_names[gs]; 1166 1143 } 1167 1144 1168 1145 /* ··· 2035 2032 rnp = rcu_get_root(); 2036 2033 raw_spin_lock_irq_rcu_node(rnp); /* GP before ->gp_seq update. */ 2037 2034 2038 - /* Declare grace period done. */ 2039 - rcu_seq_end(&rcu_state.gp_seq); 2035 + /* Declare grace period done, trace first to use old GP number. */ 2040 2036 trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq, TPS("end")); 2037 + rcu_seq_end(&rcu_state.gp_seq); 2041 2038 rcu_state.gp_state = RCU_GP_IDLE; 2042 2039 /* Check for GP requests since above loop. */ 2043 2040 rdp = this_cpu_ptr(&rcu_data); ··· 2603 2600 * This function checks for grace-period requests that fail to motivate 2604 2601 * RCU to come out of its idle mode. 2605 2602 */ 2606 - static void 2607 - rcu_check_gp_start_stall(struct rcu_node *rnp, struct rcu_data *rdp) 2603 + void 2604 + rcu_check_gp_start_stall(struct rcu_node *rnp, struct rcu_data *rdp, 2605 + const unsigned long gpssdelay) 2608 2606 { 2609 - const unsigned long gpssdelay = rcu_jiffies_till_stall_check() * HZ; 2610 2607 unsigned long flags; 2611 2608 unsigned long j; 2612 2609 struct rcu_node *rnp_root = rcu_get_root(); ··· 2693 2690 local_irq_restore(flags); 2694 2691 } 2695 2692 2696 - rcu_check_gp_start_stall(rnp, rdp); 2693 + rcu_check_gp_start_stall(rnp, rdp, rcu_jiffies_till_stall_check()); 2697 2694 2698 2695 /* If there are callbacks ready, invoke them. */ 2699 2696 if (rcu_segcblist_ready_cbs(&rdp->cblist))
+2 -13
kernel/rcu/tree.h
··· 57 57 /* some rcu_state fields as well as */ 58 58 /* following. */ 59 59 unsigned long gp_seq; /* Track rsp->rcu_gp_seq. */ 60 - unsigned long gp_seq_needed; /* Track rsp->rcu_gp_seq_needed. */ 60 + unsigned long gp_seq_needed; /* Track furthest future GP request. */ 61 61 unsigned long completedqs; /* All QSes done for this node. */ 62 62 unsigned long qsmask; /* CPUs or groups that need to switch in */ 63 63 /* order for current grace period to proceed.*/ ··· 163 163 struct rcu_data { 164 164 /* 1) quiescent-state and grace-period handling : */ 165 165 unsigned long gp_seq; /* Track rsp->rcu_gp_seq counter. */ 166 - unsigned long gp_seq_needed; /* Track rsp->rcu_gp_seq_needed ctr. */ 166 + unsigned long gp_seq_needed; /* Track furthest future GP request. */ 167 167 union rcu_noqs cpu_no_qs; /* No QSes yet for this CPU. */ 168 168 bool core_needs_qs; /* Core waits for quiesc state. */ 169 169 bool beenonline; /* CPU online at least once. */ ··· 397 397 static const char *tp_rcu_varname __used __tracepoint_string = rcu_name; 398 398 #define RCU_NAME rcu_name 399 399 #endif /* #else #ifdef CONFIG_TRACING */ 400 - 401 - /* 402 - * RCU implementation internal declarations: 403 - */ 404 - extern struct rcu_state rcu_sched_state; 405 - 406 - extern struct rcu_state rcu_bh_state; 407 - 408 - #ifdef CONFIG_PREEMPT_RCU 409 - extern struct rcu_state rcu_preempt_state; 410 - #endif /* #ifdef CONFIG_PREEMPT_RCU */ 411 400 412 401 int rcu_dynticks_snap(struct rcu_data *rdp); 413 402
+7 -3
kernel/rcu/tree_exp.h
··· 450 450 } 451 451 INIT_WORK(&rnp->rew.rew_work, sync_rcu_exp_select_node_cpus); 452 452 preempt_disable(); 453 - cpu = cpumask_next(rnp->grplo - 1, cpu_online_mask); 453 + cpu = find_next_bit(&rnp->ffmask, BITS_PER_LONG, -1); 454 454 /* If all offline, queue the work on an unbound CPU. */ 455 - if (unlikely(cpu > rnp->grphi)) 455 + if (unlikely(cpu > rnp->grphi - rnp->grplo)) 456 456 cpu = WORK_CPU_UNBOUND; 457 + else 458 + cpu += rnp->grplo; 457 459 queue_work_on(cpu, rcu_par_gp_wq, &rnp->rew.rew_work); 458 460 preempt_enable(); 459 461 rnp->exp_need_flush = true; ··· 692 690 */ 693 691 if (t->rcu_read_lock_nesting > 0) { 694 692 raw_spin_lock_irqsave_rcu_node(rnp, flags); 695 - if (rnp->expmask & rdp->grpmask) 693 + if (rnp->expmask & rdp->grpmask) { 696 694 rdp->deferred_qs = true; 695 + WRITE_ONCE(t->rcu_read_unlock_special.b.exp_hint, true); 696 + } 697 697 raw_spin_unlock_irqrestore_rcu_node(rnp, flags); 698 698 } 699 699
+25 -12
kernel/rcu/tree_plugin.h
··· 397 397 return rnp->gp_tasks != NULL; 398 398 } 399 399 400 + /* Bias and limit values for ->rcu_read_lock_nesting. */ 401 + #define RCU_NEST_BIAS INT_MAX 402 + #define RCU_NEST_NMAX (-INT_MAX / 2) 403 + #define RCU_NEST_PMAX (INT_MAX / 2) 404 + 400 405 /* 401 406 * Preemptible RCU implementation for rcu_read_lock(). 402 407 * Just increment ->rcu_read_lock_nesting, shared state will be updated ··· 410 405 void __rcu_read_lock(void) 411 406 { 412 407 current->rcu_read_lock_nesting++; 408 + if (IS_ENABLED(CONFIG_PROVE_LOCKING)) 409 + WARN_ON_ONCE(current->rcu_read_lock_nesting > RCU_NEST_PMAX); 413 410 barrier(); /* critical section after entry code. */ 414 411 } 415 412 EXPORT_SYMBOL_GPL(__rcu_read_lock); ··· 431 424 --t->rcu_read_lock_nesting; 432 425 } else { 433 426 barrier(); /* critical section before exit code. */ 434 - t->rcu_read_lock_nesting = INT_MIN; 427 + t->rcu_read_lock_nesting = -RCU_NEST_BIAS; 435 428 barrier(); /* assign before ->rcu_read_unlock_special load */ 436 429 if (unlikely(READ_ONCE(t->rcu_read_unlock_special.s))) 437 430 rcu_read_unlock_special(t); 438 431 barrier(); /* ->rcu_read_unlock_special load before assign */ 439 432 t->rcu_read_lock_nesting = 0; 440 433 } 441 - #ifdef CONFIG_PROVE_LOCKING 442 - { 443 - int rrln = READ_ONCE(t->rcu_read_lock_nesting); 434 + if (IS_ENABLED(CONFIG_PROVE_LOCKING)) { 435 + int rrln = t->rcu_read_lock_nesting; 444 436 445 - WARN_ON_ONCE(rrln < 0 && rrln > INT_MIN / 2); 437 + WARN_ON_ONCE(rrln < 0 && rrln > RCU_NEST_NMAX); 446 438 } 447 - #endif /* #ifdef CONFIG_PROVE_LOCKING */ 448 439 } 449 440 EXPORT_SYMBOL_GPL(__rcu_read_unlock); 450 441 ··· 602 597 */ 603 598 static bool rcu_preempt_need_deferred_qs(struct task_struct *t) 604 599 { 605 - return (this_cpu_ptr(&rcu_data)->deferred_qs || 600 + return (__this_cpu_read(rcu_data.deferred_qs) || 606 601 READ_ONCE(t->rcu_read_unlock_special.s)) && 607 602 t->rcu_read_lock_nesting <= 0; 608 603 } ··· 622 617 if (!rcu_preempt_need_deferred_qs(t)) 623 618 return; 624 619 if (couldrecurse) 625 - t->rcu_read_lock_nesting -= INT_MIN; 620 + t->rcu_read_lock_nesting -= RCU_NEST_BIAS; 626 621 local_irq_save(flags); 627 622 rcu_preempt_deferred_qs_irqrestore(t, flags); 628 623 if (couldrecurse) 629 - t->rcu_read_lock_nesting += INT_MIN; 624 + t->rcu_read_lock_nesting += RCU_NEST_BIAS; 630 625 } 631 626 632 627 /* ··· 647 642 648 643 local_irq_save(flags); 649 644 irqs_were_disabled = irqs_disabled_flags(flags); 650 - if ((preempt_bh_were_disabled || irqs_were_disabled) && 651 - t->rcu_read_unlock_special.b.blocked) { 645 + if (preempt_bh_were_disabled || irqs_were_disabled) { 646 + WRITE_ONCE(t->rcu_read_unlock_special.b.exp_hint, false); 652 647 /* Need to defer quiescent state until everything is enabled. */ 653 - raise_softirq_irqoff(RCU_SOFTIRQ); 648 + if (irqs_were_disabled) { 649 + /* Enabling irqs does not reschedule, so... */ 650 + raise_softirq_irqoff(RCU_SOFTIRQ); 651 + } else { 652 + /* Enabling BH or preempt does reschedule, so... */ 653 + set_tsk_need_resched(current); 654 + set_preempt_need_resched(); 655 + } 654 656 local_irq_restore(flags); 655 657 return; 656 658 } 659 + WRITE_ONCE(t->rcu_read_unlock_special.b.exp_hint, false); 657 660 rcu_preempt_deferred_qs_irqrestore(t, flags); 658 661 } 659 662
+2 -4
kernel/rcu/update.c
··· 335 335 /* Initialize and register callbacks for each crcu_array element. */ 336 336 for (i = 0; i < n; i++) { 337 337 if (checktiny && 338 - (crcu_array[i] == call_rcu || 339 - crcu_array[i] == call_rcu_bh)) { 338 + (crcu_array[i] == call_rcu)) { 340 339 might_sleep(); 341 340 continue; 342 341 } ··· 351 352 /* Wait for all callbacks to be invoked. */ 352 353 for (i = 0; i < n; i++) { 353 354 if (checktiny && 354 - (crcu_array[i] == call_rcu || 355 - crcu_array[i] == call_rcu_bh)) 355 + (crcu_array[i] == call_rcu)) 356 356 continue; 357 357 for (j = 0; j < i; j++) 358 358 if (crcu_array[j] == crcu_array[i])
+1 -1
kernel/sched/core.c
··· 5788 5788 * 5789 5789 * Do sync before park smpboot threads to take care the rcu boost case. 5790 5790 */ 5791 - synchronize_rcu_mult(call_rcu, call_rcu_sched); 5791 + synchronize_rcu(); 5792 5792 5793 5793 if (!sched_smp_initialized) 5794 5794 return 0;
+3 -3
kernel/sched/membarrier.c
··· 210 210 * future scheduler executions will observe the new 211 211 * thread flag state for this mm. 212 212 */ 213 - synchronize_sched(); 213 + synchronize_rcu(); 214 214 } 215 215 atomic_or(MEMBARRIER_STATE_GLOBAL_EXPEDITED_READY, 216 216 &mm->membarrier_state); ··· 246 246 * Ensure all future scheduler executions will observe the 247 247 * new thread flag state for this process. 248 248 */ 249 - synchronize_sched(); 249 + synchronize_rcu(); 250 250 } 251 251 atomic_or(state, &mm->membarrier_state); 252 252 ··· 298 298 if (tick_nohz_full_enabled()) 299 299 return -EINVAL; 300 300 if (num_online_cpus() > 1) 301 - synchronize_sched(); 301 + synchronize_rcu(); 302 302 return 0; 303 303 case MEMBARRIER_CMD_GLOBAL_EXPEDITED: 304 304 return membarrier_global_expedited();
+12 -12
kernel/trace/ftrace.c
··· 173 173 { 174 174 /* 175 175 * This function is just a stub to implement a hard force 176 - * of synchronize_sched(). This requires synchronizing 176 + * of synchronize_rcu(). This requires synchronizing 177 177 * tasks even in userspace and idle. 178 178 * 179 179 * Yes, function tracing is rude. ··· 934 934 ftrace_profile_enabled = 0; 935 935 /* 936 936 * unregister_ftrace_profiler calls stop_machine 937 - * so this acts like an synchronize_sched. 937 + * so this acts like an synchronize_rcu. 938 938 */ 939 939 unregister_ftrace_profiler(); 940 940 } ··· 1086 1086 1087 1087 /* 1088 1088 * Some of the ops may be dynamically allocated, 1089 - * they are freed after a synchronize_sched(). 1089 + * they are freed after a synchronize_rcu(). 1090 1090 */ 1091 1091 preempt_disable_notrace(); 1092 1092 ··· 1286 1286 { 1287 1287 if (!hash || hash == EMPTY_HASH) 1288 1288 return; 1289 - call_rcu_sched(&hash->rcu, __free_ftrace_hash_rcu); 1289 + call_rcu(&hash->rcu, __free_ftrace_hash_rcu); 1290 1290 } 1291 1291 1292 1292 void ftrace_free_filter(struct ftrace_ops *ops) ··· 1501 1501 * the ip is not in the ops->notrace_hash. 1502 1502 * 1503 1503 * This needs to be called with preemption disabled as 1504 - * the hashes are freed with call_rcu_sched(). 1504 + * the hashes are freed with call_rcu(). 1505 1505 */ 1506 1506 static int 1507 1507 ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip, void *regs) ··· 4496 4496 if (ftrace_enabled && !ftrace_hash_empty(hash)) 4497 4497 ftrace_run_modify_code(&probe->ops, FTRACE_UPDATE_CALLS, 4498 4498 &old_hash_ops); 4499 - synchronize_sched(); 4499 + synchronize_rcu(); 4500 4500 4501 4501 hlist_for_each_entry_safe(entry, tmp, &hhd, hlist) { 4502 4502 hlist_del(&entry->hlist); ··· 5314 5314 mutex_unlock(&graph_lock); 5315 5315 5316 5316 /* Wait till all users are no longer using the old hash */ 5317 - synchronize_sched(); 5317 + synchronize_rcu(); 5318 5318 5319 5319 free_ftrace_hash(old_hash); 5320 5320 } ··· 5707 5707 list_for_each_entry_safe(mod_map, n, &ftrace_mod_maps, list) { 5708 5708 if (mod_map->mod == mod) { 5709 5709 list_del_rcu(&mod_map->list); 5710 - call_rcu_sched(&mod_map->rcu, ftrace_free_mod_map); 5710 + call_rcu(&mod_map->rcu, ftrace_free_mod_map); 5711 5711 break; 5712 5712 } 5713 5713 } ··· 5927 5927 struct ftrace_mod_map *mod_map; 5928 5928 const char *ret = NULL; 5929 5929 5930 - /* mod_map is freed via call_rcu_sched() */ 5930 + /* mod_map is freed via call_rcu() */ 5931 5931 preempt_disable(); 5932 5932 list_for_each_entry_rcu(mod_map, &ftrace_mod_maps, list) { 5933 5933 ret = ftrace_func_address_lookup(mod_map, addr, size, off, sym); ··· 6262 6262 6263 6263 /* 6264 6264 * Some of the ops may be dynamically allocated, 6265 - * they must be freed after a synchronize_sched(). 6265 + * they must be freed after a synchronize_rcu(). 6266 6266 */ 6267 6267 preempt_disable_notrace(); 6268 6268 ··· 6433 6433 rcu_assign_pointer(tr->function_pids, NULL); 6434 6434 6435 6435 /* Wait till all users are no longer using pid filtering */ 6436 - synchronize_sched(); 6436 + synchronize_rcu(); 6437 6437 6438 6438 trace_free_pid_list(pid_list); 6439 6439 } ··· 6580 6580 rcu_assign_pointer(tr->function_pids, pid_list); 6581 6581 6582 6582 if (filtered_pids) { 6583 - synchronize_sched(); 6583 + synchronize_rcu(); 6584 6584 trace_free_pid_list(filtered_pids); 6585 6585 } else if (pid_list) { 6586 6586 /* Register a probe to set whether to ignore the tracing of a task */
+6 -6
kernel/trace/ring_buffer.c
··· 1834 1834 * There could have been a race between checking 1835 1835 * record_disable and incrementing it. 1836 1836 */ 1837 - synchronize_sched(); 1837 + synchronize_rcu(); 1838 1838 for_each_buffer_cpu(buffer, cpu) { 1839 1839 cpu_buffer = buffer->buffers[cpu]; 1840 1840 rb_check_pages(cpu_buffer); ··· 3151 3151 * This prevents all writes to the buffer. Any attempt to write 3152 3152 * to the buffer after this will fail and return NULL. 3153 3153 * 3154 - * The caller should call synchronize_sched() after this. 3154 + * The caller should call synchronize_rcu() after this. 3155 3155 */ 3156 3156 void ring_buffer_record_disable(struct ring_buffer *buffer) 3157 3157 { ··· 3253 3253 * This prevents all writes to the buffer. Any attempt to write 3254 3254 * to the buffer after this will fail and return NULL. 3255 3255 * 3256 - * The caller should call synchronize_sched() after this. 3256 + * The caller should call synchronize_rcu() after this. 3257 3257 */ 3258 3258 void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu) 3259 3259 { ··· 4191 4191 void 4192 4192 ring_buffer_read_prepare_sync(void) 4193 4193 { 4194 - synchronize_sched(); 4194 + synchronize_rcu(); 4195 4195 } 4196 4196 EXPORT_SYMBOL_GPL(ring_buffer_read_prepare_sync); 4197 4197 ··· 4363 4363 atomic_inc(&cpu_buffer->record_disabled); 4364 4364 4365 4365 /* Make sure all commits have finished */ 4366 - synchronize_sched(); 4366 + synchronize_rcu(); 4367 4367 4368 4368 raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); 4369 4369 ··· 4496 4496 goto out; 4497 4497 4498 4498 /* 4499 - * We can't do a synchronize_sched here because this 4499 + * We can't do a synchronize_rcu here because this 4500 4500 * function can be called in atomic context. 4501 4501 * Normally this will be called from the same CPU as cpu. 4502 4502 * If not it's up to the caller to protect this.
+5 -5
kernel/trace/trace.c
··· 1681 1681 ring_buffer_record_disable(buffer); 1682 1682 1683 1683 /* Make sure all commits have finished */ 1684 - synchronize_sched(); 1684 + synchronize_rcu(); 1685 1685 ring_buffer_reset_cpu(buffer, cpu); 1686 1686 1687 1687 ring_buffer_record_enable(buffer); ··· 1698 1698 ring_buffer_record_disable(buffer); 1699 1699 1700 1700 /* Make sure all commits have finished */ 1701 - synchronize_sched(); 1701 + synchronize_rcu(); 1702 1702 1703 1703 buf->time_start = buffer_ftrace_now(buf, buf->cpu); 1704 1704 ··· 2250 2250 preempt_enable(); 2251 2251 2252 2252 /* Wait for all current users to finish */ 2253 - synchronize_sched(); 2253 + synchronize_rcu(); 2254 2254 2255 2255 for_each_tracing_cpu(cpu) { 2256 2256 free_page((unsigned long)per_cpu(trace_buffered_event, cpu)); ··· 5398 5398 if (tr->current_trace->reset) 5399 5399 tr->current_trace->reset(tr); 5400 5400 5401 - /* Current trace needs to be nop_trace before synchronize_sched */ 5401 + /* Current trace needs to be nop_trace before synchronize_rcu */ 5402 5402 tr->current_trace = &nop_trace; 5403 5403 5404 5404 #ifdef CONFIG_TRACER_MAX_TRACE ··· 5412 5412 * The update_max_tr is called from interrupts disabled 5413 5413 * so a synchronized_sched() is sufficient. 5414 5414 */ 5415 - synchronize_sched(); 5415 + synchronize_rcu(); 5416 5416 free_snapshot(tr); 5417 5417 } 5418 5418 #endif
+2 -2
kernel/trace/trace_events_filter.c
··· 1614 1614 1615 1615 /* 1616 1616 * The calls can still be using the old filters. 1617 - * Do a synchronize_sched() and to ensure all calls are 1617 + * Do a synchronize_rcu() and to ensure all calls are 1618 1618 * done with them before we free them. 1619 1619 */ 1620 1620 tracepoint_synchronize_unregister(); ··· 1845 1845 if (filter) { 1846 1846 /* 1847 1847 * No event actually uses the system filter 1848 - * we can free it without synchronize_sched(). 1848 + * we can free it without synchronize_rcu(). 1849 1849 */ 1850 1850 __free_filter(system->filter); 1851 1851 system->filter = filter;
+1 -1
kernel/trace/trace_kprobe.c
··· 333 333 * event_call related objects, which will be accessed in 334 334 * the kprobe_trace_func/kretprobe_trace_func. 335 335 */ 336 - synchronize_sched(); 336 + synchronize_rcu(); 337 337 kfree(link); /* Ignored if link == NULL */ 338 338 } 339 339
+2 -2
kernel/tracepoint.c
··· 92 92 while (early_probes) { 93 93 tmp = early_probes; 94 94 early_probes = tmp->next; 95 - call_rcu_sched(tmp, rcu_free_old_probes); 95 + call_rcu(tmp, rcu_free_old_probes); 96 96 } 97 97 98 98 return 0; ··· 123 123 * cover both cases. So let us chain the SRCU and sched RCU 124 124 * callbacks to wait for both grace periods. 125 125 */ 126 - call_rcu_sched(&tp_probes->rcu, rcu_free_old_probes); 126 + call_rcu(&tp_probes->rcu, rcu_free_old_probes); 127 127 } 128 128 } 129 129
+4 -4
kernel/workqueue.c
··· 3396 3396 del_timer_sync(&pool->mayday_timer); 3397 3397 3398 3398 /* sched-RCU protected to allow dereferences from get_work_pool() */ 3399 - call_rcu_sched(&pool->rcu, rcu_free_pool); 3399 + call_rcu(&pool->rcu, rcu_free_pool); 3400 3400 } 3401 3401 3402 3402 /** ··· 3503 3503 put_unbound_pool(pool); 3504 3504 mutex_unlock(&wq_pool_mutex); 3505 3505 3506 - call_rcu_sched(&pwq->rcu, rcu_free_pwq); 3506 + call_rcu(&pwq->rcu, rcu_free_pwq); 3507 3507 3508 3508 /* 3509 3509 * If we're the last pwq going away, @wq is already dead and no one 3510 3510 * is gonna access it anymore. Schedule RCU free. 3511 3511 */ 3512 3512 if (is_last) 3513 - call_rcu_sched(&wq->rcu, rcu_free_wq); 3513 + call_rcu(&wq->rcu, rcu_free_wq); 3514 3514 } 3515 3515 3516 3516 /** ··· 4195 4195 * The base ref is never dropped on per-cpu pwqs. Directly 4196 4196 * schedule RCU free. 4197 4197 */ 4198 - call_rcu_sched(&wq->rcu, rcu_free_wq); 4198 + call_rcu(&wq->rcu, rcu_free_wq); 4199 4199 } else { 4200 4200 /* 4201 4201 * We're the sole accessor of @wq at this point. Directly
+1 -1
lib/percpu-refcount.c
··· 181 181 ref->confirm_switch = confirm_switch ?: percpu_ref_noop_confirm_switch; 182 182 183 183 percpu_ref_get(ref); /* put after confirmation */ 184 - call_rcu_sched(&ref->rcu, percpu_ref_switch_to_atomic_rcu); 184 + call_rcu(&ref->rcu, percpu_ref_switch_to_atomic_rcu); 185 185 } 186 186 187 187 static void __percpu_ref_switch_to_percpu(struct percpu_ref *ref)
+2 -2
mm/khugepaged.c
··· 1225 1225 { 1226 1226 struct mm_struct *mm = mm_slot->mm; 1227 1227 1228 - VM_BUG_ON(NR_CPUS != 1 && !spin_is_locked(&khugepaged_mm_lock)); 1228 + lockdep_assert_held(&khugepaged_mm_lock); 1229 1229 1230 1230 if (khugepaged_test_exit(mm)) { 1231 1231 /* free mm_slot */ ··· 1631 1631 int progress = 0; 1632 1632 1633 1633 VM_BUG_ON(!pages); 1634 - VM_BUG_ON(NR_CPUS != 1 && !spin_is_locked(&khugepaged_mm_lock)); 1634 + lockdep_assert_held(&khugepaged_mm_lock); 1635 1635 1636 1636 if (khugepaged_scan.mm_slot) 1637 1637 mm_slot = khugepaged_scan.mm_slot;
+1 -1
mm/mmu_gather.c
··· 199 199 200 200 if (*batch) { 201 201 tlb_table_invalidate(tlb); 202 - call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu); 202 + call_rcu(&(*batch)->rcu, tlb_remove_table_rcu); 203 203 *batch = NULL; 204 204 } 205 205 }
+2 -2
mm/slab.c
··· 962 962 * To protect lockless access to n->shared during irq disabled context. 963 963 * If n->shared isn't NULL in irq disabled context, accessing to it is 964 964 * guaranteed to be valid until irq is re-enabled, because it will be 965 - * freed after synchronize_sched(). 965 + * freed after synchronize_rcu(). 966 966 */ 967 967 if (old_shared && force_change) 968 - synchronize_sched(); 968 + synchronize_rcu(); 969 969 970 970 fail: 971 971 kfree(old_shared);
+3 -3
mm/slab_common.c
··· 724 724 css_get(&s->memcg_params.memcg->css); 725 725 726 726 s->memcg_params.deact_fn = deact_fn; 727 - call_rcu_sched(&s->memcg_params.deact_rcu_head, kmemcg_deactivate_rcufn); 727 + call_rcu(&s->memcg_params.deact_rcu_head, kmemcg_deactivate_rcufn); 728 728 } 729 729 730 730 void memcg_deactivate_kmem_caches(struct mem_cgroup *memcg) ··· 839 839 mutex_unlock(&slab_mutex); 840 840 841 841 /* 842 - * SLUB deactivates the kmem_caches through call_rcu_sched. Make 842 + * SLUB deactivates the kmem_caches through call_rcu. Make 843 843 * sure all registered rcu callbacks have been invoked. 844 844 */ 845 845 if (IS_ENABLED(CONFIG_SLUB)) 846 - rcu_barrier_sched(); 846 + rcu_barrier(); 847 847 848 848 /* 849 849 * SLAB and SLUB create memcg kmem_caches through workqueue and SLUB
+1 -2
mm/swap.c
··· 823 823 VM_BUG_ON_PAGE(!PageHead(page), page); 824 824 VM_BUG_ON_PAGE(PageCompound(page_tail), page); 825 825 VM_BUG_ON_PAGE(PageLRU(page_tail), page); 826 - VM_BUG_ON(NR_CPUS != 1 && 827 - !spin_is_locked(&lruvec_pgdat(lruvec)->lru_lock)); 826 + lockdep_assert_held(&lruvec_pgdat(lruvec)->lru_lock); 828 827 829 828 if (!list) 830 829 SetPageLRU(page_tail);
+1 -1
net/bridge/br_mdb.c
··· 728 728 rcu_assign_pointer(*pp, p->next); 729 729 hlist_del_init(&p->mglist); 730 730 del_timer(&p->timer); 731 - call_rcu_bh(&p->rcu, br_multicast_free_pg); 731 + call_rcu(&p->rcu, br_multicast_free_pg); 732 732 err = 0; 733 733 734 734 if (!mp->ports && !mp->host_joined &&
+7 -7
net/bridge/br_multicast.c
··· 260 260 hlist_del_rcu(&mp->hlist[mdb->ver]); 261 261 mdb->size--; 262 262 263 - call_rcu_bh(&mp->rcu, br_multicast_free_group); 263 + call_rcu(&mp->rcu, br_multicast_free_group); 264 264 265 265 out: 266 266 spin_unlock(&br->multicast_lock); ··· 291 291 del_timer(&p->timer); 292 292 br_mdb_notify(br->dev, p->port, &pg->addr, RTM_DELMDB, 293 293 p->flags); 294 - call_rcu_bh(&p->rcu, br_multicast_free_pg); 294 + call_rcu(&p->rcu, br_multicast_free_pg); 295 295 296 296 if (!mp->ports && !mp->host_joined && 297 297 netif_running(br->dev)) ··· 358 358 } 359 359 360 360 br_mdb_rehash_seq++; 361 - call_rcu_bh(&mdb->rcu, br_mdb_free); 361 + call_rcu(&mdb->rcu, br_mdb_free); 362 362 363 363 out: 364 364 rcu_assign_pointer(*mdbp, mdb); ··· 1629 1629 rcu_assign_pointer(*pp, p->next); 1630 1630 hlist_del_init(&p->mglist); 1631 1631 del_timer(&p->timer); 1632 - call_rcu_bh(&p->rcu, br_multicast_free_pg); 1632 + call_rcu(&p->rcu, br_multicast_free_pg); 1633 1633 br_mdb_notify(br->dev, port, group, RTM_DELMDB, 1634 1634 p->flags); 1635 1635 ··· 2051 2051 hlist_for_each_entry_safe(mp, n, &mdb->mhash[i], 2052 2052 hlist[ver]) { 2053 2053 del_timer(&mp->timer); 2054 - call_rcu_bh(&mp->rcu, br_multicast_free_group); 2054 + call_rcu(&mp->rcu, br_multicast_free_group); 2055 2055 } 2056 2056 } 2057 2057 2058 2058 if (mdb->old) { 2059 2059 spin_unlock_bh(&br->multicast_lock); 2060 - rcu_barrier_bh(); 2060 + rcu_barrier(); 2061 2061 spin_lock_bh(&br->multicast_lock); 2062 2062 WARN_ON(mdb->old); 2063 2063 } 2064 2064 2065 2065 mdb->old = mdb; 2066 - call_rcu_bh(&mdb->rcu, br_mdb_free); 2066 + call_rcu(&mdb->rcu, br_mdb_free); 2067 2067 2068 2068 out: 2069 2069 spin_unlock_bh(&br->multicast_lock);
+2 -2
net/core/netpoll.c
··· 800 800 ops->ndo_netpoll_cleanup(np->dev); 801 801 802 802 RCU_INIT_POINTER(np->dev->npinfo, NULL); 803 - call_rcu_bh(&npinfo->rcu, rcu_cleanup_netpoll_info); 803 + call_rcu(&npinfo->rcu, rcu_cleanup_netpoll_info); 804 804 } else 805 805 RCU_INIT_POINTER(np->dev->npinfo, NULL); 806 806 } ··· 811 811 ASSERT_RTNL(); 812 812 813 813 /* Wait for transmitting packets to finish before freeing. */ 814 - synchronize_rcu_bh(); 814 + synchronize_rcu(); 815 815 __netpoll_cleanup(np); 816 816 kfree(np); 817 817 }
+1 -1
net/core/skmsg.c
··· 580 580 write_unlock_bh(&sk->sk_callback_lock); 581 581 sk_psock_clear_state(psock, SK_PSOCK_TX_ENABLED); 582 582 583 - call_rcu_sched(&psock->rcu, sk_psock_destroy); 583 + call_rcu(&psock->rcu, sk_psock_destroy); 584 584 } 585 585 EXPORT_SYMBOL_GPL(sk_psock_drop); 586 586
+1 -1
net/decnet/af_decnet.c
··· 2405 2405 2406 2406 proto_unregister(&dn_proto); 2407 2407 2408 - rcu_barrier_bh(); /* Wait for completion of call_rcu_bh()'s */ 2408 + rcu_barrier(); /* Wait for completion of call_rcu()'s */ 2409 2409 } 2410 2410 module_exit(decnet_exit); 2411 2411 #endif
+1 -1
net/sched/sch_api.c
··· 540 540 541 541 if (--tab->refcnt == 0) { 542 542 list_del(&tab->list); 543 - call_rcu_bh(&tab->rcu, stab_kfree_rcu); 543 + call_rcu(&tab->rcu, stab_kfree_rcu); 544 544 } 545 545 } 546 546 EXPORT_SYMBOL(qdisc_put_stab);
+4 -4
net/sched/sch_generic.c
··· 1372 1372 if (!tp_head) { 1373 1373 RCU_INIT_POINTER(*miniqp->p_miniq, NULL); 1374 1374 /* Wait for flying RCU callback before it is freed. */ 1375 - rcu_barrier_bh(); 1375 + rcu_barrier(); 1376 1376 return; 1377 1377 } 1378 1378 ··· 1380 1380 &miniqp->miniq1 : &miniqp->miniq2; 1381 1381 1382 1382 /* We need to make sure that readers won't see the miniq 1383 - * we are about to modify. So wait until previous call_rcu_bh callback 1383 + * we are about to modify. So wait until previous call_rcu callback 1384 1384 * is done. 1385 1385 */ 1386 - rcu_barrier_bh(); 1386 + rcu_barrier(); 1387 1387 miniq->filter_list = tp_head; 1388 1388 rcu_assign_pointer(*miniqp->p_miniq, miniq); 1389 1389 ··· 1392 1392 * block potential new user of miniq_old until all readers 1393 1393 * are not seeing it. 1394 1394 */ 1395 - call_rcu_bh(&miniq_old->rcu, mini_qdisc_rcu_func); 1395 + call_rcu(&miniq_old->rcu, mini_qdisc_rcu_func); 1396 1396 } 1397 1397 EXPORT_SYMBOL(mini_qdisc_pair_swap); 1398 1398
+35
scripts/checkpatch.pl
··· 573 573 } 574 574 $mode_perms_search = "(?:${mode_perms_search})"; 575 575 576 + our %deprecated_apis = ( 577 + "synchronize_rcu_bh" => "synchronize_rcu", 578 + "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited", 579 + "call_rcu_bh" => "call_rcu", 580 + "rcu_barrier_bh" => "rcu_barrier", 581 + "synchronize_sched" => "synchronize_rcu", 582 + "synchronize_sched_expedited" => "synchronize_rcu_expedited", 583 + "call_rcu_sched" => "call_rcu", 584 + "rcu_barrier_sched" => "rcu_barrier", 585 + "get_state_synchronize_sched" => "get_state_synchronize_rcu", 586 + "cond_synchronize_sched" => "cond_synchronize_rcu", 587 + ); 588 + 589 + #Create a search pattern for all these strings to speed up a loop below 590 + our $deprecated_apis_search = ""; 591 + foreach my $entry (keys %deprecated_apis) { 592 + $deprecated_apis_search .= '|' if ($deprecated_apis_search ne ""); 593 + $deprecated_apis_search .= $entry; 594 + } 595 + $deprecated_apis_search = "(?:${deprecated_apis_search})"; 596 + 576 597 our $mode_perms_world_writable = qr{ 577 598 S_IWUGO | 578 599 S_IWOTH | ··· 6387 6366 if ($line =~ /^.\s*__initcall\s*\(/) { 6388 6367 WARN("USE_DEVICE_INITCALL", 6389 6368 "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); 6369 + } 6370 + 6371 + # check for spin_is_locked(), suggest lockdep instead 6372 + if ($line =~ /\bspin_is_locked\(/) { 6373 + WARN("USE_LOCKDEP", 6374 + "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr); 6375 + } 6376 + 6377 + # check for deprecated apis 6378 + if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) { 6379 + my $deprecated_api = $1; 6380 + my $new_api = $deprecated_apis{$deprecated_api}; 6381 + WARN("DEPRECATED_API", 6382 + "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr); 6390 6383 } 6391 6384 6392 6385 # check for various structs that are normally const (ops, kgdb, device_tree)
+1 -1
tools/include/linux/kernel.h
··· 116 116 #define round_down(x, y) ((x) & ~__round_mask(x, y)) 117 117 118 118 #define current_gfp_context(k) 0 119 - #define synchronize_sched() 119 + #define synchronize_rcu() 120 120 121 121 #endif
+8
tools/testing/selftests/rcutorture/bin/kvm.sh
··· 194 194 shift 195 195 done 196 196 197 + if test -z "$TORTURE_INITRD" || tools/testing/selftests/rcutorture/bin/mkinitrd.sh 198 + then 199 + : 200 + else 201 + echo No initrd and unable to create one, aborting test >&2 202 + exit 1 203 + fi 204 + 197 205 CONFIGFRAG=${KVM}/configs/${TORTURE_SUITE}; export CONFIGFRAG 198 206 199 207 if test -z "$configs"
+136
tools/testing/selftests/rcutorture/bin/mkinitrd.sh
··· 1 + #!/bin/bash 2 + # 3 + # Create an initrd directory if one does not already exist. 4 + # 5 + # This program is free software; you can redistribute it and/or modify 6 + # it under the terms of the GNU General Public License as published by 7 + # the Free Software Foundation; either version 2 of the License, or 8 + # (at your option) any later version. 9 + # 10 + # This program is distributed in the hope that it will be useful, 11 + # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + # GNU General Public License for more details. 14 + # 15 + # You should have received a copy of the GNU General Public License 16 + # along with this program; if not, you can access it online at 17 + # http://www.gnu.org/licenses/gpl-2.0.html. 18 + # 19 + # Copyright (C) IBM Corporation, 2013 20 + # 21 + # Author: Connor Shu <Connor.Shu@ibm.com> 22 + 23 + D=tools/testing/selftests/rcutorture 24 + 25 + # Prerequisite checks 26 + [ -z "$D" ] && echo >&2 "No argument supplied" && exit 1 27 + if [ ! -d "$D" ]; then 28 + echo >&2 "$D does not exist: Malformed kernel source tree?" 29 + exit 1 30 + fi 31 + if [ -s "$D/initrd/init" ]; then 32 + echo "$D/initrd/init already exists, no need to create it" 33 + exit 0 34 + fi 35 + 36 + T=${TMPDIR-/tmp}/mkinitrd.sh.$$ 37 + trap 'rm -rf $T' 0 2 38 + mkdir $T 39 + 40 + cat > $T/init << '__EOF___' 41 + #!/bin/sh 42 + # Run in userspace a few milliseconds every second. This helps to 43 + # exercise the NO_HZ_FULL portions of RCU. 44 + while : 45 + do 46 + q= 47 + for i in \ 48 + a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a \ 49 + a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a \ 50 + a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a \ 51 + a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a \ 52 + a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a \ 53 + a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a 54 + do 55 + q="$q $i" 56 + done 57 + sleep 1 58 + done 59 + __EOF___ 60 + 61 + # Try using dracut to create initrd 62 + if command -v dracut >/dev/null 2>&1 63 + then 64 + echo Creating $D/initrd using dracut. 65 + # Filesystem creation 66 + dracut --force --no-hostonly --no-hostonly-cmdline --module "base" $T/initramfs.img 67 + cd $D 68 + mkdir -p initrd 69 + cd initrd 70 + zcat $T/initramfs.img | cpio -id 71 + cp $T/init init 72 + chmod +x init 73 + echo Done creating $D/initrd using dracut 74 + exit 0 75 + fi 76 + 77 + # No dracut, so create a C-language initrd/init program and statically 78 + # link it. This results in a very small initrd, but might be a bit less 79 + # future-proof than dracut. 80 + echo "Could not find dracut, attempting C initrd" 81 + cd $D 82 + mkdir -p initrd 83 + cd initrd 84 + cat > init.c << '___EOF___' 85 + #ifndef NOLIBC 86 + #include <unistd.h> 87 + #include <sys/time.h> 88 + #endif 89 + 90 + volatile unsigned long delaycount; 91 + 92 + int main(int argc, int argv[]) 93 + { 94 + int i; 95 + struct timeval tv; 96 + struct timeval tvb; 97 + 98 + for (;;) { 99 + sleep(1); 100 + /* Need some userspace time. */ 101 + if (gettimeofday(&tvb, NULL)) 102 + continue; 103 + do { 104 + for (i = 0; i < 1000 * 100; i++) 105 + delaycount = i * i; 106 + if (gettimeofday(&tv, NULL)) 107 + break; 108 + tv.tv_sec -= tvb.tv_sec; 109 + if (tv.tv_sec > 1) 110 + break; 111 + tv.tv_usec += tv.tv_sec * 1000 * 1000; 112 + tv.tv_usec -= tvb.tv_usec; 113 + } while (tv.tv_usec < 1000); 114 + } 115 + return 0; 116 + } 117 + ___EOF___ 118 + 119 + # build using nolibc on supported archs (smaller executable) and fall 120 + # back to regular glibc on other ones. 121 + if echo -e "#if __x86_64__||__i386__||__i486__||__i586__||__i686__" \ 122 + "||__ARM_EABI__||__aarch64__\nyes\n#endif" \ 123 + | ${CROSS_COMPILE}gcc -E -nostdlib -xc - \ 124 + | grep -q '^yes'; then 125 + # architecture supported by nolibc 126 + ${CROSS_COMPILE}gcc -fno-asynchronous-unwind-tables -fno-ident \ 127 + -nostdlib -include ../bin/nolibc.h -lgcc -s -static -Os \ 128 + -o init init.c 129 + else 130 + ${CROSS_COMPILE}gcc -s -static -Os -o init init.c 131 + fi 132 + 133 + rm init.c 134 + echo "Done creating a statically linked C-language initrd" 135 + 136 + exit 0
+2197
tools/testing/selftests/rcutorture/bin/nolibc.h
··· 1 + /* SPDX-License-Identifier: LGPL-2.1 OR MIT */ 2 + /* nolibc.h 3 + * Copyright (C) 2017-2018 Willy Tarreau <w@1wt.eu> 4 + */ 5 + 6 + /* some archs (at least aarch64) don't expose the regular syscalls anymore by 7 + * default, either because they have an "_at" replacement, or because there are 8 + * more modern alternatives. For now we'd rather still use them. 9 + */ 10 + #define __ARCH_WANT_SYSCALL_NO_AT 11 + #define __ARCH_WANT_SYSCALL_NO_FLAGS 12 + #define __ARCH_WANT_SYSCALL_DEPRECATED 13 + 14 + #include <asm/unistd.h> 15 + #include <asm/ioctls.h> 16 + #include <asm/errno.h> 17 + #include <linux/fs.h> 18 + #include <linux/loop.h> 19 + 20 + #define NOLIBC 21 + 22 + /* Build a static executable this way : 23 + * $ gcc -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \ 24 + * -static -include nolibc.h -lgcc -o hello hello.c 25 + * 26 + * Useful calling convention table found here : 27 + * http://man7.org/linux/man-pages/man2/syscall.2.html 28 + * 29 + * This doc is even better : 30 + * https://w3challs.com/syscalls/ 31 + */ 32 + 33 + 34 + /* this way it will be removed if unused */ 35 + static int errno; 36 + 37 + #ifndef NOLIBC_IGNORE_ERRNO 38 + #define SET_ERRNO(v) do { errno = (v); } while (0) 39 + #else 40 + #define SET_ERRNO(v) do { } while (0) 41 + #endif 42 + 43 + /* errno codes all ensure that they will not conflict with a valid pointer 44 + * because they all correspond to the highest addressable memry page. 45 + */ 46 + #define MAX_ERRNO 4095 47 + 48 + /* Declare a few quite common macros and types that usually are in stdlib.h, 49 + * stdint.h, ctype.h, unistd.h and a few other common locations. 50 + */ 51 + 52 + #define NULL ((void *)0) 53 + 54 + /* stdint types */ 55 + typedef unsigned char uint8_t; 56 + typedef signed char int8_t; 57 + typedef unsigned short uint16_t; 58 + typedef signed short int16_t; 59 + typedef unsigned int uint32_t; 60 + typedef signed int int32_t; 61 + typedef unsigned long long uint64_t; 62 + typedef signed long long int64_t; 63 + typedef unsigned long size_t; 64 + typedef signed long ssize_t; 65 + typedef unsigned long uintptr_t; 66 + typedef signed long intptr_t; 67 + typedef signed long ptrdiff_t; 68 + 69 + /* for stat() */ 70 + typedef unsigned int dev_t; 71 + typedef unsigned long ino_t; 72 + typedef unsigned int mode_t; 73 + typedef signed int pid_t; 74 + typedef unsigned int uid_t; 75 + typedef unsigned int gid_t; 76 + typedef unsigned long nlink_t; 77 + typedef signed long off_t; 78 + typedef signed long blksize_t; 79 + typedef signed long blkcnt_t; 80 + typedef signed long time_t; 81 + 82 + /* for poll() */ 83 + struct pollfd { 84 + int fd; 85 + short int events; 86 + short int revents; 87 + }; 88 + 89 + /* for select() */ 90 + struct timeval { 91 + long tv_sec; 92 + long tv_usec; 93 + }; 94 + 95 + /* for pselect() */ 96 + struct timespec { 97 + long tv_sec; 98 + long tv_nsec; 99 + }; 100 + 101 + /* for gettimeofday() */ 102 + struct timezone { 103 + int tz_minuteswest; 104 + int tz_dsttime; 105 + }; 106 + 107 + /* for getdents64() */ 108 + struct linux_dirent64 { 109 + uint64_t d_ino; 110 + int64_t d_off; 111 + unsigned short d_reclen; 112 + unsigned char d_type; 113 + char d_name[]; 114 + }; 115 + 116 + /* commonly an fd_set represents 256 FDs */ 117 + #define FD_SETSIZE 256 118 + typedef struct { uint32_t fd32[FD_SETSIZE/32]; } fd_set; 119 + 120 + /* needed by wait4() */ 121 + struct rusage { 122 + struct timeval ru_utime; 123 + struct timeval ru_stime; 124 + long ru_maxrss; 125 + long ru_ixrss; 126 + long ru_idrss; 127 + long ru_isrss; 128 + long ru_minflt; 129 + long ru_majflt; 130 + long ru_nswap; 131 + long ru_inblock; 132 + long ru_oublock; 133 + long ru_msgsnd; 134 + long ru_msgrcv; 135 + long ru_nsignals; 136 + long ru_nvcsw; 137 + long ru_nivcsw; 138 + }; 139 + 140 + /* stat flags (WARNING, octal here) */ 141 + #define S_IFDIR 0040000 142 + #define S_IFCHR 0020000 143 + #define S_IFBLK 0060000 144 + #define S_IFREG 0100000 145 + #define S_IFIFO 0010000 146 + #define S_IFLNK 0120000 147 + #define S_IFSOCK 0140000 148 + #define S_IFMT 0170000 149 + 150 + #define S_ISDIR(mode) (((mode) & S_IFDIR) == S_IFDIR) 151 + #define S_ISCHR(mode) (((mode) & S_IFCHR) == S_IFCHR) 152 + #define S_ISBLK(mode) (((mode) & S_IFBLK) == S_IFBLK) 153 + #define S_ISREG(mode) (((mode) & S_IFREG) == S_IFREG) 154 + #define S_ISFIFO(mode) (((mode) & S_IFIFO) == S_IFIFO) 155 + #define S_ISLNK(mode) (((mode) & S_IFLNK) == S_IFLNK) 156 + #define S_ISSOCK(mode) (((mode) & S_IFSOCK) == S_IFSOCK) 157 + 158 + #define DT_UNKNOWN 0 159 + #define DT_FIFO 1 160 + #define DT_CHR 2 161 + #define DT_DIR 4 162 + #define DT_BLK 6 163 + #define DT_REG 8 164 + #define DT_LNK 10 165 + #define DT_SOCK 12 166 + 167 + /* all the *at functions */ 168 + #ifndef AT_FDWCD 169 + #define AT_FDCWD -100 170 + #endif 171 + 172 + /* lseek */ 173 + #define SEEK_SET 0 174 + #define SEEK_CUR 1 175 + #define SEEK_END 2 176 + 177 + /* reboot */ 178 + #define LINUX_REBOOT_MAGIC1 0xfee1dead 179 + #define LINUX_REBOOT_MAGIC2 0x28121969 180 + #define LINUX_REBOOT_CMD_HALT 0xcdef0123 181 + #define LINUX_REBOOT_CMD_POWER_OFF 0x4321fedc 182 + #define LINUX_REBOOT_CMD_RESTART 0x01234567 183 + #define LINUX_REBOOT_CMD_SW_SUSPEND 0xd000fce2 184 + 185 + 186 + /* The format of the struct as returned by the libc to the application, which 187 + * significantly differs from the format returned by the stat() syscall flavours. 188 + */ 189 + struct stat { 190 + dev_t st_dev; /* ID of device containing file */ 191 + ino_t st_ino; /* inode number */ 192 + mode_t st_mode; /* protection */ 193 + nlink_t st_nlink; /* number of hard links */ 194 + uid_t st_uid; /* user ID of owner */ 195 + gid_t st_gid; /* group ID of owner */ 196 + dev_t st_rdev; /* device ID (if special file) */ 197 + off_t st_size; /* total size, in bytes */ 198 + blksize_t st_blksize; /* blocksize for file system I/O */ 199 + blkcnt_t st_blocks; /* number of 512B blocks allocated */ 200 + time_t st_atime; /* time of last access */ 201 + time_t st_mtime; /* time of last modification */ 202 + time_t st_ctime; /* time of last status change */ 203 + }; 204 + 205 + #define WEXITSTATUS(status) (((status) & 0xff00) >> 8) 206 + #define WIFEXITED(status) (((status) & 0x7f) == 0) 207 + 208 + 209 + /* Below comes the architecture-specific code. For each architecture, we have 210 + * the syscall declarations and the _start code definition. This is the only 211 + * global part. On all architectures the kernel puts everything in the stack 212 + * before jumping to _start just above us, without any return address (_start 213 + * is not a function but an entry pint). So at the stack pointer we find argc. 214 + * Then argv[] begins, and ends at the first NULL. Then we have envp which 215 + * starts and ends with a NULL as well. So envp=argv+argc+1. 216 + */ 217 + 218 + #if defined(__x86_64__) 219 + /* Syscalls for x86_64 : 220 + * - registers are 64-bit 221 + * - syscall number is passed in rax 222 + * - arguments are in rdi, rsi, rdx, r10, r8, r9 respectively 223 + * - the system call is performed by calling the syscall instruction 224 + * - syscall return comes in rax 225 + * - rcx and r8..r11 may be clobbered, others are preserved. 226 + * - the arguments are cast to long and assigned into the target registers 227 + * which are then simply passed as registers to the asm code, so that we 228 + * don't have to experience issues with register constraints. 229 + * - the syscall number is always specified last in order to allow to force 230 + * some registers before (gcc refuses a %-register at the last position). 231 + */ 232 + 233 + #define my_syscall0(num) \ 234 + ({ \ 235 + long _ret; \ 236 + register long _num asm("rax") = (num); \ 237 + \ 238 + asm volatile ( \ 239 + "syscall\n" \ 240 + : "=a" (_ret) \ 241 + : "0"(_num) \ 242 + : "rcx", "r8", "r9", "r10", "r11", "memory", "cc" \ 243 + ); \ 244 + _ret; \ 245 + }) 246 + 247 + #define my_syscall1(num, arg1) \ 248 + ({ \ 249 + long _ret; \ 250 + register long _num asm("rax") = (num); \ 251 + register long _arg1 asm("rdi") = (long)(arg1); \ 252 + \ 253 + asm volatile ( \ 254 + "syscall\n" \ 255 + : "=a" (_ret) \ 256 + : "r"(_arg1), \ 257 + "0"(_num) \ 258 + : "rcx", "r8", "r9", "r10", "r11", "memory", "cc" \ 259 + ); \ 260 + _ret; \ 261 + }) 262 + 263 + #define my_syscall2(num, arg1, arg2) \ 264 + ({ \ 265 + long _ret; \ 266 + register long _num asm("rax") = (num); \ 267 + register long _arg1 asm("rdi") = (long)(arg1); \ 268 + register long _arg2 asm("rsi") = (long)(arg2); \ 269 + \ 270 + asm volatile ( \ 271 + "syscall\n" \ 272 + : "=a" (_ret) \ 273 + : "r"(_arg1), "r"(_arg2), \ 274 + "0"(_num) \ 275 + : "rcx", "r8", "r9", "r10", "r11", "memory", "cc" \ 276 + ); \ 277 + _ret; \ 278 + }) 279 + 280 + #define my_syscall3(num, arg1, arg2, arg3) \ 281 + ({ \ 282 + long _ret; \ 283 + register long _num asm("rax") = (num); \ 284 + register long _arg1 asm("rdi") = (long)(arg1); \ 285 + register long _arg2 asm("rsi") = (long)(arg2); \ 286 + register long _arg3 asm("rdx") = (long)(arg3); \ 287 + \ 288 + asm volatile ( \ 289 + "syscall\n" \ 290 + : "=a" (_ret) \ 291 + : "r"(_arg1), "r"(_arg2), "r"(_arg3), \ 292 + "0"(_num) \ 293 + : "rcx", "r8", "r9", "r10", "r11", "memory", "cc" \ 294 + ); \ 295 + _ret; \ 296 + }) 297 + 298 + #define my_syscall4(num, arg1, arg2, arg3, arg4) \ 299 + ({ \ 300 + long _ret; \ 301 + register long _num asm("rax") = (num); \ 302 + register long _arg1 asm("rdi") = (long)(arg1); \ 303 + register long _arg2 asm("rsi") = (long)(arg2); \ 304 + register long _arg3 asm("rdx") = (long)(arg3); \ 305 + register long _arg4 asm("r10") = (long)(arg4); \ 306 + \ 307 + asm volatile ( \ 308 + "syscall\n" \ 309 + : "=a" (_ret), "=r"(_arg4) \ 310 + : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \ 311 + "0"(_num) \ 312 + : "rcx", "r8", "r9", "r11", "memory", "cc" \ 313 + ); \ 314 + _ret; \ 315 + }) 316 + 317 + #define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ 318 + ({ \ 319 + long _ret; \ 320 + register long _num asm("rax") = (num); \ 321 + register long _arg1 asm("rdi") = (long)(arg1); \ 322 + register long _arg2 asm("rsi") = (long)(arg2); \ 323 + register long _arg3 asm("rdx") = (long)(arg3); \ 324 + register long _arg4 asm("r10") = (long)(arg4); \ 325 + register long _arg5 asm("r8") = (long)(arg5); \ 326 + \ 327 + asm volatile ( \ 328 + "syscall\n" \ 329 + : "=a" (_ret), "=r"(_arg4), "=r"(_arg5) \ 330 + : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \ 331 + "0"(_num) \ 332 + : "rcx", "r9", "r11", "memory", "cc" \ 333 + ); \ 334 + _ret; \ 335 + }) 336 + 337 + #define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ 338 + ({ \ 339 + long _ret; \ 340 + register long _num asm("rax") = (num); \ 341 + register long _arg1 asm("rdi") = (long)(arg1); \ 342 + register long _arg2 asm("rsi") = (long)(arg2); \ 343 + register long _arg3 asm("rdx") = (long)(arg3); \ 344 + register long _arg4 asm("r10") = (long)(arg4); \ 345 + register long _arg5 asm("r8") = (long)(arg5); \ 346 + register long _arg6 asm("r9") = (long)(arg6); \ 347 + \ 348 + asm volatile ( \ 349 + "syscall\n" \ 350 + : "=a" (_ret), "=r"(_arg4), "=r"(_arg5) \ 351 + : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \ 352 + "r"(_arg6), "0"(_num) \ 353 + : "rcx", "r11", "memory", "cc" \ 354 + ); \ 355 + _ret; \ 356 + }) 357 + 358 + /* startup code */ 359 + asm(".section .text\n" 360 + ".global _start\n" 361 + "_start:\n" 362 + "pop %rdi\n" // argc (first arg, %rdi) 363 + "mov %rsp, %rsi\n" // argv[] (second arg, %rsi) 364 + "lea 8(%rsi,%rdi,8),%rdx\n" // then a NULL then envp (third arg, %rdx) 365 + "and $-16, %rsp\n" // x86 ABI : esp must be 16-byte aligned when 366 + "sub $8, %rsp\n" // entering the callee 367 + "call main\n" // main() returns the status code, we'll exit with it. 368 + "movzb %al, %rdi\n" // retrieve exit code from 8 lower bits 369 + "mov $60, %rax\n" // NR_exit == 60 370 + "syscall\n" // really exit 371 + "hlt\n" // ensure it does not return 372 + ""); 373 + 374 + /* fcntl / open */ 375 + #define O_RDONLY 0 376 + #define O_WRONLY 1 377 + #define O_RDWR 2 378 + #define O_CREAT 0x40 379 + #define O_EXCL 0x80 380 + #define O_NOCTTY 0x100 381 + #define O_TRUNC 0x200 382 + #define O_APPEND 0x400 383 + #define O_NONBLOCK 0x800 384 + #define O_DIRECTORY 0x10000 385 + 386 + /* The struct returned by the stat() syscall, equivalent to stat64(). The 387 + * syscall returns 116 bytes and stops in the middle of __unused. 388 + */ 389 + struct sys_stat_struct { 390 + unsigned long st_dev; 391 + unsigned long st_ino; 392 + unsigned long st_nlink; 393 + unsigned int st_mode; 394 + unsigned int st_uid; 395 + 396 + unsigned int st_gid; 397 + unsigned int __pad0; 398 + unsigned long st_rdev; 399 + long st_size; 400 + long st_blksize; 401 + 402 + long st_blocks; 403 + unsigned long st_atime; 404 + unsigned long st_atime_nsec; 405 + unsigned long st_mtime; 406 + 407 + unsigned long st_mtime_nsec; 408 + unsigned long st_ctime; 409 + unsigned long st_ctime_nsec; 410 + long __unused[3]; 411 + }; 412 + 413 + #elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) 414 + /* Syscalls for i386 : 415 + * - mostly similar to x86_64 416 + * - registers are 32-bit 417 + * - syscall number is passed in eax 418 + * - arguments are in ebx, ecx, edx, esi, edi, ebp respectively 419 + * - all registers are preserved (except eax of course) 420 + * - the system call is performed by calling int $0x80 421 + * - syscall return comes in eax 422 + * - the arguments are cast to long and assigned into the target registers 423 + * which are then simply passed as registers to the asm code, so that we 424 + * don't have to experience issues with register constraints. 425 + * - the syscall number is always specified last in order to allow to force 426 + * some registers before (gcc refuses a %-register at the last position). 427 + * 428 + * Also, i386 supports the old_select syscall if newselect is not available 429 + */ 430 + #define __ARCH_WANT_SYS_OLD_SELECT 431 + 432 + #define my_syscall0(num) \ 433 + ({ \ 434 + long _ret; \ 435 + register long _num asm("eax") = (num); \ 436 + \ 437 + asm volatile ( \ 438 + "int $0x80\n" \ 439 + : "=a" (_ret) \ 440 + : "0"(_num) \ 441 + : "memory", "cc" \ 442 + ); \ 443 + _ret; \ 444 + }) 445 + 446 + #define my_syscall1(num, arg1) \ 447 + ({ \ 448 + long _ret; \ 449 + register long _num asm("eax") = (num); \ 450 + register long _arg1 asm("ebx") = (long)(arg1); \ 451 + \ 452 + asm volatile ( \ 453 + "int $0x80\n" \ 454 + : "=a" (_ret) \ 455 + : "r"(_arg1), \ 456 + "0"(_num) \ 457 + : "memory", "cc" \ 458 + ); \ 459 + _ret; \ 460 + }) 461 + 462 + #define my_syscall2(num, arg1, arg2) \ 463 + ({ \ 464 + long _ret; \ 465 + register long _num asm("eax") = (num); \ 466 + register long _arg1 asm("ebx") = (long)(arg1); \ 467 + register long _arg2 asm("ecx") = (long)(arg2); \ 468 + \ 469 + asm volatile ( \ 470 + "int $0x80\n" \ 471 + : "=a" (_ret) \ 472 + : "r"(_arg1), "r"(_arg2), \ 473 + "0"(_num) \ 474 + : "memory", "cc" \ 475 + ); \ 476 + _ret; \ 477 + }) 478 + 479 + #define my_syscall3(num, arg1, arg2, arg3) \ 480 + ({ \ 481 + long _ret; \ 482 + register long _num asm("eax") = (num); \ 483 + register long _arg1 asm("ebx") = (long)(arg1); \ 484 + register long _arg2 asm("ecx") = (long)(arg2); \ 485 + register long _arg3 asm("edx") = (long)(arg3); \ 486 + \ 487 + asm volatile ( \ 488 + "int $0x80\n" \ 489 + : "=a" (_ret) \ 490 + : "r"(_arg1), "r"(_arg2), "r"(_arg3), \ 491 + "0"(_num) \ 492 + : "memory", "cc" \ 493 + ); \ 494 + _ret; \ 495 + }) 496 + 497 + #define my_syscall4(num, arg1, arg2, arg3, arg4) \ 498 + ({ \ 499 + long _ret; \ 500 + register long _num asm("eax") = (num); \ 501 + register long _arg1 asm("ebx") = (long)(arg1); \ 502 + register long _arg2 asm("ecx") = (long)(arg2); \ 503 + register long _arg3 asm("edx") = (long)(arg3); \ 504 + register long _arg4 asm("esi") = (long)(arg4); \ 505 + \ 506 + asm volatile ( \ 507 + "int $0x80\n" \ 508 + : "=a" (_ret) \ 509 + : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \ 510 + "0"(_num) \ 511 + : "memory", "cc" \ 512 + ); \ 513 + _ret; \ 514 + }) 515 + 516 + #define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ 517 + ({ \ 518 + long _ret; \ 519 + register long _num asm("eax") = (num); \ 520 + register long _arg1 asm("ebx") = (long)(arg1); \ 521 + register long _arg2 asm("ecx") = (long)(arg2); \ 522 + register long _arg3 asm("edx") = (long)(arg3); \ 523 + register long _arg4 asm("esi") = (long)(arg4); \ 524 + register long _arg5 asm("edi") = (long)(arg5); \ 525 + \ 526 + asm volatile ( \ 527 + "int $0x80\n" \ 528 + : "=a" (_ret) \ 529 + : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \ 530 + "0"(_num) \ 531 + : "memory", "cc" \ 532 + ); \ 533 + _ret; \ 534 + }) 535 + 536 + /* startup code */ 537 + asm(".section .text\n" 538 + ".global _start\n" 539 + "_start:\n" 540 + "pop %eax\n" // argc (first arg, %eax) 541 + "mov %esp, %ebx\n" // argv[] (second arg, %ebx) 542 + "lea 4(%ebx,%eax,4),%ecx\n" // then a NULL then envp (third arg, %ecx) 543 + "and $-16, %esp\n" // x86 ABI : esp must be 16-byte aligned when 544 + "push %ecx\n" // push all registers on the stack so that we 545 + "push %ebx\n" // support both regparm and plain stack modes 546 + "push %eax\n" 547 + "call main\n" // main() returns the status code in %eax 548 + "movzbl %al, %ebx\n" // retrieve exit code from lower 8 bits 549 + "movl $1, %eax\n" // NR_exit == 1 550 + "int $0x80\n" // exit now 551 + "hlt\n" // ensure it does not 552 + ""); 553 + 554 + /* fcntl / open */ 555 + #define O_RDONLY 0 556 + #define O_WRONLY 1 557 + #define O_RDWR 2 558 + #define O_CREAT 0x40 559 + #define O_EXCL 0x80 560 + #define O_NOCTTY 0x100 561 + #define O_TRUNC 0x200 562 + #define O_APPEND 0x400 563 + #define O_NONBLOCK 0x800 564 + #define O_DIRECTORY 0x10000 565 + 566 + /* The struct returned by the stat() syscall, 32-bit only, the syscall returns 567 + * exactly 56 bytes (stops before the unused array). 568 + */ 569 + struct sys_stat_struct { 570 + unsigned long st_dev; 571 + unsigned long st_ino; 572 + unsigned short st_mode; 573 + unsigned short st_nlink; 574 + unsigned short st_uid; 575 + unsigned short st_gid; 576 + 577 + unsigned long st_rdev; 578 + unsigned long st_size; 579 + unsigned long st_blksize; 580 + unsigned long st_blocks; 581 + 582 + unsigned long st_atime; 583 + unsigned long st_atime_nsec; 584 + unsigned long st_mtime; 585 + unsigned long st_mtime_nsec; 586 + 587 + unsigned long st_ctime; 588 + unsigned long st_ctime_nsec; 589 + unsigned long __unused[2]; 590 + }; 591 + 592 + #elif defined(__ARM_EABI__) 593 + /* Syscalls for ARM in ARM or Thumb modes : 594 + * - registers are 32-bit 595 + * - stack is 8-byte aligned 596 + * ( http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka4127.html) 597 + * - syscall number is passed in r7 598 + * - arguments are in r0, r1, r2, r3, r4, r5 599 + * - the system call is performed by calling svc #0 600 + * - syscall return comes in r0. 601 + * - only lr is clobbered. 602 + * - the arguments are cast to long and assigned into the target registers 603 + * which are then simply passed as registers to the asm code, so that we 604 + * don't have to experience issues with register constraints. 605 + * - the syscall number is always specified last in order to allow to force 606 + * some registers before (gcc refuses a %-register at the last position). 607 + * 608 + * Also, ARM supports the old_select syscall if newselect is not available 609 + */ 610 + #define __ARCH_WANT_SYS_OLD_SELECT 611 + 612 + #define my_syscall0(num) \ 613 + ({ \ 614 + register long _num asm("r7") = (num); \ 615 + register long _arg1 asm("r0"); \ 616 + \ 617 + asm volatile ( \ 618 + "svc #0\n" \ 619 + : "=r"(_arg1) \ 620 + : "r"(_num) \ 621 + : "memory", "cc", "lr" \ 622 + ); \ 623 + _arg1; \ 624 + }) 625 + 626 + #define my_syscall1(num, arg1) \ 627 + ({ \ 628 + register long _num asm("r7") = (num); \ 629 + register long _arg1 asm("r0") = (long)(arg1); \ 630 + \ 631 + asm volatile ( \ 632 + "svc #0\n" \ 633 + : "=r"(_arg1) \ 634 + : "r"(_arg1), \ 635 + "r"(_num) \ 636 + : "memory", "cc", "lr" \ 637 + ); \ 638 + _arg1; \ 639 + }) 640 + 641 + #define my_syscall2(num, arg1, arg2) \ 642 + ({ \ 643 + register long _num asm("r7") = (num); \ 644 + register long _arg1 asm("r0") = (long)(arg1); \ 645 + register long _arg2 asm("r1") = (long)(arg2); \ 646 + \ 647 + asm volatile ( \ 648 + "svc #0\n" \ 649 + : "=r"(_arg1) \ 650 + : "r"(_arg1), "r"(_arg2), \ 651 + "r"(_num) \ 652 + : "memory", "cc", "lr" \ 653 + ); \ 654 + _arg1; \ 655 + }) 656 + 657 + #define my_syscall3(num, arg1, arg2, arg3) \ 658 + ({ \ 659 + register long _num asm("r7") = (num); \ 660 + register long _arg1 asm("r0") = (long)(arg1); \ 661 + register long _arg2 asm("r1") = (long)(arg2); \ 662 + register long _arg3 asm("r2") = (long)(arg3); \ 663 + \ 664 + asm volatile ( \ 665 + "svc #0\n" \ 666 + : "=r"(_arg1) \ 667 + : "r"(_arg1), "r"(_arg2), "r"(_arg3), \ 668 + "r"(_num) \ 669 + : "memory", "cc", "lr" \ 670 + ); \ 671 + _arg1; \ 672 + }) 673 + 674 + #define my_syscall4(num, arg1, arg2, arg3, arg4) \ 675 + ({ \ 676 + register long _num asm("r7") = (num); \ 677 + register long _arg1 asm("r0") = (long)(arg1); \ 678 + register long _arg2 asm("r1") = (long)(arg2); \ 679 + register long _arg3 asm("r2") = (long)(arg3); \ 680 + register long _arg4 asm("r3") = (long)(arg4); \ 681 + \ 682 + asm volatile ( \ 683 + "svc #0\n" \ 684 + : "=r"(_arg1) \ 685 + : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \ 686 + "r"(_num) \ 687 + : "memory", "cc", "lr" \ 688 + ); \ 689 + _arg1; \ 690 + }) 691 + 692 + #define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ 693 + ({ \ 694 + register long _num asm("r7") = (num); \ 695 + register long _arg1 asm("r0") = (long)(arg1); \ 696 + register long _arg2 asm("r1") = (long)(arg2); \ 697 + register long _arg3 asm("r2") = (long)(arg3); \ 698 + register long _arg4 asm("r3") = (long)(arg4); \ 699 + register long _arg5 asm("r4") = (long)(arg5); \ 700 + \ 701 + asm volatile ( \ 702 + "svc #0\n" \ 703 + : "=r" (_arg1) \ 704 + : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \ 705 + "r"(_num) \ 706 + : "memory", "cc", "lr" \ 707 + ); \ 708 + _arg1; \ 709 + }) 710 + 711 + /* startup code */ 712 + asm(".section .text\n" 713 + ".global _start\n" 714 + "_start:\n" 715 + #if defined(__THUMBEB__) || defined(__THUMBEL__) 716 + /* We enter here in 32-bit mode but if some previous functions were in 717 + * 16-bit mode, the assembler cannot know, so we need to tell it we're in 718 + * 32-bit now, then switch to 16-bit (is there a better way to do it than 719 + * adding 1 by hand ?) and tell the asm we're now in 16-bit mode so that 720 + * it generates correct instructions. Note that we do not support thumb1. 721 + */ 722 + ".code 32\n" 723 + "add r0, pc, #1\n" 724 + "bx r0\n" 725 + ".code 16\n" 726 + #endif 727 + "pop {%r0}\n" // argc was in the stack 728 + "mov %r1, %sp\n" // argv = sp 729 + "add %r2, %r1, %r0, lsl #2\n" // envp = argv + 4*argc ... 730 + "add %r2, %r2, $4\n" // ... + 4 731 + "and %r3, %r1, $-8\n" // AAPCS : sp must be 8-byte aligned in the 732 + "mov %sp, %r3\n" // callee, an bl doesn't push (lr=pc) 733 + "bl main\n" // main() returns the status code, we'll exit with it. 734 + "and %r0, %r0, $0xff\n" // limit exit code to 8 bits 735 + "movs r7, $1\n" // NR_exit == 1 736 + "svc $0x00\n" 737 + ""); 738 + 739 + /* fcntl / open */ 740 + #define O_RDONLY 0 741 + #define O_WRONLY 1 742 + #define O_RDWR 2 743 + #define O_CREAT 0x40 744 + #define O_EXCL 0x80 745 + #define O_NOCTTY 0x100 746 + #define O_TRUNC 0x200 747 + #define O_APPEND 0x400 748 + #define O_NONBLOCK 0x800 749 + #define O_DIRECTORY 0x4000 750 + 751 + /* The struct returned by the stat() syscall, 32-bit only, the syscall returns 752 + * exactly 56 bytes (stops before the unused array). In big endian, the format 753 + * differs as devices are returned as short only. 754 + */ 755 + struct sys_stat_struct { 756 + #if defined(__ARMEB__) 757 + unsigned short st_dev; 758 + unsigned short __pad1; 759 + #else 760 + unsigned long st_dev; 761 + #endif 762 + unsigned long st_ino; 763 + unsigned short st_mode; 764 + unsigned short st_nlink; 765 + unsigned short st_uid; 766 + unsigned short st_gid; 767 + #if defined(__ARMEB__) 768 + unsigned short st_rdev; 769 + unsigned short __pad2; 770 + #else 771 + unsigned long st_rdev; 772 + #endif 773 + unsigned long st_size; 774 + unsigned long st_blksize; 775 + unsigned long st_blocks; 776 + unsigned long st_atime; 777 + unsigned long st_atime_nsec; 778 + unsigned long st_mtime; 779 + unsigned long st_mtime_nsec; 780 + unsigned long st_ctime; 781 + unsigned long st_ctime_nsec; 782 + unsigned long __unused[2]; 783 + }; 784 + 785 + #elif defined(__aarch64__) 786 + /* Syscalls for AARCH64 : 787 + * - registers are 64-bit 788 + * - stack is 16-byte aligned 789 + * - syscall number is passed in x8 790 + * - arguments are in x0, x1, x2, x3, x4, x5 791 + * - the system call is performed by calling svc 0 792 + * - syscall return comes in x0. 793 + * - the arguments are cast to long and assigned into the target registers 794 + * which are then simply passed as registers to the asm code, so that we 795 + * don't have to experience issues with register constraints. 796 + * 797 + * On aarch64, select() is not implemented so we have to use pselect6(). 798 + */ 799 + #define __ARCH_WANT_SYS_PSELECT6 800 + 801 + #define my_syscall0(num) \ 802 + ({ \ 803 + register long _num asm("x8") = (num); \ 804 + register long _arg1 asm("x0"); \ 805 + \ 806 + asm volatile ( \ 807 + "svc #0\n" \ 808 + : "=r"(_arg1) \ 809 + : "r"(_num) \ 810 + : "memory", "cc" \ 811 + ); \ 812 + _arg1; \ 813 + }) 814 + 815 + #define my_syscall1(num, arg1) \ 816 + ({ \ 817 + register long _num asm("x8") = (num); \ 818 + register long _arg1 asm("x0") = (long)(arg1); \ 819 + \ 820 + asm volatile ( \ 821 + "svc #0\n" \ 822 + : "=r"(_arg1) \ 823 + : "r"(_arg1), \ 824 + "r"(_num) \ 825 + : "memory", "cc" \ 826 + ); \ 827 + _arg1; \ 828 + }) 829 + 830 + #define my_syscall2(num, arg1, arg2) \ 831 + ({ \ 832 + register long _num asm("x8") = (num); \ 833 + register long _arg1 asm("x0") = (long)(arg1); \ 834 + register long _arg2 asm("x1") = (long)(arg2); \ 835 + \ 836 + asm volatile ( \ 837 + "svc #0\n" \ 838 + : "=r"(_arg1) \ 839 + : "r"(_arg1), "r"(_arg2), \ 840 + "r"(_num) \ 841 + : "memory", "cc" \ 842 + ); \ 843 + _arg1; \ 844 + }) 845 + 846 + #define my_syscall3(num, arg1, arg2, arg3) \ 847 + ({ \ 848 + register long _num asm("x8") = (num); \ 849 + register long _arg1 asm("x0") = (long)(arg1); \ 850 + register long _arg2 asm("x1") = (long)(arg2); \ 851 + register long _arg3 asm("x2") = (long)(arg3); \ 852 + \ 853 + asm volatile ( \ 854 + "svc #0\n" \ 855 + : "=r"(_arg1) \ 856 + : "r"(_arg1), "r"(_arg2), "r"(_arg3), \ 857 + "r"(_num) \ 858 + : "memory", "cc" \ 859 + ); \ 860 + _arg1; \ 861 + }) 862 + 863 + #define my_syscall4(num, arg1, arg2, arg3, arg4) \ 864 + ({ \ 865 + register long _num asm("x8") = (num); \ 866 + register long _arg1 asm("x0") = (long)(arg1); \ 867 + register long _arg2 asm("x1") = (long)(arg2); \ 868 + register long _arg3 asm("x2") = (long)(arg3); \ 869 + register long _arg4 asm("x3") = (long)(arg4); \ 870 + \ 871 + asm volatile ( \ 872 + "svc #0\n" \ 873 + : "=r"(_arg1) \ 874 + : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \ 875 + "r"(_num) \ 876 + : "memory", "cc" \ 877 + ); \ 878 + _arg1; \ 879 + }) 880 + 881 + #define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ 882 + ({ \ 883 + register long _num asm("x8") = (num); \ 884 + register long _arg1 asm("x0") = (long)(arg1); \ 885 + register long _arg2 asm("x1") = (long)(arg2); \ 886 + register long _arg3 asm("x2") = (long)(arg3); \ 887 + register long _arg4 asm("x3") = (long)(arg4); \ 888 + register long _arg5 asm("x4") = (long)(arg5); \ 889 + \ 890 + asm volatile ( \ 891 + "svc #0\n" \ 892 + : "=r" (_arg1) \ 893 + : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \ 894 + "r"(_num) \ 895 + : "memory", "cc" \ 896 + ); \ 897 + _arg1; \ 898 + }) 899 + 900 + #define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ 901 + ({ \ 902 + register long _num asm("x8") = (num); \ 903 + register long _arg1 asm("x0") = (long)(arg1); \ 904 + register long _arg2 asm("x1") = (long)(arg2); \ 905 + register long _arg3 asm("x2") = (long)(arg3); \ 906 + register long _arg4 asm("x3") = (long)(arg4); \ 907 + register long _arg5 asm("x4") = (long)(arg5); \ 908 + register long _arg6 asm("x5") = (long)(arg6); \ 909 + \ 910 + asm volatile ( \ 911 + "svc #0\n" \ 912 + : "=r" (_arg1) \ 913 + : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \ 914 + "r"(_arg6), "r"(_num) \ 915 + : "memory", "cc" \ 916 + ); \ 917 + _arg1; \ 918 + }) 919 + 920 + /* startup code */ 921 + asm(".section .text\n" 922 + ".global _start\n" 923 + "_start:\n" 924 + "ldr x0, [sp]\n" // argc (x0) was in the stack 925 + "add x1, sp, 8\n" // argv (x1) = sp 926 + "lsl x2, x0, 3\n" // envp (x2) = 8*argc ... 927 + "add x2, x2, 8\n" // + 8 (skip null) 928 + "add x2, x2, x1\n" // + argv 929 + "and sp, x1, -16\n" // sp must be 16-byte aligned in the callee 930 + "bl main\n" // main() returns the status code, we'll exit with it. 931 + "and x0, x0, 0xff\n" // limit exit code to 8 bits 932 + "mov x8, 93\n" // NR_exit == 93 933 + "svc #0\n" 934 + ""); 935 + 936 + /* fcntl / open */ 937 + #define O_RDONLY 0 938 + #define O_WRONLY 1 939 + #define O_RDWR 2 940 + #define O_CREAT 0x40 941 + #define O_EXCL 0x80 942 + #define O_NOCTTY 0x100 943 + #define O_TRUNC 0x200 944 + #define O_APPEND 0x400 945 + #define O_NONBLOCK 0x800 946 + #define O_DIRECTORY 0x4000 947 + 948 + /* The struct returned by the newfstatat() syscall. Differs slightly from the 949 + * x86_64's stat one by field ordering, so be careful. 950 + */ 951 + struct sys_stat_struct { 952 + unsigned long st_dev; 953 + unsigned long st_ino; 954 + unsigned int st_mode; 955 + unsigned int st_nlink; 956 + unsigned int st_uid; 957 + unsigned int st_gid; 958 + 959 + unsigned long st_rdev; 960 + unsigned long __pad1; 961 + long st_size; 962 + int st_blksize; 963 + int __pad2; 964 + 965 + long st_blocks; 966 + long st_atime; 967 + unsigned long st_atime_nsec; 968 + long st_mtime; 969 + 970 + unsigned long st_mtime_nsec; 971 + long st_ctime; 972 + unsigned long st_ctime_nsec; 973 + unsigned int __unused[2]; 974 + }; 975 + 976 + #elif defined(__mips__) && defined(_ABIO32) 977 + /* Syscalls for MIPS ABI O32 : 978 + * - WARNING! there's always a delayed slot! 979 + * - WARNING again, the syntax is different, registers take a '$' and numbers 980 + * do not. 981 + * - registers are 32-bit 982 + * - stack is 8-byte aligned 983 + * - syscall number is passed in v0 (starts at 0xfa0). 984 + * - arguments are in a0, a1, a2, a3, then the stack. The caller needs to 985 + * leave some room in the stack for the callee to save a0..a3 if needed. 986 + * - Many registers are clobbered, in fact only a0..a2 and s0..s8 are 987 + * preserved. See: https://www.linux-mips.org/wiki/Syscall as well as 988 + * scall32-o32.S in the kernel sources. 989 + * - the system call is performed by calling "syscall" 990 + * - syscall return comes in v0, and register a3 needs to be checked to know 991 + * if an error occured, in which case errno is in v0. 992 + * - the arguments are cast to long and assigned into the target registers 993 + * which are then simply passed as registers to the asm code, so that we 994 + * don't have to experience issues with register constraints. 995 + */ 996 + 997 + #define my_syscall0(num) \ 998 + ({ \ 999 + register long _num asm("v0") = (num); \ 1000 + register long _arg4 asm("a3"); \ 1001 + \ 1002 + asm volatile ( \ 1003 + "addiu $sp, $sp, -32\n" \ 1004 + "syscall\n" \ 1005 + "addiu $sp, $sp, 32\n" \ 1006 + : "=r"(_num), "=r"(_arg4) \ 1007 + : "r"(_num) \ 1008 + : "memory", "cc", "at", "v1", "hi", "lo", \ 1009 + \ 1010 + ); \ 1011 + _arg4 ? -_num : _num; \ 1012 + }) 1013 + 1014 + #define my_syscall1(num, arg1) \ 1015 + ({ \ 1016 + register long _num asm("v0") = (num); \ 1017 + register long _arg1 asm("a0") = (long)(arg1); \ 1018 + register long _arg4 asm("a3"); \ 1019 + \ 1020 + asm volatile ( \ 1021 + "addiu $sp, $sp, -32\n" \ 1022 + "syscall\n" \ 1023 + "addiu $sp, $sp, 32\n" \ 1024 + : "=r"(_num), "=r"(_arg4) \ 1025 + : "0"(_num), \ 1026 + "r"(_arg1) \ 1027 + : "memory", "cc", "at", "v1", "hi", "lo", \ 1028 + \ 1029 + ); \ 1030 + _arg4 ? -_num : _num; \ 1031 + }) 1032 + 1033 + #define my_syscall2(num, arg1, arg2) \ 1034 + ({ \ 1035 + register long _num asm("v0") = (num); \ 1036 + register long _arg1 asm("a0") = (long)(arg1); \ 1037 + register long _arg2 asm("a1") = (long)(arg2); \ 1038 + register long _arg4 asm("a3"); \ 1039 + \ 1040 + asm volatile ( \ 1041 + "addiu $sp, $sp, -32\n" \ 1042 + "syscall\n" \ 1043 + "addiu $sp, $sp, 32\n" \ 1044 + : "=r"(_num), "=r"(_arg4) \ 1045 + : "0"(_num), \ 1046 + "r"(_arg1), "r"(_arg2) \ 1047 + : "memory", "cc", "at", "v1", "hi", "lo", \ 1048 + \ 1049 + ); \ 1050 + _arg4 ? -_num : _num; \ 1051 + }) 1052 + 1053 + #define my_syscall3(num, arg1, arg2, arg3) \ 1054 + ({ \ 1055 + register long _num asm("v0") = (num); \ 1056 + register long _arg1 asm("a0") = (long)(arg1); \ 1057 + register long _arg2 asm("a1") = (long)(arg2); \ 1058 + register long _arg3 asm("a2") = (long)(arg3); \ 1059 + register long _arg4 asm("a3"); \ 1060 + \ 1061 + asm volatile ( \ 1062 + "addiu $sp, $sp, -32\n" \ 1063 + "syscall\n" \ 1064 + "addiu $sp, $sp, 32\n" \ 1065 + : "=r"(_num), "=r"(_arg4) \ 1066 + : "0"(_num), \ 1067 + "r"(_arg1), "r"(_arg2), "r"(_arg3) \ 1068 + : "memory", "cc", "at", "v1", "hi", "lo", \ 1069 + \ 1070 + ); \ 1071 + _arg4 ? -_num : _num; \ 1072 + }) 1073 + 1074 + #define my_syscall4(num, arg1, arg2, arg3, arg4) \ 1075 + ({ \ 1076 + register long _num asm("v0") = (num); \ 1077 + register long _arg1 asm("a0") = (long)(arg1); \ 1078 + register long _arg2 asm("a1") = (long)(arg2); \ 1079 + register long _arg3 asm("a2") = (long)(arg3); \ 1080 + register long _arg4 asm("a3") = (long)(arg4); \ 1081 + \ 1082 + asm volatile ( \ 1083 + "addiu $sp, $sp, -32\n" \ 1084 + "syscall\n" \ 1085 + "addiu $sp, $sp, 32\n" \ 1086 + : "=r" (_num), "=r"(_arg4) \ 1087 + : "0"(_num), \ 1088 + "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4) \ 1089 + : "memory", "cc", "at", "v1", "hi", "lo", \ 1090 + \ 1091 + ); \ 1092 + _arg4 ? -_num : _num; \ 1093 + }) 1094 + 1095 + #define my_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ 1096 + ({ \ 1097 + register long _num asm("v0") = (num); \ 1098 + register long _arg1 asm("a0") = (long)(arg1); \ 1099 + register long _arg2 asm("a1") = (long)(arg2); \ 1100 + register long _arg3 asm("a2") = (long)(arg3); \ 1101 + register long _arg4 asm("a3") = (long)(arg4); \ 1102 + register long _arg5 = (long)(arg5); \ 1103 + \ 1104 + asm volatile ( \ 1105 + "addiu $sp, $sp, -32\n" \ 1106 + "sw %7, 16($sp)\n" \ 1107 + "syscall\n " \ 1108 + "addiu $sp, $sp, 32\n" \ 1109 + : "=r" (_num), "=r"(_arg4) \ 1110 + : "0"(_num), \ 1111 + "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5) \ 1112 + : "memory", "cc", "at", "v1", "hi", "lo", \ 1113 + \ 1114 + ); \ 1115 + _arg4 ? -_num : _num; \ 1116 + }) 1117 + 1118 + /* startup code, note that it's called __start on MIPS */ 1119 + asm(".section .text\n" 1120 + ".set nomips16\n" 1121 + ".global __start\n" 1122 + ".set noreorder\n" 1123 + ".option pic0\n" 1124 + ".ent __start\n" 1125 + "__start:\n" 1126 + "lw $a0,($sp)\n" // argc was in the stack 1127 + "addiu $a1, $sp, 4\n" // argv = sp + 4 1128 + "sll $a2, $a0, 2\n" // a2 = argc * 4 1129 + "add $a2, $a2, $a1\n" // envp = argv + 4*argc ... 1130 + "addiu $a2, $a2, 4\n" // ... + 4 1131 + "li $t0, -8\n" 1132 + "and $sp, $sp, $t0\n" // sp must be 8-byte aligned 1133 + "addiu $sp,$sp,-16\n" // the callee expects to save a0..a3 there! 1134 + "jal main\n" // main() returns the status code, we'll exit with it. 1135 + "nop\n" // delayed slot 1136 + "and $a0, $v0, 0xff\n" // limit exit code to 8 bits 1137 + "li $v0, 4001\n" // NR_exit == 4001 1138 + "syscall\n" 1139 + ".end __start\n" 1140 + ""); 1141 + 1142 + /* fcntl / open */ 1143 + #define O_RDONLY 0 1144 + #define O_WRONLY 1 1145 + #define O_RDWR 2 1146 + #define O_APPEND 0x0008 1147 + #define O_NONBLOCK 0x0080 1148 + #define O_CREAT 0x0100 1149 + #define O_TRUNC 0x0200 1150 + #define O_EXCL 0x0400 1151 + #define O_NOCTTY 0x0800 1152 + #define O_DIRECTORY 0x10000 1153 + 1154 + /* The struct returned by the stat() syscall. 88 bytes are returned by the 1155 + * syscall. 1156 + */ 1157 + struct sys_stat_struct { 1158 + unsigned int st_dev; 1159 + long st_pad1[3]; 1160 + unsigned long st_ino; 1161 + unsigned int st_mode; 1162 + unsigned int st_nlink; 1163 + unsigned int st_uid; 1164 + unsigned int st_gid; 1165 + unsigned int st_rdev; 1166 + long st_pad2[2]; 1167 + long st_size; 1168 + long st_pad3; 1169 + long st_atime; 1170 + long st_atime_nsec; 1171 + long st_mtime; 1172 + long st_mtime_nsec; 1173 + long st_ctime; 1174 + long st_ctime_nsec; 1175 + long st_blksize; 1176 + long st_blocks; 1177 + long st_pad4[14]; 1178 + }; 1179 + 1180 + #endif 1181 + 1182 + 1183 + /* Below are the C functions used to declare the raw syscalls. They try to be 1184 + * architecture-agnostic, and return either a success or -errno. Declaring them 1185 + * static will lead to them being inlined in most cases, but it's still possible 1186 + * to reference them by a pointer if needed. 1187 + */ 1188 + static __attribute__((unused)) 1189 + void *sys_brk(void *addr) 1190 + { 1191 + return (void *)my_syscall1(__NR_brk, addr); 1192 + } 1193 + 1194 + static __attribute__((noreturn,unused)) 1195 + void sys_exit(int status) 1196 + { 1197 + my_syscall1(__NR_exit, status & 255); 1198 + while(1); // shut the "noreturn" warnings. 1199 + } 1200 + 1201 + static __attribute__((unused)) 1202 + int sys_chdir(const char *path) 1203 + { 1204 + return my_syscall1(__NR_chdir, path); 1205 + } 1206 + 1207 + static __attribute__((unused)) 1208 + int sys_chmod(const char *path, mode_t mode) 1209 + { 1210 + #ifdef __NR_fchmodat 1211 + return my_syscall4(__NR_fchmodat, AT_FDCWD, path, mode, 0); 1212 + #else 1213 + return my_syscall2(__NR_chmod, path, mode); 1214 + #endif 1215 + } 1216 + 1217 + static __attribute__((unused)) 1218 + int sys_chown(const char *path, uid_t owner, gid_t group) 1219 + { 1220 + #ifdef __NR_fchownat 1221 + return my_syscall5(__NR_fchownat, AT_FDCWD, path, owner, group, 0); 1222 + #else 1223 + return my_syscall3(__NR_chown, path, owner, group); 1224 + #endif 1225 + } 1226 + 1227 + static __attribute__((unused)) 1228 + int sys_chroot(const char *path) 1229 + { 1230 + return my_syscall1(__NR_chroot, path); 1231 + } 1232 + 1233 + static __attribute__((unused)) 1234 + int sys_close(int fd) 1235 + { 1236 + return my_syscall1(__NR_close, fd); 1237 + } 1238 + 1239 + static __attribute__((unused)) 1240 + int sys_dup(int fd) 1241 + { 1242 + return my_syscall1(__NR_dup, fd); 1243 + } 1244 + 1245 + static __attribute__((unused)) 1246 + int sys_dup2(int old, int new) 1247 + { 1248 + return my_syscall2(__NR_dup2, old, new); 1249 + } 1250 + 1251 + static __attribute__((unused)) 1252 + int sys_execve(const char *filename, char *const argv[], char *const envp[]) 1253 + { 1254 + return my_syscall3(__NR_execve, filename, argv, envp); 1255 + } 1256 + 1257 + static __attribute__((unused)) 1258 + pid_t sys_fork(void) 1259 + { 1260 + return my_syscall0(__NR_fork); 1261 + } 1262 + 1263 + static __attribute__((unused)) 1264 + int sys_fsync(int fd) 1265 + { 1266 + return my_syscall1(__NR_fsync, fd); 1267 + } 1268 + 1269 + static __attribute__((unused)) 1270 + int sys_getdents64(int fd, struct linux_dirent64 *dirp, int count) 1271 + { 1272 + return my_syscall3(__NR_getdents64, fd, dirp, count); 1273 + } 1274 + 1275 + static __attribute__((unused)) 1276 + pid_t sys_getpgrp(void) 1277 + { 1278 + return my_syscall0(__NR_getpgrp); 1279 + } 1280 + 1281 + static __attribute__((unused)) 1282 + pid_t sys_getpid(void) 1283 + { 1284 + return my_syscall0(__NR_getpid); 1285 + } 1286 + 1287 + static __attribute__((unused)) 1288 + int sys_gettimeofday(struct timeval *tv, struct timezone *tz) 1289 + { 1290 + return my_syscall2(__NR_gettimeofday, tv, tz); 1291 + } 1292 + 1293 + static __attribute__((unused)) 1294 + int sys_ioctl(int fd, unsigned long req, void *value) 1295 + { 1296 + return my_syscall3(__NR_ioctl, fd, req, value); 1297 + } 1298 + 1299 + static __attribute__((unused)) 1300 + int sys_kill(pid_t pid, int signal) 1301 + { 1302 + return my_syscall2(__NR_kill, pid, signal); 1303 + } 1304 + 1305 + static __attribute__((unused)) 1306 + int sys_link(const char *old, const char *new) 1307 + { 1308 + #ifdef __NR_linkat 1309 + return my_syscall5(__NR_linkat, AT_FDCWD, old, AT_FDCWD, new, 0); 1310 + #else 1311 + return my_syscall2(__NR_link, old, new); 1312 + #endif 1313 + } 1314 + 1315 + static __attribute__((unused)) 1316 + off_t sys_lseek(int fd, off_t offset, int whence) 1317 + { 1318 + return my_syscall3(__NR_lseek, fd, offset, whence); 1319 + } 1320 + 1321 + static __attribute__((unused)) 1322 + int sys_mkdir(const char *path, mode_t mode) 1323 + { 1324 + #ifdef __NR_mkdirat 1325 + return my_syscall3(__NR_mkdirat, AT_FDCWD, path, mode); 1326 + #else 1327 + return my_syscall2(__NR_mkdir, path, mode); 1328 + #endif 1329 + } 1330 + 1331 + static __attribute__((unused)) 1332 + long sys_mknod(const char *path, mode_t mode, dev_t dev) 1333 + { 1334 + #ifdef __NR_mknodat 1335 + return my_syscall4(__NR_mknodat, AT_FDCWD, path, mode, dev); 1336 + #else 1337 + return my_syscall3(__NR_mknod, path, mode, dev); 1338 + #endif 1339 + } 1340 + 1341 + static __attribute__((unused)) 1342 + int sys_mount(const char *src, const char *tgt, const char *fst, 1343 + unsigned long flags, const void *data) 1344 + { 1345 + return my_syscall5(__NR_mount, src, tgt, fst, flags, data); 1346 + } 1347 + 1348 + static __attribute__((unused)) 1349 + int sys_open(const char *path, int flags, mode_t mode) 1350 + { 1351 + #ifdef __NR_openat 1352 + return my_syscall4(__NR_openat, AT_FDCWD, path, flags, mode); 1353 + #else 1354 + return my_syscall3(__NR_open, path, flags, mode); 1355 + #endif 1356 + } 1357 + 1358 + static __attribute__((unused)) 1359 + int sys_pivot_root(const char *new, const char *old) 1360 + { 1361 + return my_syscall2(__NR_pivot_root, new, old); 1362 + } 1363 + 1364 + static __attribute__((unused)) 1365 + int sys_poll(struct pollfd *fds, int nfds, int timeout) 1366 + { 1367 + return my_syscall3(__NR_poll, fds, nfds, timeout); 1368 + } 1369 + 1370 + static __attribute__((unused)) 1371 + ssize_t sys_read(int fd, void *buf, size_t count) 1372 + { 1373 + return my_syscall3(__NR_read, fd, buf, count); 1374 + } 1375 + 1376 + static __attribute__((unused)) 1377 + ssize_t sys_reboot(int magic1, int magic2, int cmd, void *arg) 1378 + { 1379 + return my_syscall4(__NR_reboot, magic1, magic2, cmd, arg); 1380 + } 1381 + 1382 + static __attribute__((unused)) 1383 + int sys_sched_yield(void) 1384 + { 1385 + return my_syscall0(__NR_sched_yield); 1386 + } 1387 + 1388 + static __attribute__((unused)) 1389 + int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout) 1390 + { 1391 + #if defined(__ARCH_WANT_SYS_OLD_SELECT) && !defined(__NR__newselect) 1392 + struct sel_arg_struct { 1393 + unsigned long n; 1394 + fd_set *r, *w, *e; 1395 + struct timeval *t; 1396 + } arg = { .n = nfds, .r = rfds, .w = wfds, .e = efds, .t = timeout }; 1397 + return my_syscall1(__NR_select, &arg); 1398 + #elif defined(__ARCH_WANT_SYS_PSELECT6) && defined(__NR_pselect6) 1399 + struct timespec t; 1400 + 1401 + if (timeout) { 1402 + t.tv_sec = timeout->tv_sec; 1403 + t.tv_nsec = timeout->tv_usec * 1000; 1404 + } 1405 + return my_syscall6(__NR_pselect6, nfds, rfds, wfds, efds, timeout ? &t : NULL, NULL); 1406 + #else 1407 + #ifndef __NR__newselect 1408 + #define __NR__newselect __NR_select 1409 + #endif 1410 + return my_syscall5(__NR__newselect, nfds, rfds, wfds, efds, timeout); 1411 + #endif 1412 + } 1413 + 1414 + static __attribute__((unused)) 1415 + int sys_setpgid(pid_t pid, pid_t pgid) 1416 + { 1417 + return my_syscall2(__NR_setpgid, pid, pgid); 1418 + } 1419 + 1420 + static __attribute__((unused)) 1421 + pid_t sys_setsid(void) 1422 + { 1423 + return my_syscall0(__NR_setsid); 1424 + } 1425 + 1426 + static __attribute__((unused)) 1427 + int sys_stat(const char *path, struct stat *buf) 1428 + { 1429 + struct sys_stat_struct stat; 1430 + long ret; 1431 + 1432 + #ifdef __NR_newfstatat 1433 + /* only solution for arm64 */ 1434 + ret = my_syscall4(__NR_newfstatat, AT_FDCWD, path, &stat, 0); 1435 + #else 1436 + ret = my_syscall2(__NR_stat, path, &stat); 1437 + #endif 1438 + buf->st_dev = stat.st_dev; 1439 + buf->st_ino = stat.st_ino; 1440 + buf->st_mode = stat.st_mode; 1441 + buf->st_nlink = stat.st_nlink; 1442 + buf->st_uid = stat.st_uid; 1443 + buf->st_gid = stat.st_gid; 1444 + buf->st_rdev = stat.st_rdev; 1445 + buf->st_size = stat.st_size; 1446 + buf->st_blksize = stat.st_blksize; 1447 + buf->st_blocks = stat.st_blocks; 1448 + buf->st_atime = stat.st_atime; 1449 + buf->st_mtime = stat.st_mtime; 1450 + buf->st_ctime = stat.st_ctime; 1451 + return ret; 1452 + } 1453 + 1454 + 1455 + static __attribute__((unused)) 1456 + int sys_symlink(const char *old, const char *new) 1457 + { 1458 + #ifdef __NR_symlinkat 1459 + return my_syscall3(__NR_symlinkat, old, AT_FDCWD, new); 1460 + #else 1461 + return my_syscall2(__NR_symlink, old, new); 1462 + #endif 1463 + } 1464 + 1465 + static __attribute__((unused)) 1466 + mode_t sys_umask(mode_t mode) 1467 + { 1468 + return my_syscall1(__NR_umask, mode); 1469 + } 1470 + 1471 + static __attribute__((unused)) 1472 + int sys_umount2(const char *path, int flags) 1473 + { 1474 + return my_syscall2(__NR_umount2, path, flags); 1475 + } 1476 + 1477 + static __attribute__((unused)) 1478 + int sys_unlink(const char *path) 1479 + { 1480 + #ifdef __NR_unlinkat 1481 + return my_syscall3(__NR_unlinkat, AT_FDCWD, path, 0); 1482 + #else 1483 + return my_syscall1(__NR_unlink, path); 1484 + #endif 1485 + } 1486 + 1487 + static __attribute__((unused)) 1488 + pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage) 1489 + { 1490 + return my_syscall4(__NR_wait4, pid, status, options, rusage); 1491 + } 1492 + 1493 + static __attribute__((unused)) 1494 + pid_t sys_waitpid(pid_t pid, int *status, int options) 1495 + { 1496 + return sys_wait4(pid, status, options, 0); 1497 + } 1498 + 1499 + static __attribute__((unused)) 1500 + pid_t sys_wait(int *status) 1501 + { 1502 + return sys_waitpid(-1, status, 0); 1503 + } 1504 + 1505 + static __attribute__((unused)) 1506 + ssize_t sys_write(int fd, const void *buf, size_t count) 1507 + { 1508 + return my_syscall3(__NR_write, fd, buf, count); 1509 + } 1510 + 1511 + 1512 + /* Below are the libc-compatible syscalls which return x or -1 and set errno. 1513 + * They rely on the functions above. Similarly they're marked static so that it 1514 + * is possible to assign pointers to them if needed. 1515 + */ 1516 + 1517 + static __attribute__((unused)) 1518 + int brk(void *addr) 1519 + { 1520 + void *ret = sys_brk(addr); 1521 + 1522 + if (!ret) { 1523 + SET_ERRNO(ENOMEM); 1524 + return -1; 1525 + } 1526 + return 0; 1527 + } 1528 + 1529 + static __attribute__((noreturn,unused)) 1530 + void exit(int status) 1531 + { 1532 + sys_exit(status); 1533 + } 1534 + 1535 + static __attribute__((unused)) 1536 + int chdir(const char *path) 1537 + { 1538 + int ret = sys_chdir(path); 1539 + 1540 + if (ret < 0) { 1541 + SET_ERRNO(-ret); 1542 + ret = -1; 1543 + } 1544 + return ret; 1545 + } 1546 + 1547 + static __attribute__((unused)) 1548 + int chmod(const char *path, mode_t mode) 1549 + { 1550 + int ret = sys_chmod(path, mode); 1551 + 1552 + if (ret < 0) { 1553 + SET_ERRNO(-ret); 1554 + ret = -1; 1555 + } 1556 + return ret; 1557 + } 1558 + 1559 + static __attribute__((unused)) 1560 + int chown(const char *path, uid_t owner, gid_t group) 1561 + { 1562 + int ret = sys_chown(path, owner, group); 1563 + 1564 + if (ret < 0) { 1565 + SET_ERRNO(-ret); 1566 + ret = -1; 1567 + } 1568 + return ret; 1569 + } 1570 + 1571 + static __attribute__((unused)) 1572 + int chroot(const char *path) 1573 + { 1574 + int ret = sys_chroot(path); 1575 + 1576 + if (ret < 0) { 1577 + SET_ERRNO(-ret); 1578 + ret = -1; 1579 + } 1580 + return ret; 1581 + } 1582 + 1583 + static __attribute__((unused)) 1584 + int close(int fd) 1585 + { 1586 + int ret = sys_close(fd); 1587 + 1588 + if (ret < 0) { 1589 + SET_ERRNO(-ret); 1590 + ret = -1; 1591 + } 1592 + return ret; 1593 + } 1594 + 1595 + static __attribute__((unused)) 1596 + int dup2(int old, int new) 1597 + { 1598 + int ret = sys_dup2(old, new); 1599 + 1600 + if (ret < 0) { 1601 + SET_ERRNO(-ret); 1602 + ret = -1; 1603 + } 1604 + return ret; 1605 + } 1606 + 1607 + static __attribute__((unused)) 1608 + int execve(const char *filename, char *const argv[], char *const envp[]) 1609 + { 1610 + int ret = sys_execve(filename, argv, envp); 1611 + 1612 + if (ret < 0) { 1613 + SET_ERRNO(-ret); 1614 + ret = -1; 1615 + } 1616 + return ret; 1617 + } 1618 + 1619 + static __attribute__((unused)) 1620 + pid_t fork(void) 1621 + { 1622 + pid_t ret = sys_fork(); 1623 + 1624 + if (ret < 0) { 1625 + SET_ERRNO(-ret); 1626 + ret = -1; 1627 + } 1628 + return ret; 1629 + } 1630 + 1631 + static __attribute__((unused)) 1632 + int fsync(int fd) 1633 + { 1634 + int ret = sys_fsync(fd); 1635 + 1636 + if (ret < 0) { 1637 + SET_ERRNO(-ret); 1638 + ret = -1; 1639 + } 1640 + return ret; 1641 + } 1642 + 1643 + static __attribute__((unused)) 1644 + int getdents64(int fd, struct linux_dirent64 *dirp, int count) 1645 + { 1646 + int ret = sys_getdents64(fd, dirp, count); 1647 + 1648 + if (ret < 0) { 1649 + SET_ERRNO(-ret); 1650 + ret = -1; 1651 + } 1652 + return ret; 1653 + } 1654 + 1655 + static __attribute__((unused)) 1656 + pid_t getpgrp(void) 1657 + { 1658 + pid_t ret = sys_getpgrp(); 1659 + 1660 + if (ret < 0) { 1661 + SET_ERRNO(-ret); 1662 + ret = -1; 1663 + } 1664 + return ret; 1665 + } 1666 + 1667 + static __attribute__((unused)) 1668 + pid_t getpid(void) 1669 + { 1670 + pid_t ret = sys_getpid(); 1671 + 1672 + if (ret < 0) { 1673 + SET_ERRNO(-ret); 1674 + ret = -1; 1675 + } 1676 + return ret; 1677 + } 1678 + 1679 + static __attribute__((unused)) 1680 + int gettimeofday(struct timeval *tv, struct timezone *tz) 1681 + { 1682 + int ret = sys_gettimeofday(tv, tz); 1683 + 1684 + if (ret < 0) { 1685 + SET_ERRNO(-ret); 1686 + ret = -1; 1687 + } 1688 + return ret; 1689 + } 1690 + 1691 + static __attribute__((unused)) 1692 + int ioctl(int fd, unsigned long req, void *value) 1693 + { 1694 + int ret = sys_ioctl(fd, req, value); 1695 + 1696 + if (ret < 0) { 1697 + SET_ERRNO(-ret); 1698 + ret = -1; 1699 + } 1700 + return ret; 1701 + } 1702 + 1703 + static __attribute__((unused)) 1704 + int kill(pid_t pid, int signal) 1705 + { 1706 + int ret = sys_kill(pid, signal); 1707 + 1708 + if (ret < 0) { 1709 + SET_ERRNO(-ret); 1710 + ret = -1; 1711 + } 1712 + return ret; 1713 + } 1714 + 1715 + static __attribute__((unused)) 1716 + int link(const char *old, const char *new) 1717 + { 1718 + int ret = sys_link(old, new); 1719 + 1720 + if (ret < 0) { 1721 + SET_ERRNO(-ret); 1722 + ret = -1; 1723 + } 1724 + return ret; 1725 + } 1726 + 1727 + static __attribute__((unused)) 1728 + off_t lseek(int fd, off_t offset, int whence) 1729 + { 1730 + off_t ret = sys_lseek(fd, offset, whence); 1731 + 1732 + if (ret < 0) { 1733 + SET_ERRNO(-ret); 1734 + ret = -1; 1735 + } 1736 + return ret; 1737 + } 1738 + 1739 + static __attribute__((unused)) 1740 + int mkdir(const char *path, mode_t mode) 1741 + { 1742 + int ret = sys_mkdir(path, mode); 1743 + 1744 + if (ret < 0) { 1745 + SET_ERRNO(-ret); 1746 + ret = -1; 1747 + } 1748 + return ret; 1749 + } 1750 + 1751 + static __attribute__((unused)) 1752 + int mknod(const char *path, mode_t mode, dev_t dev) 1753 + { 1754 + int ret = sys_mknod(path, mode, dev); 1755 + 1756 + if (ret < 0) { 1757 + SET_ERRNO(-ret); 1758 + ret = -1; 1759 + } 1760 + return ret; 1761 + } 1762 + 1763 + static __attribute__((unused)) 1764 + int mount(const char *src, const char *tgt, 1765 + const char *fst, unsigned long flags, 1766 + const void *data) 1767 + { 1768 + int ret = sys_mount(src, tgt, fst, flags, data); 1769 + 1770 + if (ret < 0) { 1771 + SET_ERRNO(-ret); 1772 + ret = -1; 1773 + } 1774 + return ret; 1775 + } 1776 + 1777 + static __attribute__((unused)) 1778 + int open(const char *path, int flags, mode_t mode) 1779 + { 1780 + int ret = sys_open(path, flags, mode); 1781 + 1782 + if (ret < 0) { 1783 + SET_ERRNO(-ret); 1784 + ret = -1; 1785 + } 1786 + return ret; 1787 + } 1788 + 1789 + static __attribute__((unused)) 1790 + int pivot_root(const char *new, const char *old) 1791 + { 1792 + int ret = sys_pivot_root(new, old); 1793 + 1794 + if (ret < 0) { 1795 + SET_ERRNO(-ret); 1796 + ret = -1; 1797 + } 1798 + return ret; 1799 + } 1800 + 1801 + static __attribute__((unused)) 1802 + int poll(struct pollfd *fds, int nfds, int timeout) 1803 + { 1804 + int ret = sys_poll(fds, nfds, timeout); 1805 + 1806 + if (ret < 0) { 1807 + SET_ERRNO(-ret); 1808 + ret = -1; 1809 + } 1810 + return ret; 1811 + } 1812 + 1813 + static __attribute__((unused)) 1814 + ssize_t read(int fd, void *buf, size_t count) 1815 + { 1816 + ssize_t ret = sys_read(fd, buf, count); 1817 + 1818 + if (ret < 0) { 1819 + SET_ERRNO(-ret); 1820 + ret = -1; 1821 + } 1822 + return ret; 1823 + } 1824 + 1825 + static __attribute__((unused)) 1826 + int reboot(int cmd) 1827 + { 1828 + int ret = sys_reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, 0); 1829 + 1830 + if (ret < 0) { 1831 + SET_ERRNO(-ret); 1832 + ret = -1; 1833 + } 1834 + return ret; 1835 + } 1836 + 1837 + static __attribute__((unused)) 1838 + void *sbrk(intptr_t inc) 1839 + { 1840 + void *ret; 1841 + 1842 + /* first call to find current end */ 1843 + if ((ret = sys_brk(0)) && (sys_brk(ret + inc) == ret + inc)) 1844 + return ret + inc; 1845 + 1846 + SET_ERRNO(ENOMEM); 1847 + return (void *)-1; 1848 + } 1849 + 1850 + static __attribute__((unused)) 1851 + int sched_yield(void) 1852 + { 1853 + int ret = sys_sched_yield(); 1854 + 1855 + if (ret < 0) { 1856 + SET_ERRNO(-ret); 1857 + ret = -1; 1858 + } 1859 + return ret; 1860 + } 1861 + 1862 + static __attribute__((unused)) 1863 + int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout) 1864 + { 1865 + int ret = sys_select(nfds, rfds, wfds, efds, timeout); 1866 + 1867 + if (ret < 0) { 1868 + SET_ERRNO(-ret); 1869 + ret = -1; 1870 + } 1871 + return ret; 1872 + } 1873 + 1874 + static __attribute__((unused)) 1875 + int setpgid(pid_t pid, pid_t pgid) 1876 + { 1877 + int ret = sys_setpgid(pid, pgid); 1878 + 1879 + if (ret < 0) { 1880 + SET_ERRNO(-ret); 1881 + ret = -1; 1882 + } 1883 + return ret; 1884 + } 1885 + 1886 + static __attribute__((unused)) 1887 + pid_t setsid(void) 1888 + { 1889 + pid_t ret = sys_setsid(); 1890 + 1891 + if (ret < 0) { 1892 + SET_ERRNO(-ret); 1893 + ret = -1; 1894 + } 1895 + return ret; 1896 + } 1897 + 1898 + static __attribute__((unused)) 1899 + unsigned int sleep(unsigned int seconds) 1900 + { 1901 + struct timeval my_timeval = { seconds, 0 }; 1902 + 1903 + if (sys_select(0, 0, 0, 0, &my_timeval) < 0) 1904 + return my_timeval.tv_sec + !!my_timeval.tv_usec; 1905 + else 1906 + return 0; 1907 + } 1908 + 1909 + static __attribute__((unused)) 1910 + int stat(const char *path, struct stat *buf) 1911 + { 1912 + int ret = sys_stat(path, buf); 1913 + 1914 + if (ret < 0) { 1915 + SET_ERRNO(-ret); 1916 + ret = -1; 1917 + } 1918 + return ret; 1919 + } 1920 + 1921 + static __attribute__((unused)) 1922 + int symlink(const char *old, const char *new) 1923 + { 1924 + int ret = sys_symlink(old, new); 1925 + 1926 + if (ret < 0) { 1927 + SET_ERRNO(-ret); 1928 + ret = -1; 1929 + } 1930 + return ret; 1931 + } 1932 + 1933 + static __attribute__((unused)) 1934 + int tcsetpgrp(int fd, pid_t pid) 1935 + { 1936 + return ioctl(fd, TIOCSPGRP, &pid); 1937 + } 1938 + 1939 + static __attribute__((unused)) 1940 + mode_t umask(mode_t mode) 1941 + { 1942 + return sys_umask(mode); 1943 + } 1944 + 1945 + static __attribute__((unused)) 1946 + int umount2(const char *path, int flags) 1947 + { 1948 + int ret = sys_umount2(path, flags); 1949 + 1950 + if (ret < 0) { 1951 + SET_ERRNO(-ret); 1952 + ret = -1; 1953 + } 1954 + return ret; 1955 + } 1956 + 1957 + static __attribute__((unused)) 1958 + int unlink(const char *path) 1959 + { 1960 + int ret = sys_unlink(path); 1961 + 1962 + if (ret < 0) { 1963 + SET_ERRNO(-ret); 1964 + ret = -1; 1965 + } 1966 + return ret; 1967 + } 1968 + 1969 + static __attribute__((unused)) 1970 + pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage) 1971 + { 1972 + pid_t ret = sys_wait4(pid, status, options, rusage); 1973 + 1974 + if (ret < 0) { 1975 + SET_ERRNO(-ret); 1976 + ret = -1; 1977 + } 1978 + return ret; 1979 + } 1980 + 1981 + static __attribute__((unused)) 1982 + pid_t waitpid(pid_t pid, int *status, int options) 1983 + { 1984 + pid_t ret = sys_waitpid(pid, status, options); 1985 + 1986 + if (ret < 0) { 1987 + SET_ERRNO(-ret); 1988 + ret = -1; 1989 + } 1990 + return ret; 1991 + } 1992 + 1993 + static __attribute__((unused)) 1994 + pid_t wait(int *status) 1995 + { 1996 + pid_t ret = sys_wait(status); 1997 + 1998 + if (ret < 0) { 1999 + SET_ERRNO(-ret); 2000 + ret = -1; 2001 + } 2002 + return ret; 2003 + } 2004 + 2005 + static __attribute__((unused)) 2006 + ssize_t write(int fd, const void *buf, size_t count) 2007 + { 2008 + ssize_t ret = sys_write(fd, buf, count); 2009 + 2010 + if (ret < 0) { 2011 + SET_ERRNO(-ret); 2012 + ret = -1; 2013 + } 2014 + return ret; 2015 + } 2016 + 2017 + /* some size-optimized reimplementations of a few common str* and mem* 2018 + * functions. They're marked static, except memcpy() and raise() which are used 2019 + * by libgcc on ARM, so they are marked weak instead in order not to cause an 2020 + * error when building a program made of multiple files (not recommended). 2021 + */ 2022 + 2023 + static __attribute__((unused)) 2024 + void *memmove(void *dst, const void *src, size_t len) 2025 + { 2026 + ssize_t pos = (dst <= src) ? -1 : (long)len; 2027 + void *ret = dst; 2028 + 2029 + while (len--) { 2030 + pos += (dst <= src) ? 1 : -1; 2031 + ((char *)dst)[pos] = ((char *)src)[pos]; 2032 + } 2033 + return ret; 2034 + } 2035 + 2036 + static __attribute__((unused)) 2037 + void *memset(void *dst, int b, size_t len) 2038 + { 2039 + char *p = dst; 2040 + 2041 + while (len--) 2042 + *(p++) = b; 2043 + return dst; 2044 + } 2045 + 2046 + static __attribute__((unused)) 2047 + int memcmp(const void *s1, const void *s2, size_t n) 2048 + { 2049 + size_t ofs = 0; 2050 + char c1 = 0; 2051 + 2052 + while (ofs < n && !(c1 = ((char *)s1)[ofs] - ((char *)s2)[ofs])) { 2053 + ofs++; 2054 + } 2055 + return c1; 2056 + } 2057 + 2058 + static __attribute__((unused)) 2059 + char *strcpy(char *dst, const char *src) 2060 + { 2061 + char *ret = dst; 2062 + 2063 + while ((*dst++ = *src++)); 2064 + return ret; 2065 + } 2066 + 2067 + static __attribute__((unused)) 2068 + char *strchr(const char *s, int c) 2069 + { 2070 + while (*s) { 2071 + if (*s == (char)c) 2072 + return (char *)s; 2073 + s++; 2074 + } 2075 + return NULL; 2076 + } 2077 + 2078 + static __attribute__((unused)) 2079 + char *strrchr(const char *s, int c) 2080 + { 2081 + const char *ret = NULL; 2082 + 2083 + while (*s) { 2084 + if (*s == (char)c) 2085 + ret = s; 2086 + s++; 2087 + } 2088 + return (char *)ret; 2089 + } 2090 + 2091 + static __attribute__((unused)) 2092 + size_t nolibc_strlen(const char *str) 2093 + { 2094 + size_t len; 2095 + 2096 + for (len = 0; str[len]; len++); 2097 + return len; 2098 + } 2099 + 2100 + #define strlen(str) ({ \ 2101 + __builtin_constant_p((str)) ? \ 2102 + __builtin_strlen((str)) : \ 2103 + nolibc_strlen((str)); \ 2104 + }) 2105 + 2106 + static __attribute__((unused)) 2107 + int isdigit(int c) 2108 + { 2109 + return (unsigned int)(c - '0') <= 9; 2110 + } 2111 + 2112 + static __attribute__((unused)) 2113 + long atol(const char *s) 2114 + { 2115 + unsigned long ret = 0; 2116 + unsigned long d; 2117 + int neg = 0; 2118 + 2119 + if (*s == '-') { 2120 + neg = 1; 2121 + s++; 2122 + } 2123 + 2124 + while (1) { 2125 + d = (*s++) - '0'; 2126 + if (d > 9) 2127 + break; 2128 + ret *= 10; 2129 + ret += d; 2130 + } 2131 + 2132 + return neg ? -ret : ret; 2133 + } 2134 + 2135 + static __attribute__((unused)) 2136 + int atoi(const char *s) 2137 + { 2138 + return atol(s); 2139 + } 2140 + 2141 + static __attribute__((unused)) 2142 + const char *ltoa(long in) 2143 + { 2144 + /* large enough for -9223372036854775808 */ 2145 + static char buffer[21]; 2146 + char *pos = buffer + sizeof(buffer) - 1; 2147 + int neg = in < 0; 2148 + unsigned long n = neg ? -in : in; 2149 + 2150 + *pos-- = '\0'; 2151 + do { 2152 + *pos-- = '0' + n % 10; 2153 + n /= 10; 2154 + if (pos < buffer) 2155 + return pos + 1; 2156 + } while (n); 2157 + 2158 + if (neg) 2159 + *pos-- = '-'; 2160 + return pos + 1; 2161 + } 2162 + 2163 + __attribute__((weak,unused)) 2164 + void *memcpy(void *dst, const void *src, size_t len) 2165 + { 2166 + return memmove(dst, src, len); 2167 + } 2168 + 2169 + /* needed by libgcc for divide by zero */ 2170 + __attribute__((weak,unused)) 2171 + int raise(int signal) 2172 + { 2173 + return kill(getpid(), signal); 2174 + } 2175 + 2176 + /* Here come a few helper functions */ 2177 + 2178 + static __attribute__((unused)) 2179 + void FD_ZERO(fd_set *set) 2180 + { 2181 + memset(set, 0, sizeof(*set)); 2182 + } 2183 + 2184 + static __attribute__((unused)) 2185 + void FD_SET(int fd, fd_set *set) 2186 + { 2187 + if (fd < 0 || fd >= FD_SETSIZE) 2188 + return; 2189 + set->fd32[fd / 32] |= 1 << (fd & 31); 2190 + } 2191 + 2192 + /* WARNING, it only deals with the 4096 first majors and 256 first minors */ 2193 + static __attribute__((unused)) 2194 + dev_t makedev(unsigned int major, unsigned int minor) 2195 + { 2196 + return ((major & 0xfff) << 8) | (minor & 0xff); 2197 + }
+12 -87
tools/testing/selftests/rcutorture/doc/initrd.txt
··· 1 - This document describes one way to create the initrd directory hierarchy 2 - in order to allow an initrd to be built into your kernel. The trick 3 - here is to steal the initrd file used on your Linux laptop, Ubuntu in 4 - this case. There are probably much better ways of doing this. 1 + The rcutorture scripting tools automatically create the needed initrd 2 + directory using dracut. Failing that, this tool will create an initrd 3 + containing a single statically linked binary named "init" that loops 4 + over a very long sleep() call. In both cases, this creation is done 5 + by tools/testing/selftests/rcutorture/bin/mkinitrd.sh. 5 6 6 - That said, here are the commands: 7 + However, if you are attempting to run rcutorture on a system that does 8 + not have dracut installed, and if you don't like the notion of static 9 + linking, you might wish to press an existing initrd into service: 7 10 8 11 ------------------------------------------------------------------------ 9 12 cd tools/testing/selftests/rcutorture ··· 14 11 mkdir initrd 15 12 cd initrd 16 13 cpio -id < /tmp/initrd.img.zcat 17 - ------------------------------------------------------------------------ 18 - 19 - Another way to create an initramfs image is using "dracut"[1], which is 20 - available on many distros, however the initramfs dracut generates is a cpio 21 - archive with another cpio archive in it, so an extra step is needed to create 22 - the initrd directory hierarchy. 23 - 24 - Here are the commands to create a initrd directory for rcutorture using 25 - dracut: 26 - 27 - ------------------------------------------------------------------------ 28 - dracut --no-hostonly --no-hostonly-cmdline --module "base bash shutdown" /tmp/initramfs.img 29 - cd tools/testing/selftests/rcutorture 30 - mkdir initrd 31 - cd initrd 32 - /usr/lib/dracut/skipcpio /tmp/initramfs.img | zcat | cpio -id < /tmp/initramfs.img 14 + # Manually verify that initrd contains needed binaries and libraries. 33 15 ------------------------------------------------------------------------ 34 16 35 17 Interestingly enough, if you are running rcutorture, you don't really ··· 27 39 ------------------------------------------------------------------------ 28 40 #!/bin/sh 29 41 30 - [ -d /dev ] || mkdir -m 0755 /dev 31 - [ -d /root ] || mkdir -m 0700 /root 32 - [ -d /sys ] || mkdir /sys 33 - [ -d /proc ] || mkdir /proc 34 - [ -d /tmp ] || mkdir /tmp 35 - mkdir -p /var/lock 36 - mount -t sysfs -o nodev,noexec,nosuid sysfs /sys 37 - mount -t proc -o nodev,noexec,nosuid proc /proc 38 - # Some things don't work properly without /etc/mtab. 39 - ln -sf /proc/mounts /etc/mtab 40 - 41 - # Note that this only becomes /dev on the real filesystem if udev's scripts 42 - # are used; which they will be, but it's worth pointing out 43 - if ! mount -t devtmpfs -o mode=0755 udev /dev; then 44 - echo "W: devtmpfs not available, falling back to tmpfs for /dev" 45 - mount -t tmpfs -o mode=0755 udev /dev 46 - [ -e /dev/console ] || mknod --mode=600 /dev/console c 5 1 47 - [ -e /dev/kmsg ] || mknod --mode=644 /dev/kmsg c 1 11 48 - [ -e /dev/null ] || mknod --mode=666 /dev/null c 1 3 49 - fi 50 - 51 - mkdir /dev/pts 52 - mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts || true 53 - mount -t tmpfs -o "nosuid,size=20%,mode=0755" tmpfs /run 54 - mkdir /run/initramfs 55 - # compatibility symlink for the pre-oneiric locations 56 - ln -s /run/initramfs /dev/.initramfs 57 - 58 - # Export relevant variables 59 - export ROOT= 60 - export ROOTDELAY= 61 - export ROOTFLAGS= 62 - export ROOTFSTYPE= 63 - export IP= 64 - export BOOT= 65 - export BOOTIF= 66 - export UBIMTD= 67 - export break= 68 - export init=/sbin/init 69 - export quiet=n 70 - export readonly=y 71 - export rootmnt=/root 72 - export debug= 73 - export panic= 74 - export blacklist= 75 - export resume= 76 - export resume_offset= 77 - export recovery= 78 - 79 - for i in /sys/devices/system/cpu/cpu*/online 80 - do 81 - case $i in 82 - '/sys/devices/system/cpu/cpu0/online') 83 - ;; 84 - '/sys/devices/system/cpu/cpu*/online') 85 - ;; 86 - *) 87 - echo 1 > $i 88 - ;; 89 - esac 90 - done 91 - 92 42 while : 93 43 do 94 44 sleep 10 95 45 done 96 46 ------------------------------------------------------------------------ 97 47 98 - References: 99 - [1]: https://dracut.wiki.kernel.org/index.php/Main_Page 100 - [2]: http://blog.elastocloud.org/2015/06/rapid-linux-kernel-devtest-with-qemu.html 101 - [3]: https://www.centos.org/forums/viewtopic.php?t=51621 48 + This approach also allows most of the binaries and libraries in the 49 + initrd filesystem to be dispensed with, which can save significant 50 + space in rcutorture's "res" directory.
+2 -2
tools/testing/selftests/rcutorture/formal/srcu-cbmc/include/linux/types.h
··· 131 131 * weird ABI and we need to ask it explicitly. 132 132 * 133 133 * The alignment is required to guarantee that bits 0 and 1 of @next will be 134 - * clear under normal conditions -- as long as we use call_rcu(), 135 - * call_rcu_bh(), call_rcu_sched(), or call_srcu() to queue callback. 134 + * clear under normal conditions -- as long as we use call_rcu() or 135 + * call_srcu() to queue callback. 136 136 * 137 137 * This guarantee is important for few reasons: 138 138 * - future call_rcu_lazy() will make use of lower bits in the pointer;
+6 -6
virt/kvm/arm/vgic/vgic.c
··· 196 196 */ 197 197 static struct kvm_vcpu *vgic_target_oracle(struct vgic_irq *irq) 198 198 { 199 - DEBUG_SPINLOCK_BUG_ON(!spin_is_locked(&irq->irq_lock)); 199 + lockdep_assert_held(&irq->irq_lock); 200 200 201 201 /* If the interrupt is active, it must stay on the current vcpu */ 202 202 if (irq->active) ··· 273 273 { 274 274 struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; 275 275 276 - DEBUG_SPINLOCK_BUG_ON(!spin_is_locked(&vgic_cpu->ap_list_lock)); 276 + lockdep_assert_held(&vgic_cpu->ap_list_lock); 277 277 278 278 list_sort(NULL, &vgic_cpu->ap_list_head, vgic_irq_cmp); 279 279 } ··· 311 311 { 312 312 struct kvm_vcpu *vcpu; 313 313 314 - DEBUG_SPINLOCK_BUG_ON(!spin_is_locked(&irq->irq_lock)); 314 + lockdep_assert_held(&irq->irq_lock); 315 315 316 316 retry: 317 317 vcpu = vgic_target_oracle(irq); ··· 702 702 static inline void vgic_populate_lr(struct kvm_vcpu *vcpu, 703 703 struct vgic_irq *irq, int lr) 704 704 { 705 - DEBUG_SPINLOCK_BUG_ON(!spin_is_locked(&irq->irq_lock)); 705 + lockdep_assert_held(&irq->irq_lock); 706 706 707 707 if (kvm_vgic_global_state.type == VGIC_V2) 708 708 vgic_v2_populate_lr(vcpu, irq, lr); ··· 736 736 737 737 *multi_sgi = false; 738 738 739 - DEBUG_SPINLOCK_BUG_ON(!spin_is_locked(&vgic_cpu->ap_list_lock)); 739 + lockdep_assert_held(&vgic_cpu->ap_list_lock); 740 740 741 741 list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) { 742 742 int w; ··· 761 761 bool multi_sgi; 762 762 u8 prio = 0xff; 763 763 764 - DEBUG_SPINLOCK_BUG_ON(!spin_is_locked(&vgic_cpu->ap_list_lock)); 764 + lockdep_assert_held(&vgic_cpu->ap_list_lock); 765 765 766 766 count = compute_ap_list_depth(vcpu, &multi_sgi); 767 767 if (count > kvm_vgic_global_state.nr_lr || multi_sgi)