projects
/
openwrt
/
staging
/
blogic.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
| inline |
side by side
(parent:
d9d149a
)
block: add a read barrier in blk_queue_enter()
author
Ming Lei
<
[email protected]
>
Mon, 27 Mar 2017 12:06:56 +0000
(20:06 +0800)
committer
Jens Axboe
<
[email protected]
>
Wed, 29 Mar 2017 14:03:42 +0000
(08:03 -0600)
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 <
[email protected]
>
Signed-off-by: Ming Lei <
[email protected]
>
Reviewed-by: Johannes Thumshirn <
[email protected]
>
Reviewed-by: Bart Van Assche <
[email protected]
>
Signed-off-by: Jens Axboe <
[email protected]
>
block/blk-core.c
patch
|
blob
|
history
diff --git
a/block/blk-core.c
b/block/blk-core.c
index 4234332aa23c487354fd412c6cd7ba142c623aaf..6373febc77169bfbf0e38635dbb7ec2885c293d7 100644
(file)
--- 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));