[kernel/vm] implements the rps/rfs for freebsd
TRANSCRIPT
Implements the RPS/RFS for FreeBSD
@gokzy
1
誰?
• 八王子の山奥の大学院生
– 夕方は夕日に照らされる高尾山がキレイ
– 夜は星がキレイ
– @gokzy
2
GSoCで何やんの?
• Implements the RPS/RFS for FreeBSD
– Mono-queue NICで受信処理をスケールさせる
• Linux 2.6.35に入ったRPS/RFSを移植する
– 参考になるコードがあって簡単
– それでいて金がもらえて(゚∀゚)ウマウマ
3
世の中には2種類のNICがある
4
• Multi-queue
– 複数のCPUに割り込み可
– queueを複数もつ
– お高い高級品
• Mono-queue
– 1CPUにのみ割り込み可
– queueが1つ
– お求めやすい庶民の品
– Serverでもオンボはこれのことも
世の中には2種類のNICがある
5
• Multi-queue
– 複数のCPUに割り込み可
– queueを複数もつ
– お高い高級品
• Mono-queue
– 1CPUにのみ割り込み可
– queueが1つ
– お求めやすい庶民の品
– Serverでもオンボはこれのことも
Mono-queue NICに高負荷をかける
• 不幸になる
– パケットがドロップしようが1CPUに負荷が集中
6
0%
20%
40%
60%
80%
100%
CPU0CPU1CPU2CPU3CPU4CPU5CPU6CPU7
CP
U使用率
FreeBSDのTCP受信処理を見ましょう
7
どうしてそうなるの?
FreeBSDのTCP受信処理の流れ
userapp
Et her net Car d
i t hr ead i t hr ead i t hr ead i t hr ead
Devi ce
Socket+TCP+I P
Li nker l ayer+
Dr i ver
net i srsof t war et hr ead
net i srsof t war et hr ead
net i srsof t war et hr ead
net i srsof t war et hr ead
Appl i cat i on+
Socket
CPU0 CPU1 CPU2 CPU3
8
Multi-queue NICだと
userapp
Et her net Car d
i t hr ead i t hr ead i t hr ead i t hr ead
Devi ce
Socket+TCP+I P
Li nker l ayer+
Dr i ver
net i srsof t war et hr ead
net i srsof t war et hr ead
net i srsof t war et hr ead
net i srsof t war et hr ead
Appl i cat i on+
Socket
CPU0 CPU1 CPU2 CPU3
userapp
userapp
userapp
9
Mono-queue NICだと
userapp
Et her net Car d
i t hr ead i t hr ead i t hr ead i t hr ead
Devi ce
Socket+TCP+I P
Li nker l ayer+
Dr i ver
net i srsof t war et hr ead
net i srsof t war et hr ead
net i srsof t war et hr ead
net i srsof t war et hr ead
Appl i cat i on+
Socket
CPU0 CPU1 CPU2 CPU3
userapp
userapp
userapp
10
処理を分散させる
userapp
Et her net Car d
i t hr ead i t hr ead i t hr ead i t hr ead
Devi ce
Socket+TCP+I P
Li nker l ayer+
Dr i ver
net i srsof t war et hr ead
net i srsof t war et hr ead
net i srsof t war et hr ead
net i srsof t war et hr ead
Appl i cat i on+
Socket
CPU0 CPU1 CPU2 CPU3
userapp
userapp
userapp
11
Receive Packet Steering - RPS
• Mono-queueのNICで
– 割り込みが1CPUにしかかけられない
• プロトコルスタック処理を分散させる
– netisr threadのディスパッチ先をフロー毎に振り分ける
– SMPを有効活用できる
12
RPSでのディスパッチ先の決め方
• 同一フローは同じnetisrにディスパッチ
– オーダーを保証するため
• 宛先CPUの決め方
1. hashを求める
• IPアドレス(src,dst)とTCP,UDPポート(src,dst)から
2. 次式でディスパッチ先のCPUが決まる
• hash値 % netisr thread数
• 十数行追加するだけの簡単なお仕事
– これで$2000 GET
13
これ気になりますよね
• CPUをまたいでいる
– データローカリティの低下
14
userapp
Et her net Car d
i t hr ead i t hr ead i t hr ead i t hr ead
Devi ce
Socket+TCP+I P
Li nker l ayer+
Dr i ver
net i srsof t war et hr ead
net i srsof t war et hr ead
net i srsof t war et hr ead
net i srsof t war et hr ead
Appl i cat i on+
Socket
CPU0 CPU1 CPU2 CPU3
userapp
userapp
userapp
ディスパッチ先をアプリケーションが動いているCPUに
userapp
Et her net Car d
i t hr ead i t hr ead i t hr ead i t hr ead
Devi ce
Socket+TCP+I P
Li nker l ayer+
Dr i ver
net i srsof t war et hr ead
net i srsof t war et hr ead
net i srsof t war et hr ead
net i srsof t war et hr ead
Appl i cat i on+
Socket
CPU0 CPU1 CPU2 CPU3
userapp
userapp
userapp
15
Receive Flow Steering - RFS
• パケットの受信処理を,そのパケットの宛先のアプリケーションが動いているCPUでやる
• データローカリティが向上
16
RFSでのディスパッチ先の決め方
17
App
packet
App
CPU0 CPU1 CPU2 CPU3
netisr thread
Application
packet ithread
queue queuequeuequeue
• 青プロセスが宛先のパケットを受信
RFSでのディスパッチ先の決め方
18
App
packet
App
CPU0 CPU1 CPU2 CPU3
netisr thread
Application
packet
ithread
queue queuequeuequeue
• 青プロセスが動いているCPU3のqueueに積む
青プロセスが
19
• 青プロセス向けのパケット受信
packet 1
packet 2
packet 3
App
packet 1
App
CPU0 CPU1 CPU2 CPU3
netisr thread
Application
packet 4 ithread
queue queuequeuequeue
App
packet 1
packet 2
青プロセスがCPU2に移動
20
• 青プロセス向けのパケット受信
packet 1
packet 2
packet 3
App
packet 1
App
CPU0 CPU1 CPU2 CPU3
netisr thread
Application
packet 4 ithread
queue queuequeuequeue
App
App
packet 1
packet 2
CPU2のqueueに積むと…
21
• 順序が入れ替わる可能性がある
packet 1
packet 2
packet 3
App
packet 1
App
CPU0 CPU1 CPU2 CPU3
netisr thread
Application
packet 4
ithread
queue queuequeuequeue
App
App
packet 1
packet 1
プロセスの移動が発生し同一フローで未処理がある場合
22
• パケットが残っているqueueに積む
packet 1
packet 2
packet 3
App
packet 1
App
CPU0 CPU1 CPU2 CPU3
netisr thread
Application
packet 4 ithread
queue queuequeuequeue
App
App
packet 1
packet 2
フローごとにqueueの長さを管理
23
• ここでは青パケットはのqueue_lenは3
packet 1
packet 2
packet 3
App
packet 1
App
CPU0 CPU1 CPU2 CPU3
Appl i cat i on
packet 4 i t hr ead
queue queuequeuequeue
App
App
packet 1
packet 2
queue_l en : 3
ディスパッチ先を変えない条件
24
• queue_len > 0 なら元のnetisrのqueueに積む
packet 1
packet 2
packet 3
App
packet 1
App
CPU0 CPU1 CPU2 CPU3
Appl i cat i on
packet 4 i t hr ead
queue queuequeuequeue
App
App
packet 1
packet 2
queue_l en : 3
ディスパッチ先を変更する条件
• queue_len == 0 にると移動
25
packet 4
App
App
CPU0 CPU1 CPU2 CPU3
Appl i cat i on
packet 5 i t hr ead
queue queuequeuequeue
App
App
packet 3
queue_l en : 0
まとめ
• Mono-queue NICをSMP環境で有効活用!!
– パケットのオーダーを守るように実装
• ちなみにLinuxの実装もだいたい同じ
– 2.6.35以降なら即試せます
• /sys/class/net/eth[0-9]/queues/rx-[0-9]/rps_cpus
• /sys/class/net/eth[0-9]/queues/rx-[0-9]/rps_flow_cnt
• /proc/sys/net/core/rps_sock_flow_entries
26