最近Macのネットワーク速度を測っていたら、下りだけ遅いという現象に当たりました。
- インターネット下り: 1.5〜1.6Gbps
- インターネット上り: 2.3Gbps
- LAN内(Proxmoxサーバーとの直接測定)下り: 約1.8Gbps
- LAN内上り: 2.35Gbps
「下りだけ」遅い。しかも、インターネットを介さないLAN内でも遅い。条件を変えても改善せず、エラーカウンターもすべてゼロ。この切り分けの過程で、普段あまり意識しない IEEE 802.3x PAUSEフレーム(フロー制御) に出会ったので、記録として残します。
測定環境
| 要素 | 内容 |
|---|---|
| Mac | Apple Silicon, macOS 27.0.1 |
| 有線LAN | ELECOM DST-W13(USB4ドック)内蔵 Realtek RTL8156(USB 2.5GbE)= en8 |
| 対向サーバー | Proxmox VE(Intel N100、Intel igc 2.5GbE) |
| 測定 | iperf3(Macをサーバーにして、Proxmox側からクライアントをSSHで実行) |
# Mac側: サーバーを起動
iperf3 -s -p 15202
# Proxmox側: 下り測定(Proxmox → Mac)
ssh [email protected] 'iperf3 -c 192.168.2.107 -p 15202 -P 4 -t 20'
# 上り測定(-R)
ssh [email protected] 'iperf3 -c 192.168.2.107 -p 15202 -R -P 4 -t 20'
切り分け 1: 定番の疑いを片付ける
まずは定番の切り分けから。
- iperf3の並列数(-P 1 / -P 4)を変える → 下りは1.8Gbpsのまま
- 合計2Gbpsにユーザー空間で帯域制限(-b 500M ×4) → 改善なし
- Proxmox側のTSOを無効化 → 改善なし
- Proxmox側の統計 → TXドロップゼロ、qdisc(fq_codel)ドロップゼロ
送信側は健全そう。では受信側? ところがMac側を見ても:
netstat -I en8のエラーカウンター: ゼロ- ソケットバッファオーバーフロー: ゼロ
どこにも異常が記録されていないのに、下りだけ約1.8Gbpsで頭打ち。
切り分け 2: UDPで測る
TCPの影響を外すためUDPで測定し、レートを段階的に上げました。
iperf3 -c 192.168.2.107 -p 15202 -u -b 1500M -t 10 # → 受信 1.50Gbps 損失 0.007%
iperf3 -c 192.168.2.107 -p 15202 -u -b 2400M -t 10 # → 送信 1.94Gbps で止まる…
ここで2つの事実が判明。
- UDPでも送信が約1.94Gbpsで頭打ち(-b 2400Mを指定しても送れない)
- 送られた分はほぼ全部受信できている(損失0.15%程度で、Macの受信統計は増えない)
消えた分が「損失カウンタに乗らない」= どこかで黙って捨てられているか、あるいは 送信自体が止められている。
切り分け 3: PAUSEフレームの発見
UDPを4ストリームに増やしても送信合計は1.93〜1.94Gbps。では、律速はどちら側か。答えは対向NICの統計にありました。
$ ethtool -S enp2s0 | grep flow_control
rx_flow_control_xon: 3086492
rx_flow_control_xoff: 3086492
tx_flow_control_xon: 14
TCP下りを20秒流したところ、rx_flow_control_xon/xoff が +3,197 ずつ増加(UDP下り10秒では +16,507)。tx方向は不変。
これは IEEE 802.3x フロー制御(PAUSEフレーム) です。受信側のバッファが満杯に近づくと、リンク相手に対してMACレベルで「送信を一時停止せよ(XOFF)」「再開せよ(XON)」を通知します。
つまり、この構図です。
- Proxmoxはドロップゼロで正常に送っている
- しかし Mac側の受信パス(NIC/USB転送)が詰まり、PAUSEで上流を減速させている
- Macのカーネル統計には一切現れない(NIC内部で起きるため)
「下りだけ遅い」「エラーカウンターが全部ゼロ」「上りは2.35Gbpsでフルスピード」— この3つの謎が一度に説明できました。
切り分け 4: ドライバーを替えてみる
原因がMac側受信パスなら、次の疑いはmacOS内蔵の汎用NCMドライバーです。RTL8156はmacOSでは内蔵ドライバーで動きますが、Realtekは公式のDriverKitドライバー(dext)を提供しています。
Realtek公式サイトから「MAC OS 11 and later (Apple ARM)」v1.1.0を入手(pkg署名とnotarizationを検証)、インストール → dextを承認 → ドックを再接続でUSBを再列挙。com.realtek.dext.RTL815xEthernet に乗り換わりました(インターフェース名 en8、IP ともに不変)。
結果がこちら。
| 項目 | Apple NCM | Realtek dext |
|---|---|---|
| TCP下り 1接続 | 1.83Gbps / 再送201 | 1.95Gbps / 再送0 |
| TCP下り 4並列 | 1.81Gbps / 再送767 | 1.94Gbps / 再送5 |
| UDP下り 4×700M | 1.93Gbps / 損失0.15% | 1.94Gbps / 損失0% |
| TCP上り 4並列 | 2.35Gbps | 2.35Gbps(悪化なし) |
TCP再送はほぼゼロ、UDP損失はゼロ。安定性は明確に向上しました。ただし、下り上限の約1.95Gbpsと、PAUSE(約1,390回/秒)は残ります。
測定中のCPUを見ると、dextプロセスは1%強しか使っていません。ソフトウェア処理に余裕があるので、残る上限は RTL8156チップやドック内部ハブのハードウェア特性 の可能性が高いです。
WANはどうなったか
Apple公式の networkQuality で再測定:
- 下り: 1.692Gbps(ドライバー交換前の測定は 1.5〜1.6Gbps)
- 上り: 単一接続で0.46Gbps、12並列で約2.0Gbps(実効上限はここで頭打ち)
WAN下り1.69G は LAN下り1.95G より小さいので、WAN下りは回線側(ISP/契約)が主因の可能性が高い。LANの改善はWANにはほぼ効いていません。つまり当初の「WAN下り1.5〜1.6Gbps」は、旧LAN上限(1.8Gbps)とWAN側制約の 両方が重なっていた ことになります。
なお WAN上りは、単一接続だと0.46Gbps止まりでしたが、12並列で約2.0Gbps まで出ます。つまり「上りが遅い」ように見えた一部は TCP 1接続あたりの制約で、実効は上下とも2G前後でした。
まとめ
- 「下りだけ遅い」「エラー統計が全部ゼロ」で頭打ちなら、802.3x PAUSE(フロー制御)を疑う
- 対向側NICの
rx_flow_control_xon/xoffの前後差分が決定的な手がかりになった - USB 2.5GbEアダプターはmacOS内蔵NCMで動くが、Realtek公式dextに乗せ替えると安定性が明確に向上する
- 次のボトルネックはWAN側。契約プランとルーター上流の確認が次の一歩