diff options
author | Keith Busch <kbusch@kernel.org> | 2021-12-20 21:59:19 +0100 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2021-12-20 22:03:59 +0100 |
commit | 518579a9af10a4b7b952a8366566fdcc7cfce3ca (patch) | |
tree | 8370391dff5fc5f2c809724f43069cf6c094ac13 /block | |
parent | blktrace: switch trace spinlock to a raw spinlock (diff) | |
download | linux-518579a9af10a4b7b952a8366566fdcc7cfce3ca.tar.xz linux-518579a9af10a4b7b952a8366566fdcc7cfce3ca.zip |
blk-mq: blk-mq: check quiesce state before queue_rqs
The low level drivers don't expect to see new requests after a
successful quiesce completes. Check the queue quiesce state within the
rcu protected area prior to calling the driver's queue_rqs().
Fixes: 3c67d44de787 ("block: add mq_ops->queue_rqs hook")
Signed-off-by: Keith Busch <kbusch@kernel.org>
Link: https://lore.kernel.org/r/20211220205919.180191-1-kbusch@kernel.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-mq.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c index 51991232824a..0d7c9d3e0329 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -2549,6 +2549,14 @@ static void blk_mq_plug_issue_direct(struct blk_plug *plug, bool from_schedule) blk_mq_commit_rqs(hctx, &queued, from_schedule); } +static void __blk_mq_flush_plug_list(struct request_queue *q, + struct blk_plug *plug) +{ + if (blk_queue_quiesced(q)) + return; + q->mq_ops->queue_rqs(&plug->mq_list); +} + void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule) { struct blk_mq_hw_ctx *this_hctx; @@ -2580,7 +2588,7 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule) if (q->mq_ops->queue_rqs && !(rq->mq_hctx->flags & BLK_MQ_F_TAG_QUEUE_SHARED)) { blk_mq_run_dispatch_ops(q, - q->mq_ops->queue_rqs(&plug->mq_list)); + __blk_mq_flush_plug_list(q, plug)); if (rq_list_empty(plug->mq_list)) return; } |