* [Devel] [PATCH RHEL10 COMMIT] sched/loadavg: fix build with CONFIG_CGROUP_SCHED=n [not found] <20260625220832.2201873-1-eva.kurchatova@virtuozzo.com> @ 2026-08-20 16:57 ` Konstantin Khorenko 2026-08-20 16:57 ` [Devel] [PATCH RHEL10 COMMIT] sched/core: guard cpu_cgrp_subsys.depends_on with CONFIG_CGROUP_CPUACCT Konstantin Khorenko ` (4 subsequent siblings) 5 siblings, 0 replies; 7+ messages in thread From: Konstantin Khorenko @ 2026-08-20 16:57 UTC (permalink / raw) The commit is pushed to "branch-rh10-6.12.0-211.39.1.16.x.vz10-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git after rh10-6.12.0-211.39.1.16.6.vz10 ------> commit f869ffa52901a2949cf1554e573e3500b9f85f32 Author: Eva Kurchatova <eva.kurchatova@virtuozzo.com> Date: Thu Aug 20 18:42:45 2026 +0200 sched/loadavg: fix build with CONFIG_CGROUP_SCHED=n get_avenrun_tg() dereferences struct task_group, which is only defined under CONFIG_CGROUP_SCHED in kernel/sched/sched.h. Both the function and its unconditional caller are compiled regardless of that option: kernel/sched/loadavg.c is pulled into build_utility.c, and do_sysinfo() calls get_avenrun_tg() from a branch that is dead at runtime with CONFIG_VE=n but still compiled. So CONFIG_CGROUP_SCHED=n does not build: kernel/sched/loadavg.c: error: invalid use of undefined type 'struct task_group' Compile get_avenrun_tg() only when CONFIG_CGROUP_SCHED is enabled and provide a stub otherwise. The stub returns -ENOSYS, the same error the real implementation returns when there is no per-Container task group to report. do_sysinfo() ignores the return value and info->loads is already zeroed by memset(), so no caller has to change. calc_load_ve() walks the very same task_group internals, so require CONFIG_CGROUP_SCHED there as well instead of relying on CONFIG_VE selecting it. Fixes: c80eee4588ff ("ve/sched/loadavg: Calculate avenrun for Containers root cpu cgroups") Feature: statistics: loadavg virtualization https://virtuozzo.atlassian.net/browse/VSTOR-134732 Signed-off-by: Eva Kurchatova <eva.kurchatova@virtuozzo.com> --- include/linux/sched/loadavg.h | 11 ++++++++++- kernel/sched/loadavg.c | 6 ++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/include/linux/sched/loadavg.h b/include/linux/sched/loadavg.h index 771e753e4670..b97635dc47d4 100644 --- a/include/linux/sched/loadavg.h +++ b/include/linux/sched/loadavg.h @@ -2,6 +2,7 @@ #ifndef _LINUX_SCHED_LOADAVG_H #define _LINUX_SCHED_LOADAVG_H +#include <linux/errno.h> #include <linux/types.h> /* @@ -18,8 +19,16 @@ extern unsigned long avenrun[]; /* Load averages */ extern void get_avenrun(unsigned long *loads, unsigned long offset, int shift); struct task_group; +#ifdef CONFIG_CGROUP_SCHED extern int get_avenrun_tg(struct task_group *tg, unsigned long *loads, unsigned long offset, int shift); +#else +static inline int get_avenrun_tg(struct task_group *tg, unsigned long *loads, + unsigned long offset, int shift) +{ + return -ENOSYS; +} +#endif #define FSHIFT 11 /* nr of bits of precision */ #define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */ @@ -51,7 +60,7 @@ extern unsigned long calc_load_n(unsigned long load, unsigned long exp, extern bool calc_global_load(void); -#ifdef CONFIG_VE +#if defined(CONFIG_VE) && defined(CONFIG_CGROUP_SCHED) extern void calc_load_ve(void); #else #define calc_load_ve() do { } while (0) diff --git a/kernel/sched/loadavg.c b/kernel/sched/loadavg.c index bc0b6bcdae2d..2f66772750ea 100644 --- a/kernel/sched/loadavg.c +++ b/kernel/sched/loadavg.c @@ -78,6 +78,7 @@ void get_avenrun(unsigned long *loads, unsigned long offset, int shift) loads[2] = (avenrun[2] + offset) << shift; } +#ifdef CONFIG_CGROUP_SCHED int get_avenrun_tg(struct task_group *tg, unsigned long *loads, unsigned long offset, int shift) { @@ -93,6 +94,7 @@ int get_avenrun_tg(struct task_group *tg, unsigned long *loads, return 0; } +#endif /* CONFIG_CGROUP_SCHED */ long calc_load_fold_active(struct rq *this_rq, long adjust) { @@ -109,7 +111,7 @@ long calc_load_fold_active(struct rq *this_rq, long adjust) return delta; } -#ifdef CONFIG_VE +#if defined(CONFIG_VE) && defined(CONFIG_CGROUP_SCHED) extern struct list_head ve_root_list; extern raw_spinlock_t load_ve_lock; @@ -166,7 +168,7 @@ void calc_load_ve(void) kstat_glob.nr_unint_avg[2] = calc_load(kstat_glob.nr_unint_avg[2], EXP_15, nr_unint); write_seqcount_end(&kstat_glob.nr_unint_avg_seq); } -#endif /* CONFIG_VE */ +#endif /* CONFIG_VE && CONFIG_CGROUP_SCHED */ /** * fixed_power_int - compute: x^n, in O(log n) time ^ permalink raw reply [flat|nested] 7+ messages in thread
* [Devel] [PATCH RHEL10 COMMIT] sched/core: guard cpu_cgrp_subsys.depends_on with CONFIG_CGROUP_CPUACCT [not found] <20260625220832.2201873-1-eva.kurchatova@virtuozzo.com> 2026-08-20 16:57 ` [Devel] [PATCH RHEL10 COMMIT] sched/loadavg: fix build with CONFIG_CGROUP_SCHED=n Konstantin Khorenko @ 2026-08-20 16:57 ` Konstantin Khorenko 2026-08-20 16:57 ` [Devel] [PATCH RHEL10 COMMIT] sched: move MAX_CPU_RATE out of CONFIG_CFS_CPULIMIT Konstantin Khorenko ` (3 subsequent siblings) 5 siblings, 0 replies; 7+ messages in thread From: Konstantin Khorenko @ 2026-08-20 16:57 UTC (permalink / raw) The commit is pushed to "branch-rh10-6.12.0-211.39.1.16.x.vz10-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git after rh10-6.12.0-211.39.1.16.6.vz10 ------> commit 8fca9705e9ef7ec90da46ea4ccfbc17982505d3c Author: Eva Kurchatova <eva.kurchatova@virtuozzo.com> Date: Thu Aug 20 18:42:57 2026 +0200 sched/core: guard cpu_cgrp_subsys.depends_on with CONFIG_CGROUP_CPUACCT cpuacct_cgrp_id is only declared when CONFIG_CGROUP_CPUACCT is enabled - SUBSYS(cpuacct) in include/linux/cgroup_subsys.h sits under IS_ENABLED(CONFIG_CGROUP_CPUACCT) - while the cpu controller itself is built whenever CONFIG_CGROUP_SCHED is set. With CONFIG_CGROUP_SCHED=y and CONFIG_CGROUP_CPUACCT=n the initializer does not compile: kernel/sched/core.c: error: 'cpuacct_cgrp_id' undeclared here (not in a function) There is nothing for the cpu controller to depend on when cpuacct is not built, so simply drop the dependency in that configuration. Fixes: 776275586407 ("cgroup: allow cpuacct to be enabled in v2 hierarchy") Feature: sched: emulate virtual cpus for Containers https://virtuozzo.atlassian.net/browse/VSTOR-134732 Signed-off-by: Eva Kurchatova <eva.kurchatova@virtuozzo.com> --- kernel/sched/core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index d5b4d8c97a0c..7d2214749245 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -10441,7 +10441,9 @@ struct cgroup_subsys cpu_cgrp_subsys = { .dfl_cftypes = cpu_files, .early_init = true, .threaded = true, +#ifdef CONFIG_CGROUP_CPUACCT .depends_on = 1 << cpuacct_cgrp_id, +#endif }; #endif /* CONFIG_CGROUP_SCHED */ ^ permalink raw reply [flat|nested] 7+ messages in thread
* [Devel] [PATCH RHEL10 COMMIT] sched: move MAX_CPU_RATE out of CONFIG_CFS_CPULIMIT [not found] <20260625220832.2201873-1-eva.kurchatova@virtuozzo.com> 2026-08-20 16:57 ` [Devel] [PATCH RHEL10 COMMIT] sched/loadavg: fix build with CONFIG_CGROUP_SCHED=n Konstantin Khorenko 2026-08-20 16:57 ` [Devel] [PATCH RHEL10 COMMIT] sched/core: guard cpu_cgrp_subsys.depends_on with CONFIG_CGROUP_CPUACCT Konstantin Khorenko @ 2026-08-20 16:57 ` Konstantin Khorenko 2026-08-20 16:57 ` [Devel] [PATCH RHEL10 COMMIT] sched/cpuacct: guard ve_root_tg() with CONFIG_CFS_CPULIMIT Konstantin Khorenko ` (2 subsequent siblings) 5 siblings, 0 replies; 7+ messages in thread From: Konstantin Khorenko @ 2026-08-20 16:57 UTC (permalink / raw) The commit is pushed to "branch-rh10-6.12.0-211.39.1.16.x.vz10-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git after rh10-6.12.0-211.39.1.16.6.vz10 ------> commit 6ced1cd98dfd43facb3c9de5019ebc25fd7d25fb Author: Eva Kurchatova <eva.kurchatova@virtuozzo.com> Date: Thu Aug 20 18:43:16 2026 +0200 sched: move MAX_CPU_RATE out of CONFIG_CFS_CPULIMIT MAX_CPU_RATE is the scale of task_group::cpu_rate, but it was defined in the middle of the body of struct task_group, inside the block guarded by CONFIG_CFS_CPULIMIT. cpu_cgroup_update_vcpustat() uses it to normalize the per-vcpu usage reported in a Container's /proc/stat, and that code is compiled unconditionally, so CONFIG_CFS_CPULIMIT=n does not build: kernel/sched/cpuacct.c: error: 'MAX_CPU_RATE' undeclared (first use in this function) x86_64 defconfig is exactly such a configuration: CONFIG_VE defaults to y, while CONFIG_CFS_BANDWIDTH - the only thing that selects CONFIG_CFS_CPULIMIT - is off. Move the definition out of the struct and out of the ifdef. Nothing else in cpu_cgroup_update_vcpustat() needs CONFIG_CFS_CPULIMIT: tg_cpu_rate() and tg_nr_cpus() already degrade to "no limit configured", so the vcpustat calculation keeps working and a Container simply gets num_online_cpus() vcpus running at full rate. Compiling the calculation out instead would leave tg->vcpustat all zeroes, and /proc/stat inside a Container would report no CPU time at all. Fixes: 4e99efb641da ("sched: Port CONFIG_CFS_CPULIMIT feature") Feature: sched: ability to limit number of CPUs available to a CT https://virtuozzo.atlassian.net/browse/VSTOR-134732 Signed-off-by: Eva Kurchatova <eva.kurchatova@virtuozzo.com> Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> --- kernel/sched/sched.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 1a8a0ff522cb..2a3f73933456 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -533,12 +533,19 @@ struct task_group { #endif #ifdef CONFIG_CFS_CPULIMIT -#define MAX_CPU_RATE 1024 unsigned long cpu_rate; unsigned int nr_cpus; #endif }; +/* + * The scale of task_group::cpu_rate: 1024 means one full CPU. It is also + * used to normalize the per-vcpu usage reported in a Container's /proc/stat, + * which is done regardless of CONFIG_CFS_CPULIMIT, so keep the definition + * unconditional. + */ +#define MAX_CPU_RATE 1024 + #ifdef CONFIG_GROUP_SCHED_WEIGHT #define ROOT_TASK_GROUP_LOAD NICE_0_LOAD ^ permalink raw reply [flat|nested] 7+ messages in thread
* [Devel] [PATCH RHEL10 COMMIT] sched/cpuacct: guard ve_root_tg() with CONFIG_CFS_CPULIMIT [not found] <20260625220832.2201873-1-eva.kurchatova@virtuozzo.com> ` (2 preceding siblings ...) 2026-08-20 16:57 ` [Devel] [PATCH RHEL10 COMMIT] sched: move MAX_CPU_RATE out of CONFIG_CFS_CPULIMIT Konstantin Khorenko @ 2026-08-20 16:57 ` Konstantin Khorenko [not found] ` <20260625220832.2201873-2-eva.kurchatova@virtuozzo.com> 2026-08-21 16:48 ` [Devel] [PATCH vz10 01/14] sched: fix VZ build errors with CONFIG_CGROUP_SCHED=n Konstantin Khorenko 5 siblings, 0 replies; 7+ messages in thread From: Konstantin Khorenko @ 2026-08-20 16:57 UTC (permalink / raw) The commit is pushed to "branch-rh10-6.12.0-211.39.1.16.x.vz10-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git after rh10-6.12.0-211.39.1.16.6.vz10 ------> commit bd117ee4adf3296f8cb3910e212a42ce66a61268 Author: Konstantin Khorenko <khorenko@virtuozzo.com> Date: Thu Aug 20 18:43:29 2026 +0200 sched/cpuacct: guard ve_root_tg() with CONFIG_CFS_CPULIMIT ve_root_tg() has exactly two callers, tg_cpu_rate() and tg_nr_cpus(), and both reference it only from inside #ifdef CONFIG_CFS_CPULIMIT: the task_group fields they read, ::cpu_rate and ::nr_cpus, do not exist without that option. So with CONFIG_CFS_CPULIMIT=n the helper is not used at all, and since our configs set CONFIG_WERROR=y the build fails: kernel/sched/cpuacct.c:373:27: error: 've_root_tg' defined but not used [-Werror=unused-function] x86_64 defconfig hits this: CONFIG_VE defaults to y, while CONFIG_CFS_BANDWIDTH - the only thing that selects CONFIG_CFS_CPULIMIT - is off. Compile ve_root_tg() under the same condition as its call sites. Fixes: 095994c57b84 ("ve/sched/stat: Introduce functions to calculate vcpustat data") Feature: sched: emulate virtual cpus for Containers https://virtuozzo.atlassian.net/browse/VSTOR-134732 Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> --- kernel/sched/cpuacct.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/sched/cpuacct.c b/kernel/sched/cpuacct.c index 01a2b2c3c5b7..6b0ed967316e 100644 --- a/kernel/sched/cpuacct.c +++ b/kernel/sched/cpuacct.c @@ -370,6 +370,7 @@ struct cgroup_subsys cpuacct_cgrp_subsys = { .threaded = true, }; +#ifdef CONFIG_CFS_CPULIMIT static struct task_group *ve_root_tg(struct task_group *tg) { struct cgroup_subsys_state *css; @@ -379,6 +380,7 @@ static struct task_group *ve_root_tg(struct task_group *tg) { css = css_ve_root1(&tg->css); return css ? css_tg(css) : NULL; } +#endif static unsigned int tg_cpu_rate(struct task_group *tg) { ^ permalink raw reply [flat|nested] 7+ messages in thread
[parent not found: <20260625220832.2201873-2-eva.kurchatova@virtuozzo.com>]
* Re: [Devel] [PATCH vz10 02/14] mm: fix VZ build errors with CONFIG_MEMCG=n [not found] ` <20260625220832.2201873-2-eva.kurchatova@virtuozzo.com> @ 2026-08-21 14:03 ` Konstantin Khorenko 0 siblings, 0 replies; 7+ messages in thread From: Konstantin Khorenko @ 2026-08-21 14:03 UTC (permalink / raw) On 6/26/26 00:08, Eva Kurchatova wrote: > Guard VZ-specific code that uses memory cgroup internals > (memory_cgrp_id, struct mem_cgroup, root_mem_cgroup) with > CONFIG_MEMCG. > > Without CONFIG_MEMCG: > - oom_berserker() and oom_kill_memcg_member() dereference struct > mem_cgroup fields that do not exist. > - si_meminfo_ve(), fill_meminfo_ve(), and fill_vmstat_ve() use > memory_cgrp_id and mem_cgroup_from_css() which are undeclared. > - proc_oom_score() VE-specific path references memory_cgrp_id. > > Wrap affected functions and their call sites with CONFIG_MEMCG (or > CONFIG_VE && CONFIG_MEMCG where appropriate) and provide stubs where > needed. Also guard VZ-specific nid field accesses in memcontrol.c > with CONFIG_MEMCG_V1 and move the numa_migrate cftypes entry inside > the existing CONFIG_NUMA block. > > Signed-off-by: Eva Kurchatova <eva.kurchatova@virtuozzo.com> > > https://virtuozzo.atlassian.net/browse/VSTOR-134732 > Feature: fix kunit > --- > fs/proc/base.c | 4 ++++ > fs/proc/meminfo.c | 4 ++++ > mm/memcontrol.c | 9 +++++++-- > mm/oom_kill.c | 8 ++++++++ > mm/show_mem.c | 2 ++ > mm/vmstat.c | 7 +++++-- > 6 files changed, 30 insertions(+), 4 deletions(-) > > diff --git a/fs/proc/base.c b/fs/proc/base.c > index 8174b2a8a5dc..db7d304f1905 100644 > --- a/fs/proc/base.c > +++ b/fs/proc/base.c > @@ -692,6 +692,7 @@ static int proc_oom_score(struct seq_file *m, struct pid_namespace *ns, > unsigned long points = 0; > long badness; > > +#ifdef CONFIG_MEMCG > scoped_guard (rcu) { > struct cgroup_subsys_state *css = task_css(task, memory_cgrp_id); > > @@ -702,6 +703,9 @@ static int proc_oom_score(struct seq_file *m, struct pid_namespace *ns, > memcg = mem_cgroup_from_css(css); > totalpages = mem_cgroup_get_max(memcg); > } > +#else > + scoped_guard (rcu) { > +#endif > } Empty block with scoped_guard ? > > badness = oom_badness(task, totalpages, NULL); > diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c > index ac3c88e68728..4db69eed0e21 100644 > --- a/fs/proc/meminfo.c > +++ b/fs/proc/meminfo.c > @@ -73,6 +73,7 @@ static int meminfo_proc_show_mi(struct seq_file *m, struct meminfo *mi) > return 0; > } > > +#if defined(CONFIG_VE) && defined(CONFIG_MEMCG) > static void fill_meminfo_ve(struct meminfo *mi, struct ve_struct *ve) > { > struct cgroup_subsys_state *css; > @@ -84,6 +85,7 @@ static void fill_meminfo_ve(struct meminfo *mi, struct ve_struct *ve) > css_put(css); > > } > +#endif > > static int meminfo_proc_show_ve(struct seq_file *m, void *v, > struct ve_struct *ve) > @@ -104,11 +106,13 @@ static int meminfo_proc_show_ve(struct seq_file *m, void *v, > mi.si = &i; > mi.ve = ve; > > +#if defined(CONFIG_VE) && defined(CONFIG_MEMCG) > if (!ve_is_super(ve) && ve->meminfo_val == VE_MEMINFO_DEFAULT) { > fill_meminfo_ve(&mi, ve); > > return meminfo_proc_show_mi(m, &mi); > } > +#endif > > committed = vm_memory_committed(); > > diff --git a/mm/memcontrol.c b/mm/memcontrol.c > index 6301319529ee..c27ee90e599c 100644 > --- a/mm/memcontrol.c > +++ b/mm/memcontrol.c > @@ -714,8 +714,11 @@ percpu_stats_memcg(struct mem_cgroup *memcg, struct mem_cgroup_per_node **pn) > } while (memcg->percpu_stats_disabled); > > if (pn) { > +#ifdef CONFIG_MEMCG_V1 > unsigned int nid = (*pn)->nid; > - > +#else > + unsigned int nid = lruvec_pgdat(&(*pn)->lruvec)->node_id; > +#endif Three objections to deriving the node id from the lruvec instead of keeping the field: 1) It reads a lazily initialized field. lruvec_pgdat(&(*pn)->lruvec) reads pn->lruvec.pgdat, but lruvec_init() memsets the whole structure and never sets pgdat - it is filled in on the first lookup, by mem_cgroup_lruvec(): if (unlikely(lruvec->pgdat != pgdat)) lruvec->pgdat = pgdat; For the only caller that passes a non-NULL pn today - __mod_memcg_lruvec_state(), which always gets its lruvec from mem_cgroup_lruvec() or folio_lruvec() - the pointer is already set by then, so as it stands this will not oops. But it makes a correctness-critical read depend on initialization performed elsewhere: add a second caller whose lruvec comes from another source and you get NULL->node_id, with nothing in the compiler or in the code to warn about it. 2) It costs more on a hot path. __mod_memcg_lruvec_state() is one of the hottest paths in memcg accounting, and this turns a single unsigned short field read into two pointer dereferences (pn->lruvec.pgdat, then ->node_id) for no gain. 3) It makes the two configurations behave differently by construction. With v1 the node id comes from a field, without v1 it is derived from the pgdat. In statistics accounting code that is the last thing you want: the configurations diverge by design rather than by accident. So I went the other way instead - declare nid in the CONFIG_MEMCG_V1=n branch of struct mem_cgroup_per_node as well: #ifdef CONFIG_MEMCG_V1 ... RH_KABI_FILL_HOLE(unsigned short nid) #else + /* + * Not a v1 field: percpu_stats_memcg() needs the node id to find + * the matching per-node structure of the parent memcg. + */ + unsigned short nid; CACHELINE_PADDING(_pad1_); #endif It goes before CACHELINE_PADDING(_pad1_) on purpose: nid is written once at allocation and only read afterwards, so it belongs on the read-mostly side of the false-sharing boundary that the padding exists to maintain. With this, both the reader in percpu_stats_memcg() and the writer in alloc_mem_cgroup_per_node_info() stay unconditional and no .c file has to change. The v1 branch is untouched, so the layout of the shipped kernel - and its kABI checksum - does not change either: RH_KABI_FILL_HOLE() expands to nothing under __GENKSYMS__, and genksyms only ever sees the configuration it is run with, which has MEMCG_V1=y. Note that MEMCG=y with MEMCG_V1=n is not an exotic combination, by the way: MEMCG_V1 is default n upstream, so any plain modern config built from this tree hits it. > *pn = memcg->nodeinfo[nid]; > } > return memcg; > @@ -4179,7 +4182,9 @@ static bool alloc_mem_cgroup_per_node_info(struct mem_cgroup *memcg, int node) > > lruvec_init(&pn->lruvec); > pn->memcg = memcg; > +#ifdef CONFIG_MEMCG_V1 > pn->nid = node; > +#endif > > memcg->nodeinfo[node] = pn; > return true; > @@ -5258,12 +5263,12 @@ static struct cftype memory_files[] = { > .name = "numa_stat", > .seq_show = memory_numa_stat_show, > }, > -#endif > { > .name = "numa_migrate", > .flags = CFTYPE_NOT_ON_ROOT, > .write = memcg_numa_migrate_write, > }, > +#endif > { > .name = "oom.group", > .flags = CFTYPE_NOT_ON_ROOT | CFTYPE_NS_DELEGATABLE, > diff --git a/mm/oom_kill.c b/mm/oom_kill.c > index 1fd5f99ce3b9..b26a15072d06 100644 > --- a/mm/oom_kill.c > +++ b/mm/oom_kill.c > @@ -1034,6 +1034,7 @@ static void __oom_kill_process(struct task_struct *victim, const char *message) > * Kill provided task unless it's secured by setting > * oom_score_adj to OOM_SCORE_ADJ_MIN. > */ > +#ifdef CONFIG_MEMCG > static int oom_kill_memcg_member(struct task_struct *task, void *message) > { > if (task->signal->oom_score_adj != OOM_SCORE_ADJ_MIN && > @@ -1043,10 +1044,12 @@ static int oom_kill_memcg_member(struct task_struct *task, void *message) > } > return 0; > } > +#endif > > /* > * Kill more processes if oom happens too often in this context. > */ > +#ifdef CONFIG_MEMCG > static void oom_berserker(struct oom_control *oc) > { > static DEFINE_RATELIMIT_STATE(berserker_rs, > @@ -1150,6 +1153,9 @@ static void oom_berserker(struct oom_control *oc) > > pr_err("OOM killer in rage %d: %d tasks killed\n", rage, killed); > } > +#else > +static inline void oom_berserker(struct oom_control *oc) { } > +#endif /* CONFIG_MEMCG */ > > atomic_t global_oom = ATOMIC_INIT(0); > > @@ -1196,6 +1202,7 @@ static void oom_kill_process(struct oom_control *oc, const char *message) > /* > * If necessary, kill all tasks in the selected memory cgroup. > */ > +#ifdef CONFIG_MEMCG > if (oom_group) { > memcg_memory_event(oom_group, MEMCG_OOM_GROUP_KILL); > mem_cgroup_print_oom_group(oom_group); > @@ -1203,6 +1210,7 @@ static void oom_kill_process(struct oom_control *oc, const char *message) > (void *)message); > mem_cgroup_put(oom_group); > } > +#endif > oom_berserker(oc); > } > > diff --git a/mm/show_mem.c b/mm/show_mem.c > index 3ab11c945bf4..4c879177a531 100644 > --- a/mm/show_mem.c > +++ b/mm/show_mem.c > @@ -91,6 +91,7 @@ void si_meminfo(struct sysinfo *val) > > EXPORT_SYMBOL(si_meminfo); > > +#if defined(CONFIG_VE) && defined(CONFIG_MEMCG) > void si_meminfo_ve(struct sysinfo *si, struct ve_struct *ve) > { > unsigned long memtotal, memused, swaptotal, swapused; > @@ -138,6 +139,7 @@ void si_meminfo_ve(struct sysinfo *si, struct ve_struct *ve) > /* bufferram, totalhigh and freehigh left 0 */ > } > EXPORT_SYMBOL(si_meminfo_ve); > +#endif > > #ifdef CONFIG_NUMA > void si_meminfo_node(struct sysinfo *val, int nid) > diff --git a/mm/vmstat.c b/mm/vmstat.c > index 47cb6bf4ecec..de4f8b4e51b6 100644 > --- a/mm/vmstat.c > +++ b/mm/vmstat.c > @@ -1855,6 +1855,7 @@ static const struct seq_operations zoneinfo_op = { > (IS_ENABLED(CONFIG_VM_EVENT_COUNTERS) ? \ > NR_VM_EVENT_ITEMS : 0)) > > +#if defined(CONFIG_VE) && defined(CONFIG_MEMCG) > static void fill_vmstat_ve(unsigned long *stat, struct ve_struct *ve) > { > struct cgroup_subsys_state *css; > @@ -1863,10 +1864,10 @@ static void fill_vmstat_ve(unsigned long *stat, struct ve_struct *ve) > mem_cgroup_fill_vmstat(mem_cgroup_from_css(css), stat); > css_put(css); > } > +#endif > > static void *vmstat_start(struct seq_file *m, loff_t *pos) > { > - struct ve_struct *ve; > unsigned long *v; > int i; > > @@ -1880,12 +1881,14 @@ static void *vmstat_start(struct seq_file *m, loff_t *pos) > if (!v) > return ERR_PTR(-ENOMEM); > > - ve = get_exec_env(); > +#if defined(CONFIG_VE) && defined(CONFIG_MEMCG) > + struct ve_struct *ve = get_exec_env(); > if (!ve_is_super(ve)) { > memset(v, 0, NR_VMSTAT_ITEMS * sizeof(unsigned long)); > fill_vmstat_ve(v, ve); > return (unsigned long *)m->private + *pos; > } > +#endif > > for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) > v[i] = global_zone_page_state(i); ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Devel] [PATCH vz10 01/14] sched: fix VZ build errors with CONFIG_CGROUP_SCHED=n [not found] <20260625220832.2201873-1-eva.kurchatova@virtuozzo.com> ` (4 preceding siblings ...) [not found] ` <20260625220832.2201873-2-eva.kurchatova@virtuozzo.com> @ 2026-08-21 16:48 ` Konstantin Khorenko 5 siblings, 0 replies; 7+ messages in thread From: Konstantin Khorenko @ 2026-08-21 16:48 UTC (permalink / raw) This patchset is superseded by [PATCH vz10 00/32] Fix the VZ kernel build so that KUnit can run -- Best regards, Konstantin Khorenko, Virtuozzo Linux Kernel Team On 6/26/26 00:08, Eva Kurchatova wrote: > Guard VZ-specific code that depends on struct task_group, > root_task_group, cpu_cgrp_id and cpuacct_cgrp_id with the appropriate > Kconfig options. > > Without CONFIG_CGROUP_SCHED: > - struct task_group is incomplete, so get_avenrun_tg() and > calc_load_ve() fail to compile. > - cpu_cgrp_id is undeclared, so the link_ve_root_cpu_cgroup() call in > cgroup_mark_ve_roots() does not build. > > Without CONFIG_CGROUP_CPUACCT: > - cpuacct_cgrp_id is undeclared, so the cpu_cgrp_subsys.depends_on > initializer fails. > - cpu_cgroup_update_vcpustat() uses MAX_CPU_RATE which requires > CONFIG_CFS_CPULIMIT. > > Add a static inline stub for get_avenrun_tg() when CONFIG_CGROUP_SCHED > is disabled, tighten the guards on calc_load_ve() to require both > CONFIG_VE and CONFIG_CGROUP_SCHED, and wrap cpu_cgroup_update_vcpustat() > with CONFIG_CFS_CPULIMIT. > > Signed-off-by: Eva Kurchatova <eva.kurchatova@virtuozzo.com> > > https://virtuozzo.atlassian.net/browse/VSTOR-134732 > Feature: fix kunit > --- > include/linux/sched/loadavg.h | 10 +++++++++- > kernel/sched/core.c | 2 ++ > kernel/sched/cpuacct.c | 5 +++++ > kernel/sched/loadavg.c | 6 ++++-- > 4 files changed, 20 insertions(+), 3 deletions(-) > > diff --git a/include/linux/sched/loadavg.h b/include/linux/sched/loadavg.h > index 771e753e4670..f019a7306600 100644 > --- a/include/linux/sched/loadavg.h > +++ b/include/linux/sched/loadavg.h > @@ -18,8 +18,16 @@ extern unsigned long avenrun[]; /* Load averages */ > extern void get_avenrun(unsigned long *loads, unsigned long offset, int shift); > > struct task_group; > +#ifdef CONFIG_CGROUP_SCHED > extern int get_avenrun_tg(struct task_group *tg, unsigned long *loads, > unsigned long offset, int shift); > +#else > +static inline int get_avenrun_tg(struct task_group *tg, unsigned long *loads, > + unsigned long offset, int shift) > +{ > + return -1; > +} > +#endif > > #define FSHIFT 11 /* nr of bits of precision */ > #define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */ > @@ -51,7 +59,7 @@ extern unsigned long calc_load_n(unsigned long load, unsigned long exp, > > extern bool calc_global_load(void); > > -#ifdef CONFIG_VE > +#if defined(CONFIG_VE) && defined(CONFIG_CGROUP_SCHED) > extern void calc_load_ve(void); > #else > #define calc_load_ve() do { } while (0) > diff --git a/kernel/sched/core.c b/kernel/sched/core.c > index d5b4d8c97a0c..7d2214749245 100644 > --- a/kernel/sched/core.c > +++ b/kernel/sched/core.c > @@ -10441,7 +10441,9 @@ struct cgroup_subsys cpu_cgrp_subsys = { > .dfl_cftypes = cpu_files, > .early_init = true, > .threaded = true, > +#ifdef CONFIG_CGROUP_CPUACCT > .depends_on = 1 << cpuacct_cgrp_id, > +#endif > }; > > #endif /* CONFIG_CGROUP_SCHED */ > diff --git a/kernel/sched/cpuacct.c b/kernel/sched/cpuacct.c > index 01a2b2c3c5b7..98c13ff2bac8 100644 > --- a/kernel/sched/cpuacct.c > +++ b/kernel/sched/cpuacct.c > @@ -542,6 +542,7 @@ static void fixup_vcpustat_delta(struct kernel_cpustat *cur, > cur->cpustat[CPUTIME_STEAL] = 0; > } > > +#ifdef CONFIG_CFS_CPULIMIT > static void cpu_cgroup_update_vcpustat(struct cgroup_subsys_state *cpu_css, > struct cgroup_subsys_state *cpuacct_css) > { > @@ -632,6 +633,10 @@ static void cpu_cgroup_update_vcpustat(struct cgroup_subsys_state *cpu_css, > out_unlock: > spin_unlock(&tg->vcpustat_lock); > } > +#else > +static inline void cpu_cgroup_update_vcpustat(struct cgroup_subsys_state *cpu_css, > + struct cgroup_subsys_state *cpuacct_css) {} > +#endif > > int cpu_cgroup_proc_stat(struct cgroup_subsys_state *cpu_css, > struct cgroup_subsys_state *cpuacct_css, > diff --git a/kernel/sched/loadavg.c b/kernel/sched/loadavg.c > index bc0b6bcdae2d..c4ca3c83f1cf 100644 > --- a/kernel/sched/loadavg.c > +++ b/kernel/sched/loadavg.c > @@ -78,6 +78,7 @@ void get_avenrun(unsigned long *loads, unsigned long offset, int shift) > loads[2] = (avenrun[2] + offset) << shift; > } > > +#ifdef CONFIG_CGROUP_SCHED > int get_avenrun_tg(struct task_group *tg, unsigned long *loads, > unsigned long offset, int shift) > { > @@ -93,6 +94,7 @@ int get_avenrun_tg(struct task_group *tg, unsigned long *loads, > > return 0; > } > +#endif > > long calc_load_fold_active(struct rq *this_rq, long adjust) > { > @@ -109,7 +111,7 @@ long calc_load_fold_active(struct rq *this_rq, long adjust) > return delta; > } > > -#ifdef CONFIG_VE > +#if defined(CONFIG_VE) && defined(CONFIG_CGROUP_SCHED) > extern struct list_head ve_root_list; > extern raw_spinlock_t load_ve_lock; > > @@ -166,7 +168,7 @@ void calc_load_ve(void) > kstat_glob.nr_unint_avg[2] = calc_load(kstat_glob.nr_unint_avg[2], EXP_15, nr_unint); > write_seqcount_end(&kstat_glob.nr_unint_avg_seq); > } > -#endif /* CONFIG_VE */ > +#endif /* CONFIG_VE && CONFIG_CGROUP_SCHED */ > > /** > * fixed_power_int - compute: x^n, in O(log n) time ^ permalink raw reply [flat|nested] 7+ messages in thread
* [Devel] [PATCH vz10 02/32] sched/core: guard cpu_cgrp_subsys.depends_on with CONFIG_CGROUP_CPUACCT
@ 2026-08-21 16:36 Konstantin Khorenko
2026-08-21 16:42 ` [Devel] [PATCH RHEL10 COMMIT] " Konstantin Khorenko
0 siblings, 1 reply; 7+ messages in thread
From: Konstantin Khorenko @ 2026-08-21 16:36 UTC (permalink / raw)
From: Eva Kurchatova <eva.kurchatova@virtuozzo.com>
cpuacct_cgrp_id is only declared when CONFIG_CGROUP_CPUACCT is enabled -
SUBSYS(cpuacct) in include/linux/cgroup_subsys.h sits under
IS_ENABLED(CONFIG_CGROUP_CPUACCT) - while the cpu controller itself is
built whenever CONFIG_CGROUP_SCHED is set. With CONFIG_CGROUP_SCHED=y
and CONFIG_CGROUP_CPUACCT=n the initializer does not compile:
kernel/sched/core.c: error: 'cpuacct_cgrp_id' undeclared here
(not in a function)
There is nothing for the cpu controller to depend on when cpuacct is not
built, so simply drop the dependency in that configuration.
Fixes: 776275586407 ("cgroup: allow cpuacct to be enabled in v2 hierarchy")
Feature: sched: emulate virtual cpus for Containers
https://virtuozzo.atlassian.net/browse/VSTOR-134732
Signed-off-by: Eva Kurchatova <eva.kurchatova@virtuozzo.com>
Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
kernel/sched/core.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index d5b4d8c97a0c..7d2214749245 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -10441,7 +10441,9 @@ struct cgroup_subsys cpu_cgrp_subsys = {
.dfl_cftypes = cpu_files,
.early_init = true,
.threaded = true,
+#ifdef CONFIG_CGROUP_CPUACCT
.depends_on = 1 << cpuacct_cgrp_id,
+#endif
};
#endif /* CONFIG_CGROUP_SCHED */
--
2.47.1
^ permalink raw reply [flat|nested] 7+ messages in thread* [Devel] [PATCH RHEL10 COMMIT] sched/core: guard cpu_cgrp_subsys.depends_on with CONFIG_CGROUP_CPUACCT 2026-08-21 16:36 [Devel] [PATCH vz10 02/32] sched/core: guard cpu_cgrp_subsys.depends_on with CONFIG_CGROUP_CPUACCT Konstantin Khorenko @ 2026-08-21 16:42 ` Konstantin Khorenko 0 siblings, 0 replies; 7+ messages in thread From: Konstantin Khorenko @ 2026-08-21 16:42 UTC (permalink / raw) The commit is pushed to "branch-rh10-6.12.0-211.39.1.16.x.vz10-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git after rh10-6.12.0-211.39.1.16.6.vz10 ------> commit 9ce0ac5c94b699acee8b79cb0685d38f7b5aea5c Author: Eva Kurchatova <eva.kurchatova@virtuozzo.com> Date: Fri Aug 21 18:36:48 2026 +0200 sched/core: guard cpu_cgrp_subsys.depends_on with CONFIG_CGROUP_CPUACCT cpuacct_cgrp_id is only declared when CONFIG_CGROUP_CPUACCT is enabled - SUBSYS(cpuacct) in include/linux/cgroup_subsys.h sits under IS_ENABLED(CONFIG_CGROUP_CPUACCT) - while the cpu controller itself is built whenever CONFIG_CGROUP_SCHED is set. With CONFIG_CGROUP_SCHED=y and CONFIG_CGROUP_CPUACCT=n the initializer does not compile: kernel/sched/core.c: error: 'cpuacct_cgrp_id' undeclared here (not in a function) There is nothing for the cpu controller to depend on when cpuacct is not built, so simply drop the dependency in that configuration. Fixes: 776275586407 ("cgroup: allow cpuacct to be enabled in v2 hierarchy") Feature: sched: emulate virtual cpus for Containers https://virtuozzo.atlassian.net/browse/VSTOR-134732 Signed-off-by: Eva Kurchatova <eva.kurchatova@virtuozzo.com> Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com> --- kernel/sched/core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index d5b4d8c97a0c7..7d2214749245b 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -10441,7 +10441,9 @@ struct cgroup_subsys cpu_cgrp_subsys = { .dfl_cftypes = cpu_files, .early_init = true, .threaded = true, +#ifdef CONFIG_CGROUP_CPUACCT .depends_on = 1 << cpuacct_cgrp_id, +#endif }; #endif /* CONFIG_CGROUP_SCHED */ ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-08-21 16:48 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <20260625220832.2201873-1-eva.kurchatova@virtuozzo.com>
2026-08-20 16:57 ` [Devel] [PATCH RHEL10 COMMIT] sched/loadavg: fix build with CONFIG_CGROUP_SCHED=n Konstantin Khorenko
2026-08-20 16:57 ` [Devel] [PATCH RHEL10 COMMIT] sched/core: guard cpu_cgrp_subsys.depends_on with CONFIG_CGROUP_CPUACCT Konstantin Khorenko
2026-08-20 16:57 ` [Devel] [PATCH RHEL10 COMMIT] sched: move MAX_CPU_RATE out of CONFIG_CFS_CPULIMIT Konstantin Khorenko
2026-08-20 16:57 ` [Devel] [PATCH RHEL10 COMMIT] sched/cpuacct: guard ve_root_tg() with CONFIG_CFS_CPULIMIT Konstantin Khorenko
[not found] ` <20260625220832.2201873-2-eva.kurchatova@virtuozzo.com>
2026-08-21 14:03 ` [Devel] [PATCH vz10 02/14] mm: fix VZ build errors with CONFIG_MEMCG=n Konstantin Khorenko
2026-08-21 16:48 ` [Devel] [PATCH vz10 01/14] sched: fix VZ build errors with CONFIG_CGROUP_SCHED=n Konstantin Khorenko
2026-08-21 16:36 [Devel] [PATCH vz10 02/32] sched/core: guard cpu_cgrp_subsys.depends_on with CONFIG_CGROUP_CPUACCT Konstantin Khorenko
2026-08-21 16:42 ` [Devel] [PATCH RHEL10 COMMIT] " Konstantin Khorenko
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.