More Related Content Similar to Linux packet-forwarding Similar to Linux packet-forwarding (20) More from Masakazu Asama (8) Linux packet-forwarding2. はじめまして?
• 新潟県三条市にある地域 ISP 有限会社銀座堂でサーバ管理やネット
ワーク管理をしています
• 弊社では上流 ISP(OCN さんと新潟県内の ISP) や Echigo-IX(新潟県
内の地域 IX) との接続に Linux(Vyatta Core) を使って BGP 接続を
しています
• 2010 年頃から Linux カーネルのパケット転送処理について調べ
InternetWeek で発表したりしていました
• 趣味では IETF で標準化が進められている MAP(Mapping of
Address and Port with Encapsulation) というプロトコルを Linux
カーネルに実装し Vyatta Core に組み込み ASAMAP という名前で
オープンソースで公開したりしています
2
3. ASAMAP?
• IPv4 over IPv6 技術のうち DS-Lite/464XLAT/MAP-E/MAP-T の
キャリア側装置と顧客側装置の両方に対応
• IPv4 over IPv6 技術とはキャリア内ネットワークを極力 IPv6 のみで
構築しつつ顧客ネットワークに IPv4 サービスも提供するための技術
• IPv4 ヘッダを IPv6 に書き換えるトランスレーションを用いる方法
(464XLAT/MAP-T) と IPv4 パケットを IPv6 でカプセル化する方法
(DS-Lite/MAP-E) の 2 種類に分けられ
• さらにキャリア側装置に NAPT 機能を持つ方法 (DS-Lite/464XLAT)
と持たない方法 (MAP-E/MAP-T) の 2 種類に分けられる
3
MAP 対応 Vyatta (ASAMAP) 仮置き場
http://enog.jp/ masakazu/vyatta/map/
ASAMAP 開発秘話
http://www.slideshare.net/m-asama/asamap
4. 目次
• Receive Livelock と Linux NAPI
• 大量のパケット受信時の問題とそれに対して Linux カーネルが取っ
た対策
• 参考) ハードウェアによる負荷低減支援機能
• パケット転送の並列処理と RSS (Receive Side Scaling)
• パケット転送処理を複数の CPU コアで並列処理するための Linux
カーネルの仕組み
• 参考) RSS と NUMA
• 割り込み問題再び
• 参考) Intel DPDK
4
6. 割り込みモデルとポーリング・モデル
• 割り込みモデル
• メリット
• パケットの受信を CPU がすぐに気づくことが出来るので遅延が
小さい
• デメリット
• 割り込みによって生じるコンテキスト・スイッチは非常に重い処
理なため頻繁にパケット送受信を行う環境では性能劣化を招く
❖ Receive Livelock
• ポーリング・モデル
• メリット
• コンテキスト・スイッチによる処理コストはかからない
• デメリット
• ポーリング間隔のどこでパケットを受信するかによって遅延が
変動し全体としても遅延が大きくなる
6
7. Receive Livelock
• デッド・ロックしているわけでもないのに割り込みが れてしまうこ
とで割り込みハンドラしか実行していないような状態になること
• 割り込み処理はかなり高い優先度を割り当てられているためパケット
受信の際に何も考えず割り込みを発生させると他の処理を一切出来な
いような状態になる
7
※1) Eliminating Receive Livelock in an Interrupt-Driven Kernel
http://www.stanford.edu/class/cs240/readings/p217-mogul.pdf
1Gbps の Ethernet で 64 バイトのフレームを
ワイヤレートで流した際に発生する割り込みの回数
毎秒 1,488,100 回
(割り込み発生間隔 672 ナノ秒)
最近の Linux のタイマー割り込みの回数
毎秒 250 回
8. Linux NAPI
• 割り込みモデルとポーリング・モデルのいいとこ取り
• 基本的には割り込みモデルで動作
• パケットを受信した際に割り込みを無効化し処理が完了するまではポー
リング・モードで動作
• 処理すべきパケットの処理が完了したら割り込みを有効化
• 2002 年 11 月にリリースされた Linux カーネル 2.4.20 の tg3 ドラ
イバにおいて実装され順次その他の NIC ドライバでも採用
8
10. メモリ
Linux NAPI
10
CPU#2CPU#1
NIC#1 NIC#2
net_device 構造体他@NIC#1
softnet_data 構造体@CPU#1
net_device 構造体他@NIC#2
softnet_data 構造体@CPU#2
!
TX
!
RX
!
TX
!
RX
softnet_data 構造体は ksoftirqd
カーネル・スレッドがネットワーク絡
みの処理を行う際に必要とするデータ
をまとめた構造体
ksoftirqd は CPU の数だけ存在するの
で softnet_data 構造体も CPU の数
だけ存在する
11. メモリ
Linux NAPI
11
CPU#2CPU#1
NIC#1 NIC#2
net_device 構造体他@NIC#1
softnet_data 構造体@CPU#1
net_device 構造体他@NIC#2
softnet_data 構造体@CPU#2
!
TX
!
RX
!
TX
!
RX
net_device 構造体は NIC 1 つにつき
1 つ存在する構造体
通常はその直後に NIC ドライバ毎に異
なる構造体がくっついていて (例えば
e1000 の場合は e1000_adapter) そ
の中には NAPI の設定のための
napi_struct 構造体が含まれる
12. メモリ
Linux NAPI
12
CPU#2CPU#1
NIC#1 NIC#2
net_device 構造体他@NIC#1
softnet_data 構造体@CPU#1
net_device 構造体他@NIC#2
softnet_data 構造体@CPU#2
!
TX
!
RX
!
TX
!
RXNIC は受信 (RX) 用の受信バッファと
送信 (TX) 用の送信バッファを持つ
受信バッファと送信バッファは一般的
にリング構造をとっておりそれぞれ
NIC と CPU の間で排他制御無しで
データのやり取りを行う
21. ハードウェアによる負荷低減支援機能
• Ethernet Flow Control
• 一時的に対向装置 (Ethernet L2 スイッチ等) に送信をやめてもら
うことができる機能
• 自身の受信バッファがいっぱいになったときに対向装置に PAUSE
フレームを送信することで送信を一時的にやめるようお願いする
• NIC が対応している場合
ethtool -A ethX (options…)
で設定することができる
• Interrupt Coalescing (Interrupt Moderation)
• パケット受信時に NIC が割り込みを間引くことで OS の負担を低
減させる機能
• NIC が対応している場合
ethtool -C ethX (options…)
で設定することができる
21
22. Receive Side Scaling (RSS)
• 背景
• 最近のシステムでは CPU コアを複数持っているものが当たり前と
なっておりネットワークの処理もそれらで並列実行したい
• 仕組み
• NIC 側で複数のキューを持たせる
• パケットの受信時にヘッダ情報からキューを選択し対応する CPU
に割り込みする
• 同一フローのパケット (IP アドレスと TCP/UDP ポート番号が同
じパケット) は同じキューが選択されるためリオーダは生じない
• どの情報からキューを選択するかは変更可能
• 前提
• PCI-Express バスに接続された複数キューに対応した NIC
• PCI-Express で導入された MSI/MSI-X を用いて NIC から割り
込みのルーティングする必要があるため
22
23. Receive Side Scaling (RSS)
• 受信キューと割り込み番号の対応の確認
!
!
!
!
!
!
!
• 受信キューと割り込み先 CPU の対応付け
23
[root@linux ~]# cat /proc/interrupts
CPU0 CPU1
...
52: 0 0 PCI-MSI-edge p1p1-TxRx-0
53: 0 0 PCI-MSI-edge p1p1-TxRx-1
54: 0 0 PCI-MSI-edge p1p1
55: 0 0 PCI-MSI-edge p1p2-TxRx-0
56: 0 0 PCI-MSI-edge p1p2-TxRx-1
57: 0 0 PCI-MSI-edge p1p2
...
[root@linux ~]# echo 1 > /proc/irq/52/smp_affinity
[root@linux ~]# echo 2 > /proc/irq/53/smp_affinity
[root@linux ~]# echo 1 > /proc/irq/55/smp_affinity
[root@linux ~]# echo 2 > /proc/irq/56/smp_affinity
24. Receive Side Scaling (RSS)
• CPU の個数等の情報から自動的に IRQ の割り込み先を設定してくれ
る irqbalance というコマンドがある
• デーモンとして起動する場合は以下のように実行
!
• 一度だけ設定しデーモンとして起動させたくない場合は以下のように
実行
24
[root@linux ~]# irqbalance
[root@linux ~]# irqbalance --oneshot
25. メモリ
Receive Side Scaling (RSS)
25
CPU#2CPU#1
NIC#1 NIC#2
net_device 構造体他@NIC#1
softnet_data 構造体@CPU#1
net_device 構造体他@NIC#2
softnet_data 構造体@CPU#2
!
TX
!
RX
!
TX
!
RX
26. メモリ
Receive Side Scaling (RSS)
26
CPU#2CPU#1
NIC#1 NIC#2
net_device 構造体他@NIC#1
softnet_data 構造体@CPU#1
net_device 構造体他@NIC#2
softnet_data 構造体@CPU#2
TX
#1
TX
#2
RX
#1
RX
#2
TX
#1
TX
#2
RX
#1
RX
#2
27. メモリ
Receive Side Scaling (RSS)
27
CPU#2CPU#1
NIC#1 NIC#2
net_device 構造体他@NIC#1
softnet_data 構造体@CPU#1
net_device 構造体他@NIC#2
softnet_data 構造体@CPU#2
TX
#1
TX
#2
RX
#1
RX
#2
TX
#1
TX
#2
RX
#1
RX
#2
napi_struct 構造体はキューの数だけ
用意される
28. メモリ
Receive Side Scaling (RSS)
28
CPU#2CPU#1
NIC#1 NIC#2
net_device 構造体他@NIC#1
softnet_data 構造体@CPU#1
net_device 構造体他@NIC#2
softnet_data 構造体@CPU#2
TX
#1
TX
#2
RX
#1
RX
#2
TX
#1
TX
#2
RX
#1
RX
#2
パケット
(1) パケットを受信した NIC#1
は受信したパケットのヘッダ情報
からキューを決定しそのキューの
受信バッファに書き込む
29. メモリ
Receive Side Scaling (RSS)
29
CPU#2CPU#1
NIC#1 NIC#2
net_device 構造体他@NIC#1
softnet_data 構造体@CPU#1
net_device 構造体他@NIC#2
softnet_data 構造体@CPU#2
TX
#1
TX
#2
RX
#1
RX
#2
TX
#1
TX
#2
RX
#1
RX
#2
パケット
(2) NIC#1 は割り込みを使って
CPU#2 に通知
30. メモリ
Receive Side Scaling (RSS)
30
CPU#2CPU#1
NIC#1 NIC#2
net_device 構造体他@NIC#1
softnet_data 構造体@CPU#1
net_device 構造体他@NIC#2
softnet_data 構造体@CPU#2
TX
#1
TX
#2
RX
#1
RX
#2
TX
#1
TX
#2
RX
#1
RX
#2
パケット
(3) CPU#2 は実行中のタスクの
状態を保存し割り込みハンドラ
に移行する
31. メモリ
Receive Side Scaling (RSS)
31
CPU#2CPU#1
NIC#1 NIC#2
net_device 構造体他@NIC#1
softnet_data 構造体@CPU#1
net_device 構造体他@NIC#2
softnet_data 構造体@CPU#2
TX
#1
TX
#2
RX
#1
RX
#2
TX
#1
TX
#2
RX
#1
RX
#2
パケット
(4) CPU#2 は NIC#1 の自分に
対する割り込みを無効化
32. メモリ
Receive Side Scaling (RSS)
32
CPU#2CPU#1
NIC#1 NIC#2
net_device 構造体他@NIC#1
softnet_data 構造体@CPU#1
net_device 構造体他@NIC#2
softnet_data 構造体@CPU#2
TX
#1
TX
#2
RX
#1
RX
#2
TX
#1
TX
#2
RX
#1
RX
#2
パケット
(5) CPU#2 の softnet_data 構造
体の poll_list リストに NIC#1 の
RX#2 に対応する napi_struct 構
造体をリンクする
33. メモリ
Receive Side Scaling (RSS)
33
CPU#2CPU#1
NIC#1 NIC#2
net_device 構造体他@NIC#1
softnet_data 構造体@CPU#1
net_device 構造体他@NIC#2
softnet_data 構造体@CPU#2
TX
#1
TX
#2
RX
#1
RX
#2
TX
#1
TX
#2
RX
#1
RX
#2
パケット
(6) 割り込みハンドラは終了しスケ
ジューラが呼び出され通常はそのま
ま ksoftirqd カーネル・スレッドに
処理が移る
34. メモリ
Receive Side Scaling (RSS)
34
CPU#2CPU#1
NIC#1 NIC#2
net_device 構造体他@NIC#1
softnet_data 構造体@CPU#1
net_device 構造体他@NIC#2
softnet_data 構造体@CPU#2
TX
#1
TX
#2
RX
#1
RX
#2
TX
#1
TX
#2
RX
#1
RX
#2
パケット
(7) ksoftirqd は softnet_data 構造体
の poll_list にリンクされた
napi_struct 構造体の受信バッファか
らパケットを取り出し受信処理を行う
35. メモリ
Receive Side Scaling (RSS)
35
CPU#2CPU#1
NIC#1 NIC#2
net_device 構造体他@NIC#1
softnet_data 構造体@CPU#1
net_device 構造体他@NIC#2
softnet_data 構造体@CPU#2
TX
#1
TX
#2
RX
#1
RX
#2
TX
#1
TX
#2
RX
#1
RX
#2
(8) 処理が終わったら NIC#1 の自
分に対する割り込みを有効化する
36. 性能測定・構成
3613
性能測定・構成
Unidirectional Bidirectional
DELL PowerEdge R410!
Xeon L5520 @ 2.27GHz x 2(8 cores)!
Fedora 15/Linux Kernel 3.0.6(2.6.40.6)
DELL PowerEdge R410!
Xeon L5520 @ 2.27GHz x 2(8 cores)!
Fedora 15/Linux Kernel 3.0.6(2.6.40.6)
Spirent TestCenter Spirent TestCenter
Intel X520-SR2!
10G NIC(82599EB)!
SourceForge ixgbe
Intel X520-SR2!
10G NIC(82599EB)!
SourceForge ixgbe
128flow
128flow
128flow
Loss < 0.01% Loss < 0.01%30 sec.30 sec.
37. RSS による性能改善 (Unidirectional)
37
0Mbps
2,000Mbps
4,000Mbps
6,000Mbps
8,000Mbps
10,000Mbps
64 128 256 512 1024 1280 1518
RSS=1,1 CPU:0,0 RSS=1,1 CPU:4,6
RSS=4,4 CPU:0,2,4,6 RSS=8,8 CPU:0,1,..,7
38. RSS による性能改善 (Unidirectional)
38
0pps
1,000,000pps
2,000,000pps
3,000,000pps
4,000,000pps
5,000,000pps
6,000,000pps
64 128 256 512 1024 1280 1518
RSS=1,1 CPU:0,0 RSS=1,1 CPU:4,6
RSS=4,4 CPU:0,2,4,6 RSS=8,8 CPU:0,1,..,7
39. RSS による性能改善 (Bidirectional)
39
0Mbps
4,000Mbps
8,000Mbps
12,000Mbps
16,000Mbps
20,000Mbps
64 128 256 512 1024 1280 1518
RSS=1,1 CPU:0,0 RSS=1,1 CPU:4,6
RSS=4,4 CPU:0,2,4,6 RSS=8,8 CPU:0,1,..,7
40. RSS による性能改善 (Bidirectional)
40
0pps
1,000,000pps
2,000,000pps
3,000,000pps
4,000,000pps
5,000,000pps
6,000,000pps
64 128 256 512 1024 1280 1518
RSS=1,1 CPU:0,0 RSS=1,1 CPU:4,6
RSS=4,4 CPU:0,2,4,6 RSS=8,8 CPU:0,1,..,7
42. NUMA とメモリの距離
42
#0
CPU ソケット#0
#2 #4 #6
メモリ・コントローラ#0
メモリ・ノード#0
#1
CPU ソケット#1
#3 #5 #7
メモリ・コントローラ#1
メモリ・ノード#1
#0 #1 #2 #3 #4 #5 #6 #7
#0 #1 #2 #3 #4 #5 #6 #7
NIC#1 NIC#2
44. ロス許容と性能評価
44
0pps
1,000,000pps
2,000,000pps
3,000,000pps
4,000,000pps
5,000,000pps
6,000,000pps
64 128 256 512 1024 1280 1518
RSS=8,8 Loss<0.01 RSS=8,8 Loss<0.1 RSS=8,8 Loss<1.0
45. 割り込みモデルとポーリング・モデル (再
45
NIC
CPU
① NIC が受信したパケットを
受信バッファに書き込む
② NIC が割り込みで CPU に
通知
③ CPU は実行中のタスクの
状態を保存し割り込み
ハンドラを実行
② CPU は定期的に受信バッファ
を確認し新しいパケットが
届いていたら処理する
① 受信したパケットを受信バッ
ファに書き込む
NIC
CPU
割り込みモデル ポーリング・モデル
46. 参考) Intel DPDK
• Intel 社がオープン・ソース (BSD ライセンス) で開発しているデータ・
プレーンを開発するための SDK (Data Plane Development Kit)
• http://www.dpdk.org/
• 割り込みではなくすべてポーリングでパケット処理を行う
• Linux の UIO (デバイスをユーザ・ランドから直接制御するための仕
組み) を用いて割り込みモードではなくポーリング・モードで動作す
るドライバ (PMD: Poll-Mode Driver) で NIC を制御する
• 実はオープン・ソースになっていないだけで UIO でなくカーネル
内で動作させるモノも存在する?
• どこにも define されていないのに存在する大量の ifdef
RTE_EXEC_ENV_BAREMETAL
• DMA 転送されたパケットを CPU の LLC にプリ・フェッチしていた
りページ・サイズ大きくすることで TLB ミスがあまり起こらないよ
うにしていたりと小細工も満載
46
47. 参考) Intel DPDK
47
TRANSFORMING COMMUNICATIONSIntel Confidential8 TRANSFORMING COMMUNICATIONS8
IA パフォーマンスの年々の向上
iAでのPv4 レイヤー 3 フォワード性能
0
20
40
60
80
100
120
140
160
2006
2x2C Sossaman
2.0 GHz
2007
2x4C Clovertown
2.33 GHz
2008
2x4C Harpertown
2.33 GHz
2009
2x4C Nehalem
2.53 GHz
2010
2x6C Westmere
2.40 GHz
2011
1x8C Sandy Bridge
2.0 GHz
2012
2x8C Sandy Bridge
2.0 GHZ
(PCIe* Gen2 の機器でテスト)
標準の“off-the-shelf” IAプラットフォームで魅力的な性能を提供します
* Other names and brands may be
claimed as the property of others.
64B
Mpps
10G
40G
100G
内蔵PCIe* コントローラー
80G
内蔵メモリーコントローラー
の登場
+
インテル® DPDK
Internet Week 2012 D1 パケットフォワーディングを支える技術
3) パケットフォワーディング高速化技術(幸村 裕子/インテル株式会社)から引用
https://www.nic.ad.jp/ja/materials/iw/2012/proceedings/d1/d1-Kohmura.pdf