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 e3508247b74d6c6c8a1cf9dc2058a45a6b9d18b4
Author: Konstantin Khorenko <[email protected]>
Date:   Wed Jun 3 23:57:17 2026 +0200

    fs/fuse kio: zero cs_stats accumulators on each seqlock retry
    
    do_show_cs_stats() sums the per-cpu latency/rate counters into the
    on-stack accumulators inside a read_seqretry() loop:
      iolat, netlat, read_ops_rate, write_ops_rate, sync_ops_rate.
    
    The accumulators were initialised only once, before the loop.
    
    If a writer (pcs_cs_update_stat() / pcs_cs_stat_up(), both under
    write_seqlock(&cs->stat.seqlock)) runs concurrently, read_seqretry()
    re-executes the loop body, summing every per-cpu counter a second time
    on top of the already-populated structs - producing over-counted values
    in the cs_stats output.
    
    Zero the accumulators at the top of each pass so a retry starts clean,
    and remove the initialization in the header as redundant.
    
    Fixes: d3a72ba5c1ae ("fs/fuse kio: implement cs_stats statistics info")
    https://virtuozzo.atlassian.net/browse/VSTOR-132310
    Signed-off-by: Konstantin Khorenko <[email protected]>
    
    Feature: vStorage
---
 fs/fuse/kio/pcs/fuse_stat.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/fs/fuse/kio/pcs/fuse_stat.c b/fs/fuse/kio/pcs/fuse_stat.c
index 447e4a617655..41bb9c71af90 100644
--- a/fs/fuse/kio/pcs/fuse_stat.c
+++ b/fs/fuse/kio/pcs/fuse_stat.c
@@ -331,15 +331,25 @@ static int do_show_cs_stats(struct pcs_cs *cs, void *ctx)
        struct seq_file *m = ctx;
        int rpc_state = cs->rpc ? cs->rpc->state : PCS_RPC_UNCONN;
        unsigned int in_flight_avg = cs->in_flight_avg;
-       struct fuse_lat_stat iolat = {}, netlat = {};
-       struct pcs_perf_rate_cnt read_ops_rate = {}, write_ops_rate = {},
-                                sync_ops_rate = {};
+       struct fuse_lat_stat iolat, netlat;
+       struct pcs_perf_rate_cnt read_ops_rate, write_ops_rate, sync_ops_rate;
        unsigned seq;
 
        do {
                int cpu;
 
                seq = read_seqbegin(&cs->stat.seqlock);
+               /*
+                * read_seqretry() may re-run this loop if a writer updated the
+                * stats meanwhile; zero the accumulators on every pass so a
+                * retry does not sum the per-cpu counters on top of the values
+                * already gathered by the previous (aborted) pass.
+                */
+               memset(&iolat, 0, sizeof(iolat));
+               memset(&netlat, 0, sizeof(netlat));
+               memset(&read_ops_rate, 0, sizeof(read_ops_rate));
+               memset(&write_ops_rate, 0, sizeof(write_ops_rate));
+               memset(&sync_ops_rate, 0, sizeof(sync_ops_rate));
                for_each_possible_cpu(cpu) {
                        struct fuse_lat_stat *pcpu_iolat, *pcpu_netlat;
                        struct pcs_perf_rate_cnt *pcpu_read_rate,
_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to