Skip to content

Commit 55d3b85

Browse files
Tahsin ErdoganMichal Hocko
authored andcommitted
mm: do not call mem_cgroup_free() from within mem_cgroup_alloc()
mem_cgroup_free() indirectly calls wb_domain_exit() which is not prepared to deal with a struct wb_domain object that hasn't executed wb_domain_init(). For instance, the following warning message is printed by lockdep if alloc_percpu() fails in mem_cgroup_alloc(): INFO: trying to register non-static key. the code is fine but needs lockdep annotation. turning off the locking correctness validator. CPU: 1 PID: 1950 Comm: mkdir Not tainted 4.10.0+ torvalds#151 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Call Trace: dump_stack+0x67/0x99 register_lock_class+0x36d/0x540 __lock_acquire+0x7f/0x1a30 ? irq_work_queue+0x73/0x90 ? wake_up_klogd+0x36/0x40 ? console_unlock+0x45d/0x540 ? vprintk_emit+0x211/0x2e0 lock_acquire+0xcc/0x200 ? try_to_del_timer_sync+0x60/0x60 del_timer_sync+0x3c/0xc0 ? try_to_del_timer_sync+0x60/0x60 wb_domain_exit+0x14/0x20 mem_cgroup_free+0x14/0x40 mem_cgroup_css_alloc+0x3f9/0x620 cgroup_apply_control_enable+0x190/0x390 cgroup_mkdir+0x290/0x3d0 kernfs_iop_mkdir+0x58/0x80 vfs_mkdir+0x10e/0x1a0 SyS_mkdirat+0xa8/0xd0 SyS_mkdir+0x14/0x20 entry_SYSCALL_64_fastpath+0x18/0xad Add __mem_cgroup_free() which skips wb_domain_exit(). This is used by both mem_cgroup_free() and mem_cgroup_alloc() clean up. Fixes: 0b8f73e ("mm: memcontrol: clean up alloc, online, offline, free functions") Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Tahsin Erdogan <[email protected]> Acked-by: Michal Hocko <[email protected]> Cc: Johannes Weiner <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 960b0dc commit 55d3b85

File tree

1 file changed

+8
-3
lines changed

1 file changed

+8
-3
lines changed

mm/memcontrol.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4142,17 +4142,22 @@ static void free_mem_cgroup_per_node_info(struct mem_cgroup *memcg, int node)
41424142
kfree(memcg->nodeinfo[node]);
41434143
}
41444144

4145-
static void mem_cgroup_free(struct mem_cgroup *memcg)
4145+
static void __mem_cgroup_free(struct mem_cgroup *memcg)
41464146
{
41474147
int node;
41484148

4149-
memcg_wb_domain_exit(memcg);
41504149
for_each_node(node)
41514150
free_mem_cgroup_per_node_info(memcg, node);
41524151
free_percpu(memcg->stat);
41534152
kfree(memcg);
41544153
}
41554154

4155+
static void mem_cgroup_free(struct mem_cgroup *memcg)
4156+
{
4157+
memcg_wb_domain_exit(memcg);
4158+
__mem_cgroup_free(memcg);
4159+
}
4160+
41564161
static struct mem_cgroup *mem_cgroup_alloc(void)
41574162
{
41584163
struct mem_cgroup *memcg;
@@ -4203,7 +4208,7 @@ static struct mem_cgroup *mem_cgroup_alloc(void)
42034208
fail:
42044209
if (memcg->id.id > 0)
42054210
idr_remove(&mem_cgroup_idr, memcg->id.id);
4206-
mem_cgroup_free(memcg);
4211+
__mem_cgroup_free(memcg);
42074212
return NULL;
42084213
}
42094214

0 commit comments

Comments
 (0)