libiscsi: Fix recovery slowdown regression
authorMike Christie <michaelc@cs.wisc.edu>
Tue, 9 Mar 2010 20:14:51 +0000 (14:14 -0600)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 26 Apr 2010 14:41:17 +0000 (07:41 -0700)
commit 4ae0a6c15efcc37e94e3f30e3533bdec03c53126 upstream.

We could be failing/stopping a connection due to libiscsi starting
recovery/cleanup, but the xmit path or scsi eh thread path
could be dropping the connection at the same time.

As a result the session->state gets set to failed instead of in
recovery. We end up not blocking the session
and so the replacement timeout never gets started and we only end up
failing the IO when scsi_softirq_done sees that the
cmd has been running for (cmd->allowed + 1) * rq->timeout secs.

We used to fail the IO right away so users are seeing a long
delay when using dm-multipath. This problem was added in
2.6.28.

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/scsi/libiscsi.c

index f1a4246f890c044a9cb548366cd7a79865a42f4a..c7a6a894aee0d36116343ef3085520ffc6dcee67 100644 (file)
@@ -2823,14 +2823,15 @@ static void iscsi_start_session_recovery(struct iscsi_session *session,
                session->state = ISCSI_STATE_TERMINATE;
        else if (conn->stop_stage != STOP_CONN_RECOVER)
                session->state = ISCSI_STATE_IN_RECOVERY;
+
+       old_stop_stage = conn->stop_stage;
+       conn->stop_stage = flag;
        spin_unlock_bh(&session->lock);
 
        del_timer_sync(&conn->transport_timer);
        iscsi_suspend_tx(conn);
 
        spin_lock_bh(&session->lock);
-       old_stop_stage = conn->stop_stage;
-       conn->stop_stage = flag;
        conn->c_stage = ISCSI_CONN_STOPPED;
        spin_unlock_bh(&session->lock);