[PATCH v3 2/4] block: add a read barrier in blk_queue_enter()
From: Ming Lei <tom.leiming@gmail.com>
Date: 2017-03-27 12:07:36
Subsystem:
block layer, the rest · Maintainers:
Jens Axboe, Linus Torvalds
From: Ming Lei <tom.leiming@gmail.com>
Date: 2017-03-27 12:07:36
Subsystem:
block layer, the rest · Maintainers:
Jens Axboe, Linus Torvalds
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. Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Ming Lei <tom.leiming@gmail.com> --- block/blk-core.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/block/blk-core.c b/block/blk-core.c
index ad388d5e309a..5e8963bc98d9 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c@@ -669,6 +669,15 @@ 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 __PERCPU_REF_DEAD flag of + * .q_usage_counter and reading .mq_freeze_depth, + * otherwise the following wait may never return if the + * two reads are reordered. + */ + smp_rmb(); + ret = wait_event_interruptible(q->mq_freeze_wq, !atomic_read(&q->mq_freeze_depth) || blk_queue_dying(q));
--
2.9.3