]>
Commit | Line | Data |
---|---|---|
82094b55 AF |
1 | From: Hannes Reinecke <hare@suse.de> |
2 | Date: Tue, 18 Aug 2009 10:46:26 +0200 | |
3 | Subject: libiscsi: fix iscsi transport checks to account for slower links | |
4 | References: bnc#472432 | |
5 | X-Git: 4c48a82935f833d94fcf44c2b0c5d2922acfc77a | |
6 | ||
7 | If we have not got any pdus for recv_timeout seconds, then we will | |
8 | send a iscsi ping/nop to make sure the target is still around. The | |
9 | problem is if this is a slow link, and the ping got queued after | |
10 | the data for a data_out (read), then the transport code could think | |
11 | the ping has failed when it is just slowly making its way through | |
12 | the network. This patch has us check if we are making progress while | |
13 | the nop is outstanding. If we are still reading in data, then we | |
14 | do not fail the session at that time. | |
15 | ||
16 | Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> | |
17 | Signed-off-by: Hannes Reinecke <hare@suse.de> | |
18 | --- | |
19 | drivers/scsi/libiscsi.c | 38 +++++++++++++++++++++++++++++--------- | |
20 | 1 files changed, 29 insertions(+), 9 deletions(-) | |
21 | ||
22 | diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c | |
23 | index 95720cc..14ba60f 100644 | |
24 | --- a/drivers/scsi/libiscsi.c | |
25 | +++ b/drivers/scsi/libiscsi.c | |
26 | @@ -1630,6 +1630,22 @@ static void iscsi_start_tx(struct iscsi_conn *conn) | |
27 | scsi_queue_work(conn->session->host, &conn->xmitwork); | |
28 | } | |
29 | ||
30 | +/* | |
31 | + * We want to make sure a ping is in flight. It has timed out. | |
32 | + * And we are not busy processing a pdu that is making | |
33 | + * progress but got started before the ping and is taking a while | |
34 | + * to complete so the ping is just stuck behind it in a queue. | |
35 | + */ | |
36 | +static int iscsi_has_ping_timed_out(struct iscsi_conn *conn) | |
37 | +{ | |
38 | + if (conn->ping_task && | |
39 | + time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) + | |
40 | + (conn->ping_timeout * HZ), jiffies)) | |
41 | + return 1; | |
42 | + else | |
43 | + return 0; | |
44 | +} | |
45 | + | |
46 | static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd) | |
47 | { | |
48 | struct iscsi_cls_session *cls_session; | |
49 | @@ -1665,16 +1681,20 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd) | |
50 | * if the ping timedout then we are in the middle of cleaning up | |
51 | * and can let the iscsi eh handle it | |
52 | */ | |
53 | - if (time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) + | |
54 | - (conn->ping_timeout * HZ), jiffies)) | |
55 | + if (iscsi_has_ping_timed_out(conn)) { | |
56 | rc = BLK_EH_RESET_TIMER; | |
57 | + goto done; | |
58 | + } | |
59 | /* | |
60 | * if we are about to check the transport then give the command | |
61 | * more time | |
62 | */ | |
63 | if (time_before_eq(conn->last_recv + (conn->recv_timeout * HZ), | |
64 | - jiffies)) | |
65 | + jiffies)) { | |
66 | rc = BLK_EH_RESET_TIMER; | |
67 | + goto done; | |
68 | + } | |
69 | + | |
70 | /* if in the middle of checking the transport then give us more time */ | |
71 | if (conn->ping_task) | |
72 | rc = BLK_EH_RESET_TIMER; | |
73 | @@ -1701,13 +1721,13 @@ static void iscsi_check_transport_timeouts(unsigned long data) | |
74 | ||
75 | recv_timeout *= HZ; | |
76 | last_recv = conn->last_recv; | |
77 | - if (conn->ping_task && | |
78 | - time_before_eq(conn->last_ping + (conn->ping_timeout * HZ), | |
79 | - jiffies)) { | |
80 | + | |
81 | + if (iscsi_has_ping_timed_out(conn)) { | |
82 | iscsi_conn_printk(KERN_ERR, conn, "ping timeout of %d secs " | |
83 | - "expired, last rx %lu, last ping %lu, " | |
84 | - "now %lu\n", conn->ping_timeout, last_recv, | |
85 | - conn->last_ping, jiffies); | |
86 | + "expired, recv timeout %d, last rx %lu, " | |
87 | + "last ping %lu, now %lu\n", | |
88 | + conn->ping_timeout, conn->recv_timeout, | |
89 | + last_recv, conn->last_ping, jiffies); | |
90 | spin_unlock(&session->lock); | |
91 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | |
92 | return; | |
93 | -- | |
94 | 1.6.0.2 | |
95 |