Distro Planets

Linux IPv4/IPv6 route lookup benchmarks reveal AMD SRSO mitigation as major regression source

Key Takeaway

The Speculative Return Stack Overflow (SRSO) mitigation added in Linux 6.5 introduced a 200 nanosecond regression for IPv6 route lookups on AMD Zen 4c, wiping out years of kernel networking performance improvements.

Summary

Debian developer Vincent Bernat published comprehensive benchmarks measuring Linux kernel route lookup performance from early 2.6.x releases through Linux 7.3, using an AMD EPYC 8024P (Zen 4c) processor. The testing exposes that the SRSO (Speculative Return Stack Overflow) mitigation introduced in Linux 6.5 adds approximately 20 cycles per function return, causing a severe 200 ns regression for IPv6 lookups that erased all prior optimization gains. IPv4 lookups saw a smaller 30 ns impact because the IPv4 path traverses roughly 4 function calls versus 25 for IPv6. Bernat also identified a separate 5-cycle regression he introduced in Linux 5.11 via commit c0c5a60f0f13, which added pointer-chasing overhead to ip_ignore_linkdown() when fixing net.ipv4.conf.all.ignore_routes_with_linkdown behavior.

The benchmarks cover multiple routing table scenarios: IPv6 tests used full views with 260,000 current prefixes and 40,000 2017-era prefixes, plus controlled /48 and /128 prefix sets; IPv4 tests used full views exceeding 1,000,000 prefixes, 500,000-prefix subsets, and contiguous /32 blocks. Bernat provides a reordering patch for the ip_ignore_linkdown() conditional that improves median IPv4 lookup time from 132 to 126 cycles. The article also notes mitigation impact varies significantly by CPU architecture, with Intel Xeon W-2295 showing only a few cycles of IPv4 overhead and under 3% for IPv6, primarily from the Indirect Target Selection fix that Sapphire Rapids resolved in hardware.

Kernel networking performance and mitigation impact

  • IPv6 lookup path depth: IPv6 route lookups traverse approximately 25 function calls, making them disproportionately vulnerable to per-return-cycle penalties compared to IPv4's 4 function calls.
  • SRSO mitigation cost: The Safe RET mitigation for AMD Speculative Return Stack Overflow (commit fb3bd914b3ec in Linux 6.5) adds ~20 cycles per function return, producing a 200 ns IPv6 regression versus 30 ns for IPv4.
  • Historical IPv6 optimizations: Prior gains from Wei Wang's RCU/spinlock replacement (4.15), David Ahern's data structure improvements (4.18), and Brian Vazquez's indirect call removal (5.9) were all negated by the 6.5 mitigation.
  • IPv4 ignore_routes_with_linkdown regression: Commit c0c5a60f0f13 (Linux 5.11) added three pointer dereferences to ip_ignore_linkdown(), costing ~5 cycles; reordering the conditional to check RTNH_F_LINKDOWN before calling the function recovers this overhead.
  • Mitigation control options: Administrators can disable specific mitigations via kernel command-line parameters including spec_rstack_overflow=off or use mitigations=auto,no_user_kernel starting from Linux 6.17.

Why it matters

Network operators and hosting providers running AMD Zen-based infrastructure on current kernels face substantially higher per-packet routing overhead than benchmarked in pre-6.5 releases, directly affecting high-throughput routers, software-defined networking stacks, and cloud networking dataplanes. The demonstrated ability to recover performance through conditional reordering in fib_lookup() shows that careful kernel networking code review remains essential even for minor behavioral fixes. For the broader Linux distribution ecosystem, these findings inform default mitigation policies and provide concrete data for administrators balancing security posture against latency-sensitive workload requirements.

What to do

  • Administrators can disable the SRSO mitigation using the spec_rstack_overflow=off kernel command-line parameter.
  • Starting from Linux 6.17, administrators can use the mitigations=auto,no_user_kernel parameter to protect against only some attack vectors.
  • Users can check CPU vulnerabilities and mitigations by running lscpu | grep '^Vuln'.

Original reference: vincent.bernat.ch →