Re: [PATCH V2 1/2] blk-mq: serialize queue quiesce and unquiesce by mutex

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



It doesn't matter. Because the reentry of quiesce&unquiesce queue is not
safe, must be avoided by other mechanism. otherwise, exceptions may
occur. Introduce mq_quiesce_lock looks saving possible synchronization
waits, but it should not happen. If really happen, we need fix it.

On 2020/8/25 22:17, Ming Lei wrote:
Add .mq_quiesce_mutext to request queue, so that queue quiesce and
unquiesce can be serialized. Meantime we can avoid unnecessary
synchronize_rcu() in case that queue has been quiesced already.

Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx>
Cc: Sagi Grimberg <sagi@xxxxxxxxxxx>
Cc: Bart Van Assche <bvanassche@xxxxxxx>
Cc: Johannes Thumshirn <Johannes.Thumshirn@xxxxxxx>
Cc: Chao Leng <lengchao@xxxxxxxxxx>
---
  block/blk-core.c       |  2 ++
  block/blk-mq.c         | 11 +++++++++++
  include/linux/blkdev.h |  2 ++
  3 files changed, 15 insertions(+)

diff --git a/block/blk-core.c b/block/blk-core.c
index d9d632639bd1..ffc57df70064 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -561,6 +561,8 @@ struct request_queue *blk_alloc_queue(int node_id)
  	init_waitqueue_head(&q->mq_freeze_wq);
  	mutex_init(&q->mq_freeze_lock);
+ mutex_init(&q->mq_quiesce_lock);
+
  	/*
  	 * Init percpu_ref in atomic mode so that it's faster to shutdown.
  	 * See blk_register_queue() for details.
diff --git a/block/blk-mq.c b/block/blk-mq.c
index b3d2785eefe9..817e016ef886 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -224,6 +224,11 @@ void blk_mq_quiesce_queue(struct request_queue *q)
  	unsigned int i;
  	bool rcu = false;
+ mutex_lock(&q->mq_quiesce_lock);
+
+	if (blk_queue_quiesced(q))
+		goto exit;
+
  	blk_mq_quiesce_queue_nowait(q);
queue_for_each_hw_ctx(q, hctx, i) {
@@ -234,6 +239,8 @@ void blk_mq_quiesce_queue(struct request_queue *q)
  	}
  	if (rcu)
  		synchronize_rcu();
+ exit:
+	mutex_unlock(&q->mq_quiesce_lock);
  }
  EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue);
@@ -246,10 +253,14 @@ EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue);
   */
  void blk_mq_unquiesce_queue(struct request_queue *q)
  {
+	mutex_lock(&q->mq_quiesce_lock);
+
  	blk_queue_flag_clear(QUEUE_FLAG_QUIESCED, q);
/* dispatch requests which are inserted during quiescing */
  	blk_mq_run_hw_queues(q, true);
+
+	mutex_unlock(&q->mq_quiesce_lock);
  }
  EXPORT_SYMBOL_GPL(blk_mq_unquiesce_queue);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index d8dba550ecac..5ed03066b33e 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -569,6 +569,8 @@ struct request_queue {
  	 */
  	struct mutex		mq_freeze_lock;
+ struct mutex mq_quiesce_lock;
+
  	struct blk_mq_tag_set	*tag_set;
  	struct list_head	tag_set_list;
  	struct bio_set		bio_split;




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux