All block driver code except loop_set_dio() calls queue_limits_start_update() before it freezes the request queue. Make loop_set_dio() follow this convention. This patch fixes the following lockdep complaint: ====================================================== WARNING: possible circular locking dependency detected 7.2.0-rc5-dbg #11 Not tainted ------------------------------------------------------ losetup/2924 is trying to acquire lock: ffff88816c76da68 (&q->limits_lock){+.+.}-{4:4}, at: loop_set_dio+0x318/0x720 [loop] but task is already holding lock: ffff88816c76d430 (&q->q_usage_counter(io)#24){++++}-{0:0}, at: blk_mq_freeze_queue_nomemsave+0x1a/0x30 which lock already depends on the new lock. Cc: Keith Busch Fixes: 6c8dec275ccc ("loop: set dma_alignment from the backing file for direct I/O") Reported-by: syzbot+cc0de396bac84da51919@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-block/6a7d5368.d5f0ebe7.22d851.0013.GAE@google.com/ Signed-off-by: Bart Van Assche --- drivers/block/loop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 8639fa34b847..6f12976035b0 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1452,12 +1452,12 @@ static int loop_set_dio(struct loop_device *lo, unsigned long arg) vfs_fsync(lo->lo_backing_file, 0); } + lim = queue_limits_start_update(lo->lo_queue); memflags = blk_mq_freeze_queue(lo->lo_queue); if (use_dio) lo->lo_flags |= LO_FLAGS_DIRECT_IO; else lo->lo_flags &= ~LO_FLAGS_DIRECT_IO; - lim = queue_limits_start_update(lo->lo_queue); loop_set_dma_limit(lo, &lim); queue_limits_commit_update(lo->lo_queue, &lim); blk_mq_unfreeze_queue(lo->lo_queue, memflags);