プロセスアカウンティング(pacct)

Linux 2.6.16のプロセスアカウンティング機能にはバグがあり、マルチスレッドプログラムの実行履歴を正常に記録できないという問題がある。

例えば、以下のようなプログラム。

void *worker(void *dummy) {
while(1); /* 無限ループ */
}

int main(int argc, char *argv[]) {
pthread_t pthread;
pthread_create(&pthread, NULL, worker, NULL);
pthread_exit(0);
}
ワーカースレッドがいくらCPUTIMEを消費しても、アカウンティングには記録されない。理由は、スレッドリーダーである main() を実行したスレッドが先に死んでいるため。

Linux2.6.16では、プロセスの終了時にアカウンティングを記録するが、utime/stimeの記録アルゴリズムは「先に死んだスレッドのutime/stimeの合計」+「スレッドリーダのutime/stimeの合計」で計算しているため、スレッドリーダがワーカースレッドよりも先に死ぬような状況では、最後に死んだワーカースレッドのCPU時間は全くカウントされない。(逆にスレッドリーダは2重カウントになる)

というわけで、先日これを解決するパッチを投稿したらAndrew MortonからLinusに送られた模様。次では直りますかね。

2.6.9〜2.6.16のカーネルを使っている計算センタのユーザは、この方法で課金を回避できますよwww