|
112 | 112 | # arithmetic-friendly. |
113 | 113 | TCP__TS_RECENT__OUTDATED_THRESHOLD_MS = 24 * 86_400 * 1_000 |
114 | 114 |
|
| 115 | +# TCP buffer auto-tuning bounds (Tier-3 plan |
| 116 | +# docs/refactor/tcp_buffer_autotuning.md §6). Registered now as the clamp |
| 117 | +# + default source; there is NO runtime consumer yet — Track R (receive |
| 118 | +# Dynamic Right-Sizing) and Track S (send-buffer auto-tuning) land the |
| 119 | +# readers in later phases, so this registration changes no behaviour. |
| 120 | +# |
| 121 | +# The '.default' entries deliberately keep PyTCP's current effective |
| 122 | +# defaults (rcv 65535, snd 212992) rather than Linux's small initial |
| 123 | +# values: the small-default switch that makes auto-tuning observable is a |
| 124 | +# separate, behaviour-changing phase (plan §2 / §7 / §10 step 5). Only |
| 125 | +# the '.max' clamps carry Linux-parity values today. |
| 126 | + |
| 127 | +# Linux 'net.ipv4.tcp_moderate_rcvbuf' — the enable flag for |
| 128 | +# receive-buffer Dynamic Right-Sizing (Track R). Default 1 (on), matching |
| 129 | +# Linux; the DRS grow policy (R4) reads this gate. |
| 130 | +TCP__MODERATE_RCVBUF = 1 |
| 131 | + |
| 132 | +# Linux 'net.ipv4.tcp_rmem' (min / default / max) receive-buffer bounds. |
| 133 | +# '.max' is the DRS grow clamp (Track R4); '.default' will seed the unset |
| 134 | +# 'rcv_wnd_max' once the small-default switch lands. '.max' mirrors the |
| 135 | +# Linux ~6 MiB default ceiling; '.min' mirrors Linux's 4096 floor. |
| 136 | +TCP__RMEM__MIN = 4096 |
| 137 | +TCP__RMEM__DEFAULT = 65535 |
| 138 | +TCP__RMEM__MAX = 6_291_456 |
| 139 | + |
| 140 | +# Linux 'net.ipv4.tcp_wmem' (min / default / max) send-buffer bounds. |
| 141 | +# '.max' is the send-autotune grow clamp (Track S2); '.default' will seed |
| 142 | +# the unset send bound once the small-default switch lands. '.max' mirrors |
| 143 | +# the Linux ~4 MiB default ceiling; '.min' mirrors Linux's 4096 floor. |
| 144 | +TCP__WMEM__MIN = 4096 |
| 145 | +TCP__WMEM__DEFAULT = 212992 |
| 146 | +TCP__WMEM__MAX = 4_194_304 |
| 147 | + |
115 | 148 | # Per-interface conf-plane policy storage. 'dict[str, int]' keyed by |
116 | 149 | # interface name with a mandatory '"default"' template slot — the |
117 | 150 | # operator addresses a specific interface ('tcp.<ifname>.<field>') or |
|
161 | 194 |
|
162 | 195 | from pytcp.stack.sysctl import ( # noqa: E402 |
163 | 196 | get, |
| 197 | + is_int_in_range, |
164 | 198 | is_positive_int, |
165 | 199 | register, |
166 | 200 | register_finalize_validator, |
@@ -357,3 +391,108 @@ def _finalize__persist_max_ge_rto_initial() -> None: |
357 | 391 |
|
358 | 392 |
|
359 | 393 | register_finalize_validator(_finalize__persist_max_ge_rto_initial) |
| 394 | + |
| 395 | + |
| 396 | +# TCP buffer auto-tuning knobs (Tier-3 plan |
| 397 | +# docs/refactor/tcp_buffer_autotuning.md §6). Flat (not interface_scope) |
| 398 | +# for the first pass; no runtime consumer yet. |
| 399 | +register( |
| 400 | + key="tcp.moderate_rcvbuf", |
| 401 | + module_name=__name__, |
| 402 | + attr="TCP__MODERATE_RCVBUF", |
| 403 | + default=TCP__MODERATE_RCVBUF, |
| 404 | + validator=is_int_in_range("tcp.moderate_rcvbuf", low=0, high=1), |
| 405 | + description="Linux 'net.ipv4.tcp_moderate_rcvbuf' — enable receive-buffer DRS (0=off, 1=on).", |
| 406 | +) |
| 407 | +register( |
| 408 | + key="tcp.rmem.min", |
| 409 | + module_name=__name__, |
| 410 | + attr="TCP__RMEM__MIN", |
| 411 | + default=TCP__RMEM__MIN, |
| 412 | + validator=is_positive_int("tcp.rmem.min"), |
| 413 | + description="Linux 'net.ipv4.tcp_rmem[0]' — receive-buffer minimum in bytes.", |
| 414 | +) |
| 415 | +register( |
| 416 | + key="tcp.rmem.default", |
| 417 | + module_name=__name__, |
| 418 | + attr="TCP__RMEM__DEFAULT", |
| 419 | + default=TCP__RMEM__DEFAULT, |
| 420 | + validator=is_positive_int("tcp.rmem.default"), |
| 421 | + description="Linux 'net.ipv4.tcp_rmem[1]' — receive-buffer default (unset-rcv_wnd_max seed) in bytes.", |
| 422 | +) |
| 423 | +register( |
| 424 | + key="tcp.rmem.max", |
| 425 | + module_name=__name__, |
| 426 | + attr="TCP__RMEM__MAX", |
| 427 | + default=TCP__RMEM__MAX, |
| 428 | + validator=is_positive_int("tcp.rmem.max"), |
| 429 | + description="Linux 'net.ipv4.tcp_rmem[2]' — receive-buffer maximum (DRS grow clamp) in bytes.", |
| 430 | +) |
| 431 | +register( |
| 432 | + key="tcp.wmem.min", |
| 433 | + module_name=__name__, |
| 434 | + attr="TCP__WMEM__MIN", |
| 435 | + default=TCP__WMEM__MIN, |
| 436 | + validator=is_positive_int("tcp.wmem.min"), |
| 437 | + description="Linux 'net.ipv4.tcp_wmem[0]' — send-buffer minimum in bytes.", |
| 438 | +) |
| 439 | +register( |
| 440 | + key="tcp.wmem.default", |
| 441 | + module_name=__name__, |
| 442 | + attr="TCP__WMEM__DEFAULT", |
| 443 | + default=TCP__WMEM__DEFAULT, |
| 444 | + validator=is_positive_int("tcp.wmem.default"), |
| 445 | + description="Linux 'net.ipv4.tcp_wmem[1]' — send-buffer default (unset-SO_SNDBUF seed) in bytes.", |
| 446 | +) |
| 447 | +register( |
| 448 | + key="tcp.wmem.max", |
| 449 | + module_name=__name__, |
| 450 | + attr="TCP__WMEM__MAX", |
| 451 | + default=TCP__WMEM__MAX, |
| 452 | + validator=is_positive_int("tcp.wmem.max"), |
| 453 | + description="Linux 'net.ipv4.tcp_wmem[2]' — send-buffer maximum (send-autotune grow clamp) in bytes.", |
| 454 | +) |
| 455 | + |
| 456 | + |
| 457 | +def _finalize__rmem_triple_ordered() -> None: |
| 458 | + """ |
| 459 | + Cross-knob constraint — the 'tcp.rmem' triple must satisfy |
| 460 | + min <= default <= max. An inverted triple would let the DRS grow |
| 461 | + clamp ('tcp.rmem.max') sit below the seed ('tcp.rmem.default'), so |
| 462 | + the grow policy could never raise the window above the seed. |
| 463 | + """ |
| 464 | + |
| 465 | + rmem_min, rmem_default, rmem_max = ( |
| 466 | + get("tcp.rmem.min"), |
| 467 | + get("tcp.rmem.default"), |
| 468 | + get("tcp.rmem.max"), |
| 469 | + ) |
| 470 | + if not rmem_min <= rmem_default <= rmem_max: |
| 471 | + raise ValueError( |
| 472 | + f"sysctl 'tcp.rmem' must satisfy min <= default <= max; got " |
| 473 | + f"min={rmem_min}, default={rmem_default}, max={rmem_max}.", |
| 474 | + ) |
| 475 | + |
| 476 | + |
| 477 | +def _finalize__wmem_triple_ordered() -> None: |
| 478 | + """ |
| 479 | + Cross-knob constraint — the 'tcp.wmem' triple must satisfy |
| 480 | + min <= default <= max. An inverted triple would let the |
| 481 | + send-autotune grow clamp ('tcp.wmem.max') sit below the seed |
| 482 | + ('tcp.wmem.default'). |
| 483 | + """ |
| 484 | + |
| 485 | + wmem_min, wmem_default, wmem_max = ( |
| 486 | + get("tcp.wmem.min"), |
| 487 | + get("tcp.wmem.default"), |
| 488 | + get("tcp.wmem.max"), |
| 489 | + ) |
| 490 | + if not wmem_min <= wmem_default <= wmem_max: |
| 491 | + raise ValueError( |
| 492 | + f"sysctl 'tcp.wmem' must satisfy min <= default <= max; got " |
| 493 | + f"min={wmem_min}, default={wmem_default}, max={wmem_max}.", |
| 494 | + ) |
| 495 | + |
| 496 | + |
| 497 | +register_finalize_validator(_finalize__rmem_triple_ordered) |
| 498 | +register_finalize_validator(_finalize__wmem_triple_ordered) |
0 commit comments