kiblnd_debug_tx(list_entry(tmp, kib_tx_t, tx_list));
CDEBUG(D_CONSOLE, " rxs:\n");
- for (i = 0; i < IBLND_RX_MSGS(conn->ibc_version); i++)
+ for (i = 0; i < IBLND_RX_MSGS(conn); i++)
kiblnd_debug_rx(&conn->ibc_rxs[i]);
spin_unlock(&conn->ibc_lock);
kib_conn_t *
kiblnd_create_conn(kib_peer_t *peer, struct rdma_cm_id *cmid,
- int state, int version)
+ int state, int version, kib_connparams_t *cp)
{
/* CAVEAT EMPTOR:
* If the new conn is created successfully it takes over the caller's
cmid->context = conn; /* for future CM callbacks */
conn->ibc_cmid = cmid;
+ if (cp == NULL) {
+ conn->ibc_max_frags = IBLND_CFG_RDMA_FRAGS;
+ conn->ibc_queue_depth = *kiblnd_tunables.kib_peertxcredits;
+ } else {
+ conn->ibc_max_frags = cp->ibcp_max_frags;
+ conn->ibc_queue_depth = cp->ibcp_queue_depth;
+ }
+
INIT_LIST_HEAD(&conn->ibc_early_rxs);
INIT_LIST_HEAD(&conn->ibc_tx_noops);
INIT_LIST_HEAD(&conn->ibc_tx_queue);
write_unlock_irqrestore(glock, flags);
LIBCFS_CPT_ALLOC(conn->ibc_rxs, lnet_cpt_table(), cpt,
- IBLND_RX_MSGS(version) * sizeof(kib_rx_t));
+ IBLND_RX_MSGS(conn) * sizeof(kib_rx_t));
if (conn->ibc_rxs == NULL) {
CERROR("Cannot allocate RX buffers\n");
goto failed_2;
}
rc = kiblnd_alloc_pages(&conn->ibc_rx_pages, cpt,
- IBLND_RX_MSG_PAGES(version));
+ IBLND_RX_MSG_PAGES(conn));
if (rc != 0)
goto failed_2;
#else
cq = ib_create_cq(cmid->device,
kiblnd_cq_completion, kiblnd_cq_event, conn,
- IBLND_CQ_ENTRIES(version),
+ IBLND_CQ_ENTRIES(conn),
kiblnd_get_completion_vector(conn, cpt));
#endif
- if (IS_ERR(cq)) {
- CERROR("Can't create CQ: %ld, cqe: %d\n",
- PTR_ERR(cq), IBLND_CQ_ENTRIES(version));
- goto failed_2;
- }
+ if (IS_ERR(cq)) {
+ CERROR("Failed to create CQ with %d CQEs: %ld\n",
+ IBLND_CQ_ENTRIES(conn), PTR_ERR(cq));
+ goto failed_2;
+ }
conn->ibc_cq = cq;
init_qp_attr->event_handler = kiblnd_qp_event;
init_qp_attr->qp_context = conn;
- init_qp_attr->cap.max_send_wr = IBLND_SEND_WRS(version);
- init_qp_attr->cap.max_recv_wr = IBLND_RECV_WRS(version);
+ init_qp_attr->cap.max_send_wr = IBLND_SEND_WRS(conn);
+ init_qp_attr->cap.max_recv_wr = IBLND_RECV_WRS(conn);
init_qp_attr->cap.max_send_sge = 1;
init_qp_attr->cap.max_recv_sge = 1;
init_qp_attr->sq_sig_type = IB_SIGNAL_REQ_WR;
LIBCFS_FREE(init_qp_attr, sizeof(*init_qp_attr));
/* 1 ref for caller and each rxmsg */
- atomic_set(&conn->ibc_refcount, 1 + IBLND_RX_MSGS(version));
- conn->ibc_nrx = IBLND_RX_MSGS(version);
+ atomic_set(&conn->ibc_refcount, 1 + IBLND_RX_MSGS(conn));
+ conn->ibc_nrx = IBLND_RX_MSGS(conn);
/* post receives */
- for (i = 0; i < IBLND_RX_MSGS(version); i++) {
- rc = kiblnd_post_rx(&conn->ibc_rxs[i],
- IBLND_POSTRX_NO_CREDIT);
- if (rc != 0) {
- CERROR("Can't post rxmsg: %d\n", rc);
+ for (i = 0; i < IBLND_RX_MSGS(conn); i++) {
+ rc = kiblnd_post_rx(&conn->ibc_rxs[i],
+ IBLND_POSTRX_NO_CREDIT);
+ if (rc != 0) {
+ CERROR("Can't post rxmsg: %d\n", rc);
- /* Make posted receives complete */
- kiblnd_abort_receives(conn);
+ /* Make posted receives complete */
+ kiblnd_abort_receives(conn);
- /* correct # of posted buffers
- * NB locking needed now I'm racing with completion */
+ /* correct # of posted buffers
+ * NB locking needed now I'm racing with completion */
spin_lock_irqsave(&sched->ibs_lock, flags);
- conn->ibc_nrx -= IBLND_RX_MSGS(version) - i;
+ conn->ibc_nrx -= IBLND_RX_MSGS(conn) - i;
spin_unlock_irqrestore(&sched->ibs_lock, flags);
/* cmid will be destroyed by CM(ofed) after cm_callback
rdma_destroy_qp(conn->ibc_cmid);
conn->ibc_cmid = NULL;
- /* Drop my own and unused rxbuffer refcounts */
- while (i++ <= IBLND_RX_MSGS(version))
- kiblnd_conn_decref(conn);
+ /* Drop my own and unused rxbuffer refcounts */
+ while (i++ <= IBLND_RX_MSGS(conn))
+ kiblnd_conn_decref(conn);
return NULL;
}
if (conn->ibc_rxs != NULL) {
LIBCFS_FREE(conn->ibc_rxs,
- IBLND_RX_MSGS(conn->ibc_version) * sizeof(kib_rx_t));
+ IBLND_RX_MSGS(conn) * sizeof(kib_rx_t));
}
if (conn->ibc_connvars != NULL)
LASSERT (conn->ibc_rxs != NULL);
LASSERT (conn->ibc_hdev != NULL);
- for (i = 0; i < IBLND_RX_MSGS(conn->ibc_version); i++) {
- rx = &conn->ibc_rxs[i];
+ for (i = 0; i < IBLND_RX_MSGS(conn); i++) {
+ rx = &conn->ibc_rxs[i];
- LASSERT (rx->rx_nob >= 0); /* not posted */
+ LASSERT(rx->rx_nob >= 0); /* not posted */
- kiblnd_dma_unmap_single(conn->ibc_hdev->ibh_ibdev,
- KIBLND_UNMAP_ADDR(rx, rx_msgunmap,
- rx->rx_msgaddr),
- IBLND_MSG_SIZE, DMA_FROM_DEVICE);
- }
+ kiblnd_dma_unmap_single(conn->ibc_hdev->ibh_ibdev,
+ KIBLND_UNMAP_ADDR(rx, rx_msgunmap,
+ rx->rx_msgaddr),
+ IBLND_MSG_SIZE, DMA_FROM_DEVICE);
+ }
kiblnd_free_pages(conn->ibc_rx_pages);
int ipg;
int i;
- for (pg_off = ipg = i = 0;
- i < IBLND_RX_MSGS(conn->ibc_version); i++) {
- pg = conn->ibc_rx_pages->ibp_pages[ipg];
- rx = &conn->ibc_rxs[i];
+ for (pg_off = ipg = i = 0; i < IBLND_RX_MSGS(conn); i++) {
+ pg = conn->ibc_rx_pages->ibp_pages[ipg];
+ rx = &conn->ibc_rxs[i];
- rx->rx_conn = conn;
- rx->rx_msg = (kib_msg_t *)(((char *)page_address(pg)) + pg_off);
+ rx->rx_conn = conn;
+ rx->rx_msg = (kib_msg_t *)(((char *)page_address(pg)) + pg_off);
- rx->rx_msgaddr = kiblnd_dma_map_single(conn->ibc_hdev->ibh_ibdev,
- rx->rx_msg, IBLND_MSG_SIZE,
- DMA_FROM_DEVICE);
- LASSERT (!kiblnd_dma_mapping_error(conn->ibc_hdev->ibh_ibdev,
- rx->rx_msgaddr));
- KIBLND_UNMAP_ADDR_SET(rx, rx_msgunmap, rx->rx_msgaddr);
+ rx->rx_msgaddr =
+ kiblnd_dma_map_single(conn->ibc_hdev->ibh_ibdev,
+ rx->rx_msg, IBLND_MSG_SIZE,
+ DMA_FROM_DEVICE);
+ LASSERT(!kiblnd_dma_mapping_error(conn->ibc_hdev->ibh_ibdev,
+ rx->rx_msgaddr));
+ KIBLND_UNMAP_ADDR_SET(rx, rx_msgunmap, rx->rx_msgaddr);
CDEBUG(D_NET, "rx %d: %p "LPX64"("LPX64")\n",
i, rx->rx_msg, rx->rx_msgaddr,
(__u64)(page_to_phys(pg) + pg_off));
- pg_off += IBLND_MSG_SIZE;
- LASSERT (pg_off <= PAGE_SIZE);
+ pg_off += IBLND_MSG_SIZE;
+ LASSERT(pg_off <= PAGE_SIZE);
- if (pg_off == PAGE_SIZE) {
- pg_off = 0;
- ipg++;
- LASSERT (ipg <= IBLND_RX_MSG_PAGES(conn->ibc_version));
- }
- }
+ if (pg_off == PAGE_SIZE) {
+ pg_off = 0;
+ ipg++;
+ LASSERT(ipg <= IBLND_RX_MSG_PAGES(conn));
+ }
+ }
}
static void
}
struct ib_mr *
-kiblnd_find_rd_dma_mr(kib_hca_dev_t *hdev, kib_rdma_desc_t *rd)
+kiblnd_find_rd_dma_mr(kib_hca_dev_t *hdev, kib_rdma_desc_t *rd,
+ int negotiated_nfrags)
{
+ __u16 nfrags = (negotiated_nfrags != -1) ?
+ negotiated_nfrags : *kiblnd_tunables.kib_map_on_demand;
+
LASSERT(hdev->ibh_mrs != NULL);
if (*kiblnd_tunables.kib_map_on_demand > 0 &&
- *kiblnd_tunables.kib_map_on_demand <= rd->rd_nfrags)
+ nfrags <= rd->rd_nfrags)
return NULL;
return hdev->ibh_mrs;
spin_lock(&conn->ibc_lock);
if (conn->ibc_credits + credits >
- IBLND_MSG_QUEUE_SIZE(conn->ibc_version)) {
+ conn->ibc_queue_depth) {
rc2 = conn->ibc_credits;
spin_unlock(&conn->ibc_lock);
- CERROR("Bad credits from %s: %d + %d > %d\n",
- libcfs_nid2str(conn->ibc_peer->ibp_nid),
- rc2, credits,
- IBLND_MSG_QUEUE_SIZE(conn->ibc_version));
+ CERROR("Bad credits from %s: %d + %d > %d\n",
+ libcfs_nid2str(conn->ibc_peer->ibp_nid),
+ rc2, credits,
+ conn->ibc_queue_depth);
- kiblnd_close_conn(conn, -EPROTO);
- kiblnd_post_rx(rx, IBLND_POSTRX_NO_CREDIT);
- return;
- }
+ kiblnd_close_conn(conn, -EPROTO);
+ kiblnd_post_rx(rx, IBLND_POSTRX_NO_CREDIT);
+ return;
+ }
conn->ibc_credits += credits;
nob += rd->rd_frags[i].rf_nob;
}
- /* looking for pre-mapping MR */
- mr = kiblnd_find_rd_dma_mr(hdev, rd);
- if (mr != NULL) {
- /* found pre-mapping MR */
- rd->rd_key = (rd != tx->tx_rd) ? mr->rkey : mr->lkey;
- return 0;
- }
+ mr = kiblnd_find_rd_dma_mr(hdev, rd,
+ (tx->tx_conn != NULL) ?
+ tx->tx_conn->ibc_max_frags : -1);
+ if (mr != NULL) {
+ /* found pre-mapping MR */
+ rd->rd_key = (rd != tx->tx_rd) ? mr->rkey : mr->lkey;
+ return 0;
+ }
if (net->ibn_fmr_ps != NULL)
return kiblnd_fmr_map_tx(net, tx, rd, nob);
int done;
struct ib_send_wr *bad_wrq;
- LASSERT (tx->tx_queued);
- /* We rely on this for QP sizing */
- LASSERT (tx->tx_nwrq > 0);
- LASSERT (tx->tx_nwrq <= 1 + IBLND_RDMA_FRAGS(ver));
+ LASSERT(tx->tx_queued);
+ /* We rely on this for QP sizing */
+ LASSERT(tx->tx_nwrq > 0);
+ LASSERT(tx->tx_nwrq <= 1 + conn->ibc_max_frags);
- LASSERT (credit == 0 || credit == 1);
- LASSERT (conn->ibc_outstanding_credits >= 0);
- LASSERT (conn->ibc_outstanding_credits <= IBLND_MSG_QUEUE_SIZE(ver));
- LASSERT (conn->ibc_credits >= 0);
- LASSERT (conn->ibc_credits <= IBLND_MSG_QUEUE_SIZE(ver));
+ LASSERT(credit == 0 || credit == 1);
+ LASSERT(conn->ibc_outstanding_credits >= 0);
+ LASSERT(conn->ibc_outstanding_credits <= conn->ibc_queue_depth);
+ LASSERT(conn->ibc_credits >= 0);
+ LASSERT(conn->ibc_credits <= conn->ibc_queue_depth);
if (conn->ibc_nsends_posted == IBLND_CONCURRENT_SENDS(ver)) {
/* tx completions outstanding... */
int nob = offsetof (kib_msg_t, ibm_u) + body_nob;
struct ib_mr *mr = hdev->ibh_mrs;
- LASSERT (tx->tx_nwrq >= 0);
- LASSERT (tx->tx_nwrq < IBLND_MAX_RDMA_FRAGS + 1);
- LASSERT (nob <= IBLND_MSG_SIZE);
+ LASSERT(tx->tx_nwrq >= 0);
+ LASSERT(tx->tx_nwrq < IBLND_MAX_RDMA_FRAGS + 1);
+ LASSERT(nob <= IBLND_MSG_SIZE);
LASSERT(mr != NULL);
kiblnd_init_msg(tx->tx_msg, type, body_nob);
break;
}
- if (tx->tx_nwrq == IBLND_RDMA_FRAGS(conn->ibc_version)) {
- CERROR("RDMA too fragmented for %s (%d): "
- "%d/%d src %d/%d dst frags\n",
- libcfs_nid2str(conn->ibc_peer->ibp_nid),
- IBLND_RDMA_FRAGS(conn->ibc_version),
- srcidx, srcrd->rd_nfrags,
- dstidx, dstrd->rd_nfrags);
- rc = -EMSGSIZE;
- break;
- }
+ if (tx->tx_nwrq >= conn->ibc_max_frags) {
+ CERROR("RDMA has too many fragments for peer %s (%d), "
+ "src idx/frags: %d/%d dst idx/frags: %d/%d\n",
+ libcfs_nid2str(conn->ibc_peer->ibp_nid),
+ conn->ibc_max_frags,
+ srcidx, srcrd->rd_nfrags,
+ dstidx, dstrd->rd_nfrags);
+ rc = -EMSGSIZE;
+ break;
+ }
wrknob = MIN(MIN(kiblnd_rd_frag_size(srcrd, srcidx),
kiblnd_rd_frag_size(dstrd, dstidx)), resid);
write_unlock_irqrestore(g_lock, flags);
- /* Allocate a peer ready to add to the peer table and retry */
- rc = kiblnd_create_peer(ni, &peer, nid);
- if (rc != 0) {
- CERROR("Can't create peer %s\n", libcfs_nid2str(nid));
- if (tx != NULL) {
- tx->tx_status = -EHOSTUNREACH;
- tx->tx_waiting = 0;
- kiblnd_tx_done(ni, tx);
- }
- return;
- }
+ /* Allocate a peer ready to add to the peer table and retry */
+ rc = kiblnd_create_peer(ni, &peer, nid);
+ if (rc != 0) {
+ CERROR("Can't create peer %s\n", libcfs_nid2str(nid));
+ if (tx != NULL) {
+ tx->tx_status = -EHOSTUNREACH;
+ tx->tx_waiting = 0;
+ kiblnd_tx_done(ni, tx);
+ }
+ return;
+ }
write_lock_irqsave(g_lock, flags);
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 %s on %s (%s:%d:%pI4h): "
+ 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,
goto failed;
}
- if (reqmsg->ibm_u.connparams.ibcp_queue_depth !=
- IBLND_MSG_QUEUE_SIZE(version)) {
- CERROR("Can't accept %s: incompatible queue depth %d (%d wanted)\n",
- libcfs_nid2str(nid), reqmsg->ibm_u.connparams.ibcp_queue_depth,
- IBLND_MSG_QUEUE_SIZE(version));
-
- if (version == IBLND_MSG_VERSION)
- rej.ibr_why = IBLND_REJECT_MSG_QUEUE_SIZE;
-
- goto failed;
- }
-
- if (reqmsg->ibm_u.connparams.ibcp_max_frags !=
- IBLND_RDMA_FRAGS(version)) {
- CERROR("Can't accept %s(version %x): "
- "incompatible max_frags %d (%d wanted)\n",
- libcfs_nid2str(nid), version,
- reqmsg->ibm_u.connparams.ibcp_max_frags,
- IBLND_RDMA_FRAGS(version));
+ if (reqmsg->ibm_u.connparams.ibcp_queue_depth >
+ IBLND_MSG_QUEUE_SIZE(version)) {
+ CERROR("Can't accept conn from %s, queue depth too large: "
+ " %d (<=%d wanted)\n",
+ libcfs_nid2str(nid),
+ reqmsg->ibm_u.connparams.ibcp_queue_depth,
+ IBLND_MSG_QUEUE_SIZE(version));
- if (version == IBLND_MSG_VERSION)
- rej.ibr_why = IBLND_REJECT_RDMA_FRAGS;
+ if (version == IBLND_MSG_VERSION)
+ rej.ibr_why = IBLND_REJECT_MSG_QUEUE_SIZE;
- goto failed;
+ goto failed;
+ }
- }
+ if (reqmsg->ibm_u.connparams.ibcp_max_frags >
+ IBLND_RDMA_FRAGS(version)) {
+ CWARN("Can't accept conn from %s (version %x): "
+ "max_frags %d too large (%d wanted)\n",
+ libcfs_nid2str(nid), version,
+ reqmsg->ibm_u.connparams.ibcp_max_frags,
+ IBLND_RDMA_FRAGS(version));
+
+ if (version >= IBLND_MSG_VERSION)
+ rej.ibr_why = IBLND_REJECT_RDMA_FRAGS;
+
+ goto failed;
+ } else if (reqmsg->ibm_u.connparams.ibcp_max_frags <
+ IBLND_RDMA_FRAGS(version) && net->ibn_fmr_ps == NULL) {
+ CWARN("Can't accept conn from %s (version %x): "
+ "max_frags %d incompatible without FMR pool "
+ "(%d wanted)\n",
+ libcfs_nid2str(nid), version,
+ reqmsg->ibm_u.connparams.ibcp_max_frags,
+ IBLND_RDMA_FRAGS(version));
+
+ if (version >= IBLND_MSG_VERSION)
+ rej.ibr_why = IBLND_REJECT_RDMA_FRAGS;
+
+ goto failed;
+ }
if (reqmsg->ibm_u.connparams.ibcp_max_msg_size > IBLND_MSG_SIZE) {
CERROR("Can't accept %s: message size %d too big (%d max)\n",
goto failed;
}
- /* assume 'nid' is a new peer; create */
- rc = kiblnd_create_peer(ni, &peer, nid);
- if (rc != 0) {
- CERROR("Can't create peer for %s\n", libcfs_nid2str(nid));
- rej.ibr_why = IBLND_REJECT_NO_RESOURCES;
- goto failed;
- }
+ /* assume 'nid' is a new peer; create */
+ rc = kiblnd_create_peer(ni, &peer, nid);
+ if (rc != 0) {
+ CERROR("Can't create peer for %s\n", libcfs_nid2str(nid));
+ rej.ibr_why = IBLND_REJECT_NO_RESOURCES;
+ goto failed;
+ }
write_lock_irqsave(g_lock, flags);
write_unlock_irqrestore(g_lock, flags);
}
- conn = kiblnd_create_conn(peer, cmid, IBLND_CONN_PASSIVE_WAIT, version);
+ conn = kiblnd_create_conn(peer, cmid, IBLND_CONN_PASSIVE_WAIT, version,
+ &reqmsg->ibm_u.connparams);
if (conn == NULL) {
kiblnd_peer_connect_failed(peer, 0, -ENOMEM);
kiblnd_peer_decref(peer);
/* conn now "owns" cmid, so I return success from here on to ensure the
* CM callback doesn't destroy cmid. */
- conn->ibc_incarnation = reqmsg->ibm_srcstamp;
- conn->ibc_credits = IBLND_MSG_QUEUE_SIZE(version);
- conn->ibc_reserved_credits = IBLND_MSG_QUEUE_SIZE(version);
- LASSERT (conn->ibc_credits + conn->ibc_reserved_credits + IBLND_OOB_MSGS(version)
- <= IBLND_RX_MSGS(version));
+ conn->ibc_incarnation = reqmsg->ibm_srcstamp;
+ conn->ibc_credits = reqmsg->ibm_u.connparams.ibcp_queue_depth;
+ conn->ibc_reserved_credits = reqmsg->ibm_u.connparams.ibcp_queue_depth;
+ LASSERT(conn->ibc_credits + conn->ibc_reserved_credits +
+ IBLND_OOB_MSGS(version) <= IBLND_RX_MSGS(conn));
ackmsg = &conn->ibc_connvars->cv_msg;
memset(ackmsg, 0, sizeof(*ackmsg));
kiblnd_init_msg(ackmsg, IBLND_MSG_CONNACK,
sizeof(ackmsg->ibm_u.connparams));
- ackmsg->ibm_u.connparams.ibcp_queue_depth = IBLND_MSG_QUEUE_SIZE(version);
- ackmsg->ibm_u.connparams.ibcp_max_msg_size = IBLND_MSG_SIZE;
- ackmsg->ibm_u.connparams.ibcp_max_frags = IBLND_RDMA_FRAGS(version);
+ ackmsg->ibm_u.connparams.ibcp_queue_depth =
+ reqmsg->ibm_u.connparams.ibcp_queue_depth;
+ ackmsg->ibm_u.connparams.ibcp_max_frags =
+ reqmsg->ibm_u.connparams.ibcp_max_frags;
+ ackmsg->ibm_u.connparams.ibcp_max_msg_size = IBLND_MSG_SIZE;
kiblnd_pack_msg(ni, ackmsg, version, 0, nid, reqmsg->ibm_srcstamp);
} else {
retry_now = 1;
}
- peer->ibp_connecting++;
-
- peer->ibp_version = version;
- peer->ibp_incarnation = incarnation;
+ peer->ibp_connecting++;
+ peer->ibp_version = version;
+ peer->ibp_incarnation = incarnation;
}
write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
reason = "Unknown";
break;
+ case IBLND_REJECT_RDMA_FRAGS:
+ if (conn->ibc_max_frags <= cp->ibcp_max_frags) {
+ CNETERR("Unsupported max frags, peer supports %d\n",
+ cp->ibcp_max_frags);
+ goto failed;
+ } else if (*kiblnd_tunables.kib_map_on_demand == 0) {
+ CNETERR("map_on_demand must be enabled to support "
+ "map_on_demand peers\n");
+ goto failed;
+ }
+
+ conn->ibc_max_frags = cp->ibcp_max_frags;
+ reason = "rdma fragments";
+ break;
+
+ case IBLND_REJECT_MSG_QUEUE_SIZE:
+ if (conn->ibc_queue_depth <= cp->ibcp_queue_depth) {
+ CNETERR("Unsupported queue depth, peer supports %d\n",
+ cp->ibcp_queue_depth);
+ goto failed;
+ }
+
+ conn->ibc_queue_depth = cp->ibcp_queue_depth;
+ reason = "queue depth";
+ break;
+
case IBLND_REJECT_CONN_STALE:
reason = "stale";
break;
break;
}
- CNETERR("%s: retrying (%s), %x, %x, "
- "queue_dep: %d, max_frag: %d, msg_size: %d\n",
- libcfs_nid2str(peer->ibp_nid),
- reason, IBLND_MSG_VERSION, version,
- cp != NULL? cp->ibcp_queue_depth :IBLND_MSG_QUEUE_SIZE(version),
- cp != NULL? cp->ibcp_max_frags : IBLND_RDMA_FRAGS(version),
- cp != NULL? cp->ibcp_max_msg_size: IBLND_MSG_SIZE);
+ CNETERR("%s: retrying (%s), %x, %x, "
+ "queue_depth: %d, max_frags: %d, msg_size: %d\n",
+ libcfs_nid2str(peer->ibp_nid),
+ reason, IBLND_MSG_VERSION, version,
+ conn->ibc_queue_depth, conn->ibc_max_frags,
+ cp != NULL ? cp->ibcp_max_msg_size : IBLND_MSG_SIZE);
kiblnd_connect_peer(peer);
+ return;
+
+ failed:
+ write_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+ peer->ibp_connecting--;
+ write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+
+ return;
}
static void
case IBLND_REJECT_CONN_RACE:
case IBLND_REJECT_CONN_STALE:
case IBLND_REJECT_CONN_UNCOMPAT:
+ case IBLND_REJECT_MSG_QUEUE_SIZE:
+ case IBLND_REJECT_RDMA_FRAGS:
kiblnd_reconnect(conn, rej->ibr_version,
incarnation, rej->ibr_why, cp);
break;
- case IBLND_REJECT_MSG_QUEUE_SIZE:
- CERROR("%s rejected: incompatible message queue depth %d, %d\n",
- libcfs_nid2str(peer->ibp_nid),
- cp != NULL ? cp->ibcp_queue_depth :
- IBLND_MSG_QUEUE_SIZE(rej->ibr_version),
- IBLND_MSG_QUEUE_SIZE(conn->ibc_version));
- break;
-
- case IBLND_REJECT_RDMA_FRAGS:
- CERROR("%s rejected: incompatible # of RDMA fragments %d, %d\n",
- libcfs_nid2str(peer->ibp_nid),
- cp != NULL ? cp->ibcp_max_frags :
- IBLND_RDMA_FRAGS(rej->ibr_version),
- IBLND_RDMA_FRAGS(conn->ibc_version));
- break;
-
case IBLND_REJECT_NO_RESOURCES:
CERROR("%s rejected: o2iblnd no resources\n",
libcfs_nid2str(peer->ibp_nid));
goto failed;
}
- if (msg->ibm_u.connparams.ibcp_queue_depth !=
- IBLND_MSG_QUEUE_SIZE(ver)) {
- CERROR("%s has incompatible queue depth %d(%d wanted)\n",
- libcfs_nid2str(peer->ibp_nid),
- msg->ibm_u.connparams.ibcp_queue_depth,
- IBLND_MSG_QUEUE_SIZE(ver));
- rc = -EPROTO;
- goto failed;
- }
+ if (msg->ibm_u.connparams.ibcp_queue_depth >
+ conn->ibc_queue_depth) {
+ CERROR("%s has incompatible queue depth %d (<=%d wanted)\n",
+ libcfs_nid2str(peer->ibp_nid),
+ msg->ibm_u.connparams.ibcp_queue_depth,
+ conn->ibc_queue_depth);
+ rc = -EPROTO;
+ goto failed;
+ }
- if (msg->ibm_u.connparams.ibcp_max_frags !=
- IBLND_RDMA_FRAGS(ver)) {
- CERROR("%s has incompatible max_frags %d (%d wanted)\n",
- libcfs_nid2str(peer->ibp_nid),
- msg->ibm_u.connparams.ibcp_max_frags,
- IBLND_RDMA_FRAGS(ver));
- rc = -EPROTO;
- goto failed;
- }
+ if (msg->ibm_u.connparams.ibcp_max_frags >
+ conn->ibc_max_frags) {
+ CERROR("%s has incompatible max_frags %d (<=%d wanted)\n",
+ libcfs_nid2str(peer->ibp_nid),
+ msg->ibm_u.connparams.ibcp_max_frags,
+ conn->ibc_max_frags);
+ rc = -EPROTO;
+ goto failed;
+ }
if (msg->ibm_u.connparams.ibcp_max_msg_size > IBLND_MSG_SIZE) {
CERROR("%s max message size %d too big (%d max)\n",
goto failed;
}
- conn->ibc_incarnation = msg->ibm_srcstamp;
- conn->ibc_credits =
- conn->ibc_reserved_credits = IBLND_MSG_QUEUE_SIZE(ver);
- LASSERT (conn->ibc_credits + conn->ibc_reserved_credits + IBLND_OOB_MSGS(ver)
- <= IBLND_RX_MSGS(ver));
+ conn->ibc_incarnation = msg->ibm_srcstamp;
+ conn->ibc_credits = msg->ibm_u.connparams.ibcp_queue_depth;
+ conn->ibc_reserved_credits = msg->ibm_u.connparams.ibcp_queue_depth;
+ conn->ibc_queue_depth = msg->ibm_u.connparams.ibcp_queue_depth;
+ conn->ibc_max_frags = msg->ibm_u.connparams.ibcp_max_frags;
+ LASSERT(conn->ibc_credits + conn->ibc_reserved_credits +
+ IBLND_OOB_MSGS(ver) <= IBLND_RX_MSGS(conn));
kiblnd_connreq_done(conn, 0);
return;
read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
- conn = kiblnd_create_conn(peer, cmid, IBLND_CONN_ACTIVE_CONNECT, version);
+ conn = kiblnd_create_conn(peer, cmid, IBLND_CONN_ACTIVE_CONNECT,
+ version, NULL);
if (conn == NULL) {
kiblnd_peer_connect_failed(peer, 1, -ENOMEM);
kiblnd_peer_decref(peer); /* lose cmid's ref */
msg = &conn->ibc_connvars->cv_msg;
- memset(msg, 0, sizeof(*msg));
- kiblnd_init_msg(msg, IBLND_MSG_CONNREQ, sizeof(msg->ibm_u.connparams));
- msg->ibm_u.connparams.ibcp_queue_depth = IBLND_MSG_QUEUE_SIZE(version);
- msg->ibm_u.connparams.ibcp_max_frags = IBLND_RDMA_FRAGS(version);
- msg->ibm_u.connparams.ibcp_max_msg_size = IBLND_MSG_SIZE;
+ memset(msg, 0, sizeof(*msg));
+ kiblnd_init_msg(msg, IBLND_MSG_CONNREQ, sizeof(msg->ibm_u.connparams));
+ msg->ibm_u.connparams.ibcp_queue_depth = conn->ibc_queue_depth;
+ msg->ibm_u.connparams.ibcp_max_frags = conn->ibc_max_frags;
+ msg->ibm_u.connparams.ibcp_max_msg_size = IBLND_MSG_SIZE;
kiblnd_pack_msg(peer->ibp_ni, msg, version,
0, peer->ibp_nid, incarnation);