ネットワーク I/O 限界の指標としてコンテキストスイッチ回数も使えるという話

Firebox X700X750e に FreeBSD を突っ込んで遊んでいたら、コンテキストスイッチで頭打ちになって面白かったのでメモ。

事の発端

B フレッツエクスプレスタイプなる、 GbE が家までやってくるという諸外国から見たら狂ってる感じの高速回線を自宅に引いた。それによりボトルネックとなった古い PC ルータを、手元にあった Firebox X700X750e でリプレースした。
出来上がったら当然ベンチマークしたくなったので、奈良とか調布とか堂島にある FreeBSD のミラーから、一斉に ISO image を fetch(1) で /dev/null に書き込むという、夜中じゃなかったら睨まれそうな方法にてベンチマークをして遊んでいた。
遊んでいる最中になにやら msk0 が発狂してしまったらしく、ベンチマーク中に突然 PPPoE がリンクダウンするという現象が発生、安定性のチェックを兼ねて sk0 に繋ぎ変えて PPPoE を張りベンチマークしたところ、トラフィックの傾向が変わったので詳細に調べてみた。

vmstat

こちらは mpd5 が作った netgraph ノードである ng0 の、繋ぐ先を sk0 に変更して、 3ホストから ftp ダウンロードを行い 18MB/s ぐらいでサチってしまっていたときの vmstat 1 の値。
cpu cs (context switch) は 25k強を推移している。さらに、割とバタついている。

 procs      memory      page                    disks     faults         cpu
 r b w     avm    fre   flt  re  pi  po    fr  sr ad0 md0   in   sy   cs us sy id
 0 0 0    119M   240M     0   0   0   0     0   0   0   0    2  127  323  0  1 99
 0 0 0    119M   240M     0   0   0   0     0   0   0   0    2  126  303  0  2 98
 0 0 0    119M   240M     0   0   0   0     0   0   0   0    2  119  306  0  1 99
 0 0 0    119M   240M     0   0   0   0     0   0   0   0  259  183  786  0  3 97
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 1881  119 3658  0 10 90
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 6280  134 11657  0 21 79
 0 0 0    119M   240M     0   0   0   0     0   0   0   1 14182  119 26491  0 33 67
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 14534  126 27786  0 29 71
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 13827  183 26191  1 31 68
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 11844  119 22613  0 21 79
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 14785  127 28040  0 32 68
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 14669  126 27891  0 34 66
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 14676  126 28256  0 29 71
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 14631  186 27982  0 26 74
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 15270  142 29148  0 27 73
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 11662  127 21984  0 27 73
 0 0 0    119M   240M     0   0   0   0     0   0   0   1 11485  119 22065  0 26 74
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 14353  119 26953  0 37 63
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 15301  185 28774  1 33 66
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 15131  150 27906  0 41 59
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 14570  126 28052  0 36 64
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 14685  126 28099  0 36 64
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 15206  126 29013  0 26 74
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 13981  186 26355  0 35 65
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 15290  127 28847  0 40 60
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 11376  119 21908  0 24 76
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 15816  119 29645  0 31 69
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 13791  184 26751  0 22 78
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 14903  146 28358  0 32 68
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 14870  127 28579  0 27 73
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 14606  119 27858  0 31 69
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 15422  126 29209  0 31 69
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 13878  183 26616  0 37 63
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12083  119 22919  0 26 74
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 15547  135 29154  0 38 63
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 13393  119 24476  0 38 63
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 15261  119 28270  0 38 63
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 13216  192 25424  0 26 74
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 14734  119 28039  0 31 69
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12785  127 24294  0 24 76
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 14702  126 27951  0 35 65
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12860  119 24887  0 21 79
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 13466  184 25632  1 34 65
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12884  119 24237  0 26 74
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 4873  127 9688  0 16 84
 0 0 0    119M   240M     2   0   0   0     0   0   0   0 10735  124 20454  0 30 70
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12036  142 22767  0 23 77
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 4329  183 8684  0  9 91
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 11835  119 22791  0 30 70
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 11325  134 21168  0 29 71
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 4014  126 8120  0 11 89
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 6882  149 13300  0 20 80
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 4826  183 9627  0 16 84
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 9719  119 18418  0 25 75
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 13628  127 25634  0 24 76
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 3631  119 7307  0 12 88
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 11749  119 22709  0 20 80
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12738  188 23873  1 31 68
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 13952  142 26133  0 37 63
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 3514  127 7036  0  8 92
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 11792  126 22765  0 28 72
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 9377  119 17917  0 25 75
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 8100  183 15876  0 13 87
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 7964  119 15689  0 13 87
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 8850  134 17423  0 17 83
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 7863  119 15410  0 17 83
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 7894  126 15503  0 13 87
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 3961  184 7966  1  9 90
 0 0 0    119M   240M     0   0   0   0     0   0   0   0    2  119  298  0  1 99
 0 0 0    119M   240M     0   0   0   0     0   0   0   0    2  127  301  0  1 99
 0 0 0    119M   240M     0   0   0   0     0   0   0   0    2  126  315  0  1 99

