Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1711530 > unrolled thread
| Started by | David Rientjes <rientjes@google.com> |
|---|---|
| First post | 2017-08-15 00:50 +0200 |
| Last post | 2017-08-21 03:00 +0200 |
| Articles | 4 — 2 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [v5 2/4] mm, oom: cgroup-aware OOM killer David Rientjes <rientjes@google.com> - 2017-08-15 00:50 +0200
Re: [v5 2/4] mm, oom: cgroup-aware OOM killer Aleksa Sarai <asarai@suse.de> - 2017-08-15 14:30 +0200
Re: [v5 2/4] mm, oom: cgroup-aware OOM killer David Rientjes <rientjes@google.com> - 2017-08-15 23:50 +0200
Re: [v5 2/4] mm, oom: cgroup-aware OOM killer David Rientjes <rientjes@google.com> - 2017-08-21 03:00 +0200
| From | David Rientjes <rientjes@google.com> |
|---|---|
| Date | 2017-08-15 00:50 +0200 |
| Subject | Re: [v5 2/4] mm, oom: cgroup-aware OOM killer |
| Message-ID | <uewlj-1wb-5@gated-at.bofh.it> |
On Mon, 14 Aug 2017, Roman Gushchin wrote:
> diff --git a/include/linux/oom.h b/include/linux/oom.h
> index 8a266e2be5a6..b7ec3bd441be 100644
> --- a/include/linux/oom.h
> +++ b/include/linux/oom.h
> @@ -39,6 +39,7 @@ struct oom_control {
> unsigned long totalpages;
> struct task_struct *chosen;
> unsigned long chosen_points;
> + struct mem_cgroup *chosen_memcg;
> };
>
> extern struct mutex oom_lock;
> @@ -79,6 +80,8 @@ extern void oom_killer_enable(void);
>
> extern struct task_struct *find_lock_task_mm(struct task_struct *p);
>
> +extern int oom_evaluate_task(struct task_struct *task, void *arg);
> +
> /* sysctls */
> extern int sysctl_oom_dump_tasks;
> extern int sysctl_oom_kill_allocating_task;
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index df6f63ee95d6..0b81dc55c6ac 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -2639,6 +2639,181 @@ static inline bool memcg_has_children(struct mem_cgroup *memcg)
> return ret;
> }
>
> +static long memcg_oom_badness(struct mem_cgroup *memcg,
> + const nodemask_t *nodemask)
> +{
> + long points = 0;
> + int nid;
> +
> + for_each_node_state(nid, N_MEMORY) {
> + if (nodemask && !node_isset(nid, *nodemask))
> + continue;
> +
> + points += mem_cgroup_node_nr_lru_pages(memcg, nid,
> + LRU_ALL_ANON | BIT(LRU_UNEVICTABLE));
> + }
> +
> + points += memcg_page_state(memcg, MEMCG_KERNEL_STACK_KB) /
> + (PAGE_SIZE / 1024);
> + points += memcg_page_state(memcg, NR_SLAB_UNRECLAIMABLE);
> + points += memcg_page_state(memcg, MEMCG_SOCK);
> + points += memcg_page_state(memcg, MEMCG_SWAP);
> +
> + return points;
> +}
I'm indifferent to the memcg evaluation criteria used to determine which
memcg should be selected over others with the same priority, others may
feel differently.
> +
> +static long oom_evaluate_memcg(struct mem_cgroup *memcg,
> + const nodemask_t *nodemask)
> +{
> + struct css_task_iter it;
> + struct task_struct *task;
> + int elegible = 0;
> +
> + css_task_iter_start(&memcg->css, 0, &it);
> + while ((task = css_task_iter_next(&it))) {
> + /*
> + * If there are no tasks, or all tasks have oom_score_adj set
> + * to OOM_SCORE_ADJ_MIN and oom_kill_all_tasks is not set,
> + * don't select this memory cgroup.
> + */
> + if (!elegible &&
> + (memcg->oom_kill_all_tasks ||
> + task->signal->oom_score_adj != OOM_SCORE_ADJ_MIN))
> + elegible = 1;
I'm curious about the decision made in this conditional and how
oom_kill_memcg_member() ignores task->signal->oom_score_adj. It means
that memory.oom_kill_all_tasks overrides /proc/pid/oom_score_adj if it
should otherwise be disabled.
It's undocumented in the changelog, but I'm questioning whether it's the
right decision. Doesn't it make sense to kill all tasks that are not oom
disabled, and allow the user to still protect certain processes by their
/proc/pid/oom_score_adj setting? Otherwise, there's no way to do that
protection without a sibling memcg and its own reservation of memory. I'm
thinking about a process that governs jobs inside the memcg and if there
is an oom kill, it wants to do logging and any cleanup necessary before
exiting itself. It seems like a powerful combination if coupled with oom
notification.
Also, s/elegible/eligible/
Otherwise, looks good!
[toc] | [next] | [standalone]
| From | Aleksa Sarai <asarai@suse.de> |
|---|---|
| Date | 2017-08-15 14:30 +0200 |
| Message-ID | <ueJ8S-1g7-17@gated-at.bofh.it> |
| In reply to | #1711530 |
On 08/15/2017 10:15 PM, Roman Gushchin wrote: > Generally, oom_score_adj should have a meaning only on a cgroup level, > so extending it to the system level doesn't sound as a good idea. But wasn't the original purpose of oom_score (and oom_score_adj) to work on a system level, aka "normal" OOM? Is there some peculiarity about memcg OOM that I'm missing? -- Aleksa Sarai Software Engineer (Containers) SUSE Linux GmbH https://www.cyphar.com/
[toc] | [prev] | [next] | [standalone]
| From | David Rientjes <rientjes@google.com> |
|---|---|
| Date | 2017-08-15 23:50 +0200 |
| Message-ID | <ueRSN-6La-9@gated-at.bofh.it> |
| In reply to | #1711530 |
On Tue, 15 Aug 2017, Roman Gushchin wrote: > > I'm curious about the decision made in this conditional and how > > oom_kill_memcg_member() ignores task->signal->oom_score_adj. It means > > that memory.oom_kill_all_tasks overrides /proc/pid/oom_score_adj if it > > should otherwise be disabled. > > > > It's undocumented in the changelog, but I'm questioning whether it's the > > right decision. Doesn't it make sense to kill all tasks that are not oom > > disabled, and allow the user to still protect certain processes by their > > /proc/pid/oom_score_adj setting? Otherwise, there's no way to do that > > protection without a sibling memcg and its own reservation of memory. I'm > > thinking about a process that governs jobs inside the memcg and if there > > is an oom kill, it wants to do logging and any cleanup necessary before > > exiting itself. It seems like a powerful combination if coupled with oom > > notification. > > Good question! > I think, that an ability to override any oom_score_adj value and get all tasks > killed is more important, than an ability to kill all processes with some > exceptions. > I'm disagreeing because getting all tasks killed is not necessarily something that only the kernel can do. If all processes are oom disabled, that's a configuration issue done by sysadmin and the kernel should decide to kill the next largest memory cgroup or lower priority memory cgroup. It's not killing things like sshd that intentionally oom disable themselves. You could argue that having an oom disabled process attached to these memcgs in the first place is also a configuration issue, but the problem is that in cgroup v2 with a restriction on processes only being attached at the leaf cgroups that there is no competition for memory in this case. I must assign memory resources to that sshd, or "Activity Manager" described by the cgroup v1 documentation, just to prevent it from being killed. I think the latter of what you describe, killing all processes with some exceptions, is actually quite powerful. I can guarantee that processes that set themselves to oom disabled are really oom disabled and I don't need to work around that in the cgroup hierarchy only because of this caveat. I can also oom disable my Activity Manger that wants to wait on oom notification and collect the oom kill logs, raise notifications, and perhaps restart the process that it manages. > In your example someone still needs to look after the remaining process, > and kill it after some timeout, if it will not quit by itself, right? > No, it can restart the process that was oom killed; or it can be sshd and I can still ssh into my machine. > The special treatment of the -1000 value (without oom_kill_all_tasks) > is required only to not to break the existing setups. > I think as a general principle that allowing an oom disabled process to be oom killed is incorrect and if you really do want these to be killed, then (1) either your oom_score_adj is already wrong or (2) you can wait on oom notification and exit.
[toc] | [prev] | [next] | [standalone]
| From | David Rientjes <rientjes@google.com> |
|---|---|
| Date | 2017-08-21 03:00 +0200 |
| Message-ID | <ugJeq-5Fm-5@gated-at.bofh.it> |
| In reply to | #1712489 |
On Wed, 16 Aug 2017, Roman Gushchin wrote: > It's natural to expect that inside a container there are their own sshd, > "activity manager" or some other stuff, which can play with oom_score_adj. > If it can override the upper cgroup-level settings, the whole delegation model > is broken. > I don't think any delegation model related to core cgroups or memory cgroup is broken, I think it's based on how memory.oom_kill_all_tasks is defined. It could very well behave as memory.oom_kill_all_eligible_tasks when enacted upon. > You can think about the oom_kill_all_tasks like the panic_on_oom, > but on a cgroup level. It should _guarantee_, that in case of oom > the whole cgroup will be destroyed completely, and will not remain > in a non-consistent state. > Only CAP_SYS_ADMIN has this ability to set /proc/pid/oom_score_adj to OOM_SCORE_ADJ_MIN, so it preserves the ability to change that setting, if needed, when it sets memory.oom_kill_all_tasks. If a user gains permissions to change memory.oom_kill_all_tasks, I disagree it should override the CAP_SYS_ADMIN setting of /proc/pid/oom_score_adj. I would prefer not to exclude oom disabled processes to their own sibling cgroups because they would require their own reservation with cgroup v2 and it makes the single hierarchy model much more difficult to arrange alongside cpusets, for example. > The model you're describing is based on a trust given to these oom-unkillable > processes on system level. But we can't really trust some unknown processes > inside a cgroup that they will be able to do some useful work and finish > in a reasonable time; especially in case of a global memory shortage. Yes, we prefer to panic instead of sshd, for example, being oom killed. We trust that sshd, as well as our own activity manager and security daemons are trusted to do useful work and that we never want the kernel to do this. I'm not sure why you are describing processes that CAP_SYS_ADMIN has set to be oom disabled as unknown processes. I'd be interested in hearing the opinions of others related to a per-memcg knob being allowed to override the setting of the sysadmin.
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web