[SCSI] libiscsi: fix iscsi transport checks to account for slower links
[deliverable/linux.git] / drivers / scsi / libiscsi.c
index 212fe2027a8c942dd86c955fa9928d96b9bfdd69..c648bd328a219203021d3da7ba0d3511ece54728 100644 (file)
@@ -1677,6 +1677,22 @@ static void iscsi_start_tx(struct iscsi_conn *conn)
                iscsi_conn_queue_work(conn);
 }
 
+/*
+ * We want to make sure a ping is in flight. It has timed out.
+ * And we are not busy processing a pdu that is making
+ * progress but got started before the ping and is taking a while
+ * to complete so the ping is just stuck behind it in a queue.
+ */
+static int iscsi_has_ping_timed_out(struct iscsi_conn *conn)
+{
+       if (conn->ping_task &&
+           time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) +
+                          (conn->ping_timeout * HZ), jiffies))
+               return 1;
+       else
+               return 0;
+}
+
 static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
 {
        struct iscsi_cls_session *cls_session;
@@ -1712,16 +1728,20 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd)
         * if the ping timedout then we are in the middle of cleaning up
         * and can let the iscsi eh handle it
         */
-       if (time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) +
-                           (conn->ping_timeout * HZ), jiffies))
+       if (iscsi_has_ping_timed_out(conn)) {
                rc = BLK_EH_RESET_TIMER;
+               goto done;
+       }
        /*
         * if we are about to check the transport then give the command
         * more time
         */
        if (time_before_eq(conn->last_recv + (conn->recv_timeout * HZ),
-                          jiffies))
+                          jiffies)) {
                rc = BLK_EH_RESET_TIMER;
+               goto done;
+       }
+
        /* if in the middle of checking the transport then give us more time */
        if (conn->ping_task)
                rc = BLK_EH_RESET_TIMER;
@@ -1748,13 +1768,13 @@ static void iscsi_check_transport_timeouts(unsigned long data)
 
        recv_timeout *= HZ;
        last_recv = conn->last_recv;
-       if (conn->ping_task &&
-           time_before_eq(conn->last_ping + (conn->ping_timeout * HZ),
-                          jiffies)) {
+
+       if (iscsi_has_ping_timed_out(conn)) {
                iscsi_conn_printk(KERN_ERR, conn, "ping timeout of %d secs "
-                                 "expired, last rx %lu, last ping %lu, "
-                                 "now %lu\n", conn->ping_timeout, last_recv,
-                                 conn->last_ping, jiffies);
+                                 "expired, recv timeout %d, last rx %lu, "
+                                 "last ping %lu, now %lu\n",
+                                 conn->ping_timeout, conn->recv_timeout,
+                                 last_recv, conn->last_ping, jiffies);
                spin_unlock(&session->lock);
                iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
                return;
This page took 0.025579 seconds and 5 git commands to generate.