Re: [PATCH 1/4] blk-iocost: charge flushes as pageless random writes
From: Tao Cui
Date: Wed Sep 16 2026 - 04:24:30 EST
Hi, Christoph
在 2026/9/10 13:41, Christoph Hellwig 写道:
> On Tue, Sep 08, 2026 at 10:21:32AM +0800, Tao Cui wrote:
>> From: Tao Cui <cuitao@xxxxxxxxxx>
>>
>> Standalone flushes issued by blkdev_issue_flush() are represented as
>> dataless REQ_OP_WRITE | REQ_PREFLUSH bios, which
>> calc_vtime_cost_builtin() prices at zero. The flush component of
>> flush-heavy workloads such as database commits, journal flushes, and
>> metadata sync is thus neither charged nor throttled: a cgroup at 1% weight
>> can issue ~510k flushes per 12s, monopolizing the device while iocost
>> reports zero usage.
>>
>> Price them as pageless random writes (LCOEF_WRANDIO), which provides
>> an approximation of the device time consumed by a flush. For
>> profiles where WRANDIO clamps to zero (ssd_dfl / ssd_fast), use a
>> one-page floor (LCOEF_WPAGE). After this patch, the same 1%-weight
>> cgroup is limited to 24 flushes per 12s; on ext4, write+fsync
>> workloads are correctly accounted through the journal layer (~2.2us
>> per flush on the ssd_fast profile).
>
> Flushes are actually a really interesting case. For devics with
> a non-volatile write cache they are no-ops, but submit_bio should
> ensure we never see them here.
Confirmed. submit_bio_noacct() strips REQ_PREFLUSH and completes
dataless flush bios early when !bdev_write_cache(), so they never
reach ioc_rqos_throttle(). The charge only applies where the device
actually has to drain a cache.
> But devices with a volatile write
> cache they are significantly more expensive than any kind of write.
> If we touch this we should probably figure out a way to model that.
> Note that this includes standalone flushes and PREFLUSH ones,
> so this patch might be a good start, but still is missing a very
> important part.
Right. The PREFLUSH component of data-bearing writes is the same
class of bug as the standalone flush (uncharged device time), so I'll
fold that into v2 as a bugfix: any REQ_PREFLUSH bio gets a flush
surcharge on top of its data cost, with the same write-coefficient
fallback.
For the pricing itself I'm preparing a follow-up RFC with a dedicated
flushiops= entry in io.cost.model, translated to VTIME_PER_SEC /
flushiops like the other iops coefficients, and falling back to the
write coefficients when unset. On virtio-blk, flushiops=10 throttles
a flush storm to one flush per 100ms, which is exactly the intended
budget. Parameter naming and whether the builtin profiles and
autocalibration should learn it are better discussed on that thread.