lkml.org 
[lkml]   [2026]   [Apr]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Date
Signed-off-by: Li kunyu <likunyu10@163.com>
---
block/bio.c | 2 ++
block/blk-iolatency.c | 34 ++++++++++++++++++++++++++++++++++
block/blk-merge.c | 7 ++++++-
block/blk-rq-qos.h | 11 +++++++++++
include/linux/blk_types.h | 2 ++
5 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/block/bio.c b/block/bio.c
index b8972dba68a0..7740701afc7f 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1733,6 +1733,8 @@ static inline bool bio_remaining_done(struct bio *bio)
return true;
}

+ rq_qos_done_split_bio(bio);
+
return false;
}

diff --git a/block/blk-iolatency.c b/block/blk-iolatency.c
index 53e8dd2dfa8a..ba5870bf14c5 100644
--- a/block/blk-iolatency.c
+++ b/block/blk-iolatency.c
@@ -632,6 +632,39 @@ static void blkcg_iolatency_done_bio(struct rq_qos *rqos, struct bio *bio)
}
}

+static void blkcg_iolatency_done_split_bio(struct rq_qos *rqos, struct bio *bio)
+{
+ struct blkcg_gq *blkg;
+ struct rq_wait *rqw;
+ struct iolatency_grp *iolat;
+ int inflight = 0;
+
+ blkg = bio->bi_blkg;
+ if (!blkg || !bio_flagged(bio, BIO_QOS_CHAIN_CHILD))
+ return;
+
+ iolat = blkg_to_lat(bio->bi_blkg);
+ if (!iolat)
+ return;
+
+ if (!iolat->blkiolat->enabled)
+ return;
+
+ while (blkg && blkg->parent) {
+ iolat = blkg_to_lat(blkg);
+ if (!iolat) {
+ blkg = blkg->parent;
+ continue;
+ }
+ rqw = &iolat->rq_wait;
+
+ inflight = atomic_dec_return(&rqw->inflight);
+ WARN_ON_ONCE(inflight < 0);
+
+ blkg = blkg->parent;
+ }
+}
+
static void blkcg_iolatency_exit(struct rq_qos *rqos)
{
struct blk_iolatency *blkiolat = BLKIOLATENCY(rqos);
@@ -645,6 +678,7 @@ static void blkcg_iolatency_exit(struct rq_qos *rqos)
static const struct rq_qos_ops blkcg_iolatency_ops = {
.throttle = blkcg_iolatency_throttle,
.done_bio = blkcg_iolatency_done_bio,
+ .done_split_bio = blkcg_iolatency_done_split_bio,
.exit = blkcg_iolatency_exit,
};

diff --git a/block/blk-merge.c b/block/blk-merge.c
index fcf09325b22e..c236f9b34044 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -151,8 +151,13 @@ static struct bio *bio_submit_split(struct bio *bio, int split_sectors)
if (split_sectors) {
bio = bio_submit_split_bioset(bio, split_sectors,
&bio->bi_bdev->bd_disk->bio_split);
- if (bio)
+ if (bio) {
bio->bi_opf |= REQ_NOMERGE;
+ /* Fix the issue where the inflight statistics
+ * of the chained bio in the QoS are incorrect.
+ */
+ bio_set_flag(split, BIO_QOS_CHAIN_CHILD);
+ }
}

return bio;
diff --git a/block/blk-rq-qos.h b/block/blk-rq-qos.h
index a747a504fe42..496a27b9d412 100644
--- a/block/blk-rq-qos.h
+++ b/block/blk-rq-qos.h
@@ -45,6 +45,7 @@ struct rq_qos_ops {
void (*cleanup)(struct rq_qos *, struct bio *);
void (*queue_depth_changed)(struct rq_qos *);
void (*exit)(struct rq_qos *);
+ void (*done_split_bio)(struct rq_qos *, struct bio *);
const struct blk_mq_debugfs_attr *debugfs_attrs;
};

@@ -108,6 +109,7 @@ void __rq_qos_throttle(struct rq_qos *rqos, struct bio *bio);
void __rq_qos_track(struct rq_qos *rqos, struct request *rq, struct bio *bio);
void __rq_qos_merge(struct rq_qos *rqos, struct request *rq, struct bio *bio);
void __rq_qos_done_bio(struct rq_qos *rqos, struct bio *bio);
+void __rq_qos_done_split_bio(struct rq_qos *rqos, struct bio *bio);
void __rq_qos_queue_depth_changed(struct rq_qos *rqos);

static inline void rq_qos_cleanup(struct request_queue *q, struct bio *bio)
@@ -157,6 +159,15 @@ static inline void rq_qos_done_bio(struct bio *bio)
__rq_qos_done_bio(q->rq_qos, bio);
}

+static inline void rq_qos_done_split_bio(struct bio *bio)
+{
+ if (bio->bi_bdev && bio_flagged(bio, BIO_QOS_CHAIN_CHILD)) {
+ struct request_queue *q = bdev_get_queue(bio->bi_bdev);
+ if (q->rq_qos)
+ __rq_qos_done_split_bio(q->rq_qos, bio);
+ }
+}
+
static inline void rq_qos_throttle(struct request_queue *q, struct bio *bio)
{
if (test_bit(QUEUE_FLAG_QOS_ENABLED, &q->queue_flags) && q->rq_qos) {
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 8808ee76e73c..63fee89ecc14 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -322,6 +322,8 @@ enum {
BIO_REMAPPED,
BIO_ZONE_WRITE_PLUGGING, /* bio handled through zone write plugging */
BIO_EMULATES_ZONE_APPEND, /* bio emulates a zone append operation */
+ BIO_QOS_CHAIN_CHILD, /* chained bio child, used for segmenting out
+ * the bio */
BIO_FLAG_LAST
};

--
2.47.3

\
 
 \ /
  Last update: 2026-04-29 11:44    [W:0.069 / U:9.819 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and my Meterkast|Read the blog