linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/3] Improve performance for BLK_MQ_F_BLOCKING drivers
@ 2023-07-21 17:27 Bart Van Assche
  2023-07-21 17:27 ` [PATCH v3 1/3] scsi: Inline scsi_kick_queue() Bart Van Assche
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Bart Van Assche @ 2023-07-21 17:27 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block, Christoph Hellwig, Bart Van Assche

Hi Jens,

Request queues are run asynchronously if BLK_MQ_F_BLOCKING has been set. This
results in suboptimal performance. This patch series improves performance if
BLK_MQ_F_BLOCKING has been set by running request queues synchronously
whenever possible.

Please consider this patch series for the next merge window.

Thanks,

Bart.

Changes compared to v2:
- Improved the descriptions of patches 1/3 and 2/3.
- Added a comment in patch 2/3.
- In patch 3/3, included a change for blk_execute_rq_nowait() since I noticed
  that this function may be called from a context where it is not allowed to
  sleep (nvme_uring_cmd_io() for NVMe over TCP).

Changes compared to v1:
- Fixed support for the combination BLK_MQ_F_BLOCKING + BLIST_SINGLELUN.

Bart Van Assche (3):
  scsi: Inline scsi_kick_queue()
  scsi: Remove a blk_mq_run_hw_queues() call
  block: Improve performance for BLK_MQ_F_BLOCKING drivers

 block/blk-mq.c          | 17 +++++++++++------
 drivers/scsi/scsi_lib.c | 12 ++++--------
 2 files changed, 15 insertions(+), 14 deletions(-)


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3 1/3] scsi: Inline scsi_kick_queue()
  2023-07-21 17:27 [PATCH v3 0/3] Improve performance for BLK_MQ_F_BLOCKING drivers Bart Van Assche
@ 2023-07-21 17:27 ` Bart Van Assche
  2023-07-23 20:52   ` Martin K. Petersen
  2023-07-21 17:27 ` [PATCH v3 2/3] scsi: Remove a blk_mq_run_hw_queues() call Bart Van Assche
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Bart Van Assche @ 2023-07-21 17:27 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche,
	Martin K . Petersen, James E.J. Bottomley

Inline scsi_kick_queue() to prepare for modifying the second argument
passed to blk_mq_run_hw_queues().

Reviewed-by: Christoph Hellwig <hch@lst.de>
Cc: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/scsi_lib.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index ad9afae49544..414d29eef968 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -300,11 +300,6 @@ void scsi_device_unbusy(struct scsi_device *sdev, struct scsi_cmnd *cmd)
 	cmd->budget_token = -1;
 }
 
-static void scsi_kick_queue(struct request_queue *q)
-{
-	blk_mq_run_hw_queues(q, false);
-}
-
 /*
  * Kick the queue of SCSI device @sdev if @sdev != current_sdev. Called with
  * interrupts disabled.
@@ -340,7 +335,7 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev)
 	 * but in most cases, we will be first. Ideally, each LU on the
 	 * target would get some limited time or requests on the target.
 	 */
-	scsi_kick_queue(current_sdev->request_queue);
+	blk_mq_run_hw_queues(current_sdev->request_queue, false);
 
 	spin_lock_irqsave(shost->host_lock, flags);
 	if (!starget->starget_sdev_user)
@@ -427,7 +422,7 @@ static void scsi_starved_list_run(struct Scsi_Host *shost)
 			continue;
 		spin_unlock_irqrestore(shost->host_lock, flags);
 
