Re: [v11 4/6] mm, oom: introduce memory.oom_group

From: Roman Gushchin
Date: Fri Oct 06 2017 - 08:05:13 EST


On Thu, Oct 05, 2017 at 04:31:04PM +0200, Michal Hocko wrote:
> Btw. here is how I would do the recursive oom badness. The diff is not
> the nicest one because there is some code moving but the resulting code
> is smaller and imho easier to grasp. Only compile tested though

Thanks!

I'm not against this approach, and maybe it can lead to a better code,
but the version you sent is just not there yet.

There are some problems with it:

1) If there are nested cgroups with oom_group set, you will calculate
a badness multiple times, and rely on the fact, that top memcg will
become the largest score. It can be optimized, of course, but it's
additional code.

2) cgroup_has_tasks() probably requires additional locking.
Maybe it's ok to read nr_populated_csets without explicit locking,
but it's not obvious for me.

3) Returning -1 from memcg_oom_badness() if eligible is equal to 0
is suspicious.

Right now your version has exactly the same amount of code
(skipping comments). I assume, this approach just requires some additional
thinking/rework.

Anyway, thank you for sharing this!

> ---
> diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
> index 085056e562b1..9cdba4682198 100644
> --- a/include/linux/cgroup.h
> +++ b/include/linux/cgroup.h
> @@ -122,6 +122,11 @@ void cgroup_free(struct task_struct *p);
> int cgroup_init_early(void);
> int cgroup_init(void);
>
> +static bool cgroup_has_tasks(struct cgroup *cgrp)
> +{
> + return cgrp->nr_populated_csets;
> +}
> +
> /*
> * Iteration helpers and macros.
> */
> diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
> index 8dacf73ad57e..a2dd7e3ffe23 100644
> --- a/kernel/cgroup/cgroup.c
> +++ b/kernel/cgroup/cgroup.c
> @@ -319,11 +319,6 @@ static void cgroup_idr_remove(struct idr *idr, int id)
> spin_unlock_bh(&cgroup_idr_lock);
> }
>
> -static bool cgroup_has_tasks(struct cgroup *cgrp)
> -{
> - return cgrp->nr_populated_csets;
> -}
> -
> bool cgroup_is_threaded(struct cgroup *cgrp)
> {
> return cgrp->dom_cgrp != cgrp;