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/ |-- hctx | |-- io_dump | |-- stats | `-- threshold
User can use them to analyze how IO behaves in hctx.
Signed-off-by: Yu Kuai yukuai3@huawei.com --- block/blk-flush.c | 2 ++ block/blk-io-hierarchy/Kconfig | 10 ++++++++++ block/blk-mq-sched.c | 2 ++ block/blk-mq.c | 5 +++++ block/blk-sysfs.c | 1 + include/linux/blk_types.h | 1 + 6 files changed, 21 insertions(+)
diff --git a/block/blk-flush.c b/block/blk-flush.c index 4628a9ee1904..354ed5d2a853 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -185,6 +185,7 @@ static void blk_flush_complete_seq(struct request *rq, if (list_empty(pending)) fq->flush_pending_since = jiffies; list_add_tail(&rq->queuelist, pending); + rq_hierarchy_start_io_acct(rq, STAGE_HCTX); break;
case REQ_FSEQ_DATA: @@ -264,6 +265,7 @@ static enum rq_end_io_ret flush_end_io(struct request *flush_rq,
BUG_ON(seq != REQ_FSEQ_PREFLUSH && seq != REQ_FSEQ_POSTFLUSH); list_del_init(&rq->queuelist); + rq_hierarchy_end_io_acct(rq, STAGE_HCTX); blk_flush_complete_seq(rq, fq, seq, error); }
diff --git a/block/blk-io-hierarchy/Kconfig b/block/blk-io-hierarchy/Kconfig index 3cc51933def3..6a36f7b83f51 100644 --- a/block/blk-io-hierarchy/Kconfig +++ b/block/blk-io-hierarchy/Kconfig @@ -112,4 +112,14 @@ config HIERARCHY_KYBER
If unsure, say N.
+config HIERARCHY_HCTX + bool "Enable hierarchy stats layer hctx" + default n + help + Enabling this lets blk hierarchy stats to record additional information + for hctx. Such information can be helpful to debug performance + and problems like io hang. + + If unsure, say N. + endif diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c index 67c95f31b15b..7b48630b63a7 100644 --- a/block/blk-mq-sched.c +++ b/block/blk-mq-sched.c @@ -15,6 +15,7 @@ #include "blk-mq-debugfs.h" #include "blk-mq-sched.h" #include "blk-wbt.h" +#include "blk-io-hierarchy/stats.h"
/* * Mark a hardware queue as needing a restart. @@ -298,6 +299,7 @@ static int __blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx) */ if (!list_empty(&rq_list)) { blk_mq_sched_mark_restart_hctx(hctx); + rq_list_hierarchy_end_io_acct(&rq_list, STAGE_HCTX); if (!blk_mq_dispatch_rq_list(hctx, &rq_list, 0)) return 0; need_dispatch = true; diff --git a/block/blk-mq.c b/block/blk-mq.c index bf1329ada77b..9e67d097e29b 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -2147,6 +2147,7 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list, if (nr_budgets) blk_mq_release_budgets(q, list);
+ rq_list_hierarchy_start_io_acct(list, STAGE_HCTX); spin_lock(&hctx->lock); list_splice_tail_init(list, &hctx->dispatch); spin_unlock(&hctx->lock); @@ -2508,6 +2509,7 @@ static void blk_mq_request_bypass_insert(struct request *rq, blk_insert_t flags) { struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
+ rq_hierarchy_start_io_acct(rq, STAGE_HCTX); spin_lock(&hctx->lock); if (flags & BLK_MQ_INSERT_AT_HEAD) list_add(&rq->queuelist, &hctx->dispatch); @@ -2815,6 +2817,7 @@ static void blk_mq_dispatch_plug_list(struct blk_plug *plug, bool from_sched) percpu_ref_get(&this_hctx->queue->q_usage_counter); /* passthrough requests should never be issued to the I/O scheduler */ if (is_passthrough) { + rq_list_hierarchy_start_io_acct(&list, STAGE_HCTX); spin_lock(&this_hctx->lock); list_splice_tail_init(&list, &this_hctx->dispatch); spin_unlock(&this_hctx->lock); @@ -3618,6 +3621,7 @@ static int blk_mq_hctx_notify_dead(unsigned int cpu, struct hlist_node *node) if (list_empty(&tmp)) return 0;
+ rq_list_hierarchy_start_io_acct(&tmp, STAGE_HCTX); spin_lock(&hctx->lock); list_splice_tail_init(&tmp, &hctx->dispatch); spin_unlock(&hctx->lock); @@ -4388,6 +4392,7 @@ static void blk_mq_unregister_default_hierarchy(struct request_queue *q) { blk_mq_unregister_hierarchy(q, STAGE_GETTAG); blk_mq_unregister_hierarchy(q, STAGE_PLUG); + blk_mq_unregister_hierarchy(q, STAGE_HCTX); }
/* 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 1539a137502e..428db09db8e8 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -823,6 +823,7 @@ static void blk_mq_register_default_hierarchy(struct request_queue *q) { blk_mq_register_hierarchy(q, STAGE_GETTAG); blk_mq_register_hierarchy(q, STAGE_PLUG); + blk_mq_register_hierarchy(q, STAGE_HCTX); }
/** diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 95fdc8fc2dc5..898dc10c99e2 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -498,6 +498,7 @@ enum stage_group { #if IS_ENABLED(CONFIG_MQ_IOSCHED_KYBER) STAGE_KYBER, #endif + STAGE_HCTX, NR_RQ_STAGE_GROUPS, STAGE_BIO = NR_RQ_STAGE_GROUPS, NR_STAGE_GROUPS,