@naota344の今週のLKML
今週は
- [PATCH] per-cgroup tcp buffer limitation
- [RFC PATCH 0/2] block: Allow extending partition size online
- [PATCH RFC] epoll: limit paths
[PATCH] per-cgroup tcp buffer limitation
http://permalink.gmane.org/gmane.linux.kernel.mm/67837
TCPのコネクションが使用するカーネルのメモリ量をcgroupで制限できるようにするパッチです。もともと /proc/sys/net/ipv4/tcp_mem を使えば制限はできるのですが、さらにcgroupごとに制限をかけていきます。
http://permalink.gmane.org/gmane.linux.kernel.containers/21295
もともとのRFCがこのcontainersで行なわれていたことから分かるとおり、もとはコンテナごとの制限をめざしていたようです。
それにしても、どんどんcgroupに機能が投入されていきますね…。しかし、こういうサポートが進んでいけばLinuxコンテナを使用したお手軽な仮想サーバ作りが便利になるでしょうね。
[RFC PATCH 0/2] block: Allow extending partition size online
http://permalink.gmane.org/gmane.linux.kernel/1187135
マシンの起動中にパーティションのサイズを大きくできるようにするためのpatchです。とは言えパーティションテーブルをいじるコードが入っているわけではありません。まず、fdiskなどでパーティションテーブルを編集し、新しく追加されたコマンドextedpartでカーネルのパーティションサイズの認識を変更する、という手段をとります。
http://permalink.gmane.org/gmane.linux.kernel/1187133
- 10MBのパーティションを作る
- LVMにそのパーティションを追加
- さっきのパーティションを20MBに増やす(一度消して作り直す)
- extendpart /dev/sda 1 20480でカーネルの認識を変更する
- pvresize /dev/sda1すると容量が増えている
ということが、マシンを再起動することなくできるようになるようです。
[PATCH RFC] epoll: limit paths
http://permalink.gmane.org/gmane.linux.kernel/1187571
このようなプログラムを書きます
#include <unistd.h> #include <sys/epoll.h> int main(void) { int e1, e2, p[2]; struct epoll_event evt = { .events = EPOLLIN }; e1 = epoll_create(1); e2 = epoll_create(2); pipe(p); epoll_ctl(e2, EPOLL_CTL_ADD, e1, &evt); epoll_ctl(e1, EPOLL_CTL_ADD, p[0], &evt); write(p[1], p, sizeof p); epoll_ctl(e1, EPOLL_CTL_ADD, e2, &evt); return 0; }
epollは基本的には複数のファイルデスクリプタを登録して、その中のどれかが(読みこみ可能|書きこみ可能|シャットダウン)などなど状態の変化あるいはイベントなどを検出できるような機能ですね。epoll_create()で作って、epoll_ctl(epoll_fd,EPOLL_CTL_ADD, fd, &evt)という形でepoll_fdにfdがevtで指定したeventが起きた時に検出するように登録します。
このコードだと下の図のようになっています
見事に循環してますね…。こうしてしまうとまあ予想通りにdeadlockが発生します。p[1]への書きこみでp[0]が読みこみ可能になり、それがe1に伝えられ、e1が読みこみ可能になり、e2に伝えられ…というわけです。
これに対処するためにcommit 22bacca48a1755f79b7e0f192ddb9fbb7fc6e64e というのが二月にあてられているのですがこれは総当たりしてループがないかどうか、をチェックするようになっていて https://lkml.org/lkml/2011/2/25/297 のコードのように大きなepollのグラフではかなりの時間をかけてチェックすることになってしまいます。これに対応するために前述の https://lkml.org/lkml/2011/2/25/297 ではvisitしたepollfdを覚えておくといった対応がとられているのですが、いずれにせよこのような大きなツリーでは、ループがなくともどこかに(たとえば)書きこみがあってwakeupが連鎖する時にこのループを行なわざるをえなくなっています。……ということで一端これは忘れられたようです……。
今回のpatchはあるepollfdから到達できるfdの数を制限しています。 patchでは
int path_limits[PATH_ARR_SIZE] = { 1000, 500, 100, 50, 10 };
となっていて、直接つながっているのは1000まで、2-popでつながっているのは500まで…というふうになっています。