Skip to content

Commit 8de15e9

Browse files
rgushchintorvalds
authored andcommitted
mm: memcg: link page counters to root if use_hierarchy is false
Richard reported a warning which can be reproduced by running the LTP madvise6 test (cgroup v1 in the non-hierarchical mode should be used): WARNING: CPU: 0 PID: 12 at mm/page_counter.c:57 page_counter_uncharge (mm/page_counter.c:57 mm/page_counter.c:50 mm/page_counter.c:156) Modules linked in: CPU: 0 PID: 12 Comm: kworker/0:1 Not tainted 5.9.0-rc7-22-default #77 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-48-gd9c812d-rebuilt.opensuse.org 04/01/2014 Workqueue: events drain_local_stock RIP: 0010:page_counter_uncharge (mm/page_counter.c:57 mm/page_counter.c:50 mm/page_counter.c:156) Call Trace: __memcg_kmem_uncharge (mm/memcontrol.c:3022) drain_obj_stock (./include/linux/rcupdate.h:689 mm/memcontrol.c:3114) drain_local_stock (mm/memcontrol.c:2255) process_one_work (./arch/x86/include/asm/jump_label.h:25 ./include/linux/jump_label.h:200 ./include/trace/events/workqueue.h:108 kernel/workqueue.c:2274) worker_thread (./include/linux/list.h:282 kernel/workqueue.c:2416) kthread (kernel/kthread.c:292) ret_from_fork (arch/x86/entry/entry_64.S:300) The problem occurs because in the non-hierarchical mode non-root page counters are not linked to root page counters, so the charge is not propagated to the root memory cgroup. After the removal of the original memory cgroup and reparenting of the object cgroup, the root cgroup might be uncharged by draining a objcg stock, for example. It leads to an eventual underflow of the charge and triggers a warning. Fix it by linking all page counters to corresponding root page counters in the non-hierarchical mode. Please note, that in the non-hierarchical mode all objcgs are always reparented to the root memory cgroup, even if the hierarchy has more than 1 level. This patch doesn't change it. The patch also doesn't affect how the hierarchical mode is working, which is the only sane and truly supported mode now. Thanks to Richard for reporting, debugging and providing an alternative version of the fix! Fixes: bf4f059 ("mm: memcg/slab: obj_cgroup API") Reported-by: <ltp@lists.linux.it> Signed-off-by: Roman Gushchin <guro@fb.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Reviewed-by: Shakeel Butt <shakeelb@google.com> Reviewed-by: Michal Koutný <mkoutny@suse.com> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Cc: Michal Hocko <mhocko@kernel.org> Cc: <stable@vger.kernel.org> Link: https://lkml.kernel.org/r/20201026231326.3212225-1-guro@fb.com Debugged-by: Richard Palethorpe <rpalethorpe@suse.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 7de2e9f commit 8de15e9

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

mm/memcontrol.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5345,17 +5345,22 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
53455345
memcg->swappiness = mem_cgroup_swappiness(parent);
53465346
memcg->oom_kill_disable = parent->oom_kill_disable;
53475347
}
5348-
if (parent && parent->use_hierarchy) {
5348+
if (!parent) {
5349+
page_counter_init(&memcg->memory, NULL);
5350+
page_counter_init(&memcg->swap, NULL);
5351+
page_counter_init(&memcg->kmem, NULL);
5352+
page_counter_init(&memcg->tcpmem, NULL);
5353+
} else if (parent->use_hierarchy) {
53495354
memcg->use_hierarchy = true;
53505355
page_counter_init(&memcg->memory, &parent->memory);
53515356
page_counter_init(&memcg->swap, &parent->swap);
53525357
page_counter_init(&memcg->kmem, &parent->kmem);
53535358
page_counter_init(&memcg->tcpmem, &parent->tcpmem);
53545359
} else {
5355-
page_counter_init(&memcg->memory, NULL);
5356-
page_counter_init(&memcg->swap, NULL);
5357-
page_counter_init(&memcg->kmem, NULL);
5358-
page_counter_init(&memcg->tcpmem, NULL);
5360+
page_counter_init(&memcg->memory, &root_mem_cgroup->memory);
5361+
page_counter_init(&memcg->swap, &root_mem_cgroup->swap);
5362+
page_counter_init(&memcg->kmem, &root_mem_cgroup->kmem);
5363+
page_counter_init(&memcg->tcpmem, &root_mem_cgroup->tcpmem);
53595364
/*
53605365
* Deeper hierachy with use_hierarchy == false doesn't make
53615366
* much sense so let cgroup subsystem know about this

0 commit comments

Comments
 (0)