]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.fixes/scsi-terminate-target-reset
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.fixes / scsi-terminate-target-reset
CommitLineData
2cb7cef9
BS
1From: James Bottomley <James.Bottomley@HansenPartnership.com>
2Subject: Target reset hangs
3Date: Fri, 12 Sep 2008 16:46:51 -0500
4References: bnc#427267
5
6Actually, turns out it's nothing to do with block timeouts, it's a
7target reset bug.
8
9This loop:
10
11 for (id = 0; id <= shost->max_id; id++) {
12
13Never terminates if shost->max_id is set to ~0, like aic94xx does.
14
15It's also pretty inefficient since you mostly have compact target
16numbers, but the max_id can be very high. The best way would be to sort
17the recovery list by target id and skip them if they're equal, but even
18a worst case O(N^2) traversal is probably OK here.
19
20Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
21Signed-off-by: Hannes Reinecke <hare@suse.de>
22---
23diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
24index ad019ec..94ed262 100644
25--- a/drivers/scsi/scsi_error.c
26+++ b/drivers/scsi/scsi_error.c
27@@ -1065,10 +1065,10 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
28 struct list_head *done_q)
29 {
30 struct scsi_cmnd *scmd, *tgtr_scmd, *next;
31- unsigned int id;
32+ unsigned int id = 0;
33 int rtn;
34
35- for (id = 0; id <= shost->max_id; id++) {
36+ do {
37 tgtr_scmd = NULL;
38 list_for_each_entry(scmd, work_q, eh_entry) {
39 if (id == scmd_id(scmd)) {
40@@ -1076,8 +1076,18 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
41 break;
42 }
43 }
44+ if (!tgtr_scmd) {
45+ /* not one exactly equal; find the next highest */
46+ list_for_each_entry(scmd, work_q, eh_entry) {
47+ if (scmd_id(scmd) > id &&
48+ (!tgtr_scmd ||
49+ scmd_id(tgtr_scmd) > scmd_id(scmd)))
50+ tgtr_scmd = scmd;
51+ }
52+ }
53 if (!tgtr_scmd)
54- continue;
55+ /* no more commands, that's it */
56+ break;
57
58 SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending target reset "
59 "to target %d\n",
60@@ -1096,7 +1106,8 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
61 " failed target: "
62 "%d\n",
63 current->comm, id));
64- }
65+ id++;
66+ } while(id != 0);
67
68 return list_empty(work_q);
69 }
70
71
72
73
74
75--
76To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
77the body of a message to majordomo@vger.kernel.org
78More majordomo info at http://vger.kernel.org/majordomo-info.html