The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Wenchao Hao <haowenchao2@huawei.com>
To: "James E . J . Bottomley" <jejb@linux.ibm.com>,
	"Martin K . Petersen" <martin.petersen@oracle.com>,
	<linux-scsi@vger.kernel.org>
Cc: Hannes Reinecke <hare@suse.de>, <linux-kernel@vger.kernel.org>,
	<louhongxiang@huawei.com>, <lixiaokeng@huawei.com>,
	Wenchao Hao <haowenchao2@huawei.com>
Subject: [RFC PATCH v2 06/19] scsi: scsi_error: Add flags to mark error handle steps has done
Date: Fri, 1 Sep 2023 17:41:14 +0800	[thread overview]
Message-ID: <20230901094127.2010873-7-haowenchao2@huawei.com> (raw)
In-Reply-To: <20230901094127.2010873-1-haowenchao2@huawei.com>

LUN based error handle would mainly do three steps to recover
commands which are check sense, start unit, and reset lun. It might
fallback to target/host based error handle which would do these steps
too.

Target based error handle would reset target, it would also fallback
to host based error handle.

Add some flags to mark these steps are done to avoid repeating
these steps.

The flags should be cleared when LUN/target based error handler is
waked up or when target/host based error handle finished, and set
when fallback to target/host based error handle.

scsi_eh_get_sense, scsi_eh_stu, scsi_eh_bus_device_reset and
scsi_eh_target_reset would check these flags before actually action.

Signed-off-by: Wenchao Hao <haowenchao2@huawei.com>
---
 drivers/scsi/scsi_error.c  | 55 ++++++++++++++++++++++++++++++++++++++
 include/scsi/scsi_device.h | 28 +++++++++++++++++++
 2 files changed, 83 insertions(+)

diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 16888540b663..055c04470f5c 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -57,10 +57,50 @@
 #define BUS_RESET_SETTLE_TIME   (10)
 #define HOST_RESET_SETTLE_TIME  (10)
 
+#define sdev_flags_done(flag)					\
+static inline int sdev_##flag(struct scsi_device *sdev)		\
+{								\
+	struct scsi_device_eh *eh = sdev->eh;			\
+	if (!eh)						\
+		return 0;					\
+	return eh->flag;					\
+}
+
 static int scsi_eh_try_stu(struct scsi_cmnd *scmd);
 static enum scsi_disposition scsi_try_to_abort_cmd(const struct scsi_host_template *,
 						   struct scsi_cmnd *);
 
+sdev_flags_done(get_sense_done);
+sdev_flags_done(stu_done);
+sdev_flags_done(reset_done);
+
+static inline int starget_reset_done(struct scsi_target *starget)
+{
+	struct scsi_target_eh *eh = starget->eh;
+
+	if (!eh)
+		return 0;
+	return eh->reset_done;
+}
+
+static inline void shost_clear_eh_done(struct Scsi_Host *shost)
+{
+	struct scsi_device *sdev;
+	struct scsi_target *starget;
+
+	list_for_each_entry(starget, &shost->__targets, siblings)
+		if (starget->eh)
+			starget->eh->reset_done = 0;
+
+	shost_for_each_device(sdev, shost) {
+		if (!sdev->eh)
+			continue;
+		sdev->eh->get_sense_done = 0;
+		sdev->eh->stu_done	 = 0;
+		sdev->eh->reset_done	 = 0;
+	}
+}
+
 void scsi_eh_wakeup(struct Scsi_Host *shost)
 {
 	lockdep_assert_held(shost->host_lock);
@@ -1402,6 +1442,9 @@ int scsi_eh_get_sense(struct list_head *work_q,
 					     current->comm));
 			break;
 		}
