aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2014-07-01 12:34:38 -0400
committerJens Axboe <axboe@fb.com>2014-07-01 12:34:38 -0400
commitadd703fda981b9719d37f371498b9f129acbd997 (patch)
tree905e2f2f3a7753536a83f9c4b047e44f039a4bfe /include
parent72d6f02a8d4e0dda74de3a541b1c4ae82f5f7b45 (diff)
blk-mq: use percpu_ref for mq usage count
Currently, 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. This type of code has relatively high chance of subtle bugs which are extremely difficult to trigger and it's way too hairy to be open coded in blk-mq. percpu_ref can serve the same purpose after the recent changes. This patch replaces the open-coded per-cpu usage counting and draining mechanism with percpu_ref. blk_mq_queue_enter() performs tryget_live on the ref and exit() performs put. blk_mq_freeze_queue() kills the ref and waits until the reference count reaches zero. blk_mq_unfreeze_queue() revives the ref and wakes up the waiters. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Jens Axboe <axboe@kernel.dk> Cc: Nicholas A. Bellinger <nab@linux-iscsi.org> Cc: Kent Overstreet <kmo@daterainc.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/blkdev.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index c8f344ff74fe..518b46555b80 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -21,6 +21,7 @@
21#include <linux/bsg.h> 21#include <linux/bsg.h>
22#include <linux/smp.h> 22#include <linux/smp.h>
23#include <linux/rcupdate.h> 23#include <linux/rcupdate.h>
24#include <linux/percpu-refcount.h>
24 25
25#include <asm/scatterlist.h> 26#include <asm/scatterlist.h>
26 27
@@ -484,7 +485,7 @@ struct request_queue {
484#endif 485#endif
485 struct rcu_head rcu_head; 486 struct rcu_head rcu_head;
486 wait_queue_head_t mq_freeze_wq; 487 wait_queue_head_t mq_freeze_wq;
487 struct percpu_counter mq_usage_counter; 488 struct percpu_ref mq_usage_counter;
488 struct list_head all_q_node; 489 struct list_head all_q_node;
489 490
490 struct blk_mq_tag_set *tag_set; 491 struct blk_mq_tag_set *tag_set;