Re: [PATCH v3] sched/fair: Cache NUMA node statistics to avoid O(N) scanning

kernel test robot
2026-01-26T16:24:19Z

Hi Qiliang,

kernel test robot noticed the following build errors:

[auto build test ERROR on tip/sched/core]
[also build test ERROR on linus/master v6.19-rc7 next-20260123]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Qiliang-Yuan/sched-fair-Cache-NUMA-node-statistics-to-avoid-O-N-scanning/20260126-190546
base: tip/sched/core
patch link: https://lore.kernel.org/r/20260126110250.1060512-1-realwujing%40gmail.com
patch subject: [PATCH v3] sched/fair: Cache NUMA node statistics to avoid O(N) scanning
config: x86_64-allnoconfig (https://download.01.org/0day-ci/archive/20260127/202601270016.PIXAItvH-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260127/202601270016.PIXAItvH-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601270016.PIXAItvH-lkp@intel.com/

All errors (new ones prefixed by >>):

>> kernel/sched/fair.c:10524:37: error: use of undeclared identifier 'node_stats_cache'
10524 | struct numa_stats_cache *cache = &node_stats_cache[nid];
| ^
>> kernel/sched/fair.c:10526:19: error: incomplete definition of type 'struct numa_stats_cache'
10526 | WRITE_ONCE(cache->nr_running, sgs->sum_h_nr_running);
| ~~~~~^
include/asm-generic/rwonce.h:60:33: note: expanded from macro 'WRITE_ONCE'
60 | compiletime_assert_rwonce_type(x); \
| ^
include/asm-generic/rwonce.h:36:35: note: expanded from macro 'compiletime_assert_rwonce_type'
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^
include/linux/compiler_types.h:610:10: note: expanded from macro '__native_word'
610 | (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
| ^
include/linux/compiler_types.h:649:22: note: expanded from macro 'compiletime_assert'
649 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~
include/linux/compiler_types.h:637:23: note: expanded from macro '_compiletime_assert'
637 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~
include/linux/compiler_types.h:629:9: note: expanded from macro '__compiletime_assert'
629 | if (!(condition)) \
| ^~~~~~~~~
kernel/sched/fair.c:10524:10: note: forward declaration of 'struct numa_stats_cache'
10524 | struct numa_stats_cache *cache = &node_stats_cache[nid];
| ^
>> kernel/sched/fair.c:10526:19: error: incomplete definition of type 'struct numa_stats_cache'
10526 | WRITE_ONCE(cache->nr_running, sgs->sum_h_nr_running);
| ~~~~~^
include/asm-generic/rwonce.h:60:33: note: expanded from macro 'WRITE_ONCE'
60 | compiletime_assert_rwonce_type(x); \
| ^
include/asm-generic/rwonce.h:36:35: note: expanded from macro 'compiletime_assert_rwonce_type'
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^
include/linux/compiler_types.h:610:39: note: expanded from macro '__native_word'
610 | (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
| ^
include/linux/compiler_types.h:649:22: note: expanded from macro 'compiletime_assert'
649 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~
include/linux/compiler_types.h:637:23: note: expanded from macro '_compiletime_assert'
637 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~
include/linux/compiler_types.h:629:9: note: expanded from macro '__compiletime_assert'
629 | if (!(condition)) \
| ^~~~~~~~~
kernel/sched/fair.c:10524:10: note: forward declaration of 'struct numa_stats_cache'
10524 | struct numa_stats_cache *cache = &node_stats_cache[nid];
| ^
>> kernel/sched/fair.c:10526:19: error: incomplete definition of type 'struct numa_stats_cache'
10526 | WRITE_ONCE(cache->nr_running, sgs->sum_h_nr_running);
| ~~~~~^
include/asm-generic/rwonce.h:60:33: note: expanded from macro 'WRITE_ONCE'
60 | compiletime_assert_rwonce_type(x); \
| ^
include/asm-generic/rwonce.h:36:35: note: expanded from macro 'compiletime_assert_rwonce_type'
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^
include/linux/compiler_types.h:611:10: note: expanded from macro '__native_word'
611 | sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
| ^
include/linux/compiler_types.h:649:22: note: expanded from macro 'compiletime_assert'
649 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~
include/linux/compiler_types.h:637:23: note: expanded from macro '_compiletime_assert'
637 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~
include/linux/compiler_types.h:629:9: note: expanded from macro '__compiletime_assert'
629 | if (!(condition)) \
| ^~~~~~~~~
kernel/sched/fair.c:10524:10: note: forward declaration of 'struct numa_stats_cache'
10524 | struct numa_stats_cache *cache = &node_stats_cache[nid];
| ^
>> kernel/sched/fair.c:10526:19: error: incomplete definition of type 'struct numa_stats_cache'
10526 | WRITE_ONCE(cache->nr_running, sgs->sum_h_nr_running);
| ~~~~~^
include/asm-generic/rwonce.h:60:33: note: expanded from macro 'WRITE_ONCE'
60 | compiletime_assert_rwonce_type(x); \
| ^
include/asm-generic/rwonce.h:36:35: note: expanded from macro 'compiletime_assert_rwonce_type'
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^
include/linux/compiler_types.h:611:38: note: expanded from macro '__native_word'
611 | sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
| ^
include/linux/compiler_types.h:649:22: note: expanded from macro 'compiletime_assert'
649 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~
include/linux/compiler_types.h:637:23: note: expanded from macro '_compiletime_assert'
637 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~
include/linux/compiler_types.h:629:9: note: expanded from macro '__compiletime_assert'
629 | if (!(condition)) \
| ^~~~~~~~~
kernel/sched/fair.c:10524:10: note: forward declaration of 'struct numa_stats_cache'
10524 | struct numa_stats_cache *cache = &node_stats_cache[nid];
| ^
>> kernel/sched/fair.c:10526:19: error: incomplete definition of type 'struct numa_stats_cache'
10526 | WRITE_ONCE(cache->nr_running, sgs->sum_h_nr_running);
| ~~~~~^
include/asm-generic/rwonce.h:60:33: note: expanded from macro 'WRITE_ONCE'
60 | compiletime_assert_rwonce_type(x); \
| ^
include/asm-generic/rwonce.h:36:48: note: expanded from macro 'compiletime_assert_rwonce_type'
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^
include/linux/compiler_types.h:649:22: note: expanded from macro 'compiletime_assert'
649 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~
include/linux/compiler_types.h:637:23: note: expanded from macro '_compiletime_assert'
637 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~
include/linux/compiler_types.h:629:9: note: expanded from macro '__compiletime_assert'
629 | if (!(condition)) \
| ^~~~~~~~~
kernel/sched/fair.c:10524:10: note: forward declaration of 'struct numa_stats_cache'
10524 | struct numa_stats_cache *cache = &node_stats_cache[nid];
| ^
>> kernel/sched/fair.c:10526:19: error: incomplete definition of type 'struct numa_stats_cache'
10526 | WRITE_ONCE(cache->nr_running, sgs->sum_h_nr_running);
| ~~~~~^
include/asm-generic/rwonce.h:61:15: note: expanded from macro 'WRITE_ONCE'
61 | __WRITE_ONCE(x, val); \
| ^
include/asm-generic/rwonce.h:55:20: note: expanded from macro '__WRITE_ONCE'
55 | *(volatile typeof(x) *)&(x) = (val); \
| ^
kernel/sched/fair.c:10524:10: note: forward declaration of 'struct numa_stats_cache'
10524 | struct numa_stats_cache *cache = &node_stats_cache[nid];
| ^
>> kernel/sched/fair.c:10526:19: error: incomplete definition of type 'struct numa_stats_cache'
10526 | WRITE_ONCE(cache->nr_running, sgs->sum_h_nr_running);
| ~~~~~^
include/asm-generic/rwonce.h:61:15: note: expanded from macro 'WRITE_ONCE'
61 | __WRITE_ONCE(x, val); \
| ^
include/asm-generic/rwonce.h:55:27: note: expanded from macro '__WRITE_ONCE'
55 | *(volatile typeof(x) *)&(x) = (val); \
| ^
kernel/sched/fair.c:10524:10: note: forward declaration of 'struct numa_stats_cache'
10524 | struct numa_stats_cache *cache = &node_stats_cache[nid];
| ^
kernel/sched/fair.c:10527:19: error: incomplete definition of type 'struct numa_stats_cache'
10527 | WRITE_ONCE(cache->load, sgs->group_load);
| ~~~~~^
include/asm-generic/rwonce.h:60:33: note: expanded from macro 'WRITE_ONCE'
60 | compiletime_assert_rwonce_type(x); \
| ^
include/asm-generic/rwonce.h:36:35: note: expanded from macro 'compiletime_assert_rwonce_type'
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^
include/linux/compiler_types.h:610:10: note: expanded from macro '__native_word'
610 | (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
| ^
include/linux/compiler_types.h:649:22: note: expanded from macro 'compiletime_assert'
649 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~
include/linux/compiler_types.h:637:23: note: expanded from macro '_compiletime_assert'
637 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~
include/linux/compiler_types.h:629:9: note: expanded from macro '__compiletime_assert'
629 | if (!(condition)) \
| ^~~~~~~~~
kernel/sched/fair.c:10524:10: note: forward declaration of 'struct numa_stats_cache'
10524 | struct numa_stats_cache *cache = &node_stats_cache[nid];
| ^
kernel/sched/fair.c:10527:19: error: incomplete definition of type 'struct numa_stats_cache'
10527 | WRITE_ONCE(cache->load, sgs->group_load);
| ~~~~~^
include/asm-generic/rwonce.h:60:33: note: expanded from macro 'WRITE_ONCE'
60 | compiletime_assert_rwonce_type(x); \
| ^
include/asm-generic/rwonce.h:36:35: note: expanded from macro 'compiletime_assert_rwonce_type'
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^
include/linux/compiler_types.h:610:39: note: expanded from macro '__native_word'
610 | (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
| ^
include/linux/compiler_types.h:649:22: note: expanded from macro 'compiletime_assert'
649 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~
include/linux/compiler_types.h:637:23: note: expanded from macro '_compiletime_assert'
637 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~
include/linux/compiler_types.h:629:9: note: expanded from macro '__compiletime_assert'
629 | if (!(condition)) \
| ^~~~~~~~~
kernel/sched/fair.c:10524:10: note: forward declaration of 'struct numa_stats_cache'
10524 | struct numa_stats_cache *cache = &node_stats_cache[nid];
| ^
kernel/sched/fair.c:10527:19: error: incomplete definition of type 'struct numa_stats_cache'
10527 | WRITE_ONCE(cache->load, sgs->group_load);
| ~~~~~^
include/asm-generic/rwonce.h:60:33: note: expanded from macro 'WRITE_ONCE'
60 | compiletime_assert_rwonce_type(x); \
| ^
include/asm-generic/rwonce.h:36:35: note: expanded from macro 'compiletime_assert_rwonce_type'
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^
include/linux/compiler_types.h:611:10: note: expanded from macro '__native_word'
611 | sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
| ^
include/linux/compiler_types.h:649:22: note: expanded from macro 'compiletime_assert'
649 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~
include/linux/compiler_types.h:637:23: note: expanded from macro '_compiletime_assert'
637 | __compiletime_assert(condition, msg, prefix, suffix)
| ^~~~~~~~~
include/linux/compiler_types.h:629:9: note: expanded from macro '__compiletime_assert'
629 | if (!(condition)) \
| ^~~~~~~~~
kernel/sched/fair.c:10524:10: note: forward declaration of 'struct numa_stats_cache'
10524 | struct numa_stats_cache *cache = &node_stats_cache[nid];
| ^
kernel/sched/fair.c:10527:19: error: incomplete definition of type 'struct numa_stats_cache'
10527 | WRITE_ONCE(cache->load, sgs->group_load);
| ~~~~~^
include/asm-generic/rwonce.h:60:33: note: expanded from macro 'WRITE_ONCE'
60 | compiletime_assert_rwonce_type(x); \
| ^
include/asm-generic/rwonce.h:36:35: note: expanded from macro 'compiletime_assert_rwonce_type'
36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
| ^
include/linux/compiler_types.h:611:38: note: expanded from macro '__native_word'
611 | sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
| ^
include/linux/compiler_types.h:649:22: note: expanded from macro 'compiletime_assert'
649 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~
include/linux/compiler_types.h:637:23: note: expanded from macro '_compiletime_assert'
637 | __compiletime_assert(condition, msg, prefix, suffix)

vim +/node_stats_cache +10524 kernel/sched/fair.c

10426
10427 /**
10428 * update_sg_lb_stats - Update sched_group's statistics for load balancing.
10429 * @env: The load balancing environment.
10430 * @sds: Load-balancing data with statistics of the local group.
10431 * @group: sched_group whose statistics are to be updated.
10432 * @sgs: variable to hold the statistics for this group.
10433 * @sg_overloaded: sched_group is overloaded
10434 * @sg_overutilized: sched_group is overutilized
10435 */
10436 static inline void update_sg_lb_stats(struct lb_env *env,
10437 struct sd_lb_stats *sds,
10438 struct sched_group *group,
10439 struct sg_lb_stats *sgs,
10440 bool *sg_overloaded,
10441 bool *sg_overutilized)
10442 {
10443 int i, nr_running, local_group, sd_flags = env->sd->flags;
10444 bool balancing_at_rd = !env->sd->parent;
10445
10446 memset(sgs, 0, sizeof(*sgs));
10447
10448 local_group = group == sds->local;
10449
10450 for_each_cpu_and(i, sched_group_span(group), env->cpus) {
10451 struct rq *rq = cpu_rq(i);
10452 unsigned long load = cpu_load(rq);
10453
10454 sgs->group_load += load;
10455 sgs->group_util += cpu_util_cfs(i);
10456 sgs->group_runnable += cpu_runnable(rq);
10457 sgs->sum_h_nr_running += rq->cfs.h_nr_runnable;
10458
10459 nr_running = rq->nr_running;
10460 sgs->sum_nr_running += nr_running;
10461
10462 if (cpu_overutilized(i))
10463 *sg_overutilized = 1;
10464
10465 /*
10466 * No need to call idle_cpu() if nr_running is not 0
10467 */
10468 if (!nr_running && idle_cpu(i)) {
10469 sgs->idle_cpus++;
10470 /* Idle cpu can't have misfit task */
10471 continue;
10472 }
10473
10474 /* Overload indicator is only updated at root domain */
10475 if (balancing_at_rd && nr_running > 1)
10476 *sg_overloaded = 1;
10477
10478 #ifdef CONFIG_NUMA_BALANCING
10479 /* Only fbq_classify_group() uses this to classify NUMA groups */
10480 if (sd_flags & SD_NUMA) {
10481 sgs->nr_numa_running += rq->nr_numa_running;
10482 sgs->nr_preferred_running += rq->nr_preferred_running;
10483 }
10484 #endif
10485 if (local_group)
10486 continue;
10487
10488 if (sd_flags & SD_ASYM_CPUCAPACITY) {
10489 /* Check for a misfit task on the cpu */
10490 if (sgs->group_misfit_task_load < rq->misfit_task_load) {
10491 sgs->group_misfit_task_load = rq->misfit_task_load;
10492 *sg_overloaded = 1;
10493 }
10494 } else if (env->idle && sched_reduced_capacity(rq, env->sd)) {
10495 /* Check for a task running on a CPU with reduced capacity */
10496 if (sgs->group_misfit_task_load < load)
10497 sgs->group_misfit_task_load = load;
10498 }
10499 }
10500
10501 sgs->group_capacity = group->sgc->capacity;
10502
10503 sgs->group_weight = group->group_weight;
10504
10505 /* Check if dst CPU is idle and preferred to this group */
10506 if (!local_group && env->idle && sgs->sum_h_nr_running &&
10507 sched_group_asym(env, sgs, group))
10508 sgs->group_asym_packing = 1;
10509
10510 /* Check for loaded SMT group to be balanced to dst CPU */
10511 if (!local_group && smt_balance(env, sgs, group))
10512 sgs->group_smt_balance = 1;
10513
10514 sgs->group_type = group_classify(env->sd->imbalance_pct, group, sgs);
10515
10516 /* Computing avg_load makes sense only when group is overloaded */
10517 if (sgs->group_type == group_overloaded)
10518 sgs->avg_load = (sgs->group_load * SCHED_CAPACITY_SCALE) /
10519 sgs->group_capacity;
10520
10521 /* Algorithmic Optimization: Cache node stats for O(1) NUMA lookups */
10522 if (env->sd->flags & SD_NUMA) {
10523 int nid = cpu_to_node(cpumask_first(sched_group_span(group)));
10524 struct numa_stats_cache *cache = &node_stats_cache[nid];
10525
10526 WRITE_ONCE(cache->nr_running, sgs->sum_h_nr_running);
10527 WRITE_ONCE(cache->load, sgs->group_load);
10528 WRITE_ONCE(cache->util, sgs->group_util);
10529 WRITE_ONCE(cache->runnable, sgs->group_runnable);
10530 WRITE_ONCE(cache->capacity, sgs->group_capacity);
10531 WRITE_ONCE(cache->last_update, jiffies);
10532 }
10533 }
10534

--
0-DAY CI Kernel Test Service