kiblnd_queue_tx_locked(tx, conn);
        }
 
-       kiblnd_conn_addref(conn); /* 1 ref for me.... (see b21911) */
-
        for (;;) {
                int credit;
 
        }
 
        spin_unlock(&conn->ibc_lock);
-
-       kiblnd_conn_decref(conn); /* ...until here */
 }
 
 static void
                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.
+        */
+       kiblnd_conn_addref(conn);
        write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
 
        /* Schedule blocked txs */
 
        /* schedule blocked rxs */
        kiblnd_handle_early_rxs(conn);
+
+       kiblnd_conn_decref(conn);
 }
 
 static void