]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.fixes/scsi-terminate-target-reset
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.fixes / scsi-terminate-target-reset
diff --git a/src/patches/suse-2.6.27.31/patches.fixes/scsi-terminate-target-reset b/src/patches/suse-2.6.27.31/patches.fixes/scsi-terminate-target-reset
new file mode 100644 (file)
index 0000000..b2b6a32
--- /dev/null
@@ -0,0 +1,78 @@
+From: James Bottomley <James.Bottomley@HansenPartnership.com>
+Subject: Target reset hangs
+Date: Fri, 12 Sep 2008 16:46:51 -0500
+References: bnc#427267
+
+Actually, turns out it's nothing to do with block timeouts, it's a
+target reset bug.
+
+This loop:
+
+       for (id = 0; id <= shost->max_id; id++) {
+
+Never terminates if shost->max_id is set to ~0, like aic94xx does.
+
+It's also pretty inefficient since you mostly have compact target
+numbers, but the max_id can be very high.  The best way would be to sort
+the recovery list by target id and skip them if they're equal, but even
+a worst case O(N^2) traversal is probably OK here.
+
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
+index ad019ec..94ed262 100644
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -1065,10 +1065,10 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
+                               struct list_head *done_q)
+ {
+       struct scsi_cmnd *scmd, *tgtr_scmd, *next;
+-      unsigned int id;
++      unsigned int id = 0;
+       int rtn;
+-      for (id = 0; id <= shost->max_id; id++) {
++      do {
+               tgtr_scmd = NULL;
+               list_for_each_entry(scmd, work_q, eh_entry) {
+                       if (id == scmd_id(scmd)) {
+@@ -1076,8 +1076,18 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
+                               break;
+                       }
+               }
++              if (!tgtr_scmd) {
++                      /* not one exactly equal; find the next highest */
++                      list_for_each_entry(scmd, work_q, eh_entry) {
++                              if (scmd_id(scmd) > id &&
++                                  (!tgtr_scmd ||
++                                   scmd_id(tgtr_scmd) > scmd_id(scmd)))
++                                              tgtr_scmd = scmd;
++                      }
++              }
+               if (!tgtr_scmd)
+-                      continue;
++                      /* no more commands, that's it */
++                      break;
+               SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending target reset "
+                                                 "to target %d\n",
+@@ -1096,7 +1106,8 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
+                                                         " failed target: "
+                                                         "%d\n",
+                                                         current->comm, id));
+-      }
++              id++;
++      } while(id != 0);
+       return list_empty(work_q);
+ }
+
+
+
+
+
+--
+To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at  http://vger.kernel.org/majordomo-info.html