From: Yu Kuai yukuai3@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IAAQ73
--------------------------------
Because slow io or io timeout handler can take a long time, hungtask check is forbidden in order to prevent false positive warnings. However, this also cause kenel to be silence if io really hang.
It's quite complicated to distinguish if io is slow or hanged, this patch add a switch to enable hungtask check, the switch is enabled by default, and can be turn off by:
1) disable config BLK_IO_HUNG_TASK_CHECK 2) add blk_core.io_hung_task_check=0 to boot cmd 3) echo 0 > /sys/module/blk_core/parameters/io_hung_task_check
Noted that user has to be careful to use this with hungtask panic enabeld, since there could be false positive hungtask warnings.
Signed-off-by: Yu Kuai yukuai3@huawei.com
Fixes: 4b1977698ceb ("block: Prevent hang_check firing during long I/O") Fixes: e6249cdd46e4 ("block: add blk_io_schedule() for avoiding task hung in sync dio") Fixes: de6a78b601c5 ("block: Prevent hung_check firing during long sync IO") Signed-off-by: Li Lingfeng lilingfeng3@huawei.com --- block/Kconfig | 9 +++++++++ block/bio.c | 2 +- block/blk-core.c | 13 ++++++++++++- block/blk-mq.c | 2 +- block/blk.h | 1 + 5 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/block/Kconfig b/block/Kconfig index 2e70a431d417..04bb49f13176 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -266,6 +266,15 @@ config BLK_DEV_WRITE_MOUNTED_DUMP Enabling this to dump info when opening mounted block devices for write or trying to mount write opened block devices.
+config BLK_IO_HUNG_TASK_CHECK + bool "Enable io hung task check" + depends on DETECT_HUNG_TASK + default y + help + Enabling this lets the block layer detect hungtask for io, noted + if this is set, hungtask will complain about slow io even if such + io is not hanged. Be careful to enable hungtask panic in this case. + source "block/partitions/Kconfig"
config BLK_MQ_PCI diff --git a/block/bio.c b/block/bio.c index 62419aa09d73..bf6bec43b27e 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1375,7 +1375,7 @@ int submit_bio_wait(struct bio *bio) submit_bio(bio);
/* Prevent hang_check timer from firing at us during very long I/O */ - hang_check = sysctl_hung_task_timeout_secs; + hang_check = sysctl_hung_task_timeout_secs && !io_hung_task_check; if (hang_check) while (!wait_for_completion_io_timeout(&done, hang_check * (HZ/2))) diff --git a/block/blk-core.c b/block/blk-core.c index 2f1b2f0980c4..2e0edda71e1e 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -86,6 +86,17 @@ static int __init precise_iostat_setup(char *str) } __setup("precise_iostat=", precise_iostat_setup);
+/* + * Noted if this is set, hungtask will complain about slow io even if such io is + * not hanged. Be careful to enable hungtask panic in this case. + */ +#ifdef CONFIG_BLK_IO_HUNG_TASK_CHECK +bool io_hung_task_check = true; +#else +bool io_hung_task_check; +#endif +module_param_named(io_hung_task_check, io_hung_task_check, bool, 0644); + /** * blk_queue_flag_set - atomically set a queue flag * @flag: flag to be set @@ -1205,7 +1216,7 @@ void blk_io_schedule(void) /* Prevent hang_check timer from firing at us during very long I/O */ unsigned long timeout = sysctl_hung_task_timeout_secs * HZ / 2;
- if (timeout) + if (timeout && !io_hung_task_check) io_schedule_timeout(timeout); else io_schedule(); diff --git a/block/blk-mq.c b/block/blk-mq.c index f99accfddbee..13fc3561c870 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1420,7 +1420,7 @@ blk_status_t blk_execute_rq(struct request *rq, bool at_head) * Prevent hang_check timer from firing at us during very long * I/O */ - unsigned long hang_check = sysctl_hung_task_timeout_secs; + unsigned long hang_check = sysctl_hung_task_timeout_secs && !io_hung_task_check;
if (hang_check) while (!wait_for_completion_io_timeout(&wait.done, diff --git a/block/blk.h b/block/blk.h index 67915b04b3c1..3874d6037230 100644 --- a/block/blk.h +++ b/block/blk.h @@ -13,6 +13,7 @@ struct elevator_type; #define BLK_MAX_TIMEOUT (5 * HZ)
extern struct dentry *blk_debugfs_root; +extern bool io_hung_task_check;
struct blk_flush_queue { spinlock_t mq_flush_lock;