All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mike Christie <michael.christie@oracle.com>
To: bvanassche@acm.org, mwilck@suse.com, hch@lst.de,
	martin.petersen@oracle.com, linux-scsi@vger.kernel.org,
	james.bottomley@hansenpartnership.com
Cc: Mike Christie <michael.christie@oracle.com>
Subject: [PATCH v6 02/35] scsi: Allow passthrough to override what errors to retry
Date: Fri,  4 Nov 2022 18:18:54 -0500	[thread overview]
Message-ID: <20221104231927.9613-3-michael.christie@oracle.com> (raw)
In-Reply-To: <20221104231927.9613-1-michael.christie@oracle.com>

For passthrough, we don't retry any error we get a check condition for.
This results in a lot of callers driving their own retries for those types
of errors and retrying all errors, and there has been a request to retry
specific host byte errors.

This adds the core code to allow passthrough users to specify what errors
they want scsi-ml to retry for them. We can then convert users to drop
their sense parsing and retry handling.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/scsi_error.c | 82 +++++++++++++++++++++++++++++++++++++++
 drivers/scsi/scsi_lib.c   |  1 +
 include/scsi/scsi_cmnd.h  | 26 ++++++++++++-
 3 files changed, 108 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 994b7472fc56..77d7ad07645a 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1829,6 +1829,82 @@ bool scsi_noretry_cmd(struct scsi_cmnd *scmd)
 	return false;
 }
 
+/**
+ * scsi_check_passthrough - Determine if passthrough scsi_cmnd needs a retry.
+ * @scmd: scsi_cmnd to check.
+ *
+ * Return value:
+ *	SCSI_RETURN_NOT_HANDLED - if the caller should process the command
+ *	because there is no error or the passthrough user wanted the default
+ *	error processing.
+ *	SUCCESS, FAILED or NEEDS_RETRY - if this function has determined the
+ *	command should be completed, go through the error handler due to
+ *	missing sense or should be retried.
+ */
+static enum scsi_disposition scsi_check_passthrough(struct scsi_cmnd *scmd)
+{
+	struct scsi_failure *failure;
+	struct scsi_sense_hdr sshdr;
+	enum scsi_disposition ret;
+	enum sam_status status;
+
+	if (!scmd->result || !scmd->failures)
+		return SCSI_RETURN_NOT_HANDLED;
+
+	for (failure = scmd->failures; failure->result; failure++) {
+		if (failure->result == SCMD_FAILURE_RESULT_ANY)
+			goto maybe_retry;
+
+		if (host_byte(scmd->result) &&
+		    host_byte(scmd->result) == host_byte(failure->result))
+			goto maybe_retry;
+
+		status = get_status_byte(scmd);
+		if (!status)
+			continue;
+
+		if (failure->result == SCMD_FAILURE_STAT_ANY &&
+		    !scsi_status_is_good(scmd->result))
+			goto maybe_retry;
+
+		if (status != __get_status_byte(failure->result))
+			continue;
+
+		if (__get_status_byte(failure->result) !=
+		    SAM_STAT_CHECK_CONDITION ||
+		    failure->sense == SCMD_FAILURE_SENSE_ANY)
+			goto maybe_retry;
+
+		ret = scsi_start_sense_processing(scmd, &sshdr);
+		if (ret == NEEDS_RETRY)
+			goto maybe_retry;
+		else if (ret != SUCCESS)
+			return ret;
+
+		if (failure->sense != sshdr.sense_key)
+			continue;
+
+		if (failure->asc == SCMD_FAILURE_ASC_ANY)
+			goto maybe_retry;
+
+		if (failure->asc != sshdr.asc)
+			continue;
+
+		if (failure->ascq == SCMD_FAILURE_ASCQ_ANY ||
+		    failure->ascq == sshdr.ascq)
+			goto maybe_retry;
+	}
+
+	return SCSI_RETURN_NOT_HANDLED;
+
+maybe_retry:
+	if (failure->allowed == SCMD_FAILURE_NO_LIMIT ||
+	    ++failure->retries <= failure->allowed)
+		return NEEDS_RETRY;
+
+	return SUCCESS;
+}
+
 /**
  * scsi_decide_disposition - Disposition a cmd on return from LLD.
  * @scmd:	SCSI cmd to examine.
@@ -1857,6 +1933,12 @@ enum scsi_disposition scsi_decide_disposition(struct scsi_cmnd *scmd)
 		return SUCCESS;
 	}
 
+	if (blk_rq_is_passthrough(scsi_cmd_to_rq(scmd))) {
+		rtn = scsi_check_passthrough(scmd);
+		if (rtn != SCSI_RETURN_NOT_HANDLED)
+			return rtn;
+	}
+
 	/*
 	 * first check the host byte, to see if there is anything in there
 	 * that would indicate what we need to do.
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index ec890865abae..fc1560981a03 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1128,6 +1128,7 @@ static void scsi_initialize_rq(struct request *rq)
 	init_rcu_head(&cmd->rcu);
 	cmd->jiffies_at_alloc = jiffies;
 	cmd->retries = 0;
+	cmd->failures = NULL;
 }
 
 struct request *scsi_alloc_request(struct request_queue *q, blk_opf_t opf,
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index c2cb5f69635c..016a371715b7 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -66,6 +66,23 @@ enum scsi_cmnd_submitter {
 	SUBMITTED_BY_SCSI_RESET_IOCTL = 2,
 } __packed;
 
+#define SCMD_FAILURE_RESULT_ANY	0x7fffffff
+#define SCMD_FAILURE_STAT_ANY	0xff
+#define SCMD_FAILURE_SENSE_ANY	0xff
+#define SCMD_FAILURE_ASC_ANY	0xff
+#define SCMD_FAILURE_ASCQ_ANY	0xff
+#define SCMD_FAILURE_NO_LIMIT	-1
+
+struct scsi_failure {
+	int result;
+	u8 sense;
+	u8 asc;
+	u8 ascq;
+
+	s8 allowed;
+	s8 retries;
+};
+
 struct scsi_cmnd {
 	struct scsi_device *device;
 	struct list_head eh_entry; /* entry for the host eh_abort_list/eh_cmd_q */
