[PATCH v3 OLK-6.6 0/5] Reuse SUBSYS for xcu and freezer to preserve KABI
Reuse SUBSYS for xcu and freezer to preserve KABI Liu Kai (5): xSched/cgroup: reuse SUBSYS for xcu and freezer to preserve KABI xSched/cgroup: make xcu.stat invisible at root cgroup cgroup: sync CGROUP_SUBSYS_COUNT limit with upstream to 16 xSched: enable CONFIG_CGROUP_XCU and CONFIG_XCU_SCHED_CFS in arm64/x86 defconfig xSched: update xSched manual for xcu cmdline enable option Documentation/scheduler/xsched.md | 6 +- arch/arm64/configs/openeuler_defconfig | 3 +- arch/x86/configs/openeuler_defconfig | 3 +- include/linux/cgroup_subsys.h | 8 +- include/linux/freezer.h | 24 ++++ kernel/cgroup/cgroup.c | 2 +- kernel/cgroup/legacy_freezer.c | 25 +++- kernel/xsched/cgroup.c | 174 +++++++++++++++++++++++-- 8 files changed, 217 insertions(+), 28 deletions(-) -- 2.34.1
hulk inclusion category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/8424 ---------------------------------------- Adding and enabling a new subsystem would increment CGROUP_SUBSYS_COUNT, which leads to Kernel ABI (KABI) breakage. This patch introduces a mechanism to share the same SUBSYS(xcu) slot between the 'xcu' and 'freezer' subsystems. Since 'xcu' is a cgroup v2-only controller and 'freezer' is a cgroup v1-only controller, they are mutually exclusive at runtime. We introduce a new kernel command line parameter, "xcu", to control this behavior dynamically. This approach allows us to enable both CONFIG_CGROUP_XCU and CONFIG_CGROUP_FREEZER simultaneously without exceeding the subsystem limit. The behavior based on the "xcu" cmdline parameter is as follows: 1. xcu=disable, cgroup v1: - The legacy 'frezzer' subsystem is active and functional. - The 'xcu' subsystem remains dormant. 2. xcu=enable, cgroup v1: - The 'freezer' subsystem is effectively disabled/blocked. - (Note: 'xcu' is not usable in v1 mode as it is v2-only). 3. xcu=disable, cgroup v2: - The 'xcu' subsystem is not enabled in the hierarchy. 4. xcu=enable, cgroup v2: - The 'xcu' subsystem is active and usable. - The 'freezer' logic is bypassed. This ensures backward compatibility for v1 users while enabling the new functionality for v2, all within the constraints of the kernel subsystem limit. Fixes: 43bbefc53356 ("xsched: Add XCU control group implementation and its backend in xsched CFS") Signed-off-by: Liu Kai <liukai284@huawei.com> --- include/linux/cgroup_subsys.h | 8 +- include/linux/freezer.h | 24 +++++ kernel/cgroup/legacy_freezer.c | 25 +++-- kernel/xsched/cgroup.c | 173 +++++++++++++++++++++++++++++++-- 4 files changed, 208 insertions(+), 22 deletions(-) diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h index e65ae90946c2..9ee14c9cab33 100644 --- a/include/linux/cgroup_subsys.h +++ b/include/linux/cgroup_subsys.h @@ -33,7 +33,9 @@ SUBSYS(memory) SUBSYS(devices) #endif -#if IS_ENABLED(CONFIG_CGROUP_FREEZER) +#if IS_ENABLED(CONFIG_CGROUP_XCU) +SUBSYS(xcu) +#elif IS_ENABLED(CONFIG_CGROUP_FREEZER) SUBSYS(freezer) #endif @@ -61,10 +63,6 @@ SUBSYS(pids) SUBSYS(rdma) #endif -#if IS_ENABLED(CONFIG_CGROUP_XCU) -SUBSYS(xcu) -#endif - #if IS_ENABLED(CONFIG_CGROUP_MISC) SUBSYS(misc) #endif diff --git a/include/linux/freezer.h b/include/linux/freezer.h index b303472255be..0c7a6da03d43 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h @@ -10,6 +10,10 @@ #include <linux/atomic.h> #include <linux/jump_label.h> +#ifdef CONFIG_CGROUP_XCU +#include <linux/cgroup-defs.h> +#endif + #ifdef CONFIG_FREEZER DECLARE_STATIC_KEY_FALSE(freezer_active); @@ -87,4 +91,24 @@ static inline void set_freezable(void) {} #endif /* !CONFIG_FREEZER */ +/* + * When CONFIG_CGROUP_XCU is enabled, freezer_cgrp_subsys and xcu_cgrp_subsys + * share the same set of cgroup_subsys hook functions. Consequently, the hooks for + * freezer_cgrp_subsys must be exposed externally to allow linkage with the XCU + * cgroup_subsys. + * + */ +#ifdef CONFIG_CGROUP_XCU +#define freezer_cgrp_id xcu_cgrp_id + +extern struct cftype files[]; +struct cgroup_subsys_state * +freezer_css_alloc(struct cgroup_subsys_state *parent_css); +int freezer_css_online(struct cgroup_subsys_state *css); +void freezer_css_offline(struct cgroup_subsys_state *css); +void freezer_css_free(struct cgroup_subsys_state *css); +void freezer_attach(struct cgroup_taskset *tset); +void freezer_fork(struct task_struct *task); +#endif /* CONFIG_CGROUP_XCU */ + #endif /* FREEZER_H_INCLUDED */ diff --git a/kernel/cgroup/legacy_freezer.c b/kernel/cgroup/legacy_freezer.c index bee2f9ea5e4a..9ef242b73947 100644 --- a/kernel/cgroup/legacy_freezer.c +++ b/kernel/cgroup/legacy_freezer.c @@ -24,6 +24,17 @@ #include <linux/mutex.h> #include <linux/cpu.h> +/* + * The STATIC macro is used to handle this conditional visibility: + * - Enabled: interfaces are defined as non-static (exported). + * - Disabled: interfaces remain static (file-local). + */ +#ifdef CONFIG_CGROUP_XCU +#define STATIC +#else +#define STATIC static +#endif + /* * A cgroup is freezing if any FREEZING flags are set. FREEZING_SELF is * set if "FROZEN" is written to freezer.state cgroupfs file, and cleared @@ -83,7 +94,7 @@ static const char *freezer_state_strs(unsigned int state) return "THAWED"; }; -static struct cgroup_subsys_state * +STATIC struct cgroup_subsys_state * freezer_css_alloc(struct cgroup_subsys_state *parent_css) { struct freezer *freezer; @@ -103,7 +114,7 @@ freezer_css_alloc(struct cgroup_subsys_state *parent_css) * parent's freezing state while holding both parent's and our * freezer->lock. */ -static int freezer_css_online(struct cgroup_subsys_state *css) +STATIC int freezer_css_online(struct cgroup_subsys_state *css) { struct freezer *freezer = css_freezer(css); struct freezer *parent = parent_freezer(freezer); @@ -130,7 +141,7 @@ static int freezer_css_online(struct cgroup_subsys_state *css) * @css is going away. Mark it dead and decrement system_freezing_count if * it was holding one. */ -static void freezer_css_offline(struct cgroup_subsys_state *css) +STATIC void freezer_css_offline(struct cgroup_subsys_state *css) { struct freezer *freezer = css_freezer(css); @@ -146,7 +157,7 @@ static void freezer_css_offline(struct cgroup_subsys_state *css) cpus_read_unlock(); } -static void freezer_css_free(struct cgroup_subsys_state *css) +STATIC void freezer_css_free(struct cgroup_subsys_state *css) { kfree(css_freezer(css)); } @@ -160,7 +171,7 @@ static void freezer_css_free(struct cgroup_subsys_state *css) * @freezer->lock. freezer_attach() makes the new tasks conform to the * current state and all following state changes can see the new tasks. */ -static void freezer_attach(struct cgroup_taskset *tset) +STATIC void freezer_attach(struct cgroup_taskset *tset) { struct task_struct *task; struct cgroup_subsys_state *new_css; @@ -205,7 +216,7 @@ static void freezer_attach(struct cgroup_taskset *tset) * to do anything as freezer_attach() will put @task into the appropriate * state. */ -static void freezer_fork(struct task_struct *task) +STATIC void freezer_fork(struct task_struct *task) { struct freezer *freezer; @@ -449,7 +460,7 @@ static u64 freezer_parent_freezing_read(struct cgroup_subsys_state *css, return (bool)(freezer->state & CGROUP_FREEZING_PARENT); } -static struct cftype files[] = { +STATIC struct cftype files[] = { { .name = "state", .flags = CFTYPE_NOT_ON_ROOT, diff --git a/kernel/xsched/cgroup.c b/kernel/xsched/cgroup.c index 73f044475939..fdaad68b12a6 100644 --- a/kernel/xsched/cgroup.c +++ b/kernel/xsched/cgroup.c @@ -21,6 +21,10 @@ #include <linux/xsched.h> #include <linux/delay.h> +#ifdef CONFIG_CGROUP_FREEZER +#include <linux/freezer.h> +#endif + static struct xsched_group root_xsched_group; struct xsched_group *root_xcg = &root_xsched_group; @@ -39,6 +43,61 @@ static const char xcu_sched_name[XSCHED_TYPE_NUM][SCHED_CLASS_MAX_LENGTH] = { [XSCHED_TYPE_CFS] = "cfs" }; +/* + * xcu_mode: + * 0 = disable (freezer cgroup) + * 1 = enable (xcu cgroup) + */ +static int xcu_mode; + +/** + * Parse the "xcu=" kernel command line parameter. + * + * Usage: + * xcu=enable → enable xcu_cgrp_subsys + * Otherwise → enable freezer_cgrp_subsys + * + * Returns: + * 1 (handled), 0 (not handled) + */ +static int __init xcu_setup(char *str) +{ + if (!str) + return 0; + + if (strcmp(str, "enable") == 0) + xcu_mode = 1; + + return 1; +} +__setup("xcu=", xcu_setup); + +static bool xcu_cgroup_enabled(void) +{ + return xcu_mode; +} + +/** + * xcu_cgroup_check_compat - Verify XCU mode matches the cgroup hierarchy version. + * + * Checks if the current xcu_mode aligns with the cgroup subsystem's default + * hierarchy status. + * + * IMPORTANT: cgroup_subsys_on_dfl() only returns a valid version indicator + * after the cgroup filesystem has been mounted at the root node. Calling + * this function prior to mount may yield incorrect results. + * + * Return: true if compatible, false otherwise (with a warning logged). + */ +static bool xcu_cgroup_check_compat(void) +{ + if (xcu_mode != cgroup_subsys_on_dfl(xcu_cgrp_subsys)) { + XSCHED_WARN("XCU cgrp is incompatible with the cgroup version\n"); + return false; + } + return true; +} + static int xcu_cg_set_file_show(struct xsched_group *xg, int sched_class) { if (!xg) { @@ -753,17 +812,111 @@ static struct cftype xcu_cg_files[] = { {} /* terminate */ }; +static struct cgroup_subsys_state * +xcu_freezer_compat_css_alloc(struct cgroup_subsys_state *parent_css) +{ + /* Skip allocation if XCU cmdline mismatches the cgroup version. */ + if (parent_css && !xcu_cgroup_check_compat()) + return ERR_PTR(-EPERM); + + if (xcu_cgroup_enabled()) + return xcu_css_alloc(parent_css); + +#ifdef CONFIG_CGROUP_FREEZER + return freezer_css_alloc(parent_css); +#else /* CONFIG_CGROUP_FREEZER=n xcu=disable cgroup=v1 */ + if (!parent_css) + return &root_xsched_group.css; + else + return ERR_PTR(-EPERM); +#endif +} + +static int xcu_freezer_compat_css_online(struct cgroup_subsys_state *css) +{ + if (xcu_cgroup_enabled()) + return xcu_css_online(css); + +#ifdef CONFIG_CGROUP_FREEZER + return freezer_css_online(css); +#else + return 0; +#endif +} + +static void xcu_freezer_compat_css_offline(struct cgroup_subsys_state *css) +{ + if (xcu_cgroup_enabled()) + return xcu_css_offline(css); + +#ifdef CONFIG_CGROUP_FREEZER + return freezer_css_offline(css); +#endif +} + +static void xcu_freezer_compat_css_released(struct cgroup_subsys_state *css) +{ + if (xcu_cgroup_enabled()) + return xcu_css_released(css); +} + +static void xcu_freezer_compat_css_free(struct cgroup_subsys_state *css) +{ + if (xcu_cgroup_enabled()) + return xcu_css_free(css); + +#ifdef CONFIG_CGROUP_FREEZER + return freezer_css_free(css); +#endif +} + +static int xcu_freezer_compat_can_attach(struct cgroup_taskset *tset) +{ + if (xcu_cgroup_enabled()) + return xcu_can_attach(tset); + + return 0; +} + +static void xcu_freezer_compat_cancel_attach(struct cgroup_taskset *tset) +{ + if (xcu_cgroup_enabled()) + return xcu_cancel_attach(tset); +} + +static void xcu_freezer_compat_attach(struct cgroup_taskset *tset) +{ + if (xcu_cgroup_enabled()) + return xcu_attach(tset); + +#ifdef CONFIG_CGROUP_FREEZER + return freezer_attach(tset); +#endif +} + +static void xcu_freezer_compat_fork(struct task_struct *task) +{ +#ifdef CONFIG_CGROUP_FREEZER + if (!xcu_cgroup_enabled()) + return freezer_fork(task); +#endif +} + struct cgroup_subsys xcu_cgrp_subsys = { - .css_alloc = xcu_css_alloc, - .css_online = xcu_css_online, - .css_offline = xcu_css_offline, - .css_released = xcu_css_released, - .css_free = xcu_css_free, - .can_attach = xcu_can_attach, - .cancel_attach = xcu_cancel_attach, - .attach = xcu_attach, + .css_alloc = xcu_freezer_compat_css_alloc, + .css_online = xcu_freezer_compat_css_online, + .css_offline = xcu_freezer_compat_css_offline, + .css_released = xcu_freezer_compat_css_released, + .css_free = xcu_freezer_compat_css_free, + .can_attach = xcu_freezer_compat_can_attach, + .cancel_attach = xcu_freezer_compat_cancel_attach, + .attach = xcu_freezer_compat_attach, + .fork = xcu_freezer_compat_fork, .dfl_cftypes = xcu_cg_files, +#ifdef CONFIG_CGROUP_FREEZER + .legacy_cftypes = files, + .legacy_name = "freezer", +#else .legacy_cftypes = xcu_cg_files, - .early_init = false, - .threaded = true +#endif }; -- 2.34.1
hulk inclusion category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/8424 ---------------------------------------- Set the CFTYPE_NOT_ON_ROOT flag for the xcu.stat file. The root cgroup is by default assigned to the RT scheduling class. Since the xcu interface is unavailable for RT tasks, exposing this file at the root level is illogical. Hide the interface at the root cgroup to prevent user confusion and invalid access attempts. Fixes: 43bbefc53356 ("xsched: Add XCU control group implementation and its backend in xsched CFS") Signed-off-by: Liu Kai <liukai284@huawei.com> --- kernel/xsched/cgroup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/xsched/cgroup.c b/kernel/xsched/cgroup.c index fdaad68b12a6..f8f31a24d1f9 100644 --- a/kernel/xsched/cgroup.c +++ b/kernel/xsched/cgroup.c @@ -801,6 +801,7 @@ static struct cftype xcu_cg_files[] = { }, { .name = "stat", + .flags = CFTYPE_NOT_ON_ROOT, .seq_show = xcu_stat, }, { -- 2.34.1
hulk inclusion category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/8424 ---------------------------------------- Adjust the static assertion limit from 17 to 16 to align with the community upstream. The new xcu subsystem reuses the existing freezer SUBSYS slot, avoiding an increase in CGROUP_SUBSYS_COUNT. This allows us to maintain compatibility with the upstream limit without triggering the BUILD_BUG_ON assertion. Fixes: 43bbefc53356 ("xsched: Add XCU control group implementation and its backend in xsched CFS") Signed-off-by: Liu Kai <liukai284@huawei.com> --- kernel/cgroup/cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 17521bc192ee..04301432e84a 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -6256,7 +6256,7 @@ int __init cgroup_init(void) struct cgroup_subsys *ss; int ssid; - BUILD_BUG_ON(CGROUP_SUBSYS_COUNT > 17); + BUILD_BUG_ON(CGROUP_SUBSYS_COUNT > 16); BUG_ON(cgroup_init_cftypes(NULL, cgroup_base_files)); BUG_ON(cgroup_init_cftypes(NULL, cgroup_psi_files)); BUG_ON(cgroup_init_cftypes(NULL, cgroup1_base_files)); -- 2.34.1
hulk inclusion category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/8424 ---------------------------------------- Enable CONFIG_CGROUP_XCU and CONFIG_XCU_SCHED_CFS in the openeuler defconfigs for both arm64 and x86 architectures. This allows the kernel to support Cgroup-based scheduling for CFS tasks and enables the cgroup interface for the xcu subsystem. Fixes: 94f403dcc368 ("xsched: enforce valid xsched scheduler config dependencies") Signed-off-by: Liu Kai <liukai284@huawei.com> --- arch/arm64/configs/openeuler_defconfig | 3 ++- arch/x86/configs/openeuler_defconfig | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index fc581adb563b..622d44e6d9ff 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -101,7 +101,8 @@ CONFIG_XCU_SCHEDULER=y CONFIG_XCU_VSTREAM=y CONFIG_XSCHED_NR_CUS=128 CONFIG_XCU_SCHED_RT=y -# CONFIG_XCU_SCHED_CFS is not set +CONFIG_XCU_SCHED_CFS=y +CONFIG_CGROUP_XCU=y # # CPU/Task time and stats accounting diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig index d493dbf6b8a1..e66724b15bb4 100644 --- a/arch/x86/configs/openeuler_defconfig +++ b/arch/x86/configs/openeuler_defconfig @@ -121,7 +121,8 @@ CONFIG_XCU_SCHEDULER=y CONFIG_XCU_VSTREAM=y CONFIG_XSCHED_NR_CUS=128 CONFIG_XCU_SCHED_RT=y -# CONFIG_XCU_SCHED_CFS is not set +CONFIG_XCU_SCHED_CFS=y +CONFIG_CGROUP_XCU=y # # CPU/Task time and stats accounting -- 2.34.1
hulk inclusion category: doc bugzilla: https://atomgit.com/openeuler/kernel/issues/8424 ---------------------------------------- Add documentation for the new kernel command-line option to control the xcu cgroup subsystem. The xcu cgroup subsystem is now disabled by default and requires 'xcu=enable' to be set on the cmdline to activate the functionality. Signed-off-by: Liu Kai <liukai284@huawei.com> --- Documentation/scheduler/xsched.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/scheduler/xsched.md b/Documentation/scheduler/xsched.md index 11dc0c964e0a..d8aa907f858e 100644 --- a/Documentation/scheduler/xsched.md +++ b/Documentation/scheduler/xsched.md @@ -64,11 +64,11 @@ CONFIG_CGROUP_XCU=y # 修改内核引导文件,根据实际情况编辑 vim /etc/grub2-efi.cfg -# 在XSched内核新增 cmdline 配置,关闭驱动签名校验、开启cgroup-v2 -module.sig_enforce=0 systemd.unified_cgroup_hierarchy=1 cgroup_no_v1=all +# 在XSched内核新增 cmdline 配置,关闭驱动签名校验、开启cgroup-v2,使能 xcu cgroup 子系统 +module.sig_enforce=0 cgroup_no_v1=all xcu=enable ``` -保存引导文件后,重启切换内核 +保存引导文件后,重启切换内核,**注意!!!,xcu 子系统仅支持 cgroup-v2** ### 1.3 重编驱动 -- 2.34.1
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://atomgit.com/openeuler/kernel/merge_requests/21529 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/QGZ... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://atomgit.com/openeuler/kernel/merge_requests/21529 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/QGZ...
participants (2)
-
Liu Kai -
patchwork bot