hogeとはワイルドカードのようなものです。日々起こった、さまざまなこと −すなわちワイルドカード− を取り上げて日記を書く、という意味で名付けたのかというとそうでもありません。適当に決めたらこんな理由が浮かんできました。
10/27/2011 うむ [長年日記]
■ [Linux] smp_affinity
うんこを流す計画その 2.
最近のハードウェアなら CPU コアが沢山乗っているのが当たり前なわけだけど,さて,例えば NIC にパケットが届いた際にシステムがどういう動きをするかというと,簡単に言えば,ハードウェア割り込みが発生して,それをシステムがハンドルするという流れになる.Linux ではこの割り込みをハンドルするのをある CPU だけに固定してしまったりすることができる.
例えば /proc/interrupts を見てみると,以下のようなものが出てくる.
$ cat /proc/interrupts CPU0 CPU1 CPU2 CPU3 (略) 47: 5517603 28 30 31 PCI-MSI-edge eth0 (略)
これは IRQ 47 eth0 からの割り込みを CPU0 が 5517603 回処理したということを表す.その他の CPU も同様.
で,じゃあ現在 IRQ 47 からの割り込みをハンドルする CPU の設定はどうなっているかというと,
# cat /proc/irq/47/smp_affinity f
f つまり 15,2 進数で表せば 1111 となる. この値はビットマスクであり,下位から 1 ビット目が CPU0,2 ビット目が CPU1,... というように対応付けられていて,ビットが立っていればハンドル可能という意味になる.
全部の CPU がハンドル可能だなんて許さん! CPU3 だけが処理しとけばいいんだ! という怒りっぽいあなたは以下のようにマスクを設定すれば良い.
# echo 8 > /proc/irq/47/smp_affinity
8 つまり 2 進数で表せば 1000 なので,CPU3 だけがハンドルを許可された状態となる. この状態になった後でしばらく /proc/interrupts を眺めていると,カウンタの増加が CPU3 にだけ起こっているということを確認できる.
なおこの辺の話はカーネルのコードに付属の Documentation/filesystems/proc.txt 辺りにごにょごにょと書いてある.
ちなみに Linux では何かを特定の CPU に縛り付けたりする時に affinity mask という概念をよく使う. 例えば sched_setaffinity(2) システムコールはあるプロセス (スレッド) の実行を許す CPU の集合を設定するのだけれど,これも同じく affinity mask を使う.というか使うというより affinity mask を設定するというイメージになるのだけれど.
例えばあるプロセスの実行を許可された CPU は /proc/PID/status の Cpus_allowed 項または Cpus_allowed_list 項を見れば分かる. これら 2 つの項の意味は一緒で,前者は mask 値で,後者は CPU 番号リストで得られる.
あるプロセスの実行許可をシェルから変更したい場合は,taskset(1) を使うことができる.