Skip to main content

Command Palette

Search for a command to run...

OOM Killer 簡短筆記

Updated
2 min read

緣由

滑 hacker news 時被 Out-of-memory victim selection with BPF 砸到,忽然有點好奇 OOM Killer Source Code。

Source Code

https://elixir.bootlin.com/linux/v6.6/source/mm/oom_kill.c#L192

/**
 * 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?

Out-of-memory victim selection with BPF

https://elixir.bootlin.com/linux/v6.6/source/mm/oom_kill.c#L192

More from this blog

簡介 C++ 的 Type Erase (用多型和模板做 Duck Type)

起點 讓我們先從 template 出發:foo 需要一個 callback function。 template<typename Func> void foo(Func callback) { // ... callback(); } 但是這會讓編譯錯誤訊息有點模糊:假如 callback 並不是一個可以呼叫的函數指標,或者並不是一個 callable object ,那編譯器會說錯出在第四行。但是我們都希望,編譯器在呼叫函數時就幫我們指出:這不是 foo 想要的 call...

May 14, 20243 min read

帕秋莉的魔法筆記

45 posts

後端工程師。

不定時張貼一些寫扣時的筆記。