# OOM Killer 簡短筆記

## 緣由

滑 hacker news 時被 [Out-of-memory victim selection with BPF](https://lwn.net/SubscriberLink/941614/f873a0ec485e01c5/) 砸到，忽然有點好奇 OOM Killer Source Code。

## Source Code

[https://elixir.bootlin.com/linux/v6.6/source/mm/oom\_kill.c#L192](https://elixir.bootlin.com/linux/v6.6/source/mm/oom_kill.c#L192)

```c
/**
 * oom_badness - heuristic function to determine which candidate task to kill
 * @p: task struct of which task we should calculate
 * @totalpages: total present RAM allowed for page allocation
 *
 * The heuristic for determining which task to kill is made to be as simple and
 * predictable as possible.  The goal is to return the highest value for the
 * task consuming the most memory to avoid subsequent oom failures.
 */
long oom_badness(struct task_struct *p, unsigned long totalpages)
{
	long points;
	long adj;

	if (oom_unkillable_task(p))
		return LONG_MIN;

	p = find_lock_task_mm(p);
	if (!p)
		return LONG_MIN;

	/*
	 * Do not even consider tasks which are explicitly marked oom
	 * unkillable or have been already oom reaped or the are in
	 * the middle of vfork
	 */
	adj = (long)p->signal->oom_score_adj;
	if (adj == OOM_SCORE_ADJ_MIN || test_bit(MMF_OOM_SKIP, &p->mm->flags) ||
			in_vfork(p)) {
		task_unlock(p);
		return LONG_MIN;
	}

	/*
	 * The baseline for the badness score is the proportion of RAM that each
	 * task's rss, pagetable and swap space use.
	 */
	points = get_mm_rss(p->mm) + get_mm_counter(p->mm, MM_SWAPENTS) +
		mm_pgtables_bytes(p->mm) / PAGE_SIZE;
	task_unlock(p);

	/* Normalize to oom_score_adj units */
	adj *= totalpages / 1000;
	points += adj;

	return points;
}
```

首先會排除以下 process：

* kthread
    
* 正在 vfork
    
* 已經被 oom kill
    
* 被標記 oom skip
    

然後根據佔用記憶體（rss, swap, page）計算一個分數，越大越需要被 oom kill。

## References

[How does the OOM killer decide which process to kill first?](https://unix.stackexchange.com/questions/153585/how-does-the-oom-killer-decide-which-process-to-kill-first)

[Out-of-memory victim selection with BPF](https://lwn.net/SubscriberLink/941614/f873a0ec485e01c5/)

[https://elixir.bootlin.com/linux/v6.6/source/mm/oom\_kill.c#L192](https://elixir.bootlin.com/linux/v6.6/source/mm/oom_kill.c#L192)