+		if (sdev_get_sense_done(scmd->device) ||
+		    starget_reset_done(scsi_target(scmd->device)))
+			continue;
 		if (!scsi_status_is_check_condition(scmd->result))
 			/*
 			 * don't request sense if there's no check condition
@@ -1615,6 +1658,9 @@ static int scsi_eh_stu(struct Scsi_Host *shost,
 			scsi_device_put(sdev);
 			break;
 		}
+		if (sdev_stu_done(sdev) ||
+		    starget_reset_done(scsi_target(sdev)))
+			continue;
 		stu_scmd = NULL;
 		list_for_each_entry(scmd, work_q, eh_entry)
 			if (scmd->device == sdev && SCSI_SENSE_VALID(scmd) &&
@@ -1698,6 +1744,9 @@ static int scsi_eh_bus_device_reset(struct Scsi_Host *shost,
 				bdr_scmd = scmd;
 				break;
 			}
+		if (sdev_reset_done(sdev) ||
+		    starget_reset_done(scsi_target(sdev)))
+			continue;
 
 		if (!bdr_scmd)
 			continue;
@@ -1746,6 +1795,11 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
 		}
 
 		scmd = list_entry(tmp_list.next, struct scsi_cmnd, eh_entry);
+		if (starget_reset_done(scsi_target(scmd->device))) {
+			/* push back on work queue for further processing */
+			list_move(&scmd->eh_entry, work_q);
+			continue;
+		}
 		id = scmd_id(scmd);
 
 		SCSI_LOG_ERROR_RECOVERY(3,
@@ -2359,6 +2413,7 @@ static void scsi_unjam_host(struct Scsi_Host *shost)
 	if (!scsi_eh_get_sense(&eh_work_q, &eh_done_q))
 		scsi_eh_ready_devs(shost, &eh_work_q, &eh_done_q);
 
+	shost_clear_eh_done(shost);
 	spin_lock_irqsave(shost->host_lock, flags);
 	if (shost->eh_deadline != -1)
 		shost->last_reset = 0;
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index df3f1b8d1390..b03a4f21c7df 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -108,6 +108,24 @@ struct scsi_device;
 struct scsi_target;
 
 struct scsi_device_eh {
+	/*
+	 * LUN rebased error handle would mainly do three
+	 * steps to recovery commands which are
+	 *   check sense
+	 *   start unit
+	 *   reset lun
+	 * While we would fallback to target or host based error handle
+	 * which would do these steps too. Add flags to mark thes steps
+	 * are done to avoid repeating these steps.
+	 *
+	 * The flags should be cleared when LUN based error handler is
+	 * wakedup or when target/host based error handle finished,
+	 * set when fallback to target or host based error handle.
+	 */
+	unsigned get_sense_done:1;
+	unsigned stu_done:1;
+	unsigned reset_done:1;
+
 	/*
 	 * add scsi command to error handler so it would be handuled by
 	 * driver's error handle strategy
@@ -139,6 +157,16 @@ struct scsi_device_eh {
 };
 
 struct scsi_target_eh {
+	/*
+	 * flag to mark target reset is done to avoid repeating
+	 * these steps when fallback to host based error handle
+	 *
+	 * The flag should be cleared when target based error handler
+	 * is * wakedup or when host based error handle finished,
+	 * set when fallback to host based error handle.
+	 */
+	unsigned reset_done:1;
+
 	/*
 	 * add scsi command to error handler so it would be handuled by
 	 * driver's error handle strategy
-- 
2.35.3


  parent reply	other threads:[~2023-09-01  9:42 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-01  9:41 [RFC PATCH v2 00/18] scsi: scsi_error: Introduce new error handle mechanism Wenchao Hao
2023-09-01  9:41 ` [RFC PATCH v2 01/19] scsi: scsi_error: Define framework for LUN/target based error handle Wenchao Hao
2023-09-01  9:41 ` [RFC PATCH v2 02/19] scsi: scsi_error: Move complete variable eh_action from shost to sdevice Wenchao Hao
2023-09-01  9:41 ` [RFC PATCH v2 03/19] scsi: scsi_error: Check if to do reset in scsi_try_xxx_reset Wenchao Hao
2023-09-01  9:41 ` [RFC PATCH v2 04/19] scsi: scsi_error: Add helper scsi_eh_sdev_stu to do START_UNIT Wenchao Hao
2023-09-01  9:41 ` [RFC PATCH v2 05/19] scsi: scsi_error: Add helper scsi_eh_sdev_reset to do lun reset Wenchao Hao
2023-09-01  9:41 ` Wenchao Hao [this message]
2023-09-01  9:41 ` [RFC PATCH v2 07/19] scsi: scsi_error: Add helper to handle scsi device's error command list Wenchao Hao
2023-09-01  9:41 ` [RFC PATCH v2 08/19] scsi: scsi_error: Add a general LUN based error handler Wenchao Hao
2023-09-01  9:41 ` [RFC PATCH v2 09/19] scsi: core: increase/decrease target_busy without check can_queue Wenchao Hao
2023-09-05 23:55   ` Mike Christie
2023-09-06 12:12     ` Wenchao Hao
2023-09-01  9:41 ` [RFC PATCH v2 10/19] scsi: scsi_error: Add helper to handle scsi target's error command list Wenchao Hao
2023-09-01  9:41 ` [RFC PATCH v2 11/19] scsi: scsi_error: Add a general target based error handler Wenchao Hao
2023-09-01  9:41 ` [RFC PATCH v2 12/19] scsi: scsi_debug: Add param to control LUN bassed " Wenchao Hao
2023-09-01  9:41 ` [RFC PATCH v2 13/19] scsi: scsi_debug: Add param to control target based error handle Wenchao Hao
2023-09-01  9:41 ` [RFC PATCH v2 14/19] scsi: mpt3sas: Add param to control LUN " Wenchao Hao
2023-09-01  9:41 ` [RFC PATCH v2 15/19] scsi: mpt3sas: Add param to control target " Wenchao Hao
2023-09-01  9:41 ` [RFC PATCH v2 16/19] scsi: smartpqi: Add param to control LUN " Wenchao Hao
2023-09-01  9:41 ` [RFC PATCH v2 17/19] scsi: megaraid_sas: Add param to control target " Wenchao Hao
2023-09-01  9:41 ` [RFC PATCH v2 18/19] scsi: virtio_scsi: Add param to control LUN " Wenchao Hao
2023-09-01  9:41 ` [RFC PATCH v2 19/19] scsi: iscsi_tcp: " Wenchao Hao
2023-09-05  1:32 ` [RFC PATCH v2 00/18] scsi: scsi_error: Introduce new error handle mechanism haowenchao (C)
2023-09-06  0:22 ` Mike Christie
2023-09-06 11:15   ` haowenchao (C)
2023-09-06 15:56     ` Mike Christie
2023-09-07 12:38       ` Wenchao Hao
2023-09-14  6:20 ` Wenchao Hao
2023-09-25 16:52   ` Mike Christie
2023-09-25 14:55 ` Christoph Hellwig
2023-09-25 15:07   ` Wenchao Hao
2023-09-25 17:54     ` Mike Christie
2023-09-26  7:26       ` Christoph Hellwig
2023-09-27  6:26         ` Hannes Reinecke
2023-09-26 12:57       ` Wenchao Hao
2023-09-26 17:37         ` Mike Christie
2023-09-27  9:39           ` Wenchao Hao
2023-09-27  7:59         ` Hannes Reinecke
2023-09-27  9:41           ` Wenchao Hao

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=20230901094127.2010873-7-haowenchao2@huawei.com \
    --to=haowenchao2@huawei.com \
    --cc=hare@suse.de \
    --cc=jejb@linux.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=lixiaokeng@huawei.com \
    --cc=louhongxiang@huawei.com \
    --cc=martin.petersen@oracle.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox