spin_lock(&ses->chan_lock);
                        if (CIFS_CHAN_NEEDS_RECONNECT(ses, 0))
                                seq_puts(m, "\tPrimary channel: DISCONNECTED ");
+                       if (CIFS_CHAN_IN_RECONNECT(ses, 0))
+                               seq_puts(m, "\t[RECONNECTING] ");
 
                        if (ses->chan_count > 1) {
                                seq_printf(m, "\n\n\tExtra Channels: %zu ",
                                        cifs_dump_channel(m, j, &ses->chans[j]);
                                        if (CIFS_CHAN_NEEDS_RECONNECT(ses, j))
                                                seq_puts(m, "\tDISCONNECTED ");
+                                       if (CIFS_CHAN_IN_RECONNECT(ses, j))
+                                               seq_puts(m, "\t[RECONNECTING] ");
                                }
                        }
                        spin_unlock(&ses->chan_lock);
 
 };
 
 struct cifs_chan {
+       unsigned int in_reconnect : 1; /* if session setup in progress for this channel */
        struct TCP_Server_Info *server;
        __u8 signkey[SMB3_SIGN_KEY_SIZE];
 };
 #define CIFS_MAX_CHANNELS 16
 #define CIFS_ALL_CHANNELS_SET(ses)     \
        ((1UL << (ses)->chan_count) - 1)
+#define CIFS_ALL_CHANS_GOOD(ses)               \
+       (!(ses)->chans_need_reconnect)
 #define CIFS_ALL_CHANS_NEED_RECONNECT(ses)     \
        ((ses)->chans_need_reconnect == CIFS_ALL_CHANNELS_SET(ses))
 #define CIFS_SET_ALL_CHANS_NEED_RECONNECT(ses) \
        ((ses)->chans_need_reconnect = CIFS_ALL_CHANNELS_SET(ses))
 #define CIFS_CHAN_NEEDS_RECONNECT(ses, index)  \
        test_bit((index), &(ses)->chans_need_reconnect)
+#define CIFS_CHAN_IN_RECONNECT(ses, index)     \
+       ((ses)->chans[(index)].in_reconnect)
 
        struct cifs_chan chans[CIFS_MAX_CHANNELS];
        size_t chan_count;
 
 cifs_ses_get_chan_index(struct cifs_ses *ses,
                        struct TCP_Server_Info *server);
 void
+cifs_chan_set_in_reconnect(struct cifs_ses *ses,
+                            struct TCP_Server_Info *server);
+void
+cifs_chan_clear_in_reconnect(struct cifs_ses *ses,
+                              struct TCP_Server_Info *server);
+bool
+cifs_chan_in_reconnect(struct cifs_ses *ses,
+                         struct TCP_Server_Info *server);
+void
 cifs_chan_set_need_reconnect(struct cifs_ses *ses,
                             struct TCP_Server_Info *server);
 void
 
        int rc = -ENOSYS;
        bool is_binding = false;
 
-       /* only send once per connect */
-       spin_lock(&ses->chan_lock);
-       is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses);
-       spin_unlock(&ses->chan_lock);
 
        spin_lock(&cifs_tcp_ses_lock);
-       if (ses->ses_status == SES_EXITING) {
+       if (ses->ses_status != SES_GOOD &&
+           ses->ses_status != SES_NEW &&
+           ses->ses_status != SES_NEED_RECON) {
                spin_unlock(&cifs_tcp_ses_lock);
                return 0;
        }
 
+       /* only send once per connect */
+       spin_lock(&ses->chan_lock);
+       if (CIFS_ALL_CHANS_GOOD(ses) ||
+           cifs_chan_in_reconnect(ses, server)) {
+               spin_unlock(&ses->chan_lock);
+               spin_unlock(&cifs_tcp_ses_lock);
+               return 0;
+       }
+       is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses);
+       cifs_chan_set_in_reconnect(ses, server);
+       spin_unlock(&ses->chan_lock);
+
        if (!is_binding)
                ses->ses_status = SES_IN_SETUP;
        spin_unlock(&cifs_tcp_ses_lock);
                spin_lock(&cifs_tcp_ses_lock);
                if (ses->ses_status == SES_IN_SETUP)
                        ses->ses_status = SES_NEED_RECON;
+               spin_lock(&ses->chan_lock);
+               cifs_chan_clear_in_reconnect(ses, server);
+               spin_unlock(&ses->chan_lock);
                spin_unlock(&cifs_tcp_ses_lock);
        } else {
                spin_lock(&cifs_tcp_ses_lock);
                if (ses->ses_status == SES_IN_SETUP)
                        ses->ses_status = SES_GOOD;
-               spin_unlock(&cifs_tcp_ses_lock);
-
                spin_lock(&ses->chan_lock);
+               cifs_chan_clear_in_reconnect(ses, server);
                cifs_chan_clear_need_reconnect(ses, server);
                spin_unlock(&ses->chan_lock);
+               spin_unlock(&cifs_tcp_ses_lock);
        }
 
        return rc;
 
        return 0;
 }
 
+void
+cifs_chan_set_in_reconnect(struct cifs_ses *ses,
+                            struct TCP_Server_Info *server)
+{
+       unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
+
+       ses->chans[chan_index].in_reconnect = true;
+}
+
+void
+cifs_chan_clear_in_reconnect(struct cifs_ses *ses,
+                            struct TCP_Server_Info *server)
+{
+       unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
+
+       ses->chans[chan_index].in_reconnect = false;
+}
+
+bool
+cifs_chan_in_reconnect(struct cifs_ses *ses,
+                         struct TCP_Server_Info *server)
+{
+       unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
+
+       return CIFS_CHAN_IN_RECONNECT(ses, chan_index);
+}
+
 void
 cifs_chan_set_need_reconnect(struct cifs_ses *ses,
                             struct TCP_Server_Info *server)