[PATCH v2 2/3] blk-mq: introduce async mechanism for quiesce queue
Chao Leng
lengchao at huawei.com
Fri Aug 7 05:06:30 EDT 2020
In some scenarios we need quiesce lots of queues together, if quiesce
one by one, may need long time.
Introduce async mechanism for quiesce queue: quiesce queues together
but no wait, and then wait until all queues ongoing dispatches complete.
Thus reduce serial wait time.
Signed-off-by: Chao Leng <lengchao at huawei.com>
---
block/blk-mq.c | 28 ++++++++++++++++++++++++++++
include/linux/blk-mq.h | 2 ++
2 files changed, 30 insertions(+)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index a9aa6d1e44cf..2fc2fd666bda 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -235,6 +235,34 @@ void blk_mq_quiesce_queue(struct request_queue *q)
}
EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue);
+/*
+ * blk_mq_quiesce_queue_async - do not wait until all ongoing dispatches
+ * completed, used for sync lots of queues together to reduce wait time.
+ * Must be used together with blk_mq_quiesce_queue_async_wait.
+ * Caution: do not support concurrent.
+ */
+void blk_mq_quiesce_queue_async(struct request_queue *q, atomic_t *count)
+{
+ struct blk_mq_hw_ctx *hctx;
+ unsigned int i;
+
+ blk_mq_quiesce_queue_nowait(q);
+ queue_for_each_hw_ctx(q, hctx, i) {
+ if (hctx->flags & BLK_MQ_F_BLOCKING)
+ synchronize_srcu_async(hctx->srcu, count);
+ }
+
+}
+EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue_async);
+
+void blk_mq_quiesce_queue_async_wait(atomic_t *count)
+{
+ synchronize_rcu();
+ while (atomic_read(count))
+ schedule();
+}
+EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue_async_wait);
+
/*
* blk_mq_unquiesce_queue() - counterpart of blk_mq_quiesce_queue()
* @q: request queue.
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index d6fcae17da5a..27a713ad73bb 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -515,6 +515,8 @@ void blk_mq_start_hw_queues(struct request_queue *q);
void blk_mq_start_stopped_hw_queue(struct blk_mq_hw_ctx *hctx, bool async);
void blk_mq_start_stopped_hw_queues(struct request_queue *q, bool async);
void blk_mq_quiesce_queue(struct request_queue *q);
+void blk_mq_quiesce_queue_async(struct request_queue *q, atomic_t *count);
+void blk_mq_quiesce_queue_async_wait(atomic_t *count);
void blk_mq_unquiesce_queue(struct request_queue *q);
void blk_mq_delay_run_hw_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs);
void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async);
--
2.16.4
More information about the Linux-nvme
mailing list