Re: [PATCH] block/blk-stat: fix mean loss when re-summing aggregated stats

Tao Cui <[email protected]>
Newsgroups org.kernel.vger.cgroups,org.kernel.vger.linux-block,org.kernel.vger.linux-kernel
Message-ID <[email protected]>

在 2026/7/21 01:05, Tang Yizhou 写道:
> On 20/7/26 9:38 pm, Tao Cui wrote:
>> From: Tao Cui <[email protected]>
>>
>> blk_rq_stat_sum() folds src into dst but only advances dst->mean and
>> dst->nr_samples, leaving dst->batch untouched.  The mean is computed
>> from src->batch (the raw per-cpu sum), so a stat that has already been
>> through one sum carries batch=0; if that aggregated stat is then used
>> as the src of another sum, its samples add nothing to the new mean.
>>
>> iolatency hits exactly that: iolatency_check_latencies() first sums the
>> per-cpu stats into a local stat, then sums that local stat into
>> iolat->cur_stat.  After the first sum the local stat has batch=0, so
>> every later window drives cur_stat->mean toward zero.  On non-SSD
> 
> Good catch, this is indeed a real issue.
> 
>> devices it stays at 0, making the latency_sum_ok(&cur_stat) check that
>> gates scaling up always true -- the scale-up hysteresis is effectively
>> defeated.  SSD devices use the percentile path and are unaffected.
>>
>> Keep dst->batch in sync across sums so an aggregated stat can be reused
>> as a src.  blk_rq_stat.batch is internal to blk_rq_stat_init/_add/_sum
>> (no other reader in the tree), so the wbt and blk-mq consumers, which
>> only read ->mean/->min/->nr_samples, behave as before.
>>
>> Fixes: 34dbad5d26e2 ("blk-stat: convert to callback-based statistics reporting")
>> Signed-off-by: Tao Cui <[email protected]>
>>
>> ---
>>  block/blk-stat.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/block/blk-stat.c b/block/blk-stat.c
>> index de126e1ea5ac..4d4781350083 100644
>> --- a/block/blk-stat.c
>> +++ b/block/blk-stat.c
>> @@ -36,6 +36,7 @@ void blk_rq_stat_sum(struct blk_rq_stat *dst, struct blk_rq_stat *src)
>>  	dst->mean = div_u64(src->batch + dst->mean * dst->nr_samples,
>>  				dst->nr_samples + src->nr_samples);
>>  
>> +	dst->batch += src->batch;
> 
> This change doesn't actually fix the issue. As you already found, the local
> stat's batch is 0. Also, according to the comment of blk_rq_stat_sum(), @src is
> a per-CPU stat, so there is no issue in blk_stat_timer_fn(). Your change would
> actually make this case look strange.
> 
You're right. blk_rq_stat_sum() is contracted on a raw per-cpu src,
which blk_stat_timer_fn() honors; the actual misuse is iolatency
feeding an already-aggregated stat at blk-iolatency.c. I'll drop
the blk-stat.c change and fix it on the iolatency side — merging
cur_stat with the per-window stat by their reconstructed totals, since
both already carry a valid mean. Will send a v2.

Thanks,
Tao
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.