Re: [PATCH 1/1] null_blk: fix handling of BLKPREP_DEFER case

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Folks, any comments on this patch?

Thanks,
Dmitry

On Sun, Apr 19, 2015 at 9:19 PM, Dmitry Krivenok
<krivenok.dmitry@xxxxxxxxx> wrote:
> When we fail to allocate new cmd in null_rq_prep_fn we return BLKPREP_DEFER
> which is not handled properly. In single-queue mode of null_blk the following
> command hangs forever in io_schedule():
> $ dd if=/dev/nullb0 of=/dev/null bs=8M count=5000 iflag=direct
>
> The reason is that when 64 commands have been allocated, the 65th command
> allocation will fail due to missing free tag. The request, however, will be
> kept in the queue which will never be started again (unless you run another
> command that does I/O to /dev/nullb0).
>
> This small patch tries to solve the issue by stopping the queue when we
> detect that all tags were exhausted and starting it again when we free the tag.
>
> I've verified that the command mentioned above doesn't hang anymore and also
> made sure that null_blk with my change survives fio-based stress tests.
>
> Signed-off-by: Dmitry V. Krivenok <krivenok.dmitry@xxxxxxxxx>
> ---
>  drivers/block/null_blk.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
>
> diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c
> index 65cd61a..4ac684b 100644
> --- a/drivers/block/null_blk.c
> +++ b/drivers/block/null_blk.c
> @@ -25,6 +25,7 @@ struct nullb_queue {
>      unsigned int queue_depth;
>
>      struct nullb_cmd *cmds;
> +    bool no_cmds;
>  };
>
>  struct nullb {
> @@ -171,6 +172,13 @@ static unsigned int get_tag(struct nullb_queue *nq)
>  static void free_cmd(struct nullb_cmd *cmd)
>  {
>      put_tag(cmd->nq, cmd->tag);
> +    if(cmd->nq->no_cmds) {
> +        unsigned long flags;
> +        cmd->nq->no_cmds = false;
> +        spin_lock_irqsave(cmd->rq->q->queue_lock, flags);
> +        blk_start_queue(cmd->rq->q);
> +        spin_unlock_irqrestore(cmd->rq->q->queue_lock, flags);
> +    }
>  }
>
>  static struct nullb_cmd *__alloc_cmd(struct nullb_queue *nq)
> @@ -195,6 +203,9 @@ static struct nullb_cmd *alloc_cmd(struct
> nullb_queue *nq, int can_wait)
>      DEFINE_WAIT(wait);
>
>      cmd = __alloc_cmd(nq);
> +    if (!cmd && !can_wait) {
> +        nq->no_cmds = true;
> +    }
>      if (cmd || !can_wait)
>          return cmd;
>
> @@ -341,6 +352,7 @@ static int null_rq_prep_fn(struct request_queue
> *q, struct request *req)
>  static void null_request_fn(struct request_queue *q)
>  {
>      struct request *rq;
> +    struct nullb_queue *nq = nullb_to_queue(q->queuedata);
>
>      while ((rq = blk_fetch_request(q)) != NULL) {
>          struct nullb_cmd *cmd = rq->special;
> @@ -349,6 +361,9 @@ static void null_request_fn(struct request_queue *q)
>          null_handle_cmd(cmd);
>          spin_lock_irq(q->queue_lock);
>      }
> +    if(nq->no_cmds) {
> +        blk_stop_queue(q);
> +    }
>  }
>
>  static int null_queue_rq(struct blk_mq_hw_ctx *hctx,
> @@ -430,6 +445,7 @@ static int setup_commands(struct nullb_queue *nq)
>      if (!nq->cmds)
>          return -ENOMEM;
>
> +    nq->no_cmds = false;
>      tag_size = ALIGN(nq->queue_depth, BITS_PER_LONG) / BITS_PER_LONG;
>      nq->tag_map = kzalloc(tag_size * sizeof(unsigned long), GFP_KERNEL);
>      if (!nq->tag_map) {
> --
> 2.3.5



-- 
Sincerely yours, Dmitry V. Krivenok
e-mail: krivenok.dmitry@xxxxxxxxx
skype: krivenok_dmitry
jabber: krivenok_dmitry@xxxxxxxxx
icq: 242-526-443
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux