diff options
author | Tejun Heo <tj@kernel.org> | 2015-09-25 16:24:27 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2015-09-25 16:25:07 -0400 |
commit | a3e72739b7a7ea225dd11c4096f97123f6427d87 (patch) | |
tree | 60f7c8d79db9e09f2ac8b097928fa0e4034ba631 /kernel/cgroup.c | |
parent | c0522908d22e0b8669e01a7706720996c773e7f4 (diff) |
cgroup: fix too early usage of static_branch_disable()
49d1dc4b8179 ("cgroup: implement static_key based
cgroup_subsys_enabled() and cgroup_subsys_on_dfl()") converted cgroup
enabled test to use static_key; however, cgroup_disable() is called
before static_key subsystem itself is initialized and thus leads to
the following warning when "cgroup_disable=" parameter is specified.
WARNING: CPU: 0 PID: 0 at kernel/jump_label.c:99 static_key_slow_dec+0x44/0x60()
static_key_slow_dec used before call to jump_label_init
...
Call Trace:
[<ffffffff813b18c2>] dump_stack+0x44/0x62
[<ffffffff8108dd52>] warn_slowpath_common+0x82/0xc0
[<ffffffff8108ddec>] warn_slowpath_fmt+0x5c/0x80
[<ffffffff8119c054>] static_key_slow_dec+0x44/0x60
[<ffffffff81d826b6>] cgroup_disable+0xaf/0xd6
[<ffffffff81d5f9de>] unknown_bootoption+0x8c/0x194
[<ffffffff810b0c03>] parse_args+0x273/0x4a0
[<ffffffff81d5fd67>] start_kernel+0x205/0x4b8
...
Fix it by making cgroup_disable() to record the subsystems to disable
in cgroup_disable_mask and moving the actual application to
cgroup_init() which is late enough and where the enabled state is
first used.
Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Andrey Wagin <avagin@gmail.com>
Link: http://lkml.kernel.org/g/CANaxB-yFuS4SA2znSvcKrO9L_CbHciHYW+o9bN8sZJ8eR9FxYA@mail.gmail.com
Fixes: 49d1dc4b81797f88270832b11e9f73809e7e7209
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index f924158a1b65..ae23814b0c6e 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -5124,6 +5124,8 @@ int __init cgroup_init_early(void) | |||
5124 | return 0; | 5124 | return 0; |
5125 | } | 5125 | } |
5126 | 5126 | ||
5127 | static unsigned long cgroup_disable_mask __initdata; | ||
5128 | |||
5127 | /** | 5129 | /** |
5128 | * cgroup_init - cgroup initialization | 5130 | * cgroup_init - cgroup initialization |
5129 | * | 5131 | * |
@@ -5170,8 +5172,12 @@ int __init cgroup_init(void) | |||
5170 | * disabled flag and cftype registration needs kmalloc, | 5172 | * disabled flag and cftype registration needs kmalloc, |
5171 | * both of which aren't available during early_init. | 5173 | * both of which aren't available during early_init. |
5172 | */ | 5174 | */ |
5173 | if (!cgroup_ssid_enabled(ssid)) | 5175 | if (cgroup_disable_mask & (1 << ssid)) { |
5176 | static_branch_disable(cgroup_subsys_enabled_key[ssid]); | ||
5177 | printk(KERN_INFO "Disabling %s control group subsystem\n", | ||
5178 | ss->name); | ||
5174 | continue; | 5179 | continue; |
5180 | } | ||
5175 | 5181 | ||
5176 | cgrp_dfl_root.subsys_mask |= 1 << ss->id; | 5182 | cgrp_dfl_root.subsys_mask |= 1 << ss->id; |
5177 | 5183 | ||
@@ -5595,11 +5601,7 @@ static int __init cgroup_disable(char *str) | |||
5595 | if (strcmp(token, ss->name) && | 5601 | if (strcmp(token, ss->name) && |
5596 | strcmp(token, ss->legacy_name)) | 5602 | strcmp(token, ss->legacy_name)) |
5597 | continue; | 5603 | continue; |
5598 | 5604 | cgroup_disable_mask |= 1 << i; | |
5599 | static_branch_disable(cgroup_subsys_enabled_key[i]); | ||
5600 | printk(KERN_INFO "Disabling %s control group subsystem\n", | ||
5601 | ss->name); | ||
5602 | break; | ||
5603 | } | 5605 | } |
5604 | } | 5606 | } |
5605 | return 1; | 5607 | return 1; |