[Devel] [PATCH RHEL10 COMMIT] sched/loadavg: fix build with CONFIG_CGROUP_SCHED=n

Konstantin Khorenko khorenko at virtuozzo.com
Thu Aug 20 19:57:16 MSK 2026


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 at 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 at 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


More information about the Devel mailing list