From 8b196aa7a9bf2b969b91cf2a9d4206ff7c0098a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=81=A5=E5=BA=B7=E5=AE=9D?= <2078634206@qq.com> Date: Sat, 24 Oct 2026 09:03:23 +0800 Subject: [PATCH] cpuset: count loadavg tasks inside the cpuset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The loadavg view prints "running/total" using the per-cpuset running count from cpuset_nr_running() but the denominator is the global nr_threads counter. Processes outside the cpuset move the reported total of an otherwise untouched cgroup, so the ratio is not meaningful for the cgroup it is read from. Count the total during the same task iteration that counts the running tasks and print that number instead. Verified in a two-vCPU guest with a cgroup v2 pod holding one sleeping task: the unfixed view reports "0/63" and then "0/83" after twenty sleepers are started outside the pod, while the pod still contains exactly one task; with the change both reads report "0/1". Signed-off-by: 健康宝 <2078634206@qq.com> --- kernel/cgroup/cpuset.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index f115c88cb396..2b49e159a376 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -5390,16 +5390,19 @@ static void cpuset_calc_loadavg_workfn(struct work_struct *work) cgroup_cpuset_calc_load(); schedule_delayed_work(&cpuset_calc_loadavg_work, LOAD_FREQ); } -static unsigned long cpuset_nr_running(struct cpuset *cs) +static unsigned long cpuset_nr_running(struct cpuset *cs, + unsigned long *nr_total) { struct css_task_iter it; struct task_struct *task; unsigned long nr_running = 0; + *nr_total = 0; css_task_iter_start(&cs->css, 0, &it); while ((task = css_task_iter_next(&it))) { if (task_is_running(task)) nr_running++; + (*nr_total)++; cond_resched(); } css_task_iter_end(&it); @@ -5414,7 +5417,8 @@ static int cpuset_cgroup_loadavg_show_comm(struct seq_file *sf, void *v, struct unsigned long loads_d[3] = {0}; unsigned long offset = FIXED_1/200; int shift = 0; - unsigned long n_running = cpuset_nr_running(cs); + unsigned long n_total; + unsigned long n_running = cpuset_nr_running(cs, &n_total); loads[0] = (cs->avenrun[0] + offset) << shift; loads[1] = (cs->avenrun[1] + offset) << shift; @@ -5431,11 +5435,11 @@ static int cpuset_cgroup_loadavg_show_comm(struct seq_file *sf, void *v, struct #define LOAD_INT(x) ((x) >> FSHIFT) #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) - seq_printf(sf, "%lu.%02lu %lu.%02lu %lu.%02lu %ld/%d %d\n", + seq_printf(sf, "%lu.%02lu %lu.%02lu %lu.%02lu %lu/%lu %d\n", LOAD_INT(loads[0]), LOAD_FRAC(loads[0]), LOAD_INT(loads[1]), LOAD_FRAC(loads[1]), LOAD_INT(loads[2]), LOAD_FRAC(loads[2]), - n_running, nr_threads, + n_running, n_total, idr_get_cursor(&task_active_pid_ns(current)->idr) - 1); seq_printf(sf, "%lu.%02lu %lu.%02lu %lu.%02lu\n", -- Gitee