Overview
What I wanted to learn
The R6S has two PCIe 2.5GbE controllers and one native 1GbE controller. Because those ports use different hardware and driver paths, a single aggregate benchmark would not say very much.
I wanted to compare the ports individually, in both directions, and under loads long enough to reveal queue, interrupt or stability problems. The hardware remained the same NanoPi R6S; only the boot media and software stack changed.
The mainline system ran Gentoo with Linux 6.18.38. Its two 2.5GbE controllers used the in-kernel r8169 driver, while the native controller used st_gmac. The FriendlyELEC system ran Debian 13 with Linux 6.1.141, the vendor r8125 driver on both 2.5GbE controllers, and st_gmac on the native port.
Method
Systems and physical setup
The same peers, direct cables, stream counts, test order, durations, offered UDP loads and acceptance thresholds were used for both operating systems. There was no switch in the traffic path.
Systems under test
The comparison changed the operating-system stack while retaining the same R6S and external equipment.
| Item | Gentoo / mainline | FriendlyELEC stock | Constant |
|---|---|---|---|
| Kernel | Linux 6.18.38 | Linux 6.1.141 | Same NanoPi R6S |
| 2.5GbE driver | r8169 | Vendor r8125 9.016.01 | Same two PCIe controllers |
| Native 1GbE driver | st_gmac | st_gmac | Same integrated controller |
| Traffic tool | iperf3 3.21 | Same version and parameters | |
| Peers | AQC113/Atlantic, RTL8125B/r8169, and Intel/igb | Same peer for each port | |
| Cables | Three direct 15-foot Cat6 24AWG cables | Same cable for each port | |
The 2.5GbE tests used four TCP streams and four 575 Mb/s UDP streams. The 1GbE tests used two TCP streams and two 460 Mb/s UDP streams.
Qualification phases ran for 300 seconds one-way and 600 seconds bidirectional. Sustained phases ran for 1,800 seconds one-way, 3,600 seconds bidirectional and 900 seconds for UDP. Long phases were divided into 600-second evidence segments, with a 600-second cooldown between the default and optimized aggregates.
Results
Optimized throughput
After the IRQ policy was applied, the two 2.5GbE ports produced nearly identical TCP results on the two operating systems. One-way traffic reached about 2.35 Gb/s, and both directions of the bidirectional tests remained close to that level.
The 2.5GbE difference was in UDP transmitted by the R6S. Stock sustained about 2.30 Gb/s, while mainline measured about 2.00 Gb/s. Receive-side UDP was close to 2.30 Gb/s on both systems.
Optimized weighted throughput
All values are Mb/s. Bidirectional and UDP cells list TX / RX from the R6S perspective.
| Port | Test | Mainline 6.18 | Stock 6.1 | Observation |
|---|---|---|---|---|
| 2.5G LAN | TCP TX | 2353.7 | 2353.7 | Equivalent |
| 2.5G LAN | TCP RX | 2353.6 | 2353.7 | Equivalent |
| 2.5G LAN | Bidir TX / RX | 2349.9 / 2347.7 | 2326.7 / 2348.1 | Similar |
| 2.5G LAN | UDP TX / RX | 2002.0 / 2298.3 | 2300.0 / 2300.1 | Higher stock TX |
| 2.5G WAN | TCP TX | 2353.6 | 2353.7 | Equivalent |
| 2.5G WAN | TCP RX | 2353.7 | 2353.7 | Equivalent |
| 2.5G WAN | Bidir TX / RX | 2350.4 / 2350.3 | 2342.8 / 2350.4 | Similar |
| 2.5G WAN | UDP TX / RX | 1990.5 / 2298.4 | 2300.0 / 2300.0 | Higher stock TX |
| Native 1G | TCP TX | 544.6 | 932.8 | Higher stock TX |
| Native 1G | TCP RX | 941.5 | 941.5 | Equivalent |
| Native 1G | Bidir TX / RX | 529.5 / 562.4 | 907.9 / 936.5 | Higher stock throughput |
| Native 1G | UDP TX / RX | 788.8 / 918.3 | 920.0 / 920.0 | Higher stock TX |
“Equivalent” and “similar” describe practical throughput, not exact equality at every decimal place.
The native 1GbE result
The native port behaved differently from the two PCIe ports. Receive-only TCP measured 941.5 Mb/s on both systems, but transmit-only TCP measured 932.8 Mb/s on stock and 544.6 Mb/s on mainline. The bidirectional test showed the same directional difference: 907.9 / 936.5 Mb/s on stock and 529.5 / 562.4 Mb/s on mainline.
Because the mainline receive result matched stock on the same cable and peer, I think the useful place to investigate is the R6S transmit path: st_gmac, device-tree configuration, DMA or queue setup, or clocking.
This is an inference from the direction of the results, not a demonstrated root cause.
IRQ affinity
What interrupt placement changed
The optimized policy assigned the 2.5G LAN port to CPU 5, the 2.5G WAN port to CPU 6 and the native 1GbE port to CPU 4. The largest improvements were on the receive side of the two 2.5GbE ports.
Selected stock default-to-optimized changes
Weighted Mb/s before and after the IRQ policy.
| Port | Test | Default | Optimized | Change |
|---|---|---|---|---|
| 2.5G LAN | TCP RX | 2085.6 | 2353.7 | +12.9% |
| 2.5G LAN | Bidir RX | 1751.7 | 2348.1 | +34.0% |
| 2.5G LAN | UDP RX | 1114.0 | 2300.1 | +106.5% |
| 2.5G WAN | TCP RX | 2085.6 | 2353.7 | +12.9% |
| 2.5G WAN | Bidir RX | 1771.5 | 2350.4 | +32.7% |
| 2.5G WAN | UDP RX | 1114.0 | 2300.0 | +106.5% |
Mainline showed the same general sensitivity. On its 2.5G LAN port, bidirectional receive increased from 1,424.6 to 2,347.7 Mb/s, and UDP receive increased from 1,518.9 to 2,298.3 Mb/s.
The native port did not materially improve under the same policy. That is why I treat IRQ placement and the native-port transmit result as separate issues.
Validation notes
Failures, counters and limitations
The validator considers throughput, packet loss and counter growth. A nonzero overall status therefore does not always mean that a throughput threshold was missed.
- The optimized stock run cleared every configured throughput and loss threshold. Its nonzero status came from
eth2 rx_missed_errors +31and small private-counter growth. - The optimized mainline run missed the native 1GbE transmit and bidirectional thresholds. One 2.5GbE LAN UDP-transmit segment also measured 0.558% loss against a 0.500% ceiling.
- The first stock attempt was excluded from the clean comparison after the AQC113 peer stopped passing frames while carrier remained up. Cycling the peer interface restored traffic. I preserved that attempt, reset the peers and reran the complete comparison from the beginning.
- The stock image required a compatibility-only change because the vendor
r8125driver exposed stale IRQ entries in sysfs. IRQ discovery was changed to ignore entries without live affinity files under/proc. Traffic settings and acceptance thresholds were not changed. - Both optimized runs peaked at 65.6°C, with no evidence of thermal throttling.
- The R6S and peer evidence archives were checksum-verified and copied off the test systems.