Disable writeback throttling by default for loop devices to avoid deadlock scenarios when RQOS features are enabled. This way is fine for loop because the backing device covers writeback throttle too. Update lo_backfile_support_nowait() to check both backing file's FMODE_NOWAIT support and the queue's QOS enablement status. This prevents deadlocks in submit_bio() code path when RQOS takes online wait and blocks backing file IOs. Fixes: 0ba93a906dda ("loop: try to handle loop aio command via NOWAIT IO first") Signed-off-by: Ming Lei --- drivers/block/loop.c | 13 ++++++++++++- include/linux/blkdev.h | 2 ++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 705373b9668d..107760085ac5 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -443,9 +443,18 @@ static int lo_submit_rw_aio(struct loop_device *lo, struct loop_cmd *cmd, return ret; } +/* + * Allow NOWAIT only if the backing file supports it, and loop disk's + * RQOS feature isn't enabled. + * + * RQOS takes online wait in submit_bio() code path, and IOs to backing + * file may be blocked, then deadlock is caused, see + * submit_bio_noacct_nocheck(). + */ static bool lo_backfile_support_nowait(const struct loop_device *lo) { - return lo->lo_backing_file->f_mode & FMODE_NOWAIT; + return (lo->lo_backing_file->f_mode & FMODE_NOWAIT) && + !test_bit(QUEUE_FLAG_QOS_ENABLED, &lo->lo_queue->queue_flags); } static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd, @@ -2250,6 +2259,8 @@ static int loop_add(int i) lo->idr_visible = true; mutex_unlock(&loop_ctl_mutex); + wbt_disable_default(disk); + return i; out_cleanup_disk: diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index cb4ba09959ee..4ed2248c19ea 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -449,6 +449,8 @@ int blkdev_zone_mgmt(struct block_device *bdev, enum req_op op, sector_t sectors, sector_t nr_sectors); int blk_revalidate_disk_zones(struct gendisk *disk); +void wbt_disable_default(struct gendisk *disk); + /* * Independent access ranges: struct blk_independent_access_range describes * a range of contiguous sectors that can be accessed using device command -- 2.47.0