[PATCH 2/2] SCSI: implement scsi_eh_schedule_host()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch implements scsi_eh_schedule_host() which provides a way to
directly invoke SCSI EH without SCSI command from drivers implementing
->eh_strategy_handler.  This allows such drivers to use EH to handle
exception conditions which are not associated with particular SCSI
command.

Signed-off-by: Tejun Heo <htejun@xxxxxxxxx>

---

Jeff, I think using separate variable (->host_eh_scheduled) is the
simplest way to implement this.  Adding more semantics to ->host_busy
and failed doesn't sound very attractive to me.

 drivers/scsi/scsi_error.c |   38 +++++++++++++++++++++++++++++++++++++-
 include/scsi/scsi_eh.h    |    1 +
 include/scsi/scsi_host.h  |    1 +
 3 files changed, 39 insertions(+), 1 deletions(-)

544d293f756e7041f676ac30152445339111a9c8
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index c314095..bc8a253 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -114,6 +114,42 @@ int scsi_eh_schedule_cmd(struct scsi_cmn
 EXPORT_SYMBOL_GPL(scsi_eh_schedule_cmd);
 
 /**
+ * scsi_eh_schedule_host - schedule scsi host for error handling
+ * @shost:	SCSI host to invoke error handling on.
+ *
+ * Description:
+ *	This function is used by LLDDs which don't use standard SCSI
+ *	EH to schedule @shost for EH.  This allows such LLDDs to use
+ *	EH for handling exceptions not associated with command.
+ *
+ * Return value:
+ *	0 on failure.
+ **/
+int scsi_eh_schedule_host(struct Scsi_Host *shost)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	WARN_ON(!shost->hostt->eh_strategy_handler);
+
+	if (!shost->ehandler)
+		return 0;
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	if (scsi_host_set_state(shost, SHOST_RECOVERY))
+		if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY))
+			goto out_unlock;
+
+	ret = 1;
+	shost->host_eh_scheduled++;
+	scsi_eh_wakeup(shost);
+ out_unlock:
+	spin_unlock_irqrestore(shost->host_lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(scsi_eh_schedule_host);
+
+/**
  * scsi_add_timer - Start timeout timer for a single scsi command.
  * @scmd:	scsi command that is about to start running.
  * @timeout:	amount of time to allow this command to run.
@@ -1541,7 +1577,7 @@ int scsi_error_handler(void *data)
 	 */
 	set_current_state(TASK_INTERRUPTIBLE);
 	while (!kthread_should_stop()) {
-		if (shost->host_failed == 0 ||
+		if ((shost->host_failed == 0 && shost->host_eh_scheduled == 0) ||
 		    shost->host_failed != shost->host_busy) {
 			SCSI_LOG_ERROR_RECOVERY(1,
 				printk("Error handler scsi_eh_%d sleeping\n",
diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h
index dd0a50e..b1c09f4 100644
--- a/include/scsi/scsi_eh.h
+++ b/include/scsi/scsi_eh.h
@@ -36,6 +36,7 @@ static inline int scsi_sense_valid(struc
 
 
 extern int scsi_eh_schedule_cmd(struct scsi_cmnd *scmd);
+extern int scsi_eh_schedule_host(struct Scsi_Host *shost);
 extern void scsi_eh_finish_cmd(struct scsi_cmnd *scmd,
 			       struct list_head *done_q);
 extern void scsi_eh_flush_done_q(struct list_head *done_q);
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index dc6862d..a991b9c 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -473,6 +473,7 @@ struct Scsi_Host {
 	 */
 	unsigned int host_busy;		   /* commands actually active on low-level */
 	unsigned int host_failed;	   /* commands that failed. */
+	unsigned int host_eh_scheduled;	   /* EH scheduled without command */
     
 	unsigned short host_no;  /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */
 	int resetting; /* if set, it means that last_reset is a valid value */
-- 
1.2.4

-
: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux