diff mbox series

[1/2] scsi: Add scsi_done_direct() for immediate completion.

Message ID 20220201210954.570896-2-sebastian@breakpoint.cc
State New
Headers show
Series Add scsi_done_direct() to complete request directly. | expand

Commit Message

Sebastian Andrzej Siewior Feb. 1, 2022, 9:09 p.m. UTC
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.

Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
---
 drivers/scsi/scsi_lib.c  | 27 +++++++++++++++++++++++----
 include/scsi/scsi_cmnd.h |  1 +
 2 files changed, 24 insertions(+), 4 deletions(-)

Comments

Bart Van Assche Feb. 2, 2022, 8:49 p.m. UTC | #1
On 2/1/22 13:09, Sebastian Andrzej Siewior wrote:
> -void scsi_done(struct scsi_cmnd *cmd)
> +static bool scsi_done_need_blk_compl(struct scsi_cmnd *cmd)

I'm not happy about the name of this function. The word "need" in the 
function name suggests that this function does not modify any state. 
However, the body of the function shows that it may complete a SCSI 
command. How about renaming the existing scsi_done() function into 
scsi_done_internal() or so and adding a "bool complete_directly" 
argument to that function?

BTW, I only received patch 1/2 but not patch 2/2. Please Cc the 
linux-scsi mailing list for the entire patch series when reposting the 
patch series.

Thanks,

Bart.
diff mbox series

Patch

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 0a70aa763a961..778ef6d09616f 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1625,26 +1625,45 @@  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 bool scsi_done_need_blk_compl(struct scsi_cmnd *cmd)
 {
 	switch (cmd->submitter) {
 	case SUBMITTED_BY_BLOCK_LAYER:
 		break;
 	case SUBMITTED_BY_SCSI_ERROR_HANDLER:
-		return scsi_eh_done(cmd);
+		scsi_eh_done(cmd);
+		return false;
 	case SUBMITTED_BY_SCSI_RESET_IOCTL:
-		return;
+		return false;
 	}
 
 	if (unlikely(blk_should_fake_timeout(scsi_cmd_to_rq(cmd)->q)))
-		return;
+		return false;
 	if (unlikely(test_and_set_bit(SCMD_STATE_COMPLETE, &cmd->state)))
+		return false;
+	return true;
+}
+
+void scsi_done(struct scsi_cmnd *cmd)
+{
+	if (!scsi_done_need_blk_compl(cmd))
 		return;
+
 	trace_scsi_dispatch_cmd_done(cmd);
 	blk_mq_complete_request(scsi_cmd_to_rq(cmd));
 }
 EXPORT_SYMBOL(scsi_done);
 
+void scsi_done_direct(struct scsi_cmnd *cmd)
+{
+	if (!scsi_done_need_blk_compl(cmd))
+		return;
+
+	trace_scsi_dispatch_cmd_done(cmd);
+	blk_mq_complete_request_direct(scsi_cmd_to_rq(cmd), scsi_complete);
+}
+EXPORT_SYMBOL(scsi_done_direct);
+
 static void scsi_mq_put_budget(struct request_queue *q, int budget_token)
 {
 	struct scsi_device *sdev = q->queuedata;
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 6794d7322cbde..ff1c4b51f7aef 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -168,6 +168,7 @@  static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)
 }
 
 void scsi_done(struct scsi_cmnd *cmd);
+void scsi_done_direct(struct scsi_cmnd *cmd);
 
 extern void scsi_finish_command(struct scsi_cmnd *cmd);