Commit 531ed626 authored by Tejun Heo's avatar Tejun Heo Committed by Jens Axboe

blk-mq: fix a memory ordering bug in blk_mq_queue_enter()

blk-mq uses a percpu_counter to keep track of how many usages are in
flight.  The percpu_counter is drained while freezing to ensure that
no usage is left in-flight after freezing is complete.

blk_mq_queue_enter/exit() and blk_mq_[un]freeze_queue() implement this
per-cpu gating mechanism; unfortunately, it contains a subtle bug -
smp_wmb() in blk_mq_queue_enter() doesn't prevent prevent the cpu from
fetching @q->bypass_depth before incrementing @q->mq_usage_counter and
if freezing happens inbetween the caller can slip through and freezing
can be complete while there are active users.

Use smp_mb() instead so that bypass_depth and mq_usage_counter
modifications and tests are properly interlocked.
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Nicholas A. Bellinger <nab@linux-iscsi.org>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent 17737d3b
...@@ -81,7 +81,7 @@ static int blk_mq_queue_enter(struct request_queue *q) ...@@ -81,7 +81,7 @@ static int blk_mq_queue_enter(struct request_queue *q)
int ret; int ret;
__percpu_counter_add(&q->mq_usage_counter, 1, 1000000); __percpu_counter_add(&q->mq_usage_counter, 1, 1000000);
smp_wmb(); smp_mb();
/* we have problems freezing the queue if it's initializing */ /* we have problems freezing the queue if it's initializing */
if (!blk_queue_dying(q) && if (!blk_queue_dying(q) &&
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment