hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IAGRKP CVE: NA
--------------------------------
The time will be used later for dumping request in blk-io-hierarchy.
Signed-off-by: Yu Kuai yukuai3@huawei.com --- block/blk-core.c | 4 ++++ block/blk-flush.c | 1 + block/blk-merge.c | 1 + block/blk-mq.c | 1 + block/blk.h | 45 ++++++++++++++++++++++++++++++++++++++++++ include/linux/blkdev.h | 3 +++ 6 files changed, 55 insertions(+)
diff --git a/block/blk-core.c b/block/blk-core.c index caf3a897739e..5db196c0ef87 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -2106,6 +2106,7 @@ bool bio_attempt_back_merge(struct request_queue *q, struct request *req, req->biotail->bi_next = bio; req->biotail = bio; req->__data_len += bio->bi_iter.bi_size; + blk_rq_update_bi_alloc_time(req, bio, NULL);
blk_account_io_start(req, false); return true; @@ -2129,6 +2130,7 @@ bool bio_attempt_front_merge(struct request_queue *q, struct request *req,
req->__sector = bio->bi_iter.bi_sector; req->__data_len += bio->bi_iter.bi_size; + blk_rq_update_bi_alloc_time(req, bio, NULL);
blk_account_io_start(req, false); return true; @@ -2149,6 +2151,7 @@ bool bio_attempt_discard_merge(struct request_queue *q, struct request *req, req->biotail = bio; req->__data_len += bio->bi_iter.bi_size; req->nr_phys_segments = segments + 1; + blk_rq_update_bi_alloc_time(req, bio, NULL);
blk_account_io_start(req, false); return true; @@ -3727,6 +3730,7 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
rq->__data_len = bio->bi_iter.bi_size; rq->bio = rq->biotail = bio; + blk_rq_update_bi_alloc_time(rq, bio, NULL);
if (bio->bi_disk) rq->rq_disk = bio->bi_disk; diff --git a/block/blk-flush.c b/block/blk-flush.c index c1bfcde165af..5dda142819b2 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -377,6 +377,7 @@ static bool blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq, flush_rq->rq_flags |= RQF_FLUSH_SEQ; flush_rq->rq_disk = first_rq->rq_disk; flush_rq->end_io = flush_end_io; + blk_rq_init_bi_alloc_time(flush_rq, first_rq);
/* * Order WRITE ->end_io and WRITE rq->ref, and its pair is the one diff --git a/block/blk-merge.c b/block/blk-merge.c index d2fabe1fdf32..9f9d803e064b 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -784,6 +784,7 @@ static struct request *attempt_merge(struct request_queue *q, req->biotail = next->biotail;
req->__data_len += blk_rq_bytes(next); + blk_rq_update_bi_alloc_time(req, NULL, next);
if (!blk_discard_mergable(req)) elv_merge_requests(q, req, next); diff --git a/block/blk-mq.c b/block/blk-mq.c index 76dd32ee6172..f96f4bb8be92 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -367,6 +367,7 @@ static struct request *blk_mq_rq_ctx_init(struct blk_mq_alloc_data *data, rq->rq_disk = NULL; rq->part = NULL; rq->start_time_ns = blk_time_get_ns(); + blk_rq_init_bi_alloc_time(rq, NULL); rq->io_start_time_ns = 0; rq->nr_phys_segments = 0; #if defined(CONFIG_BLK_DEV_INTEGRITY) diff --git a/block/blk.h b/block/blk.h index 6a27b1a87c45..87c9ce9728a8 100644 --- a/block/blk.h +++ b/block/blk.h @@ -147,6 +147,51 @@ static inline void __blk_get_queue(struct request_queue *q) kobject_get(&q->kobj); }
+#ifdef CONFIG_BLK_BIO_ALLOC_TIME +static inline u64 blk_time_get_ns(void); +static inline void blk_rq_init_bi_alloc_time(struct request *rq, + struct request *first_rq) +{ + rq->bi_alloc_time_ns = first_rq ? first_rq->bi_alloc_time_ns : + blk_time_get_ns(); +} + +/* + * Used in following cases to updated request bi_alloc_time_ns: + * + * 1) Allocate a new @rq for @bio; + * 2) @bio is merged to @rq, in this case @merged_rq should be NULL; + * 3) @merged_rq is merged to @rq, in this case @bio should be NULL; + */ +static inline void blk_rq_update_bi_alloc_time(struct request *rq, + struct bio *bio, + struct request *merged_rq) +{ + if (bio) { + if (rq->bi_alloc_time_ns > bio->bi_alloc_time_ns) + rq->bi_alloc_time_ns = bio->bi_alloc_time_ns; + return; + } + + if (WARN_ON_ONCE(!merged_rq)) + return; + + if (rq->bi_alloc_time_ns > merged_rq->bi_alloc_time_ns) + rq->bi_alloc_time_ns = merged_rq->bi_alloc_time_ns; +} +#else /* CONFIG_BLK_BIO_ALLOC_TIME */ +static inline void blk_rq_init_bi_alloc_time(struct request *rq, + struct request *first_rq) +{ +} + +static inline void blk_rq_update_bi_alloc_time(struct request *rq, + struct bio *bio, + struct request *merged_rq) +{ +} +#endif /* CONFIG_BLK_BIO_ALLOC_TIME */ + bool is_flush_rq(struct request *req);
struct blk_flush_queue *blk_alloc_flush_queue(struct request_queue *q, diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 241f59eb5b64..c487c32b1bf4 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -225,6 +225,9 @@ struct request { u64 start_time_ns; /* Time that I/O was submitted to the device. */ u64 io_start_time_ns; +#ifdef CONFIG_BLK_BIO_ALLOC_TIME + u64 bi_alloc_time_ns; +#endif
#ifdef CONFIG_BLK_WBT unsigned short wbt_flags;