hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IAGRKP CVE: NA
--------------------------------
Like blk-throttle, following new debugfs entries will be created as well:
/sys/kernel/debug/block/sda/blk_io_hierarchy/ |-- gettag | |-- io_dump | |-- stats | `-- threshold
User can use them to analyze how IO behaves in gettag.
Signed-off-by: Yu Kuai yukuai3@huawei.com --- block/blk-core.c | 7 +++++++ block/blk-io-hierarchy/Kconfig | 10 ++++++++++ block/blk-io-hierarchy/debugfs.c | 3 +++ block/blk-mq-tag.c | 5 +++++ block/blk-sysfs.c | 11 +++++++++++ include/linux/blk_types.h | 2 +- 6 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/block/blk-core.c b/block/blk-core.c index 5db196c0ef87..bd232d9106ad 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -43,6 +43,7 @@ #include "blk-mq.h" #include "blk-mq-sched.h" #include "blk-rq-qos.h" +#include "blk-io-hierarchy/stats.h"
#ifdef CONFIG_DEBUG_FS struct dentry *blk_debugfs_root; @@ -1001,6 +1002,11 @@ void blk_exit_queue(struct request_queue *q) bdi_put(q->backing_dev_info); }
+static void blk_mq_unregister_default_hierarchy(struct request_queue *q) +{ + blk_mq_unregister_hierarchy(q, STAGE_GETTAG); +} + /** * blk_cleanup_queue - shutdown a request queue * @q: request queue to shutdown @@ -1088,6 +1094,7 @@ void blk_cleanup_queue(struct request_queue *q) blk_exit_queue(q);
if (q->mq_ops) { + blk_mq_unregister_default_hierarchy(q); blk_mq_cancel_work_sync(q); blk_mq_exit_queue(q); } diff --git a/block/blk-io-hierarchy/Kconfig b/block/blk-io-hierarchy/Kconfig index ad1b7abc7610..2b9ccc2060b6 100644 --- a/block/blk-io-hierarchy/Kconfig +++ b/block/blk-io-hierarchy/Kconfig @@ -48,4 +48,14 @@ config HIERARCHY_WBT
If unsure, say N.
+config HIERARCHY_GETTAG + bool "Enable hierarchy stats layer gettag" + default n + help + Enabling this lets blk hierarchy stats to record additional information + for gettag. Such information can be helpful to debug performance + and problems like io hang. + + If unsure, say N. + endif diff --git a/block/blk-io-hierarchy/debugfs.c b/block/blk-io-hierarchy/debugfs.c index 327ed5c88edc..79062cd90c08 100644 --- a/block/blk-io-hierarchy/debugfs.c +++ b/block/blk-io-hierarchy/debugfs.c @@ -25,6 +25,9 @@ static const char *stage_name[NR_STAGE_GROUPS] = { #ifdef CONFIG_HIERARCHY_WBT [STAGE_WBT] = "wbt", #endif +#ifdef CONFIG_HIERARCHY_GETTAG + [STAGE_GETTAG] = "gettag", +#endif };
const char *hierarchy_stage_name(enum stage_group stage) diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c index 65464f0fe0fa..f7b21d7f136e 100644 --- a/block/blk-mq-tag.c +++ b/block/blk-mq-tag.c @@ -13,6 +13,7 @@ #include "blk.h" #include "blk-mq.h" #include "blk-mq-tag.h" +#include "blk-io-hierarchy/stats.h"
bool blk_mq_has_free_tags(struct blk_mq_tags *tags) { @@ -134,6 +135,8 @@ unsigned int blk_mq_get_tag(struct blk_mq_alloc_data *data) if (data->flags & BLK_MQ_REQ_NOWAIT) return BLK_MQ_TAG_FAIL;
+ if (data->bio) + bio_hierarchy_start_io_acct(data->bio, STAGE_GETTAG); ws = bt_wait_ptr(bt, data->hctx); do { struct sbitmap_queue *bt_prev; @@ -185,6 +188,8 @@ unsigned int blk_mq_get_tag(struct blk_mq_alloc_data *data) } while (1);
finish_wait(&ws->wait, &wait); + if (data->bio) + bio_hierarchy_end_io_acct(data->bio, STAGE_GETTAG);
found_tag: return tag + tag_offset; diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 1c4d795bbdc4..1a8872409ab8 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -17,6 +17,7 @@ #include "blk-mq.h" #include "blk-mq-debugfs.h" #include "blk-wbt.h" +#include "blk-io-hierarchy/stats.h"
struct queue_sysfs_entry { struct attribute attr; @@ -924,6 +925,14 @@ struct kobj_type blk_queue_ktype = { .release = blk_release_queue, };
+static void blk_mq_register_default_hierarchy(struct request_queue *q) +{ + if (!q->mq_ops) + return; + + blk_mq_register_hierarchy(q, STAGE_GETTAG); +} + /** * blk_register_queue - register a block layer queue with sysfs * @disk: Disk of which the request queue should be registered with sysfs. @@ -973,6 +982,8 @@ int blk_register_queue(struct gendisk *disk) has_elevator = true; }
+ blk_mq_register_default_hierarchy(q); + blk_queue_flag_set(QUEUE_FLAG_REGISTERED, q); wbt_enable_default(q); blk_throtl_register_queue(q); diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 7ffe59d6d64e..3e9068552ab0 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -392,7 +392,7 @@ enum stage_group { #ifdef CONFIG_BLK_WBT STAGE_WBT, #endif - STAGE_BIO_RESERVE, + STAGE_GETTAG, NR_BIO_STAGE_GROUPS, NR_RQ_STAGE_GROUPS, NR_STAGE_GROUPS,