FAILED: patch "[PATCH] blk-mq: order adding requests to hctx->dispatch and checking" failed to apply to 4.14-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From d7d8535f377e9ba87edbf7fbbd634ac942f3f54f Mon Sep 17 00:00:00 2001
From: Ming Lei <[email protected]>
Date: Mon, 17 Aug 2020 18:01:15 +0800
Subject: [PATCH] blk-mq: order adding requests to hctx->dispatch and checking
SCHED_RESTART
SCHED_RESTART code path is relied to re-run queue for dispatch requests in hctx->dispatch. Meantime the SCHED_RSTART flag is checked when adding requests to hctx->dispatch.
memory barriers have to be used for ordering the following two pair of OPs:
1) adding requests to hctx->dispatch and checking SCHED_RESTART in blk_mq_dispatch_rq_list()
2) clearing SCHED_RESTART and checking if there is request in hctx->dispatch in blk_mq_sched_restart().
Without the added memory barrier, either:
1) blk_mq_sched_restart() may miss requests added to hctx->dispatch meantime blk_mq_dispatch_rq_list() observes SCHED_RESTART, and not run queue in dispatch side
or
2) blk_mq_dispatch_rq_list still sees SCHED_RESTART, and not run queue in dispatch side, meantime checking if there is request in hctx->dispatch from blk_mq_sched_restart() is missed.
IO hang in ltp/fs_fill test is reported by kernel test robot:
https://lkml.org/lkml/2020/7/26/77
Turns out it is caused by the above out-of-order OPs. And the IO hang can't be observed any more after applying this patch.
block/blk-mq-sched.c +9 -0
@@ -78,6 +78,15 @@ void blk_mq_sched_restart(struct blk_mq_hw_ctx *hctx)return ;clear_bit (BLK_MQ_S_SCHED_RESTART , &hctx->state); +/* +* Order clearing SCHED_RESTART and list_empty_careful(&hctx->dispatch) +* in blk_mq_run_hw_queue(). Its pair is the barrier in +* blk_mq_dispatch_rq_list(). So dispatch code won't see SCHED_RESTART, +* meantime new request added to hctx->dispatch is missed to check in +* blk_mq_run_hw_queue(). +*/ +smp_mb (); +blk_mq_run_hw_queue (hctx, true); }
block/blk-mq.c +9 -0
@@ -1437,6 +1437,15 @@ bool blk_mq_dispatch_rq_list(struct blk_mq_hw_ctx *hctx, struct list_head *list,list_splice_tail_init (list, &hctx->dispatch);spin_unlock (&hctx->lock); +/* +* Order adding requests to hctx->dispatch and checking +* SCHED_RESTART flag. The pair of this smp_mb() is the one +* in blk_mq_sched_restart(). Avoid restart code path to +* miss the new added requests to hctx->dispatch, meantime +* SCHED_RESTART is observed here. +*/ +smp_mb (); +/* * If SCHED_RESTART was set by the caller of this function and * it is no longer set that means that it was cleared by another