From: Li Lingfeng <lilingfeng3@xxxxxxxxxx> When interrupt is turned on while a lock holding by spin_lock_irq it throws a warning because of potential deadlock. blk_mq_mark_tag_wait spin_lock_irq(&wq->lock) --> turn off interrupt and get lockA blk_mq_get_driver_tag __blk_mq_tag_busy spin_lock_irq(&tags->lock) spin_unlock_irq(&tags->lock) --> release lockB and turn on interrupt accidentally ... --> Interrupt may be triggered and try get wq->lock while it is held blk_complete_reqs ... blk_mq_put_tag ... __wake_up_common_lock spin_lock_irqsave --> try get lock again ... spin_unlock_irq(&wq->lock) Fix it by using spin_lock_irqsave to get lockB instead of spin_lock_irq. Fixes: 4f1731df60f9 ("blk-mq: fix potential io hang by wrong 'wake_batch'") Signed-off-by: Li Lingfeng <lilingfeng3@xxxxxxxxxx> --- block/blk-mq-tag.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c index cc57e2dd9a0b..2cafcf11ee8b 100644 --- a/block/blk-mq-tag.c +++ b/block/blk-mq-tag.c @@ -38,6 +38,7 @@ static void blk_mq_update_wake_batch(struct blk_mq_tags *tags, void __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx) { unsigned int users; + unsigned long flags; struct blk_mq_tags *tags = hctx->tags; /* @@ -56,11 +57,11 @@ void __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx) return; } - spin_lock_irq(&tags->lock); + spin_lock_irqsave(&tags->lock, flags); users = tags->active_queues + 1; WRITE_ONCE(tags->active_queues, users); blk_mq_update_wake_batch(tags, users); - spin_unlock_irq(&tags->lock); + spin_unlock_irqrestore(&tags->lock, flags); } /* -- 2.31.1