From 312e0bc67a7276d06dec6a10f55e591aa4939f23 Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Sun, 27 Sep 2026 19:21:40 -0700 Subject: [PATCH 1/2] tcp: ACK ceiling 50176 -> 11680, one acknowledgment per GRO run (#89) At 50,176 bytes the data-driven acknowledgment carried 35-48 segments, fewer than two per sender burst. Losing two of them (the WiFiPi TX drop of #89) left the sender with no feedback until a probe and the 100-200 ms delayed-ACK hold. At 11,680 (8 x 1460) the crossing falls inside the first 16-frame GRO run, so one acknowledgment leaves per run. Measured on the A1200 (WiFiPi, main 95e3983a, inbound iperf, same harness and driver, only this constant differs): bytes per acknowledgment (median) 60,932 (5 controls) -> 23,360 acknowledgments per second ~89 -> 218 throughput 41.8-44.0 -> 50.3 Mbit/s One test leg: the stall reduction is not yet shown. Co-Authored-By: Claude Opus 5.5 --- port/netxduo-amiga/inc/nx_user.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/port/netxduo-amiga/inc/nx_user.h b/port/netxduo-amiga/inc/nx_user.h index f8796a6ab..d4c2ca00d 100644 --- a/port/netxduo-amiga/inc/nx_user.h +++ b/port/netxduo-amiga/inc/nx_user.h @@ -118,9 +118,14 @@ extern struct TX_THREAD_STRUCT *_nx_ip_input_thread; BSD_TCP_WINDOW_MAX at 262,144 the buffer's half would be 128 KB, one acknowledgment per ninety segments, and every one of them releases a burst that size at the sender's line rate into the card's receive ring. - Pinned at what the largest pre-scaling buffer produced, so a machine that - was already at the old ceiling acknowledges exactly as it did. */ -#define NX_TCP_ACK_THRESHOLD_MAX 50176 + At 50,176 an acknowledgment carried 35-48 segments, fewer than two per + sender burst, so two lost acknowledgments (the Wi-Fi drop of #89) left the + sender nothing until a probe and the 100-200 ms delayed-ACK hold. At + eight segments the crossing falls inside the first GRO run (sana2_rx.c, + 16 frames), so one acknowledgment leaves per run: on the A1200 WiFiPi, + main 95e3983a, 60,932 -> 23,360 bytes per acknowledgment (median), 89 -> + 218 per second, 42.3-44.0 -> 50.3 Mbit/s inbound. */ +#define NX_TCP_ACK_THRESHOLD_MAX 11680 /* The clock the SYN cache times a handshake with (nx_tcp_syncache.c): the E-Clock in milliseconds, src/common/compat.c. An accepted socket then From bde5e03466c5010a17a1d303a44e4980cc7908c5 Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Sun, 27 Sep 2026 19:23:38 -0700 Subject: [PATCH 2/2] tcp: ACK ceiling comment: stall mechanism is the leading model, n=1 (#89) Co-Authored-By: Claude Opus 5.5 --- port/netxduo-amiga/inc/nx_user.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/port/netxduo-amiga/inc/nx_user.h b/port/netxduo-amiga/inc/nx_user.h index d4c2ca00d..add106273 100644 --- a/port/netxduo-amiga/inc/nx_user.h +++ b/port/netxduo-amiga/inc/nx_user.h @@ -119,12 +119,13 @@ extern struct TX_THREAD_STRUCT *_nx_ip_input_thread; acknowledgment per ninety segments, and every one of them releases a burst that size at the sender's line rate into the card's receive ring. At 50,176 an acknowledgment carried 35-48 segments, fewer than two per - sender burst, so two lost acknowledgments (the Wi-Fi drop of #89) left the - sender nothing until a probe and the 100-200 ms delayed-ACK hold. At - eight segments the crossing falls inside the first GRO run (sana2_rx.c, - 16 frames), so one acknowledgment leaves per run: on the A1200 WiFiPi, - main 95e3983a, 60,932 -> 23,360 bytes per acknowledgment (median), 89 -> - 218 per second, 42.3-44.0 -> 50.3 Mbit/s inbound. */ + sender burst. Leading model for the #89 stalls (hw4, not yet shown to go + away): two lost acknowledgments leave the sender nothing until a probe and + the 100-200 ms delayed-ACK hold. At eight segments the crossing falls + inside the first GRO run (sana2_rx.c, 16 frames), so one acknowledgment + leaves per run. A1200 WiFiPi, main 95e3983a, 5 control legs vs ONE test + leg: 60,932 -> 23,360 bytes per acknowledgment (median), 89 -> 218 per + second, 41.8-44.0 -> 50.3 Mbit/s inbound. */ #define NX_TCP_ACK_THRESHOLD_MAX 11680 /* The clock the SYN cache times a handshake with (nx_tcp_syncache.c): the