blob: 71bc5dfaff7606cb0112bec772d027972c04b05a [file]
# Deterministic, host-speed-independent zperf throughput measurement.
#
# Layer this on top of overlay-loopback.conf, e.g.:
# -DEXTRA_CONF_FILE="overlay-loopback.conf;overlay-loopback-icount.conf"
#
# All traffic stays inside the guest (loopback), so QEMU icount mode can be
# safely enabled. In icount mode the virtual CPU advances virtual time by
# 2^SHIFT ns per executed instruction, so the reported throughput becomes a
# deterministic function of instructions-per-byte instead of host wall clock.
# Force QEMU icount on. It is disabled by default when networking + shell are
# enabled, but with loopback-only traffic there is no real host I/O in the
# measurement path.
CONFIG_QEMU_ICOUNT=y
CONFIG_QEMU_ICOUNT_SHIFT=5
CONFIG_QEMU_ICOUNT_SLEEP=n
# icount only works with a single CPU.
CONFIG_MP_MAX_NUM_CPUS=1
# Run the kernel tick at 10 kHz. The default qemu_x86 rate is 100 Hz, which
# (a) compiles in the UDP uploader's clock-compensation path that divides by
# the per-packet duration - a division by zero once the unlimited rate drives
# that duration to 0 - and (b) is far too coarse to pace traffic. A >1 kHz tick
# removes the compensation path and gives fine-grained timing.
CONFIG_SYS_CLOCK_TICKS_PER_SEC=10000
# Loopback-only: no QEMU SLIP/TAP host networking. This removes the external,
# real-time network backend that would otherwise make icount non-deterministic
# (and require a host-side slip.sock).
CONFIG_NET_QEMU_SLIP=n
CONFIG_NET_SLIP_TAP=n
# Self-driven loopback runner (see src/main.c). Avoids the interactive shell,
# which can stall under icount waiting on real-time stdin.
CONFIG_ZPERF_LOOPBACK_SELFTEST=y
# The UDP uploader needs a receive timeout to collect the server statistics.
CONFIG_NET_CONTEXT_RCVTIMEO=y
# The zperf receivers register several sockets with the socket service; give
# zvfs_poll() enough slots for the TCP listener plus its sessions.
CONFIG_ZVFS_POLL_MAX=16
# The loopback driver delivers each packet synchronously in the sender's
# context, so the whole receive path (and, for this sample, the blocking client
# upload) runs on the caller's stack. Give the involved threads generous stacks
# to absorb that nesting; otherwise the guest overflows and faults at boot.
CONFIG_MAIN_STACK_SIZE=3072
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2560
CONFIG_NET_RX_STACK_SIZE=2560
CONFIG_NET_TX_STACK_SIZE=2560
CONFIG_NET_MGMT_EVENT_STACK_SIZE=2560
CONFIG_NET_SOCKETS_SERVICE_STACK_SIZE=2560
# Do not try to add IPv4/6 address to network interface but let the system
# use the localhost addresses.
CONFIG_NET_CONFIG_MY_IPV4_ADDR=""
CONFIG_NET_CONFIG_MY_IPV6_ADDR=""
# Disable statistics so that the stats collection will not lower the numbers.
CONFIG_NET_STATISTICS=n
# Push near-MTU-sized frames through the stack so the per-packet cost is
# dominated by data-touching work (checksums, buffer/fragment walking) rather
# than fixed per-call overhead. The selftest sends a 1220 byte payload (see the
# Kconfig default): that is the IPv6 TCP MSS at a 1280 byte MTU (1280 - 40 IPv6
# - 20 TCP), so every TCP write is a single full-sized segment for both IPv4 and
# IPv6 (avoiding a tiny trailing segment that would otherwise halve IPv6 TCP),
# and the UDP datagrams stay under the MTU for both families so no IP
# fragmentation is needed. Raise the loopback L3 MTU accordingly and lift
# zperf's own packet ceiling above the (larger, fragmenting) payload below.
CONFIG_NET_LOOPBACK_MTU=1280
CONFIG_NET_ZPERF_MAX_PACKET_SIZE=2100
# Keep the net_buf data size (1100, from overlay-loopback.conf) below the MTU so
# each 1280 byte packet spans two buffer fragments. This deliberately exercises
# the fragment-chain walk in net_pkt_get_len() and friends.
# Exercise the IP fragmentation + reassembly subsystem: the runner adds an extra
# UDP run per family whose payload (see ZPERF_LOOPBACK_SELFTEST_FRAG_PACKET_SIZE)
# exceeds the MTU, so ipv4.c/ipv6.c must fragment on TX and reassemble on RX.
CONFIG_NET_IPV4_FRAGMENT=y
CONFIG_NET_IPV6_FRAGMENT=y
# Exercise traffic classes and SO_PRIORITY: with more than one TX/RX queue the
# stack routes prioritised traffic through dedicated per-traffic-class threads
# (net_tc.c) instead of the caller's context. The runner sets a non-default
# priority on every upload so this path is always taken.
CONFIG_NET_TC_TX_COUNT=2
CONFIG_NET_TC_RX_COUNT=2
CONFIG_NET_CONTEXT_PRIORITY=y
CONFIG_NET_ALLOW_ANY_PRIORITY=y