diff options
author | Sebastian Andrzej Siewior <sebastian@breakpoint.cc> | 2022-02-03 23:29:25 +0300 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2022-02-08 07:14:15 +0300 |
commit | b84b6ec0f9767c82d0cfe5b2ac2c41de6b3d37e8 (patch) | |
tree | 00a7f2afa65288147a550a67f73a4e7577b55559 /drivers | |
parent | 7cddf7e8d1e88603d0e86997259fdec98da6f70a (diff) | |
download | linux-b84b6ec0f9767c82d0cfe5b2ac2c41de6b3d37e8.tar.xz |
scsi: core: Add scsi_done_direct() for immediate completion
Add scsi_done_direct() which behaves like scsi_done() except that it
invokes blk_mq_complete_request_direct() in order to complete the request.
Callers from process context can complete the request directly instead
waking ksoftirqd.
Link: https://lore.kernel.org/r/Yfw7JaszshmfYa1d@flow
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 0a70aa763a96..a1c18ba5e8d3 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1625,8 +1625,10 @@ static blk_status_t scsi_prepare_cmd(struct request *req) return scsi_cmd_to_driver(cmd)->init_command(cmd); } -void scsi_done(struct scsi_cmnd *cmd) +static void scsi_done_internal(struct scsi_cmnd *cmd, bool complete_directly) { + struct request *req = scsi_cmd_to_rq(cmd); + switch (cmd->submitter) { case SUBMITTED_BY_BLOCK_LAYER: break; @@ -1641,10 +1643,25 @@ void scsi_done(struct scsi_cmnd *cmd) if (unlikely(test_and_set_bit(SCMD_STATE_COMPLETE, &cmd->state))) return; trace_scsi_dispatch_cmd_done(cmd); - blk_mq_complete_request(scsi_cmd_to_rq(cmd)); + + if (complete_directly) + blk_mq_complete_request_direct(req, scsi_complete); + else + blk_mq_complete_request(req); +} + +void scsi_done(struct scsi_cmnd *cmd) +{ + scsi_done_internal(cmd, false); } EXPORT_SYMBOL(scsi_done); +void scsi_done_direct(struct scsi_cmnd *cmd) +{ + scsi_done_internal(cmd, true); +} +EXPORT_SYMBOL(scsi_done_direct); + static void scsi_mq_put_budget(struct request_queue *q, int budget_token) { struct scsi_device *sdev = q->queuedata; |