diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index 65cd61a4145e..d7141d5ef4ff 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c @@ -24,6 +24,7 @@ struct nullb_queue { wait_queue_head_t wait; unsigned int queue_depth; + struct nullb *dev; struct nullb_cmd *cmds; }; @@ -153,6 +154,13 @@ static void put_tag(struct nullb_queue *nq, unsigned int tag) if (waitqueue_active(&nq->wait)) wake_up(&nq->wait); + + if (queue_mode == NULL_Q_RQ) { + struct nullb *nullb = nq->dev; + + if (blk_queue_stopped(nullb->q)) + blk_start_queue(nullb->q); + } } static unsigned int get_tag(struct nullb_queue *nq) @@ -196,7 +204,7 @@ static struct nullb_cmd *alloc_cmd(struct nullb_queue *nq, int can_wait) cmd = __alloc_cmd(nq); if (cmd || !can_wait) - return cmd; + goto out; do { prepare_to_wait(&nq->wait, &wait, TASK_UNINTERRUPTIBLE); @@ -208,6 +216,11 @@ static struct nullb_cmd *alloc_cmd(struct nullb_queue *nq, int can_wait) } while (1); finish_wait(&nq->wait, &wait); +out: + if (!cmd) { + BUG_ON(queue_mode != NULL_Q_RQ); + blk_stop_queue(nq->dev->q); + } return cmd; } @@ -372,6 +385,7 @@ static void null_init_queue(struct nullb *nullb, struct nullb_queue *nq) init_waitqueue_head(&nq->wait); nq->queue_depth = nullb->queue_depth; + nq->dev = nullb; } static int null_init_hctx(struct blk_mq_hw_ctx *hctx, void *data,