diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index 6beb1f5b7..d5ece457e 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -1861,8 +1861,17 @@ static int null_init_global_tag_set(void) tag_set.flags |= BLK_MQ_F_NO_SCHED_BY_DEFAULT; if (g_shared_tag_bitmap) tag_set.flags |= BLK_MQ_F_TAG_HCTX_SHARED; - if (g_blocking) - tag_set.flags |= BLK_MQ_F_BLOCKING; + + /* + * A shared tag set may be used by a memory backed device, whose + * ->queue_rq() performs GFP_NOIO allocations and therefore must be + * allowed to sleep. blk-mq picks its locking (RCU or SRCU) from + * BLK_MQ_F_BLOCKING, so always mark the shared tag set blocking; + * otherwise I/O submitted through blk_mq_run_dispatch_ops() runs + * under the RCU read lock and triggers "sleeping function called + * from invalid context" in null_alloc_page(). + */ + tag_set.flags |= BLK_MQ_F_BLOCKING; error = null_init_tag_set(&tag_set, g_poll_queues); if (error)