Re: [PATCH v9 10/11] virt/steal_governor: Implement steal_governor policy loop

Shrikanth Hegde <[email protected]> Mon, 27 Jul 2026 20:12:44 +0530
Newsgroups dev.linux.lists.virtualization,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Hi Yury,

On 7/25/26 2:35 AM, Yury Norov wrote:

> 
> In v8 I pointed to the identical function in s390 code, and you agreed
> to unify them, but that didn't happen. Please do that in the next
> version.
> 

This is diff i have now. I assume this is what you had suggested.
Let me know if it differs.
  

commit b3aa88b7207c7a23ef9d60dd12f02eb4f4d79abf (HEAD -> sched/core)
Author: Shrikanth Hegde <[email protected]>
Date:   Mon Jul 27 09:11:08 2026 -0400

     refactor for kcpustat_field_total

diff --git a/arch/s390/kernel/hiperdispatch.c b/arch/s390/kernel/hiperdispatch.c
index 217206522266..0c658f229b17 100644
--- a/arch/s390/kernel/hiperdispatch.c
+++ b/arch/s390/kernel/hiperdispatch.c
@@ -210,13 +210,10 @@ static unsigned long hd_calculate_steal_percentage(void)
         int cpus, cpu;
         ktime_t now;
  
-       cpus = 0;
-       steal = 0;
         percentage = 0;
-       for_each_cpu(cpu, &hd_vmvl_cpumask) {
-               steal += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL];
-               cpus++;
-       }
+       steal = kcpustat_field_total(CPUTIME_STEAL, &hd_vmvl_cpumask);
+       cpus = cpumask_weight(&hd_vmvl_cpumask);
+
         /*
          * If there is no vertical medium and low CPUs steal time
          * is 0 as vertical high CPUs shouldn't experience steal time.
diff --git a/drivers/virt/steal_governor.c b/drivers/virt/steal_governor.c
index 715aa7f90407..1f0c377c739a 100644
--- a/drivers/virt/steal_governor.c
+++ b/drivers/virt/steal_governor.c
@@ -116,13 +116,7 @@ MODULE_PARM_DESC(low_threshold,
  /* Return collective steal time across system. */
  static u64 get_system_steal_time(void)
  {
-       int cpu;
-       u64 total_steal = 0;
-
-       for_each_possible_cpu(cpu)
-               total_steal += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL];
-
-       return total_steal;
+       return kcpustat_field_total(CPUTIME_STEAL, cpu_possible_mask);
  }
  
  /* Return number of CPUs to consider steal ratio. */
diff --git a/fs/proc/uptime.c b/fs/proc/uptime.c
index 433aa947cd57..53143c66cbe1 100644
--- a/fs/proc/uptime.c
+++ b/fs/proc/uptime.c
@@ -15,12 +15,8 @@ static int uptime_proc_show(struct seq_file *m, void *v)
         struct timespec64 idle;
         u64 idle_nsec;
         u32 rem;
-       int i;
-
-       idle_nsec = 0;
-       for_each_possible_cpu(i)
-               idle_nsec += kcpustat_field(CPUTIME_IDLE, i);
  
+       idle_nsec = kcpustat_field_total(CPUTIME_IDLE, cpu_possible_mask);
         ktime_get_boottime_ts64(&uptime);
         timens_add_boottime(&uptime);
  
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index 9ca6c2259dfe..c1e85550bf12 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -196,6 +196,17 @@ static inline void kcpustat_cpu_fetch(struct kernel_cpustat *dst, int cpu)
  }
  #endif /* !CONFIG_VIRT_CPU_ACCOUNTING_GEN */
  
+static inline u64 kcpustat_field_total(enum cpu_usage_stat usage, const struct cpumask *cpus)
+{
+       u64 total = 0;
+       int cpu;
+
+       for_each_cpu(cpu, cpus)
+               total += kcpustat_field(usage, cpu);
+
+       return total;
+}
+
  extern void account_user_time(struct task_struct *, u64);
  extern void account_guest_time(struct task_struct *, u64);
  extern void account_system_time(struct task_struct *, int, u64);



Note:
As we discussed in v8, I am leaving
fs/proc/stat.c and drivers/leds/trigger/ledtrig-activity.c etc alone.
Those functions sum up multiple CPUTIME_ fields.