OpenVZ / Virtuozzo kernel development (devel@openvz.org)
 help / color / mirror / Atom feed
* [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

* 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 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox