On Fri, 2017-03-24 at 20:36 +0800, Ming Lei wrote:
> Without the barrier, reading DEAD flag of .q_usage_counter
> and reading .mq_freeze_depth may be reordered, then the
> following wait_event_interruptible() may never return.
> 
> Signed-off-by: Ming Lei <tom.leim...@gmail.com>
> ---
>  block/blk-core.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/block/blk-core.c b/block/blk-core.c
> index ad388d5e309a..44eed17319c0 100644
> --- a/block/blk-core.c
> +++ b/block/blk-core.c
> @@ -669,6 +669,14 @@ int blk_queue_enter(struct request_queue *q, bool nowait)
>               if (nowait)
>                       return -EBUSY;
>  
> +             /*
> +              * read pair of barrier in blk_mq_freeze_queue_start(),
> +              * we need to order reading DEAD flag of .q_usage_counter
> +              * and reading .mq_freeze_depth, otherwise the following
> +              * wait may never return if the two read are reordered.
> +              */
> +             smp_rmb();
> +
>               ret = wait_event_interruptible(q->mq_freeze_wq,
>                               !atomic_read(&q->mq_freeze_depth) ||
>                               blk_queue_dying(q));

Hello Ming,

The code looks fine to me but the comment not. You probably wanted to refer
to the "dying" flag instead of the "dead" flag? The read order has to be
enforced for the "dying" flag and q_usage_counter because of the order in
which these are set by blk_set_queue_dying().

Thanks,

Bart.

Reply via email to