Page MenuHomeFreeBSD

tcp: refactor cwnd during SACK transmissions and enable TSO

Authored by rscheff on Jan 16 2024, 10:10 PM.
Referenced Files
Unknown Object (File)
Thu, Apr 11, 10:23 PM
Unknown Object (File)
Thu, Mar 28, 2:30 PM
Unknown Object (File)
Mon, Mar 25, 10:36 PM
Unknown Object (File)
Sat, Mar 23, 4:38 PM
Unknown Object (File)
Mar 6 2024, 5:43 PM
Unknown Object (File)
Mar 2 2024, 4:43 PM
Unknown Object (File)
Mar 2 2024, 4:43 PM
Unknown Object (File)
Mar 2 2024, 4:43 PM


Group Reviewers

Since the dawn of the SACK feature, TSO was never enabled
during SACK loss recovery episodes. With the use of
LRO / GRO leading to ACK compression (partial ACKs and
SACK blocks stepping by more than a singular segment),
and also features like PRR which allow increasing the
cwnd in the final phase of loss recovery (SSRB), this
frequently results in multiple passes of the
tcp_default_output() codepath.

It turns out that previously, the SACK transmission path would
only really work as the restriction to 1 MSS per call to tcp_output()
work, but allowing more than 1 MSS could result in invalid transmission

Refactoring of cwnd and moving the adjustment for SACKed data into
tcp_output() - cwnd tracking the maximum extend from snd_una - allows
both SACK loss recovery as well as SACK transmissions after RTO during
slow start.

Test Plan

On a TSO enabled NIC, with the receiver also using TSO and
LRO, verify that TSO chunks of more than 1 SMSS show up in a
packet capture. Also, when taking an RTO during a SACK loss
recovery episode, the flight size increases as per SlowStart and
Congestion Avoidance while excluding the re-transmission of
previously SACKed data.
Note that additional losses in that phase result in very small
congestion windows (since cwnd is reduced multiple times),
and entering a loss recovery then can result in lengthy
recovery until snd_max is finally reached.

Diff Detail

rG FreeBSD src repository
Lint Passed
No Test Coverage
Build Status
Buildable 56080
Build 52969: arc lint + arc unit

Event Timeline

  • change cwnd during SACK LR to flightsize
  • put cwnd inflation during classic retransmissions into tcp_output()
  • properly calculate available data during SACK transmissions
  • allow cwnd adjustments by more than MSS (LRO/TSO side effect)
  • reset scoreboard when entering LR after RTO
  • various minor style changes
rscheff retitled this revision from tcp: allow tso for sack rexmits, limited at 4 mss to tcp: refactor cwnd during SACK transmissions and enable TSO.Jan 21 2024, 6:24 PM

With this change, cwnd will reflect the expected flightsize also during SACK transmissions.
This allows the proper operation of skipping previously SACKed data after an RTO, and also the use of TSO while retransmitting.
The SACK related cwin calculation previously seems to only have worked as only a single MSS per tcp_output() call could be sent.
Keep sack_rxmit set when an attempt was made to send from the scoreboard - this prevents a longer codepath before returning. If the snd_cwnd would allow for more than the current hole to be sent, we can cycle back by specifically setting sendalot only in those cases.

While there, also do some various style changes and readability enhancements.

Is it possible to split this up? At least separate the style changes?

Is it possible to split this up? At least separate the style changes?

This includes changes in
and D43355.

I'll extract the pure style changes with no functional impact as a separate one, but want to keep this homogeneous for testing.

rscheff edited the test plan for this revision. (Show Details)
  • (int32_t)min(a,b) is still not the same as imin(a,b)
  • delta to D43355_sack_after_rto
This revision is now accepted and ready to land.Thu, Apr 4, 12:47 PM