Skip to content

net/tcp: add configurable delayed ACK threshold - #20055

Open
zhekunren wants to merge 1 commit into
apache:masterfrom
zhekunren:master
Open

net/tcp: add configurable delayed ACK threshold#20055
zhekunren wants to merge 1 commit into
apache:masterfrom
zhekunren:master

Conversation

@zhekunren

@zhekunren zhekunren commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Summary

The delayed ACK logic previously sent an ACK for at least every second
received segment (hard-coded threshold of 2 per RFC 1122). This PR adds
the NET_TCP_ACK_FREQUENCY Kconfig option (range 1-255, default 2) to
make this threshold configurable at build time.

The delayed ACK timer still forces an ACK after at most 0.5 seconds, so
RFC 1122 timing compliance is preserved regardless of the configured
threshold. The default value of 2 keeps the exact current behavior:
the new condition rx_unackseg >= FREQ - 1 is equivalent to the previous
rx_unackseg > 0, and the counter increment degenerates to the previous
rx_unackseg = 1 assignment.

Note that RFC 1122 Section 4.2.3.2 states there SHOULD be an ACK for at
least every second segment in a stream of full-sized segments. Values
above 2 no longer meet that recommendation; this is now documented in
the Kconfig help text of NET_TCP_ACK_FREQUENCY.

Impact

  • Only affects CONFIG_NET_TCP_DELAYED_ACK=y builds; no API/ABI change
  • Default configuration is behavior-equivalent to master; no change
    unless the new option is explicitly raised
  • Files touched: net/tcp/Kconfig, net/tcp/tcp_appsend.c

Testing

Logic verification (host)

The modified delayed ACK branch was replicated verbatim into a standalone
host test and exercised directly (no network stack required):

  • freq = 1: every received segment is ACKed immediately (delayed ACK
    effectively disabled)
  • freq = 2 (default): reproduces the legacy behavior exactly — segment 1
    is held (rx_unackseg = 1), segment 2 triggers the ACK (rx_unackseg
    reset to 0), and the cycle repeats; the new condition
    rx_unackseg >= FREQ - 1 is equivalent to the previous
    rx_unackseg > 0, and the ++ degenerates to = 1 because the else
    branch is only entered with the counter at 0
  • freq = 3 and freq = 5: per-segment assertions on the hold/send
    decision and counter value (segments 1..N-1 held, Nth segment ACKs and
    resets the counter)
  • freq = 5 semantics: the first ACK is sent exactly on arrival of the
    5th segment (cumulative ACK covering segments 1-5)
  • freq = 255 (uint8_t boundary): 10 full cycles, no counter
    wraparound, ACK fires exactly on segment 255
  • Periodicity: for each of freq = 1/2/3/5/255, 10 complete threshold
    cycles produce exactly 10 ACKs with no pending segment left at the end

Build: gcc -Wall -Wextra -Werror -std=c99, zero warnings; all cases
passed (exit code 0).

Build / regression

  • net/tcp/tcp_appsend.c syntax-checked with
    gcc -fsyntax-only -Wall -Wextra -Werror -std=c99
  • With the default NET_TCP_ACK_FREQUENCY=2 the generated logic is
    equivalent to master, so existing CONFIG_NET_TCP_DELAYED_ACK
    configurations are unaffected

Suggested validation on target (for reviewers)

The following can be used to verify runtime behavior on sim:nsh with
CONFIG_NET_TCP_DELAYED_ACK=y:

  1. Set NET_TCP_ACK_FREQUENCY to 5, run a bulk TCP transfer over
    loopback with CONFIG_NET_STATISTICS=y, and check that the
    received-segment / ACK-sent ratio approaches 5:1 (vs 2:1 with the
    default)
  2. Verify the 0.5 s delayed ACK timer still fires under a sparse
    segment stream (inter-segment gap > 0.5 s produces one ACK per
    segment), confirming RFC 1122 timing compliance is independent of
    the threshold
  3. Confirm FIN/RST and piggybacked-ACK paths are unchanged (they bypass
    the threshold logic via result != TCP_SNDACK / dev->d_sndlen > 0)

@github-actions github-actions Bot added Area: Networking Effects networking subsystem Size: S The size of the change in this PR is small labels Sep 4, 2026
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

@wenquan2015

Copy link
Copy Markdown

RFC 1122 §4.2.3.2 also says:
in a stream of full-sized segments there SHOULD be an ACK for at least every second segment.
When NET_TCP_ACK_FREQUENCY is set above 2, this frequency requirement is no longer met.
Need to add an explicit note in the Kconfig help text or not?

The delayed ACK logic previously sent an ACK for at least every second
received segment (hard-coded threshold of 2 per RFC 1122).  Add the
NET_TCP_ACK_FREQUENCY Kconfig option (range 1-255, default 2) to make
this threshold configurable at build time.

The delayed ACK timer still forces an ACK after at most 0.5 seconds, so
RFC 1122 timing compliance is preserved regardless of the configured
threshold.  The default value of 2 keeps the exact current behavior:
the new condition rx_unackseg >= FREQ - 1 is equivalent to the previous
rx_unackseg > 0, and the counter increment degenerates to the previous
rx_unackseg = 1 assignment.

Signed-off-by: zhekunren <zhekunren@qq.com>
Assisted-by: GLM-5.2 <noreply@z.ai>
@zhekunren

Copy link
Copy Markdown
Contributor Author

RFC 1122 §4.2.3.2 also says: in a stream of full-sized segments there SHOULD be an ACK for at least every second segment. When NET_TCP_ACK_FREQUENCY is set above 2, this frequency requirement is no longer met. Need to add an explicit note in the Kconfig help text or not?

OK. Addressed in 0a54d37: added an explicit note to the Kconfig help text that values above 2 no longer meet the RFC 1122 §4.2.3.2 SHOULD recommendation (the 0.5s delayed ACK timer still applies). PR description also updated.

Comment thread net/tcp/Kconfig
0.5 seconds, and in a stream of full-sized segments there should
be an ACK for at least every second segments.

config NET_TCP_ACK_FREQUENCY

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Networking Effects networking subsystem Size: S The size of the change in this PR is small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants