net/tcp: add configurable delayed ACK threshold - #20055
Conversation
|
RFC 1122 §4.2.3.2 also says: |
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>
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. |
| 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 |
There was a problem hiding this comment.
@zhekunren new feature requires Documentation, please add it here:
https://nuttx.apache.org/docs/latest/components/net/delay_act_and_tcp_perf.html
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_FREQUENCYKconfig option (range 1-255, default 2) tomake 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
CONFIG_NET_TCP_DELAYED_ACK=ybuilds; no API/ABI changeunless the new option is explicitly raised
net/tcp/Kconfig,net/tcp/tcp_appsend.cTesting
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 ACKeffectively disabled)
freq = 2(default): reproduces the legacy behavior exactly — segment 1is held (
rx_unackseg = 1), segment 2 triggers the ACK (rx_unacksegreset to 0), and the cycle repeats; the new condition
rx_unackseg >= FREQ - 1is equivalent to the previousrx_unackseg > 0, and the++degenerates to= 1because the elsebranch is only entered with the counter at 0
freq = 3andfreq = 5: per-segment assertions on the hold/senddecision and counter value (segments 1..N-1 held, Nth segment ACKs and
resets the counter)
freq = 5semantics: the first ACK is sent exactly on arrival of the5th segment (cumulative ACK covering segments 1-5)
freq = 255(uint8_tboundary): 10 full cycles, no counterwraparound, ACK fires exactly on segment 255
cycles produce exactly 10 ACKs with no pending segment left at the end
Build:
gcc -Wall -Wextra -Werror -std=c99, zero warnings; all casespassed (exit code 0).
Build / regression
net/tcp/tcp_appsend.csyntax-checked withgcc -fsyntax-only -Wall -Wextra -Werror -std=c99NET_TCP_ACK_FREQUENCY=2the generated logic isequivalent to master, so existing
CONFIG_NET_TCP_DELAYED_ACKconfigurations are unaffected
Suggested validation on target (for reviewers)
The following can be used to verify runtime behavior on
sim:nshwithCONFIG_NET_TCP_DELAYED_ACK=y:NET_TCP_ACK_FREQUENCYto 5, run a bulk TCP transfer overloopback with
CONFIG_NET_STATISTICS=y, and check that thereceived-segment / ACK-sent ratio approaches 5:1 (vs 2:1 with the
default)
segment stream (inter-segment gap > 0.5 s produces one ACK per
segment), confirming RFC 1122 timing compliance is independent of
the threshold
the threshold logic via
result != TCP_SNDACK/dev->d_sndlen > 0)