tun: Size staged slots from the workers and listen.batch

The TX and RX slot counts were fixed at eight and six. TX now uses one slot
per worker plus the one being read and the one being sent, at least eight.
RX keeps up to 384 recvmmsg entries in flight in four to six slots, so a
larger listen.batch takes fewer slots and RX memory never exceeds today's.
tun.staged.tx_slots and rx_slots override either, down to two. The defaults
at listen.batch 64 with up to six workers are unchanged: eight TX slots of
about 1.1 MiB and six RX slots of 4 MiB with GRO.
This commit is contained in:
Ryan Huber committed 2026-10-16 21:23:10 +00:00
1 parent ffb2835f70
commit 130ef730b4
6 files changed
+76 -17

No files matched your search

+4 -6
View File
@@ -234,8 +234,6 @@ type handoffQueue interface {
SwapRxBuf([]byte) []byte
}
const stagedTxSlots = 8
// txSlot is one staged batch. The reader fills items, a worker encrypts them into sb and signals done, and the
// ordered sender flushes sb.
type txSlot struct {
@@ -292,8 +290,8 @@ func newStagedTx(f *Interface, queue handoffQueue, q int) *stagedTx {
queue: queue,
sb: batch.NewSendBatch(f.writers[q], batch.SendBatchCap, batch.SendBatchCap*(udp.MTU+32)),
nb: make([]byte, 12),
ordered: make(chan *txSlot, stagedTxSlots),
returned: make(chan *txSlot, stagedTxSlots),
ordered: make(chan *txSlot, f.staged.txSlots),
returned: make(chan *txSlot, f.staged.txSlots),
senderDone: make(chan struct{}),
readBusy: stageBusy("tx_read", q),
encryptBusy: stageBusy("tx_encrypt", q),
@@ -309,12 +307,12 @@ func newStagedTx(f *Interface, queue handoffQueue, q int) *stagedTx {
p.senderCPU = f.cpuAffinity[(q+1)%n]
}
}
p.pool = newFlowPool(f.staged.workers, stagedTxSlots, p.encryptBusy)
p.pool = newFlowPool(f.staged.workers, f.staged.txSlots, p.encryptBusy)
// Ciphertext adds per-segment headers and tags; the arena can grow for small segments.
buf := queue.SwapRxBuf(nil)
bufSize := len(buf)
for i := range stagedTxSlots {
for i := range f.staged.txSlots {
if i > 0 {
buf = make([]byte, bufSize)
}