@@ -86,6 +103,8 @@ struct scsi_cmnd {
 
 	int retries;
 	int allowed;
+	/* optional array of failures that passthrough users want retried */
+	struct scsi_failure *failures;
 
 	unsigned char prot_op;
 	unsigned char prot_type;
@@ -331,9 +350,14 @@ static inline void set_status_byte(struct scsi_cmnd *cmd, char status)
 	cmd->result = (cmd->result & 0xffffff00) | status;
 }
 
+static inline u8 __get_status_byte(int result)
+{
+	return result & 0xff;
+}
+
 static inline u8 get_status_byte(struct scsi_cmnd *cmd)
 {
-	return cmd->result & 0xff;
+	return __get_status_byte(cmd->result);
 }
 
 static inline void set_host_byte(struct scsi_cmnd *cmd, char status)
-- 
2.25.1


  parent reply	other threads:[~2022-11-04 23:19 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-04 23:18 [PATCH v6 00/35] Allow scsi_execute users to control retries Mike Christie
2022-11-04 23:18 ` [PATCH v6 01/35] scsi: Add helper to prep sense during error handling Mike Christie
2022-11-04 23:18 ` Mike Christie [this message]
2022-11-08 23:57   ` [PATCH v6 02/35] scsi: Allow passthrough to override what errors to retry Bart Van Assche
2022-11-09  3:49     ` Mike Christie
2022-11-15  8:10   ` Christoph Hellwig
2022-11-04 23:18 ` [PATCH v6 03/35] scsi: Add struct for args to execution functions Mike Christie
2022-11-10 11:15   ` John Garry
2022-11-10 17:26     ` Bart Van Assche
2022-11-10 18:09       ` John Garry
2022-11-10 18:21         ` Mike Christie
2022-11-10 18:40     ` Mike Christie
2022-11-10 19:26       ` Mike Christie
2022-11-10 20:47         ` Bart Van Assche
2022-11-11 12:07         ` John Garry
2022-11-15  8:13           ` Christoph Hellwig
2022-11-15  8:25   ` Christoph Hellwig
2022-11-04 23:18 ` [PATCH v6 04/35] scsi: Add scsi_failure field to scsi_exec_args Mike Christie
2022-11-15  8:25   ` Christoph Hellwig
2022-11-04 23:18 ` [PATCH v6 05/35] scsi: libata: Convert to scsi_exec_req Mike Christie
2022-11-04 23:18 ` [PATCH v6 06/35] hwmon: drivetemp: " Mike Christie
2022-11-04 23:18 ` [PATCH v6 07/35] scsi: ch: " Mike Christie
2022-11-04 23:19 ` [PATCH v6 08/35] scsi: scsi_dh: " Mike Christie
2022-11-04 23:19 ` [PATCH v6 09/35] scsi: core: " Mike Christie
2022-11-04 23:19 ` [PATCH v6 10/35] scsi: spi: " Mike Christie
2022-11-04 23:19 ` [PATCH v6 11/35] scsi: sd: " Mike Christie
2022-11-04 23:19 ` [PATCH v6 12/35] scsi: zbc: " Mike Christie
2022-11-04 23:19 ` [PATCH v6 13/35] scsi: ses: " Mike Christie
2022-11-04 23:19 ` [PATCH v6 14/35] scsi: sr: " Mike Christie
2022-11-04 23:19 ` [PATCH v6 15/35] scsi: virtio_scsi: " Mike Christie
2022-11-04 23:19 ` [PATCH v6 16/35] scsi: target_core_pscsi: " Mike Christie
2022-11-04 23:19 ` [PATCH v6 17/35] scsi: cxlflash: " Mike Christie
2022-11-04 23:19 ` [PATCH v6 18/35] scsi: Remove scsi_execute functions Mike Christie
2022-11-04 23:19 ` [PATCH v6 19/35] scsi: Have scsi-ml retry scsi_probe_lun errors Mike Christie
2022-11-04 23:19 ` [PATCH v6 20/35] scsi: retry INQUIRY after timeout Mike Christie
2022-11-04 23:19 ` [PATCH v6 21/35] scsi: Have scsi-ml retry read_capacity_16 errors Mike Christie
2022-11-09 18:42   ` Bart Van Assche
2022-11-04 23:19 ` [PATCH v6 22/35] scsi: Have scsi-ml retry sd_spinup_disk errors Mike Christie
2022-11-09 18:45   ` Bart Van Assche
2022-11-04 23:19 ` [PATCH v6 23/35] scsi: hp_sw: Have scsi-ml retry scsi_exec_req errors Mike Christie
2022-11-04 23:19 ` [PATCH v6 24/35] scsi: rdac: Have scsi-ml retry send_mode_select errors Mike Christie
2022-11-04 23:19 ` [PATCH v6 25/35] scsi: spi: Have scsi-ml retry spi_execute errors Mike Christie
2022-11-04 23:19 ` [PATCH v6 26/35] scsi: sd: Have scsi-ml retry sd_sync_cache errors Mike Christie
2022-11-09 18:47   ` Bart Van Assche
2022-11-04 23:19 ` [PATCH v6 27/35] scsi: ch: Have scsi-ml retry ch_do_scsi errors Mike Christie
2022-11-09 18:50   ` Bart Van Assche
2022-11-04 23:19 ` [PATCH v6 28/35] scsi: Have scsi-ml retry scsi_mode_sense errors Mike Christie
2022-11-09 18:51   ` Bart Van Assche
2022-11-04 23:19 ` [PATCH v6 29/35] scsi: Have scsi-ml retry scsi_report_lun_scan errors Mike Christie
2022-11-09 18:53   ` Bart Van Assche
2022-11-04 23:19 ` [PATCH v6 30/35] scsi: sd: Have sd_pr_command retry UAs Mike Christie
2022-11-09 18:53   ` Bart Van Assche
2022-11-04 23:19 ` [PATCH v6 31/35] scsi: sd: Have scsi-ml retry read_capacity_10 errors Mike Christie
2022-11-09 18:55   ` Bart Van Assche
2022-11-04 23:19 ` [PATCH v6 32/35] scsi: ses: Have scsi-ml retry scsi_exec_req errors Mike Christie
2022-11-04 23:19 ` [PATCH v6 33/35] scsi: sr: Have scsi-ml retry get_sectorsize errors Mike Christie
2022-11-04 23:19 ` [PATCH v6 34/35] scsi: ufs: Have scsi-ml retry start stop errors Mike Christie
2022-11-09 19:00   ` Bart Van Assche
2022-11-04 23:19 ` [PATCH v6 35/35] scsi: Add kunit tests for scsi_check_passthrough Mike Christie
2022-11-09 19:01   ` Bart Van Assche

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221104231927.9613-3-michael.christie@oracle.com \
    --to=michael.christie@oracle.com \
    --cc=bvanassche@acm.org \
    --cc=hch@lst.de \
    --cc=james.bottomley@hansenpartnership.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    --cc=mwilck@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.