Thread (8 messages) 8 messages, 2 authors, 22d ago

[PATCH 1/4] blk-iocost: charge flushes as pageless random writes

flat view
COLD22d

From: Tao Cui <hidden>
Date: 2026-09-08 02:22:01
Also in: cgroups, lkml
Subsystem: block layer, control group - block io controller (blkio), the rest · Maintainers: Jens Axboe, Tejun Heo, Josef Bacik, Linus Torvalds

Revision v1 of 3 in this series.

Revisions (3)
  1. v1 current
  2. v2 [diff vs current]
  3. v3 [diff vs current]
From: Tao Cui <redacted>

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).

Fixes: 7caa47151ab2 ("blkcg: implement blk-iocost")
Signed-off-by: Tao Cui <redacted>
---
 block/blk-iocost.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/block/blk-iocost.c b/block/blk-iocost.c
index 2745bffcd5ee..abc512532ed9 100644
--- a/block/blk-iocost.c
+++ b/block/blk-iocost.c
@@ -2533,8 +2533,8 @@ static void calc_vtime_cost_builtin(struct bio *bio, struct ioc_gq *iocg,
 	u64 seek_pages = 0;
 	u64 cost = 0;
 
-	/* Can't calculate cost for empty bio */
-	if (!bio->bi_iter.bi_size)
+	/* Dataless WRITE|REQ_PREFLUSH (standalone flush) is priced below */
+	if (!bio->bi_iter.bi_size && !(bio->bi_opf & REQ_PREFLUSH))
 		goto out;
 
 	switch (bio_op(bio)) {
@@ -2544,6 +2544,15 @@ static void calc_vtime_cost_builtin(struct bio *bio, struct ioc_gq *iocg,
 		coef_page	= ioc->params.lcoefs[LCOEF_RPAGE];
 		break;
 	case REQ_OP_WRITE:
+		if (!bio->bi_iter.bi_size) {
+			/*
+			 * dataless WRITE|REQ_PREFLUSH: standalone flush;
+			 * at least one page so fast profiles still charge
+			 */
+			cost = max(ioc->params.lcoefs[LCOEF_WRANDIO],
+				   ioc->params.lcoefs[LCOEF_WPAGE]);
+			goto out;
+		}
 		coef_seqio	= ioc->params.lcoefs[LCOEF_WSEQIO];
 		coef_randio	= ioc->params.lcoefs[LCOEF_WRANDIO];
 		coef_page	= ioc->params.lcoefs[LCOEF_WPAGE];
-- 
2.43.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help