Number -17
17番といっても、Redsの赤丸急上昇中 長谷部選手のことではありません。
最近のkernelでは、17という数字に関係した機能が1つあるというお話です。
みなさんは、syslogメッセージで次のようなメッセージを見たことはありますか?
messages:Apr 20 10:50:26 localhost kernel: oom-killer: gfp_mask=0xd0
これは、oom-killer、つまりOut Of Memoryが発生したことを知らせるカーネルのメッセージです。Out Of Memoryとは、カーネル内でのメモリのやりくりがどうにもつかなくてメモリが足りない状況に陥ったことを表します。このような場合、カーネルは仕方ないので、プロセスをkillしてメモリを確保しようとします。そのためoom-killerと呼ばれています。
このとき、カーネルがどのプロセスをkillするかは、いろいろな要素を加味して計算した結果で選択するのですが、必ずしも影響の小さいプロセスをkillしてくれるとは限りません。そのため、時にはアプリケーション内で最も重要なプロセスがkillされる可能性もあります。
そんな事態を少しでも避けたいというシステム管理者の思いが通じたのか、oom-killerによってkillされる対象から特定のプロセスを除外することができるようになりました。
linux-2.6.16/mm/oom_kill.cに次のようなコードがあります。
-----
if (p->oomkilladj == OOM_DISABLE)
continue;
-----
ここで、pはプロセスを表します。この部分は、プロセスのoomkilladj変数がOOM_DISABLEだと、oom_killerの対象からはずすためのコードになっています。
このoomkilladjがどこで設定されるかというと、
linux-2.6.16/fs/proc/base.c
-----
static ssize_t oom_adjust_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
struct task_struct *task = proc_task(file->f_dentry->d_inode);
char buffer[8], *end;
int oom_adjust;
if (!capable(CAP_SYS_RESOURCE))
return -EPERM;
memset(buffer, 0, 8);
if (count > 6)
count = 6;
if (copy_from_user(buffer, buf, count))
return -EFAULT;
oom_adjust = simple_strtol(buffer, &end, 0);
if ((oom_adjust < -16 || oom_adjust > 15) && oom_adjust != OOM_DISABLE)
return -EINVAL;
if (*end == '\n')
end++;
task->oomkilladj = oom_adjust; ←ここです。
if (end - buffer == 0)
return -EIO;
return end - buffer;
}
-----
ということで、/procで設定できるようです。
確認のために、/procの各プロセスのファイルを見てみると、
-----
$ ls
attr cwd fd mem oom_score stat task
auxv environ loginuid mounts root statm wchan
cmdline exe maps oom_adj smaps status
-----
と、まさにそのもののファイルがありました。
さて、最後になりましたが、OOM_DISABLEの定数を確認します。
linux-2.6.16/include/linux/mm.h
-----
/* /proc/<pid>/oom_adj set to -17 protects from the oom-killer */
#define OOM_DISABLE -17
-----
ということで、-17を設定することでoom_killerから守ることができるという説明も付いてますね。
だからといって全てのプロセスに-17を設定してしまうと、カーネルがメモリが足りなくて困っているのにどうしようもなくなって、もっとひどい事態になると思いますので、設定は慎重に。

コメント