The commit is pushed to "branch-rh10-6.12.0-211.16.1.12.x.vz10-ovz" and will 
appear at [email protected]:openvz/vzkernel.git
after rh10-6.12.0-211.16.1.el10
------>
commit 2ca7833edb5c1005456d0555f03dccde3afa9f10
Author: Konstantin Khorenko <[email protected]>
Date:   Thu Jun 11 18:38:17 2026 +0200

    ve/proc/loadavg: sum nr_unint drift as signed long, not int
    
    cpu_cgroup_proc_loadavg() sums the per-CPU cfs_rq::nr_unint counters
    into a plain int accumulator and prints it with %d:
    
            int nr_running = 0;
            ...
            nr_running += tg->cfs_rq[i]->nr_unint;
    
    nr_unint is unsigned long and relies on signed reinterpretation to
    fold the migration drift: a task can increment it on one CPU while
    the matching decrement lands on another CPU after migration, so a
    single per-CPU value can be far negative (stored as a huge unsigned
    number) and only the sum over all CPUs is meaningful.
    
    This is not a wrong-value fix: reading the drift as signed and adding
    it folds to the same small non-negative sum whether the accumulator
    is int or long. The change is for consistency and clarity, not
    correctness:
    
     - calc_load_fold_active() and calc_load_ve() fold the very same
       per-CPU nr_unint in a long with an explicit (long) cast; this site
       is the odd one out;
     - an explicit (long) cast states the signed reinterpretation at the
       read site instead of hiding it in an implicit unsigned-long-to-int
       narrowing;
     - a long accumulator prints correctly with %ld and could host a
       "< 0" sanity check like calc_load_ve() has.
    
    Accumulate in long, cast each term with (long), print with %ld.
    
    Fixes: c4da3bdf69c0 ("ve/proc/loadavg: Virtualize /proc/loadavg in 
Containers")
    
    Reported-by: Pavel Tikhomirov <[email protected]>
    https://virtuozzo.atlassian.net/browse/VSTOR-132310
    Feature: statistics: loadavg virtualization
    Signed-off-by: Konstantin Khorenko <[email protected]>
---
 kernel/sched/core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index d51d70ff7560..d5b4d8c97a0c 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -10045,7 +10045,7 @@ int cpu_cgroup_proc_loadavg(struct cgroup_subsys_state 
*css,
        struct cgroup *cgrp = css->cgroup;
        struct task_group *tg = css_tg(css);
        unsigned long avnrun[3];
-       int nr_running = 0;
+       long nr_running = 0;
        int i;
 
        if (!test_bit(CGRP_VE_ROOT, &cgrp->flags))
@@ -10064,14 +10064,14 @@ int cpu_cgroup_proc_loadavg(struct 
cgroup_subsys_state *css,
                 * overhead for activate/deactivate operations. So, we
                 * don't account child cgroup unint tasks here.
                 */
-               nr_running += tg->cfs_rq[i]->nr_unint;
+               nr_running += (long)tg->cfs_rq[i]->nr_unint;
 #endif
 #ifdef CONFIG_RT_GROUP_SCHED
                nr_running += tg->rt_rq[i]->rt_nr_running;
 #endif
        }
 
-       seq_printf(p, "%lu.%02lu %lu.%02lu %lu.%02lu %d/%d %d\n",
+       seq_printf(p, "%lu.%02lu %lu.%02lu %lu.%02lu %ld/%d %d\n",
                LOAD_INT(avnrun[0]), LOAD_FRAC(avnrun[0]),
                LOAD_INT(avnrun[1]), LOAD_FRAC(avnrun[1]),
                LOAD_INT(avnrun[2]), LOAD_FRAC(avnrun[2]),
_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to