Re: [RFC 3/3] oom: Do not try to sacrifice small children

From: David Rientjes
Date: Tue Jan 12 2016 - 19:51:49 EST


On Tue, 12 Jan 2016, Michal Hocko wrote:

> diff --git a/mm/oom_kill.c b/mm/oom_kill.c
> index 8bca0b1e97f7..b5c0021c6462 100644
> --- a/mm/oom_kill.c
> +++ b/mm/oom_kill.c
> @@ -721,8 +721,16 @@ try_to_sacrifice_child(struct oom_control *oc, struct task_struct *victim,
> if (!child_victim)
> goto out;
>
> - put_task_struct(victim);
> - victim = child_victim;
> + /*
> + * Protecting the parent makes sense only if killing the child
> + * would release at least some memory (at least 1MB).
> + */
> + if (K(victim_points) >= 1024) {
> + put_task_struct(victim);
> + victim = child_victim;
> + } else {
> + put_task_struct(child_victim);
> + }
>
> out:
> return victim;

The purpose of sacrificing a child has always been to prevent a process
that has been running with a substantial amount of work done from being
terminated and losing all that work if it can be avoided. This happens a
lot: imagine a long-living front end client forking a child which simply
collects stats and malloc information at a regular intervals and writes
them out to disk or over the network. These processes may be quite small,
and we're willing to happily sacrifice them if it will save the parent.
This was, and still is, the intent of the sacrifice in the first place.

We must be able to deal with oom victims that are very small, since
userspace has complete control in prioritizing these processes in the
first place.