net: downloads at tens of megabits, not one

Measured against the host fetching the same 67 MB from Alpine's CDN at
11.5 MB/s, SchOS managed about 120 KB/s. Three causes:

- The receive window reopened when data entered the socket buffer,
  before the reader drained it; lwIP then refused segments and the
  sender waited on retransmission timers. It reopens on read now.
- The e1000 receive ring held 16 frames, so a full window arriving back
  to back lost everything past the sixteenth. 256 now.
- Without window scaling the window stops at 64 KB, one window per
  round trip. Scaling on, 256 KB window, 512 KB socket ring (a power of
  two, which the free-running indices need), copied in blocks.

Now 5.8 MB/s for the same file, and apk update in about two seconds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
Nexoniarz 2026-10-24 15:28:32 +02:00
commit 2c5a278d56
3 changed files with 53 additions and 16 deletions

View file

@ -192,6 +192,12 @@ struct e1000_rx_desc {
// Ring sizes. The manual requires the descriptor ring length to be a multiple
// of 128 bytes, i.e. a multiple of 8 descriptors.
#define E1000_NTX 16
#define E1000_NRX 16
//
// The receive ring has to hold a whole TCP window arriving at once, and more:
// a sender that has the window open sends it back to back, and every frame
// past the ring's end is dropped and waits for a retransmission. Sixteen was
// fine for a window of eight segments; with thirty-two it held downloads to a
// megabit a second. 256 buffers is half a megabyte of the 64 MB DMA arena.
#define E1000_NTX 64
#define E1000_NRX 256
#define E1000_BUFSZ 2048