こちらは ng0 を繋ぐ先を msk2 に変更したときの vmstat 1 の出力。最大 35MB/s ぐらいでかっ飛んでいました。
コンテキストスイッチ回数は 24k前後で安定。

 procs      memory      page                    disks     faults         cpu
 r b w     avm    fre   flt  re  pi  po    fr  sr ad0 md0   in   sy   cs us sy id
 0 0 0    119M   240M     0   0   0   0     0   0   0   0    3  119  308  0  1 99
 0 0 0    119M   240M     0   0   0   0     0   0   0   0    2  126  290  0  1 99
 0 0 0    119M   240M     0   0   0   0     0   0   0   0    4  190  302  0  1 99
 0 0 0    119M   240M     0   0   0   0     0   0   0   0  237  127  760  0  1 99
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 6684  119 12920  0 29 71
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12544  142 23829  0 46 54
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12645  119 23977  1 49 50
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 10196  186 19069  1 40 59
 0 0 0    119M   240M     0   0   0   0     0   0   0   3 12599  127 24066  0 50 50
 0 0 0    119M   240M     0   0   0   0     0   0   0   5 12326  119 23492  0 43 57
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12666  124 24348  0 39 61
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12734  119 24424  0 46 54
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12529  216 23920  0 49 51
 0 0 0    119M   240M     0   0   0   0     4   0   1   0 12981  127 24810  0 51 49
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12718  149 24134  0 50 50
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12486  119 23533  0 45 55
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 10333  126 19010  0 40 60
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12700  207 23892  0 44 56
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 11940  190 22923  0 42 58
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12275  119 24112  0 35 65
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12193  119 23718  0 36 64
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12542  126 24352  0 32 68
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12656  210 24283  0 46 54
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12307  127 23644  0 44 56
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12482  119 23847  0 48 52
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12594  119 24025  0 43 57
 1 0 0    119M   240M     0   0   0   0     0   0   0   0 12601  158 24139  0 43 57
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12064  207 23248  0 43 57
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12171  127 24441  0 27 73
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12008  126 24246  0 31 69
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 11978  119 24192  0 28 72
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 11860  198 23824  0 27 73
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 12044  150 24050  0 23 77
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 11865  127 23488  0 27 73
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 11938  158 23457  1 23 76
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 11870  119 23374  0 33 67
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 11423  184 22464  0 24 76
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 5902  142 11556  0 13 87
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 7151  127 13970  0 18 82
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 6434  119 12486  0 13 87
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 4990  119 9781  0 18 82
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 6689  222 13613  0 13 87
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 6289  119 12864  0 13 87
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 6617  157 13596  0 19 81
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 6099  142 12484  0 11 89
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 5852  126 11993  0 10 90
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 5514  183 11278  1 14 85
 0 0 0    119M   240M     0   0   0   0     0   0   0   0 3829  119 7957  0  7 93
 0 0 0    119M   240M     0   0   0   0     0   0   0   0    2  127  249  0  1 99
 0 0 0    119M   240M     0   0   0   0     0   0   0   0    2  119  240  0  1 99
 0 0 0    119M   240M     0   0   0   0     0   0   0   0    4  142  259  0  1 99

考察

cpu sy (system) は msk(4) を使ったときの方が高くなっているが、 cpu cs は逆に低下し、スループットは向上している。
Firebox X700X750e には sk(4) と msk(4) が 4つづつ付いている。後者の方がモダンで interrupt moderation (coalescence / throttling とも言う) を行うことが出来る。これにより msk(4) を使っていたときはコンテキストスイッチの発生が抑えられていた様子。
なお、その後何回か試していた所、最大 43MB/s ほど出た。そのとき CPU は 50% オーバーまで景気良く回っていた。
ちなみに、後述する sysctl をイジってコンテキストスイッチ回数を増やしてみたところ、大体 31k/s ぐらいまで振り切れて、スループットは 30MB/s 程度まで低下した。劣化の先にある限界は、この辺らしい。
sk(4) を使っている時はコンテキストスイッチ回数にバラつきがあったが、 duplicate ack がかなり出ていたので、短いタイムスパンで詰まったりしていそうである。

今後の展望

device polling とか使うと盛大に速くなるかもしれない。 polling(4) を参照。
なんか昔にイジった覚えがあるが、自宅サーバ復活させてなくて見れません。すみませんすみません。
http://www.muranet.jp/~mura/blosxom.cgi/bsd/samba-and-freebsd-tuning-3.html
他には、以下の sysctl をイジるとかも良いかもしれません。軽く触ったら悪化したりしたのでちゃんと見る必要がありそうですが。

inline# sysctl -a | grep holdoff
dev.mskc.0.int_holdoff: 100
dev.mskc.1.int_holdoff: 100
dev.mskc.2.int_holdoff: 100
dev.mskc.3.int_holdoff: 100
inline# sysctl -a | grep process_limit
dev.mskc.0.process_limit: 128
dev.mskc.1.process_limit: 128
dev.mskc.2.process_limit: 128
dev.mskc.3.process_limit: 128
inline# 

msk(4) に PPPoE を高トラフィックで流すと、 "msk0: watchdog timeout" とか言い残して刺さる件は、 TSO とかを切って様子見ですかね…。内側 I/F は無事とは言え地味に困る…。

参考情報

動かしていたのは FreeBSD 8.2 + mpd5 という、速い PPPoE 箱を自作するときの定番構成。
ハードウェアは Celeron M 1.3GHz に 512MB RAM と、 32bit PCI を共有する sk(4) が 4つ、 PCI-E 接続の msk(4) が 4つという構成。
FreeBSD をよく使っていないと mpd5 が使う netgraph を知らないと思いますが、非常に興味深いものなのでググって頂くと吉。誤解を恐れずに言うならば kernel 内のネットワークスタックを柔軟に繋ぎかえるフレームワークのようなもの、と言う感じ。
netgraph は kernel 内で完結しているので、 mpd5 によって netgraph で PPPoE することで、 userland PPPoE で起きるオーバーヘッドを回避することが出来る。いや、 OpenBSD みたいに pppoe(4) とかある方が分かりやすいとは思いますが。