-		scsi_kick_queue(slq);
+		blk_mq_run_hw_queues(slq, false);
 		blk_put_queue(slq);
 
 		spin_lock_irqsave(shost->host_lock, flags);

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 2/3] scsi: Remove a blk_mq_run_hw_queues() call
  2023-07-21 17:27 [PATCH v3 0/3] Improve performance for BLK_MQ_F_BLOCKING drivers Bart Van Assche
  2023-07-21 17:27 ` [PATCH v3 1/3] scsi: Inline scsi_kick_queue() Bart Van Assche
@ 2023-07-21 17:27 ` Bart Van Assche
  2023-07-23 20:53   ` Martin K. Petersen
  2023-07-21 17:27 ` [PATCH v3 3/3] block: Improve performance for BLK_MQ_F_BLOCKING drivers Bart Van Assche
  2023-07-25  2:13 ` [PATCH v3 0/3] " Jens Axboe
  3 siblings, 1 reply; 7+ messages in thread
From: Bart Van Assche @ 2023-07-21 17:27 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche,
	Martin K . Petersen, James E.J. Bottomley

blk_mq_kick_requeue_list() calls blk_mq_run_hw_queues() asynchronously.
Leave out the direct blk_mq_run_hw_queues() call. This patch causes
scsi_run_queue() to call blk_mq_run_hw_queues() asynchronously instead
of synchronously. Since scsi_run_queue() is not called from the hot I/O
submission path, this patch does not affect the hot path.

This patch prepares for allowing blk_mq_run_hw_queue() to sleep if
BLK_MQ_F_BLOCKING has been set. scsi_run_queue() may be called from
atomic context and must not sleep. Hence the removal of the
blk_mq_run_hw_queues(q, false) call. See also scsi_unblock_requests().

Cc: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/scsi_lib.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 414d29eef968..d4c514ab9fe8 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -447,8 +447,8 @@ static void scsi_run_queue(struct request_queue *q)
 	if (!list_empty(&sdev->host->starved_list))
 		scsi_starved_list_run(sdev->host);
 
+	/* Note: blk_mq_kick_requeue_list() runs the queue asynchronously. */
 	blk_mq_kick_requeue_list(q);
-	blk_mq_run_hw_queues(q, false);
 }
 
 void scsi_requeue_run_queue(struct work_struct *work)

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 3/3] block: Improve performance for BLK_MQ_F_BLOCKING drivers
  2023-07-21 17:27 [PATCH v3 0/3] Improve performance for BLK_MQ_F_BLOCKING drivers Bart Van Assche
  2023-07-21 17:27 ` [PATCH v3 1/3] scsi: Inline scsi_kick_queue() Bart Van Assche
  2023-07-21 17:27 ` [PATCH v3 2/3] scsi: Remove a blk_mq_run_hw_queues() call Bart Van Assche
@ 2023-07-21 17:27 ` Bart Van Assche
  2023-07-25  2:13 ` [PATCH v3 0/3] " Jens Axboe
  3 siblings, 0 replies; 7+ messages in thread
From: Bart Van Assche @ 2023-07-21 17:27 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche, Ming Lei,
	James E.J. Bottomley, Martin K. Petersen

blk_mq_run_queue() runs the queue asynchronously if BLK_MQ_F_BLOCKING
has been set. This is suboptimal since running the queue asynchronously
is slower than running the queue synchronously. This patch modifies
blk_mq_run_queue() as follows if BLK_MQ_F_BLOCKING has been set:
- Run the queue synchronously if it is allowed to sleep.
- Run the queue asynchronously if it is not allowed to sleep.
Additionally, blk_mq_run_hw_queue(hctx, false) calls are modified into
blk_mq_run_hw_queue(hctx, hctx->flags & BLK_MQ_F_BLOCKING) if the caller
may be invoked from atomic context.

The following caller chains have been reviewed:

blk_mq_run_hw_queue(hctx, false)
  blk_mq_get_tag()      /* may sleep, hence the functions it calls may also sleep */
  blk_execute_rq()             /* may sleep */
  blk_mq_run_hw_queues(q, async=false)
    blk_freeze_queue_start()   /* may sleep */
    blk_mq_requeue_work()      /* may sleep */
    scsi_kick_queue()
      scsi_requeue_run_queue() /* may sleep */
      scsi_run_host_queues()
        scsi_ioctl_reset()     /* may sleep */
  blk_mq_insert_requests(hctx, ctx, list, run_queue_async=false)
    blk_mq_dispatch_plug_list(plug, from_sched=false)
      blk_mq_flush_plug_list(plug, from_schedule=false)
        __blk_flush_plug(plug, from_schedule=false)
	blk_add_rq_to_plug()
	  blk_mq_submit_bio()  /* may sleep if REQ_NOWAIT has not been set */
  blk_mq_plug_issue_direct()
    blk_mq_flush_plug_list()   /* see above */
  blk_mq_dispatch_plug_list(plug, from_sched=false)
    blk_mq_flush_plug_list()   /* see above */
  blk_mq_try_issue_directly()
    blk_mq_submit_bio()        /* may sleep if REQ_NOWAIT has not been set */
  blk_mq_try_issue_list_directly(hctx, list)
    blk_mq_insert_requests() /* see above */

Cc: Christoph Hellwig <hch@lst.de>
Cc: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 block/blk-mq.c          | 16 ++++++++++------
 drivers/scsi/scsi_lib.c |  3 ++-
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index d98654869615..687ec3f4f10d 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1323,7 +1323,7 @@ void blk_execute_rq_nowait(struct request *rq, bool at_head)
 	}
 
 	blk_mq_insert_request(rq, at_head ? BLK_MQ_INSERT_AT_HEAD : 0);
-	blk_mq_run_hw_queue(hctx, false);
+	blk_mq_run_hw_queue(hctx, hctx->flags & BLK_MQ_F_BLOCKING);
 }
 EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
 
@@ -2222,6 +2222,8 @@ void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async)
 	 */
 	WARN_ON_ONCE(!async && in_interrupt());
 
+	might_sleep_if(!async && hctx->flags & BLK_MQ_F_BLOCKING);
+
 	/*
 	 * When queue is quiesced, we may be switching io scheduler, or
 	 * updating nr_hw_queues, or other things, and we can't run queue
@@ -2237,8 +2239,7 @@ void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async)
 	if (!need_run)
 		return;
 
-	if (async || (hctx->flags & BLK_MQ_F_BLOCKING) ||
-	    !cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask)) {
+	if (async || !cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask)) {
 		blk_mq_delay_run_hw_queue(hctx, 0);
 		return;
 	}
@@ -2373,7 +2374,7 @@ void blk_mq_start_hw_queue(struct blk_mq_hw_ctx *hctx)
 {
 	clear_bit(BLK_MQ_S_STOPPED, &hctx->state);
 
-	blk_mq_run_hw_queue(hctx, false);
+	blk_mq_run_hw_queue(hctx, hctx->flags & BLK_MQ_F_BLOCKING);
 }
 EXPORT_SYMBOL(blk_mq_start_hw_queue);
 
@@ -2403,7 +2404,8 @@ void blk_mq_start_stopped_hw_queues(struct request_queue *q, bool async)
 	unsigned long i;
 
 	queue_for_each_hw_ctx(q, hctx, i)
-		blk_mq_start_stopped_hw_queue(hctx, async);
+		blk_mq_start_stopped_hw_queue(hctx, async ||
+					(hctx->flags & BLK_MQ_F_BLOCKING));
 }
 EXPORT_SYMBOL(blk_mq_start_stopped_hw_queues);
 
@@ -2461,6 +2463,8 @@ static void blk_mq_insert_requests(struct blk_mq_hw_ctx *hctx,
 	list_for_each_entry(rq, list, queuelist) {
 		BUG_ON(rq->mq_ctx != ctx);
 		trace_block_rq_insert(rq);
+		if (rq->cmd_flags & REQ_NOWAIT)
+			run_queue_async = true;
 	}
 
 	spin_lock(&ctx->lock);
@@ -2621,7 +2625,7 @@ static void blk_mq_try_issue_directly(struct blk_mq_hw_ctx *hctx,
 
 	if ((rq->rq_flags & RQF_USE_SCHED) || !blk_mq_get_budget_and_tag(rq)) {
 		blk_mq_insert_request(rq, 0);
-		blk_mq_run_hw_queue(hctx, false);
+		blk_mq_run_hw_queue(hctx, rq->cmd_flags & REQ_NOWAIT);
 		return;
 	}
 
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index d4c514ab9fe8..59176946ab56 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -335,7 +335,8 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev)
 	 * but in most cases, we will be first. Ideally, each LU on the
 	 * target would get some limited time or requests on the target.
 	 */
-	blk_mq_run_hw_queues(current_sdev->request_queue, false);
+	blk_mq_run_hw_queues(current_sdev->request_queue,
+			     shost->queuecommand_may_block);
 
 	spin_lock_irqsave(shost->host_lock, flags);
 	if (!starget->starget_sdev_user)

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 1/3] scsi: Inline scsi_kick_queue()
  2023-07-21 17:27 ` [PATCH v3 1/3] scsi: Inline scsi_kick_queue() Bart Van Assche
