mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-25 20:10:23 +09:00
BACKPORT: FROMGIT: block: Improve performance for BLK_MQ_F_BLOCKING drivers
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>
Change-Id: I597e0fa587057ac22e52f73351cbfa1de2c72a6b
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Link: https://lore.kernel.org/r/20230721172731.955724-4-bvanassche@acm.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Bug: 291379528
(cherry picked from commit 65a558f66c git://git.kernel.dk/linux-block for-next)
Signed-off-by: Bart Van Assche <bvanassche@google.com>
This commit is contained in:
committed by
Bart Van Assche
parent
d12306bb95
commit
0c5273e138
@@ -59,7 +59,10 @@ void blk_execute_rq_nowait(struct gendisk *bd_disk, struct request *rq,
|
||||
* don't check dying flag for MQ because the request won't
|
||||
* be reused after dying flag is set
|
||||
*/
|
||||
blk_mq_sched_insert_request(rq, at_head, true, false);
|
||||
blk_mq_sched_insert_request(rq, at_head, true,
|
||||
rq->mq_hctx->flags & BLK_MQ_F_BLOCKING &&
|
||||
rq->cmd_flags & REQ_NOWAIT);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
|
||||
|
||||
|
||||
@@ -1561,11 +1561,9 @@ static void __blk_mq_delay_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async,
|
||||
if (unlikely(blk_mq_hctx_stopped(hctx)))
|
||||
return;
|
||||
|
||||
if (!async && !(hctx->flags & BLK_MQ_F_BLOCKING)) {
|
||||
if (cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask)) {
|
||||
__blk_mq_run_hw_queue(hctx);
|
||||
return;
|
||||
}
|
||||
if (!async && cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask)) {
|
||||
__blk_mq_run_hw_queue(hctx);
|
||||
return;
|
||||
}
|
||||
|
||||
kblockd_mod_delayed_work_on(blk_mq_hctx_next_cpu(hctx), &hctx->run_work,
|
||||
@@ -1768,7 +1766,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);
|
||||
|
||||
@@ -1798,7 +1796,8 @@ void blk_mq_start_stopped_hw_queues(struct request_queue *q, bool async)
|
||||
int 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);
|
||||
|
||||
|
||||
@@ -328,7 +328,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)
|
||||
|
||||
Reference in New Issue
Block a user