Files
tsnet-proxy/vendor/tailscale.com/wgengine/wgcfg/mem_notios.go
T
2026-10-22 12:27:19 +01:00

44 lines
1.6 KiB
Go

// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
//go:build !ios
package wgcfg
import (
"runtime"
"github.com/tailscale/wireguard-go/device"
)
func getMemoryOptions() []device.Option {
// wireguard-go is a packet pipeline:
//
// TUN read -> encrypt -> ordered network write
// network read -> decrypt -> ordered TUN write
//
// The queues that we are sizing in this function sit between head I/O
// goroutines and downstream functions. They are buffered channels.
//
// The head I/O ops tend to "run ahead" the downstream functions, especially
// when head I/O ops utilize segmentation offloading, where a single head I/O
// op can contain about 45 packets at a typical MTU, which is equivalent to
// 45 crypto ops.
//
// Small queues park I/O goroutines and hurt throughput; large queues allow
// more packet batches and their associated memory to remain outstanding. We
// have to find a balance. Crypto goroutines are sized to [runtime.NumCPU]
// in wireguard-go, so we start there, and apply a benchmark-backed scaling
// factor to reduce head I/O goroutines parking around bursts.
const cpuScalingFactor = 4
// maxQueueSize was the previous static default, prior to creation of the
// [device.Option].
const maxQueueSize = 1024
return []device.Option{
// TODO: make cgroup-aware with runtime.GOMAXPROCS(0).
// See tailscale/corp#47966.
device.WithQueueInboundSize(min(maxQueueSize, runtime.NumCPU()*cpuScalingFactor)),
device.WithQueueOutboundSize(min(maxQueueSize, runtime.NumCPU()*cpuScalingFactor)),
}
}