@ 2023-07-23 20:52   ` Martin K. Petersen
  0 siblings, 0 replies; 7+ messages in thread
From: Martin K. Petersen @ 2023-07-23 20:52 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Jens Axboe, linux-block, Christoph Hellwig, Martin K . Petersen,
	James E.J. Bottomley


Bart,

> Inline scsi_kick_queue() to prepare for modifying the second argument
> passed to blk_mq_run_hw_queues().

Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 2/3] scsi: Remove a blk_mq_run_hw_queues() call
  2023-07-21 17:27 ` [PATCH v3 2/3] scsi: Remove a blk_mq_run_hw_queues() call Bart Van Assche
@ 2023-07-23 20:53   ` Martin K. Petersen
  0 siblings, 0 replies; 7+ messages in thread
From: Martin K. Petersen @ 2023-07-23 20:53 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Jens Axboe, linux-block, Christoph Hellwig, Martin K . Petersen,
	James E.J. Bottomley


Bart,

> blk_mq_kick_requeue_list() calls blk_mq_run_hw_queues() asynchronously.
> Leave out the direct blk_mq_run_hw_queues() call. This patch causes
> scsi_run_queue() to call blk_mq_run_hw_queues() asynchronously instead
> of synchronously. Since scsi_run_queue() is not called from the hot I/O
> submission path, this patch does not affect the hot path.
>
> This patch prepares for allowing blk_mq_run_hw_queue() to sleep if
> BLK_MQ_F_BLOCKING has been set. scsi_run_queue() may be called from
> atomic context and must not sleep. Hence the removal of the
> blk_mq_run_hw_queues(q, false) call. See also scsi_unblock_requests().

Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 0/3] Improve performance for BLK_MQ_F_BLOCKING drivers
  2023-07-21 17:27 [PATCH v3 0/3] Improve performance for BLK_MQ_F_BLOCKING drivers Bart Van Assche
                   ` (2 preceding siblings ...)
  2023-07-21 17:27 ` [PATCH v3 3/3] block: Improve performance for BLK_MQ_F_BLOCKING drivers Bart Van Assche
@ 2023-07-25  2:13 ` Jens Axboe
  3 siblings, 0 replies; 7+ messages in thread
