]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.fixes/scsi-terminate-target-reset
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.fixes / scsi-terminate-target-reset
1 From: James Bottomley <James.Bottomley@HansenPartnership.com>
2 Subject: Target reset hangs
3 Date: Fri, 12 Sep 2008 16:46:51 -0500
4 References: bnc#427267
5
6 Actually, turns out it's nothing to do with block timeouts, it's a
7 target reset bug.
8
9 This loop:
10
11 for (id = 0; id <= shost->max_id; id++) {
12
13 Never terminates if shost->max_id is set to ~0, like aic94xx does.
14
15 It's also pretty inefficient since you mostly have compact target
16 numbers, but the max_id can be very high. The best way would be to sort
17 the recovery list by target id and skip them if they're equal, but even
18 a worst case O(N^2) traversal is probably OK here.
19
20 Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
21 Signed-off-by: Hannes Reinecke <hare@suse.de>
22 ---
23 diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
24 index 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 --
76 To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
77 the body of a message to majordomo@vger.kernel.org
78 More majordomo info at http://vger.kernel.org/majordomo-info.html