Whamcloud - gitweb
LU-7734 lnet: handle N NIs to 1 LND peer
[fs/lustre-release.git] / lnet / klnds / o2iblnd / o2iblnd_cb.c
index 4ff2e98..41b9cdb 100644 (file)
  *
  * You should have received a copy of the GNU General Public License
  * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * GPL HEADER END
  */
@@ -27,7 +23,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, 2015, Intel Corporation.
+ * Copyright (c) 2012, 2016, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
 
 #include "o2iblnd.h"
 
+#define MAX_CONN_RACES_BEFORE_ABORT 20
+
 static void kiblnd_peer_alive(kib_peer_t *peer);
 static void kiblnd_peer_connect_failed(kib_peer_t *peer, int active, int error);
-static void kiblnd_check_sends(kib_conn_t *conn);
 static void kiblnd_init_tx_msg(lnet_ni_t *ni, kib_tx_t *tx,
                               int type, int body_nob);
 static int kiblnd_init_rdma(kib_conn_t *conn, kib_tx_t *tx, int type,
@@ -50,8 +47,9 @@ static int kiblnd_init_rdma(kib_conn_t *conn, kib_tx_t *tx, int type,
 static void kiblnd_queue_tx_locked(kib_tx_t *tx, kib_conn_t *conn);
 static void kiblnd_queue_tx(kib_tx_t *tx, kib_conn_t *conn);
 static void kiblnd_unmap_tx(lnet_ni_t *ni, kib_tx_t *tx);
+static void kiblnd_check_sends_locked(kib_conn_t *conn);
 
-static void
+void
 kiblnd_tx_done (lnet_ni_t *ni, kib_tx_t *tx)
 {
        lnet_msg_t *lntmsg[2];
@@ -118,7 +116,7 @@ kiblnd_get_idle_tx(lnet_ni_t *ni, lnet_nid_t target)
        kib_tx_t                *tx;
        kib_tx_poolset_t        *tps;
 
-       tps = net->ibn_tx_ps[lnet_cpt_of_nid(target)];
+       tps = net->ibn_tx_ps[lnet_cpt_of_nid(target, ni)];
        node = kiblnd_pool_alloc_node(&tps->tps_poolset);
         if (node == NULL)
                 return NULL;
@@ -215,9 +213,9 @@ kiblnd_post_rx (kib_rx_t *rx, int credit)
                conn->ibc_outstanding_credits++;
        else
                conn->ibc_reserved_credits++;
+       kiblnd_check_sends_locked(conn);
        spin_unlock(&conn->ibc_lock);
 
-       kiblnd_check_sends(conn);
 out:
        kiblnd_conn_decref(conn);
        return rc;
@@ -261,7 +259,7 @@ kiblnd_handle_completion(kib_conn_t *conn, int txtype, int status, __u64 cookie)
        if (tx == NULL) {
                spin_unlock(&conn->ibc_lock);
 
-                CWARN("Unmatched completion type %x cookie "LPX64" from %s\n",
+               CWARN("Unmatched completion type %x cookie %#llx from %s\n",
                       txtype, cookie, libcfs_nid2str(conn->ibc_peer->ibp_nid));
                 kiblnd_close_conn(conn, -EPROTO);
                 return;
@@ -350,8 +348,8 @@ kiblnd_handle_rx (kib_rx_t *rx)
                     !IBLND_OOB_CAPABLE(conn->ibc_version)) /* v1 only */
                         conn->ibc_outstanding_credits++;
 
+               kiblnd_check_sends_locked(conn);
                spin_unlock(&conn->ibc_lock);
-                kiblnd_check_sends(conn);
         }
 
         switch (msg->ibm_type) {
@@ -688,7 +686,11 @@ kiblnd_setup_rd_iov(lnet_ni_t *ni, kib_tx_t *tx, kib_rdma_desc_t *rd,
                 fragnob = min(fragnob, (int)PAGE_SIZE - page_offset);
 
                 sg_set_page(sg, page, fragnob, page_offset);
-                sg++;
+               sg = sg_next(sg);
+               if (!sg) {
+                       CERROR("lacking enough sg entries to map tx\n");
+                       return -EFAULT;
+               }
 
                 if (offset + fragnob < iov->iov_len) {
                         offset += fragnob;
@@ -730,9 +732,13 @@ kiblnd_setup_rd_kiov (lnet_ni_t *ni, kib_tx_t *tx, kib_rdma_desc_t *rd,
 
                 fragnob = min((int)(kiov->kiov_len - offset), nob);
 
-                sg_set_page(sg, kiov->kiov_page, fragnob,
-                            kiov->kiov_offset + offset);
-                sg++;
+               sg_set_page(sg, kiov->kiov_page, fragnob,
+                           kiov->kiov_offset + offset);
+               sg = sg_next(sg);
+               if (!sg) {
+                       CERROR("lacking enough sg entries to map tx\n");
+                       return -EFAULT;
+               }
 
                 offset = 0;
                 kiov++;
@@ -795,9 +801,9 @@ __must_hold(&conn->ibc_lock)
             (!kiblnd_need_noop(conn) ||     /* redundant NOOP */
              (IBLND_OOB_CAPABLE(ver) && /* posted enough NOOP */
               conn->ibc_noops_posted == IBLND_OOB_MSGS(ver)))) {
-                /* OK to drop when posted enough NOOPs, since
-                 * kiblnd_check_sends will queue NOOP again when
-                 * posted NOOPs complete */
+               /* OK to drop when posted enough NOOPs, since
+                * kiblnd_check_sends_locked will queue NOOP again when
+                * posted NOOPs complete */
                spin_unlock(&conn->ibc_lock);
                kiblnd_tx_done(peer->ibp_ni, tx);
                spin_lock(&conn->ibc_lock);
@@ -848,7 +854,7 @@ __must_hold(&conn->ibc_lock)
                }
 
                LASSERTF(bad->wr_id == kiblnd_ptr2wreqid(tx, IBLND_WID_TX),
-                        "bad wr_id "LPX64", opc %d, flags %d, peer: %s\n",
+                        "bad wr_id %#llx, opc %d, flags %d, peer: %s\n",
                         bad->wr_id, bad->opcode, bad->send_flags,
                         libcfs_nid2str(conn->ibc_peer->ibp_nid));
 
@@ -897,7 +903,7 @@ __must_hold(&conn->ibc_lock)
 }
 
 static void
-kiblnd_check_sends (kib_conn_t *conn)
+kiblnd_check_sends_locked(kib_conn_t *conn)
 {
         int        ver = conn->ibc_version;
         lnet_ni_t *ni = conn->ibc_peer->ibp_ni;
@@ -910,8 +916,6 @@ kiblnd_check_sends (kib_conn_t *conn)
                 return;
         }
 
-       spin_lock(&conn->ibc_lock);
-
        LASSERT(conn->ibc_nsends_posted <=
                kiblnd_concurrent_sends(ver, ni));
         LASSERT (!IBLND_OOB_CAPABLE(ver) ||
@@ -961,8 +965,6 @@ kiblnd_check_sends (kib_conn_t *conn)
                 if (kiblnd_post_tx_locked(conn, tx, credit) != 0)
                         break;
         }
-
-       spin_unlock(&conn->ibc_lock);
 }
 
 static void
@@ -976,7 +978,7 @@ kiblnd_tx_complete (kib_tx_t *tx, int status)
 
         if (failed) {
                 if (conn->ibc_state == IBLND_CONN_ESTABLISHED)
-                        CNETERR("Tx -> %s cookie "LPX64
+                       CNETERR("Tx -> %s cookie %#llx"
                                 " sending %d waiting %d: failed %d\n",
                                 libcfs_nid2str(conn->ibc_peer->ibp_nid),
                                 tx->tx_cookie, tx->tx_sending, tx->tx_waiting,
@@ -1008,16 +1010,11 @@ kiblnd_tx_complete (kib_tx_t *tx, int status)
         if (idle)
                list_del(&tx->tx_list);
 
-        kiblnd_conn_addref(conn);               /* 1 ref for me.... */
-
+       kiblnd_check_sends_locked(conn);
        spin_unlock(&conn->ibc_lock);
 
         if (idle)
                 kiblnd_tx_done(conn->ibc_peer->ibp_ni, tx);
-
-        kiblnd_check_sends(conn);
-
-        kiblnd_conn_decref(conn);               /* ...until here */
 }
 
 static void
@@ -1203,9 +1200,8 @@ kiblnd_queue_tx (kib_tx_t *tx, kib_conn_t *conn)
 {
        spin_lock(&conn->ibc_lock);
        kiblnd_queue_tx_locked(tx, conn);
+       kiblnd_check_sends_locked(conn);
        spin_unlock(&conn->ibc_lock);
-
-       kiblnd_check_sends(conn);
 }
 
 static int kiblnd_resolve_addr(struct rdma_cm_id *cmid,
@@ -1383,7 +1379,7 @@ kiblnd_launch_tx (lnet_ni_t *ni, kib_tx_t *tx, lnet_nid_t nid)
          * connected */
        read_lock_irqsave(g_lock, flags);
 
-        peer = kiblnd_find_peer_locked(nid);
+        peer = kiblnd_find_peer_locked(ni, nid);
        if (peer != NULL && !list_empty(&peer->ibp_conns)) {
                 /* Found a peer with an established connection */
                 conn = kiblnd_get_conn_locked(peer);
@@ -1401,7 +1397,7 @@ kiblnd_launch_tx (lnet_ni_t *ni, kib_tx_t *tx, lnet_nid_t nid)
        /* Re-try with a write lock */
        write_lock(g_lock);
 
-        peer = kiblnd_find_peer_locked(nid);
+        peer = kiblnd_find_peer_locked(ni, nid);
         if (peer != NULL) {
                if (list_empty(&peer->ibp_conns)) {
                         /* found a peer, but it's still connecting... */
@@ -1439,7 +1435,7 @@ kiblnd_launch_tx (lnet_ni_t *ni, kib_tx_t *tx, lnet_nid_t nid)
 
        write_lock_irqsave(g_lock, flags);
 
-        peer2 = kiblnd_find_peer_locked(nid);
+        peer2 = kiblnd_find_peer_locked(ni, nid);
         if (peer2 != NULL) {
                if (list_empty(&peer2->ibp_conns)) {
                         /* found a peer, but it's still connecting... */
@@ -2176,13 +2172,10 @@ kiblnd_connreq_done(kib_conn_t *conn, int status)
                return;
        }
 
-       /* refcount taken by cmid is not reliable after I released the glock
-        * because this connection is visible to other threads now, another
-        * thread can find and close this connection right after I released
-        * the glock, if kiblnd_cm_callback for RDMA_CM_EVENT_DISCONNECTED is
-        * called, it can release the connection refcount taken by cmid.
-        * It means the connection could be destroyed before I finish my
-        * operations on it.
+       /* +1 ref for myself, this connection is visible to other threads
+        * now, refcount of peer:ibp_conns can be released by connection
+        * close from either a different thread, or the calling of
+        * kiblnd_check_sends_locked() below. See bz21911 for details.
         */
        kiblnd_conn_addref(conn);
        write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
@@ -2195,13 +2188,11 @@ kiblnd_connreq_done(kib_conn_t *conn, int status)
 
                kiblnd_queue_tx_locked(tx, conn);
        }
+       kiblnd_check_sends_locked(conn);
        spin_unlock(&conn->ibc_lock);
 
-       kiblnd_check_sends(conn);
-
        /* schedule blocked rxs */
        kiblnd_handle_early_rxs(conn);
-
        kiblnd_conn_decref(conn);
 }
 
@@ -2252,75 +2243,75 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob)
                __u32 ip = ntohl(peer_addr->sin_addr.s_addr);
                CERROR("Peer's port (%pI4h:%hu) is not privileged\n",
                       &ip, ntohs(peer_addr->sin_port));
-                goto failed;
-        }
+               goto failed;
+       }
 
-        if (priv_nob < offsetof(kib_msg_t, ibm_type)) {
-                CERROR("Short connection request\n");
-                goto failed;
-        }
+       if (priv_nob < offsetof(kib_msg_t, ibm_type)) {
+               CERROR("Short connection request\n");
+               goto failed;
+       }
 
-        /* Future protocol version compatibility support!  If the
-         * o2iblnd-specific protocol changes, or when LNET unifies
-         * protocols over all LNDs, the initial connection will
-         * negotiate a protocol version.  I trap this here to avoid
-         * console errors; the reject tells the peer which protocol I
-         * speak. */
-        if (reqmsg->ibm_magic == LNET_PROTO_MAGIC ||
-            reqmsg->ibm_magic == __swab32(LNET_PROTO_MAGIC))
-                goto failed;
-        if (reqmsg->ibm_magic == IBLND_MSG_MAGIC &&
-            reqmsg->ibm_version != IBLND_MSG_VERSION &&
-            reqmsg->ibm_version != IBLND_MSG_VERSION_1)
-                goto failed;
-        if (reqmsg->ibm_magic == __swab32(IBLND_MSG_MAGIC) &&
-            reqmsg->ibm_version != __swab16(IBLND_MSG_VERSION) &&
-            reqmsg->ibm_version != __swab16(IBLND_MSG_VERSION_1))
-                goto failed;
+       /* Future protocol version compatibility support!  If the
+        * o2iblnd-specific protocol changes, or when LNET unifies
+        * protocols over all LNDs, the initial connection will
+        * negotiate a protocol version.  I trap this here to avoid
+        * console errors; the reject tells the peer which protocol I
+        * speak. */
+       if (reqmsg->ibm_magic == LNET_PROTO_MAGIC ||
+           reqmsg->ibm_magic == __swab32(LNET_PROTO_MAGIC))
+               goto failed;
+       if (reqmsg->ibm_magic == IBLND_MSG_MAGIC &&
+           reqmsg->ibm_version != IBLND_MSG_VERSION &&
+           reqmsg->ibm_version != IBLND_MSG_VERSION_1)
+               goto failed;
+       if (reqmsg->ibm_magic == __swab32(IBLND_MSG_MAGIC) &&
+           reqmsg->ibm_version != __swab16(IBLND_MSG_VERSION) &&
+           reqmsg->ibm_version != __swab16(IBLND_MSG_VERSION_1))
+               goto failed;
 
-        rc = kiblnd_unpack_msg(reqmsg, priv_nob);
-        if (rc != 0) {
-                CERROR("Can't parse connection request: %d\n", rc);
-                goto failed;
-        }
+       rc = kiblnd_unpack_msg(reqmsg, priv_nob);
+       if (rc != 0) {
+               CERROR("Can't parse connection request: %d\n", rc);
+               goto failed;
+       }
 
-        nid = reqmsg->ibm_srcnid;
-        ni  = lnet_net2ni(LNET_NIDNET(reqmsg->ibm_dstnid));
+       nid = reqmsg->ibm_srcnid;
+       ni  = lnet_nid2ni_addref(reqmsg->ibm_dstnid);
 
-        if (ni != NULL) {
-                net = (kib_net_t *)ni->ni_data;
-                rej.ibr_incarnation = net->ibn_incarnation;
-        }
+       if (ni != NULL) {
+               net = (kib_net_t *)ni->ni_data;
+               rej.ibr_incarnation = net->ibn_incarnation;
+       }
 
-        if (ni == NULL ||                         /* no matching net */
-            ni->ni_nid != reqmsg->ibm_dstnid ||   /* right NET, wrong NID! */
-            net->ibn_dev != ibdev) {              /* wrong device */
+       if (ni == NULL ||                         /* no matching net */
+           ni->ni_nid != reqmsg->ibm_dstnid ||   /* right NET, wrong NID! */
+           net->ibn_dev != ibdev) {              /* wrong device */
                CERROR("Can't accept conn from %s on %s (%s:%d:%pI4h): "
-                       "bad dst nid %s\n", libcfs_nid2str(nid),
-                       ni == NULL ? "NA" : libcfs_nid2str(ni->ni_nid),
-                       ibdev->ibd_ifname, ibdev->ibd_nnets,
+                      "bad dst nid %s\n", libcfs_nid2str(nid),
+                      ni == NULL ? "NA" : libcfs_nid2str(ni->ni_nid),
+                      ibdev->ibd_ifname, ibdev->ibd_nnets,
                        &ibdev->ibd_ifip,
-                       libcfs_nid2str(reqmsg->ibm_dstnid));
+                      libcfs_nid2str(reqmsg->ibm_dstnid));
 
-                goto failed;
-        }
+               goto failed;
+       }
 
        /* check time stamp as soon as possible */
-        if (reqmsg->ibm_dststamp != 0 &&
-            reqmsg->ibm_dststamp != net->ibn_incarnation) {
-                CWARN("Stale connection request\n");
-                rej.ibr_why = IBLND_REJECT_CONN_STALE;
-                goto failed;
-        }
+       if (reqmsg->ibm_dststamp != 0 &&
+           reqmsg->ibm_dststamp != net->ibn_incarnation) {
+               CWARN("Stale connection request\n");
+               rej.ibr_why = IBLND_REJECT_CONN_STALE;
+               goto failed;
+       }
 
-        /* I can accept peer's version */
-        version = reqmsg->ibm_version;
+       /* I can accept peer's version */
+       version = reqmsg->ibm_version;
 
-        if (reqmsg->ibm_type != IBLND_MSG_CONNREQ) {
-                CERROR("Unexpected connreq msg type: %x from %s\n",
-                       reqmsg->ibm_type, libcfs_nid2str(nid));
-                goto failed;
-        }
+       if (reqmsg->ibm_type != IBLND_MSG_CONNREQ) {
+               CERROR("Unexpected connreq msg type: %x from %s\n",
+                      reqmsg->ibm_type, libcfs_nid2str(nid));
+               goto failed;
+       }
 
        if (reqmsg->ibm_u.connparams.ibcp_queue_depth >
            kiblnd_msg_queue_size(version, ni)) {
@@ -2386,7 +2377,7 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob)
 
        write_lock_irqsave(g_lock, flags);
 
-        peer2 = kiblnd_find_peer_locked(nid);
+        peer2 = kiblnd_find_peer_locked(ni, nid);
         if (peer2 != NULL) {
                 if (peer2->ibp_version == 0) {
                         peer2->ibp_version     = version;
@@ -2404,33 +2395,47 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob)
                        }
                        write_unlock_irqrestore(g_lock, flags);
 
-                       CWARN("Conn stale %s version %x/%x incarnation "LPU64"/"LPU64"\n",
+                       CWARN("Conn stale %s version %x/%x incarnation %llu/%llu\n",
                              libcfs_nid2str(nid), peer2->ibp_version, version,
                              peer2->ibp_incarnation, reqmsg->ibm_srcstamp);
 
-                        kiblnd_peer_decref(peer);
-                        rej.ibr_why = IBLND_REJECT_CONN_STALE;
-                        goto failed;
-                }
+                       kiblnd_peer_decref(peer);
+                       rej.ibr_why = IBLND_REJECT_CONN_STALE;
+                       goto failed;
+               }
 
-                /* tie-break connection race in favour of the higher NID */
-                if (peer2->ibp_connecting != 0 &&
-                    nid < ni->ni_nid) {
+               /* Tie-break connection race in favour of the higher NID.
+                * If we keep running into a race condition multiple times,
+                * we have to assume that the connection attempt with the
+                * higher NID is stuck in a connecting state and will never
+                * recover.  As such, we pass through this if-block and let
+                * the lower NID connection win so we can move forward.
+                */
+               if (peer2->ibp_connecting != 0 &&
+                   nid < ni->ni_nid && peer2->ibp_races <
+                   MAX_CONN_RACES_BEFORE_ABORT) {
+                       peer2->ibp_races++;
                        write_unlock_irqrestore(g_lock, flags);
 
-                        CWARN("Conn race %s\n", libcfs_nid2str(peer2->ibp_nid));
+                       CDEBUG(D_NET, "Conn race %s\n",
+                              libcfs_nid2str(peer2->ibp_nid));
 
-                        kiblnd_peer_decref(peer);
-                        rej.ibr_why = IBLND_REJECT_CONN_RACE;
-                        goto failed;
-                }
+                       kiblnd_peer_decref(peer);
+                       rej.ibr_why = IBLND_REJECT_CONN_RACE;
+                       goto failed;
+               }
+               if (peer2->ibp_races >= MAX_CONN_RACES_BEFORE_ABORT)
+                       CNETERR("Conn race %s: unresolved after %d attempts, letting lower NID win\n",
+                               libcfs_nid2str(peer2->ibp_nid),
+                               MAX_CONN_RACES_BEFORE_ABORT);
                /*
                 * passive connection is allowed even this peer is waiting for
                 * reconnection.
                 */
                peer2->ibp_reconnecting = 0;
-                peer2->ibp_accepting++;
-                kiblnd_peer_addref(peer2);
+               peer2->ibp_races = 0;
+               peer2->ibp_accepting++;
+               kiblnd_peer_addref(peer2);
 
                /* Race with kiblnd_launch_tx (active connect) to create peer
                 * so copy validated parameters since we now know what the
@@ -2514,10 +2519,10 @@ kiblnd_passive_connect(struct rdma_cm_id *cmid, void *priv, int priv_nob)
 
  failed:
        if (ni != NULL) {
-               lnet_ni_decref(ni);
                rej.ibr_cp.ibcp_queue_depth =
                        kiblnd_msg_queue_size(version, ni);
                rej.ibr_cp.ibcp_max_frags   = kiblnd_rdma_frags(version, ni);
+               lnet_ni_decref(ni);
        }
 
        rej.ibr_version = version;
@@ -2570,14 +2575,14 @@ kiblnd_check_reconnect(kib_conn_t *conn, int version,
                 break;
 
        case IBLND_REJECT_RDMA_FRAGS: {
-               struct lnet_ioctl_config_lnd_tunables *tunables;
+               struct lnet_ioctl_config_o2iblnd_tunables *tunables;
 
                if (!cp) {
                        reason = "can't negotiate max frags";
                        goto out;
                }
-               tunables = peer->ibp_ni->ni_lnd_tunables;
-               if (!tunables->lt_tun_u.lt_o2ib.lnd_map_on_demand) {
+               tunables = &peer->ibp_ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib;
+               if (!tunables->lnd_map_on_demand) {
                        reason = "map_on_demand must be enabled";
                        goto out;
                }
@@ -3148,9 +3153,9 @@ kiblnd_check_conns (int idx)
        struct list_head *ctmp;
        unsigned long     flags;
 
-        /* NB. We expect to have a look at all the peers and not find any
-         * RDMAs to time out, so we just use a shared lock while we
-         * take a look... */
+       /* NB. We expect to have a look at all the peers and not find any
+        * RDMAs to time out, so we just use a shared lock while we
+        * take a look... */
        read_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
 
        list_for_each(ptmp, peers) {
@@ -3213,7 +3218,11 @@ kiblnd_check_conns (int idx)
                conn = list_entry(checksends.next,
                                  kib_conn_t, ibc_connd_list);
                list_del(&conn->ibc_connd_list);
-               kiblnd_check_sends(conn);
+
+               spin_lock(&conn->ibc_lock);
+               kiblnd_check_sends_locked(conn);
+               spin_unlock(&conn->ibc_lock);
+
                kiblnd_conn_decref(conn);
        }
 }
@@ -3311,8 +3320,9 @@ kiblnd_connd (void *arg)
                 }
 
                while (reconn < KIB_RECONN_BREAK) {
-                       if (kiblnd_data.kib_reconn_sec != get_seconds()) {
-                               kiblnd_data.kib_reconn_sec = get_seconds();
+                       if (kiblnd_data.kib_reconn_sec !=
+                           ktime_get_real_seconds()) {
+                               kiblnd_data.kib_reconn_sec = ktime_get_real_seconds();
                                list_splice_init(&kiblnd_data.kib_reconn_wait,
                                                 &kiblnd_data.kib_reconn_list);
                        }
@@ -3398,6 +3408,10 @@ kiblnd_qp_event(struct ib_event *event, void *arg)
         case IB_EVENT_COMM_EST:
                 CDEBUG(D_NET, "%s established\n",
                        libcfs_nid2str(conn->ibc_peer->ibp_nid));
+               /* We received a packet but connection isn't established
+                * probably handshake packet was lost, so free to
+                * force make connection established */
+               rdma_notify(conn->ibc_cmid, IB_EVENT_COMM_EST);
                 return;
 
         default:
@@ -3504,10 +3518,10 @@ kiblnd_scheduler(void *arg)
 
        rc = cfs_cpt_bind(lnet_cpt_table(), sched->ibs_cpt);
        if (rc != 0) {
-               CWARN("Failed to bind on CPT %d, please verify whether "
-                     "all CPUs are healthy and reload modules if necessary, "
-                     "otherwise your system might under risk of low "
-                     "performance\n", sched->ibs_cpt);
+               CWARN("Unable to bind on CPU partition %d, please verify "
+                     "whether all CPUs are healthy and reload modules if "
+                     "necessary, otherwise your system might under risk of "
+                     "low performance\n", sched->ibs_cpt);
        }
 
        spin_lock_irqsave(&sched->ibs_lock, flags);