From: Jens Axboe @ 2023-07-25  2:13 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-block, Christoph Hellwig


On Fri, 21 Jul 2023 10:27:27 -0700, Bart Van Assche wrote:
> Request queues are run asynchronously if BLK_MQ_F_BLOCKING has been set. This
> results in suboptimal performance. This patch series improves performance if
> BLK_MQ_F_BLOCKING has been set by running request queues synchronously
> whenever possible.
> 
> Please consider this patch series for the next merge window.
> 
> [...]

Applied, thanks!

[1/3] scsi: Inline scsi_kick_queue()
      commit: b5ca9acff553874aaf1faf176e076cbd7cc4aa0e
[2/3] scsi: Remove a blk_mq_run_hw_queues() call
      commit: d42e2e3448a99c41c8489766eeb732d8d741d5be
[3/3] block: Improve performance for BLK_MQ_F_BLOCKING drivers
      commit: 65a558f66c308251e256317957b75d1e643c33c3

Best regards,
-- 
Jens Axboe




^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2023-07-25  2:13 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-07-21 17:27 [PATCH v3 0/3] Improve performance for BLK_MQ_F_BLOCKING drivers Bart Van Assche
2023-07-21 17:27 ` [PATCH v3 1/3] scsi: Inline scsi_kick_queue() Bart Van Assche
2023-07-23 20:52   ` Martin K. Petersen
2023-07-21 17:27 ` [PATCH v3 2/3] scsi: Remove a blk_mq_run_hw_queues() call Bart Van Assche
2023-07-23 20:53   ` Martin K. Petersen
2023-07-21 17:27 ` [PATCH v3 3/3] block: Improve performance for BLK_MQ_F_BLOCKING drivers Bart Van Assche
2023-07-25  2:13 ` [PATCH v3 0/3] " Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).