hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/release-management/issues/IB4E8P CVE: NA
--------------------------------
Like blk-throttle, following new debugfs entries will be created for rq-based disk:
/sys/kernel/debug/block/sda/blk_io_hierarchy/ |-- bio | |-- io_dump | |-- stats | `-- threshold
User can use them to analyze how bio behaves.
Signed-off-by: Yu Kuai yukuai3@huawei.com --- block/bio.c | 2 ++ block/blk-core.c | 7 +++++++ block/blk-io-hierarchy/Kconfig | 11 +++++++++++ block/blk-mq.c | 14 ++++++++++++-- block/blk-sysfs.c | 1 + 5 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/block/bio.c b/block/bio.c index d64b0da22e38..6f142d4c09ea 100644 --- a/block/bio.c +++ b/block/bio.c @@ -24,6 +24,7 @@ #include "blk.h" #include "blk-rq-qos.h" #include "blk-cgroup.h" +#include "blk-io-hierarchy/stats.h"
#define ALLOC_CACHE_THRESHOLD 16 #define ALLOC_CACHE_MAX 256 @@ -230,6 +231,7 @@ void bio_uninit(struct bio *bio) bio->pid = NULL; } #endif + bio_hierarchy_end(bio); } EXPORT_SYMBOL(bio_uninit);
diff --git a/block/blk-core.c b/block/blk-core.c index 0ba11c853051..80ea58299ef6 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -50,6 +50,7 @@ #include "blk-cgroup.h" #include "blk-throttle.h" #include "blk-ioprio.h" +#include "blk-io-hierarchy/stats.h"
struct dentry *blk_debugfs_root;
@@ -835,6 +836,12 @@ void submit_bio_noacct(struct bio *bio) break; }
+ /* + * On the one hand REQ_PREFLUSH | REQ_FUA can be cleared above, on the + * other hand it doesn't make sense to count invalid bio. Split bio will + * be accounted separately. + */ + bio_hierarchy_start(bio); if (blk_throtl_bio(bio)) return; submit_bio_noacct_nocheck(bio); diff --git a/block/blk-io-hierarchy/Kconfig b/block/blk-io-hierarchy/Kconfig index 0761a4bfb95d..ae8adf238059 100644 --- a/block/blk-io-hierarchy/Kconfig +++ b/block/blk-io-hierarchy/Kconfig @@ -142,4 +142,15 @@ config HIERARCHY_RQ_DRIVER
If unsure, say N.
+config HIERARCHY_BIO + bool "Support to record stats for bio lifetime" + default n + select BLK_BIO_ALLOC_TIME + help + Enabling this lets blk hierarchy stats to record additional information + for bio. Such information can be helpful to debug performance + and problems like io hang. + + If unsure, say N. + endif diff --git a/block/blk-mq.c b/block/blk-mq.c index 3c4b0ea44c00..7a9c9e4dc50e 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -790,8 +790,10 @@ static void req_bio_endio(struct request *rq, struct bio *bio, if (unlikely(rq->rq_flags & RQF_QUIET)) bio_set_flag(bio, BIO_QUIET); /* don't actually finish bio if it's part of flush sequence */ - if (bio->bi_iter.bi_size == 0 && !(rq->rq_flags & RQF_FLUSH_SEQ)) + if (bio->bi_iter.bi_size == 0 && !(rq->rq_flags & RQF_FLUSH_SEQ)) { + req_bio_hierarchy_end(rq, bio); bio_endio(bio); + } }
static void blk_account_io_completion(struct request *req, unsigned int bytes) @@ -856,8 +858,10 @@ static void blk_complete_request(struct request *req) if (req_op(req) == REQ_OP_ZONE_APPEND) bio->bi_iter.bi_sector = req->__sector;
- if (!is_flush) + if (!is_flush) { + req_bio_hierarchy_end(req, bio); bio_endio(bio); + } bio = next; } while (bio);
@@ -1115,6 +1119,7 @@ void blk_mq_end_request_batch(struct io_comp_batch *iob) prefetch(rq->bio); prefetch(rq->rq_next);
+ rq->io_end_time_ns = now; blk_complete_request(rq); if (iob->need_ts) __blk_mq_end_request_acct(rq, now); @@ -3043,6 +3048,8 @@ void blk_mq_submit_bio(struct bio *bio) bio = __bio_split_to_limits(bio, &q->limits, &nr_segs); if (!bio) return; + /* account for split bio. */ + bio_hierarchy_start(bio); } if (!bio_integrity_prep(bio)) return; @@ -3058,6 +3065,8 @@ void blk_mq_submit_bio(struct bio *bio) bio = __bio_split_to_limits(bio, &q->limits, &nr_segs); if (!bio) goto fail; + /* account for split bio. */ + bio_hierarchy_start(bio); } if (!bio_integrity_prep(bio)) goto fail; @@ -4412,6 +4421,7 @@ static void blk_mq_unregister_default_hierarchy(struct request_queue *q) blk_mq_unregister_hierarchy(q, STAGE_HCTX); blk_mq_unregister_hierarchy(q, STAGE_REQUEUE); blk_mq_unregister_hierarchy(q, STAGE_RQ_DRIVER); + blk_mq_unregister_hierarchy(q, STAGE_BIO); }
/* tags can _not_ be used after returning from blk_mq_exit_queue */ diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 866449af8681..7a38a1d5dceb 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -826,6 +826,7 @@ static void blk_mq_register_default_hierarchy(struct request_queue *q) blk_mq_register_hierarchy(q, STAGE_HCTX); blk_mq_register_hierarchy(q, STAGE_REQUEUE); blk_mq_register_hierarchy(q, STAGE_RQ_DRIVER); + blk_mq_register_hierarchy(q, STAGE_BIO); }
/**