Re: Improving OOM killer

Lubos Lunak
2010-02-03T22:55:10Z

On Wednesday 03 of February 2010, David Rientjes wrote:
> My rewrite for the badness() heuristic is centered on the idea that scores
> should range from 0 to 1000, 0 meaning "never kill this task" and 1000
> meaning "kill this task first." The baseline for a thread, p, may be
> something like this:
>
> unsigned int badness(struct task_struct *p,
> unsigned long totalram)
> {
> struct task_struct *child;
> struct mm_struct *mm;
> int forkcount = 0;
> long points;
>
> task_lock(p);
> mm = p->mm;
> if (!mm) {
> task_unlock(p);
> return 0;
> }
> points = (get_mm_rss(mm) +
> get_mm_counter(mm, MM_SWAPENTS)) * 1000 /
> totalram;
> task_unlock(p);
>
> list_for_each_entry(child, &p->children, sibling)
> /* No lock, child->mm won't be dereferenced */
> if (child->mm && child->mm != mm)
> forkcount++;
>
> /* Forkbombs get penalized 10% of available RAM */
> if (forkcount > 500)
> points += 100;

As far as I'm concerned, this is a huge improvement over the current code
(and, incidentally :), quite close to what I originally wanted). I'd be
willing to test it in few real-world desktop cases if you provide a patch.

> /*
> * /proc/pid/oom_adj ranges from -1000 to +1000 to either
> * completely disable oom killing or always prefer it.
> */
> points += p->signal->oom_adj;

This changes semantics of oom_adj, but given that I expect the above to make
oom_adj unnecessary on the desktop for the normal cases, I don't really mind.

--
Lubos Lunak
openSUSE Boosters team, KDE developer
l.lunak@suse.cz , l.lunak@kde.org