- /* If I get here, I've committed to send, so I complete the tx with
- * failure on any problems */
+ /* If I get here, I've committed to send, so I complete the tx with
+ * failure on any problems
+ */
- LASSERT (tx == NULL || tx->tx_conn == NULL); /* only set when assigned a conn */
- LASSERT (tx == NULL || tx->tx_nwrq > 0); /* work items have been set up */
+ LASSERT(!tx || !tx->tx_conn); /* only set when assigned a conn */
+ LASSERT(!tx || tx->tx_nwrq > 0); /* work items have been set up */
- /* Found a peer_ni with an established connection */
- conn = kiblnd_get_conn_locked(peer_ni);
- kiblnd_conn_addref(conn); /* 1 ref for me... */
+ /* Found a peer_ni with an established connection */
+ conn = kiblnd_get_conn_locked(peer_ni);
+ kiblnd_conn_addref(conn); /* 1 ref for me... */
- if (tx != NULL)
- kiblnd_queue_tx(tx, conn);
- kiblnd_conn_decref(conn); /* ...to here */
- return;
- }
+ if (tx != NULL)
+ kiblnd_queue_tx(tx, conn);
+ kiblnd_conn_decref(conn); /* ...to here */
+ return;
+ }
write_unlock_irqrestore(g_lock, flags);
} else {
conn = kiblnd_get_conn_locked(peer_ni);
write_unlock_irqrestore(g_lock, flags);
} else {
conn = kiblnd_get_conn_locked(peer_ni);
- if (tx != NULL)
- kiblnd_queue_tx(tx, conn);
- kiblnd_conn_decref(conn); /* ...to here */
- }
- return;
- }
+ if (tx != NULL)
+ kiblnd_queue_tx(tx, conn);
+ kiblnd_conn_decref(conn); /* ...to here */
+ }
+ return;
+ }
write_unlock_irqrestore(g_lock, flags);
} else {
conn = kiblnd_get_conn_locked(peer2);
write_unlock_irqrestore(g_lock, flags);
} else {
conn = kiblnd_get_conn_locked(peer2);
- if (tx != NULL)
- kiblnd_queue_tx(tx, conn);
- kiblnd_conn_decref(conn); /* ...to here */
- }
+ if (tx != NULL)
+ kiblnd_queue_tx(tx, conn);
+ kiblnd_conn_decref(conn); /* ...to here */
+ }
- kiblnd_peer_addref(peer_ni);
- list_add_tail(&peer_ni->ibp_list, kiblnd_nid2peerlist(nid));
+ kiblnd_peer_addref(peer_ni);
+ hash_add(kiblnd_data.kib_peers, &peer_ni->ibp_list, nid);
write_unlock_irqrestore(g_lock, flags);
for (i = 0; i < tunables->lnd_conns_per_peer; i++)
kiblnd_connect_peer(peer_ni);
write_unlock_irqrestore(g_lock, flags);
for (i = 0; i < tunables->lnd_conns_per_peer; i++)
kiblnd_connect_peer(peer_ni);
- int version = IBLND_MSG_VERSION;
- unsigned long flags;
- int rc;
- struct sockaddr_in *peer_addr;
- LASSERT (!in_interrupt());
+ int version = IBLND_MSG_VERSION;
+ unsigned long flags;
+ int rc;
+ struct sockaddr_in *peer_addr;
- memset(&rej, 0, sizeof(rej));
- rej.ibr_magic = IBLND_MSG_MAGIC;
- rej.ibr_why = IBLND_REJECT_FATAL;
- rej.ibr_cp.ibcp_max_msg_size = IBLND_MSG_SIZE;
+ memset(&rej, 0, sizeof(rej));
+ rej.ibr_magic = IBLND_MSG_MAGIC;
+ rej.ibr_why = IBLND_REJECT_FATAL;
+ rej.ibr_cp.ibcp_max_msg_size = IBLND_MSG_SIZE;
- peer_addr = (struct sockaddr_in *)&(cmid->route.addr.dst_addr);
- if (*kiblnd_tunables.kib_require_priv_port &&
- ntohs(peer_addr->sin_port) >= PROT_SOCK) {
+ peer_addr = (struct sockaddr_in *)&(cmid->route.addr.dst_addr);
+ if (*kiblnd_tunables.kib_require_priv_port &&
+ ntohs(peer_addr->sin_port) >= PROT_SOCK) {
__u32 ip = ntohl(peer_addr->sin_addr.s_addr);
CERROR("peer_ni's port (%pI4h:%hu) is not privileged\n",
&ip, ntohs(peer_addr->sin_port));
__u32 ip = ntohl(peer_addr->sin_addr.s_addr);
CERROR("peer_ni's port (%pI4h:%hu) is not privileged\n",
&ip, ntohs(peer_addr->sin_port));
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),
+ CERROR("Can't accept conn from %s on %s (%s:%d:%pI4h): bad dst nid %s\n", libcfs_nid2str(nid),
+ ni ? libcfs_nid2str(ni->ni_nid) : "NA",
if (reqmsg->ibm_dststamp != 0 &&
reqmsg->ibm_dststamp != net->ibn_incarnation) {
CWARN("Stale connection request\n");
if (reqmsg->ibm_dststamp != 0 &&
reqmsg->ibm_dststamp != net->ibn_incarnation) {
CWARN("Stale connection request\n");
if (reqmsg->ibm_u.connparams.ibcp_queue_depth >
kiblnd_msg_queue_size(version, ni)) {
if (reqmsg->ibm_u.connparams.ibcp_queue_depth >
kiblnd_msg_queue_size(version, ni)) {
libcfs_nid2str(nid),
reqmsg->ibm_u.connparams.ibcp_queue_depth,
kiblnd_msg_queue_size(version, ni));
libcfs_nid2str(nid),
reqmsg->ibm_u.connparams.ibcp_queue_depth,
kiblnd_msg_queue_size(version, ni));
libcfs_nid2str(nid), version,
reqmsg->ibm_u.connparams.ibcp_max_frags,
IBLND_MAX_RDMA_FRAGS);
libcfs_nid2str(nid), version,
reqmsg->ibm_u.connparams.ibcp_max_frags,
IBLND_MAX_RDMA_FRAGS);
libcfs_nid2str(nid), version,
reqmsg->ibm_u.connparams.ibcp_max_frags,
IBLND_MAX_RDMA_FRAGS);
libcfs_nid2str(nid), version,
reqmsg->ibm_u.connparams.ibcp_max_frags,
IBLND_MAX_RDMA_FRAGS);
- 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",
- libcfs_nid2str(nid),
- reqmsg->ibm_u.connparams.ibcp_max_msg_size,
- IBLND_MSG_SIZE);
- 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",
+ libcfs_nid2str(nid),
+ reqmsg->ibm_u.connparams.ibcp_max_msg_size,
+ IBLND_MSG_SIZE);
+ goto failed;
+ }
/* assume 'nid' is a new peer_ni; create */
rc = kiblnd_create_peer(ni, &peer_ni, nid);
/* assume 'nid' is a new peer_ni; create */
rc = kiblnd_create_peer(ni, &peer_ni, nid);
- peer2 = kiblnd_find_peer_locked(ni, nid);
- if (peer2 != NULL) {
- if (peer2->ibp_version == 0) {
- peer2->ibp_version = version;
- peer2->ibp_incarnation = reqmsg->ibm_srcstamp;
- }
+ peer2 = kiblnd_find_peer_locked(ni, nid);
+ if (peer2 != NULL) {
+ if (peer2->ibp_version == 0) {
+ peer2->ibp_version = version;
+ peer2->ibp_incarnation = reqmsg->ibm_srcstamp;
+ }
- /* not the guy I've talked with */
- if (peer2->ibp_incarnation != reqmsg->ibm_srcstamp ||
- peer2->ibp_version != version) {
+ /* not the guy I've talked with */
+ if (peer2->ibp_incarnation != reqmsg->ibm_srcstamp ||
+ peer2->ibp_version != version) {
kiblnd_close_peer_conns_locked(peer2, -ESTALE);
if (kiblnd_peer_active(peer2)) {
kiblnd_close_peer_conns_locked(peer2, -ESTALE);
if (kiblnd_peer_active(peer2)) {
libcfs_nid2str(nid), peer2->ibp_version, version,
peer2->ibp_incarnation, reqmsg->ibm_srcstamp);
libcfs_nid2str(nid), peer2->ibp_version, version,
peer2->ibp_incarnation, reqmsg->ibm_srcstamp);
/* Tie-break connection race in favour of the higher NID.
* If we keep running into a race condition multiple times,
/* Tie-break connection race in favour of the higher NID.
* If we keep running into a race condition multiple times,
peer2->ibp_queue_depth = peer_ni->ibp_queue_depth;
write_unlock_irqrestore(g_lock, flags);
peer2->ibp_queue_depth = peer_ni->ibp_queue_depth;
write_unlock_irqrestore(g_lock, flags);
- kiblnd_peer_decref(peer_ni);
- peer_ni = peer2;
- } else {
- /* Brand new peer_ni */
- LASSERT (peer_ni->ibp_accepting == 0);
- LASSERT (peer_ni->ibp_version == 0 &&
- peer_ni->ibp_incarnation == 0);
+ kiblnd_peer_decref(peer_ni);
+ peer_ni = peer2;
+ } else {
+ /* Brand new peer_ni */
+ LASSERT(peer_ni->ibp_accepting == 0);
+ LASSERT(peer_ni->ibp_version == 0 &&
+ peer_ni->ibp_incarnation == 0);
- peer_ni->ibp_accepting = 1;
- peer_ni->ibp_version = version;
- peer_ni->ibp_incarnation = reqmsg->ibm_srcstamp;
+ peer_ni->ibp_accepting = 1;
+ peer_ni->ibp_version = version;
+ peer_ni->ibp_incarnation = reqmsg->ibm_srcstamp;
- kiblnd_peer_addref(peer_ni);
- list_add_tail(&peer_ni->ibp_list, kiblnd_nid2peerlist(nid));
+ kiblnd_peer_addref(peer_ni);
+ hash_add(kiblnd_data.kib_peers, &peer_ni->ibp_list, nid);
- conn = kiblnd_create_conn(peer_ni, cmid, IBLND_CONN_PASSIVE_WAIT, version);
- if (conn == NULL) {
- kiblnd_peer_connect_failed(peer_ni, 0, -ENOMEM);
- kiblnd_peer_decref(peer_ni);
- rej.ibr_why = IBLND_REJECT_NO_RESOURCES;
- goto failed;
- }
+ conn = kiblnd_create_conn(peer_ni, cmid, IBLND_CONN_PASSIVE_WAIT,
+ version);
+ if (!conn) {
+ kiblnd_peer_connect_failed(peer_ni, 0, -ENOMEM);
+ kiblnd_peer_decref(peer_ni);
+ rej.ibr_why = IBLND_REJECT_NO_RESOURCES;
+ goto failed;
+ }
- /* conn now "owns" cmid, so I return success from here on to ensure the
- * CM callback doesn't destroy cmid. */
+ /* 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 = conn->ibc_queue_depth;
conn->ibc_reserved_credits = conn->ibc_queue_depth;
LASSERT(conn->ibc_credits + conn->ibc_reserved_credits +
IBLND_OOB_MSGS(version) <= IBLND_RX_MSGS(conn));
conn->ibc_incarnation = reqmsg->ibm_srcstamp;
conn->ibc_credits = conn->ibc_queue_depth;
conn->ibc_reserved_credits = conn->ibc_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));
+ ackmsg = &conn->ibc_connvars->cv_msg;
+ memset(ackmsg, 0, sizeof(*ackmsg));
- kiblnd_init_msg(ackmsg, IBLND_MSG_CONNACK,
- sizeof(ackmsg->ibm_u.connparams));
+ kiblnd_init_msg(ackmsg, IBLND_MSG_CONNACK,
+ sizeof(ackmsg->ibm_u.connparams));
ackmsg->ibm_u.connparams.ibcp_queue_depth = conn->ibc_queue_depth;
ackmsg->ibm_u.connparams.ibcp_max_frags = conn->ibc_max_frags;
ackmsg->ibm_u.connparams.ibcp_max_msg_size = IBLND_MSG_SIZE;
ackmsg->ibm_u.connparams.ibcp_queue_depth = conn->ibc_queue_depth;
ackmsg->ibm_u.connparams.ibcp_max_frags = conn->ibc_max_frags;
ackmsg->ibm_u.connparams.ibcp_max_msg_size = IBLND_MSG_SIZE;
- kiblnd_pack_msg(ni, ackmsg, version, 0, nid, reqmsg->ibm_srcstamp);
+ kiblnd_pack_msg(ni, ackmsg, version, 0, nid, reqmsg->ibm_srcstamp);
- memset(&cp, 0, sizeof(cp));
- cp.private_data = ackmsg;
- cp.private_data_len = ackmsg->ibm_nob;
- cp.responder_resources = 0; /* No atomic ops or RDMA reads */
- cp.initiator_depth = 0;
- cp.flow_control = 1;
- cp.retry_count = *kiblnd_tunables.kib_retry_count;
- cp.rnr_retry_count = *kiblnd_tunables.kib_rnr_retry_count;
+ memset(&cp, 0, sizeof(cp));
+ cp.private_data = ackmsg;
+ cp.private_data_len = ackmsg->ibm_nob;
+ cp.responder_resources = 0; /* No atomic ops or RDMA reads */
+ cp.initiator_depth = 0;
+ cp.flow_control = 1;
+ cp.retry_count = *kiblnd_tunables.kib_retry_count;
+ cp.rnr_retry_count = *kiblnd_tunables.kib_rnr_retry_count;
- rc = rdma_accept(cmid, &cp);
- if (rc != 0) {
- CERROR("Can't accept %s: %d\n", libcfs_nid2str(nid), rc);
- rej.ibr_version = version;
- rej.ibr_why = IBLND_REJECT_FATAL;
+ rc = rdma_accept(cmid, &cp);
+ if (rc != 0) {
+ CERROR("Can't accept %s: %d\n", libcfs_nid2str(nid), rc);
+ rej.ibr_version = version;
+ rej.ibr_why = IBLND_REJECT_FATAL;
- kiblnd_reject(cmid, &rej);
- kiblnd_connreq_done(conn, rc);
- kiblnd_conn_decref(conn);
- }
+ kiblnd_reject(cmid, &rej);
+ kiblnd_connreq_done(conn, rc);
+ kiblnd_conn_decref(conn);
+ }
/* 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
/* 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
- list_for_each(ptmp, peers) {
- peer_ni = list_entry(ptmp, struct kib_peer_ni, ibp_list);
-
+ hlist_for_each_entry(peer_ni, peers, ibp_list) {
/* Check tx_deadline */
list_for_each_entry_safe(tx, tx_tmp, &peer_ni->ibp_tx_queue, tx_list) {
if (ktime_compare(ktime_get(), tx->tx_deadline) >= 0) {
/* Check tx_deadline */
list_for_each_entry_safe(tx, tx_tmp, &peer_ni->ibp_tx_queue, tx_list) {
if (ktime_compare(ktime_get(), tx->tx_deadline) >= 0) {
- CERROR("Timed out RDMA with %s (%lld): "
- "c: %u, oc: %u, rc: %u\n",
+ CERROR("Timed out RDMA with %s (%lld): c: %u, oc: %u, rc: %u\n",
conn->ibc_credits,
conn->ibc_outstanding_credits,
conn->ibc_reserved_credits);
conn->ibc_credits,
conn->ibc_outstanding_credits,
conn->ibc_reserved_credits);
while (!list_empty(&closes)) {
conn = list_entry(closes.next,
struct kib_conn, ibc_connd_list);
while (!list_empty(&closes)) {
conn = list_entry(closes.next,
struct kib_conn, ibc_connd_list);
/* In case we have enough credits to return via a
* NOOP, but there were no non-blocking tx descs
/* In case we have enough credits to return via a
* NOOP, but there were no non-blocking tx descs
while (!list_empty(&checksends)) {
conn = list_entry(checksends.next,
struct kib_conn, ibc_connd_list);
while (!list_empty(&checksends)) {
conn = list_entry(checksends.next,
struct kib_conn, ibc_connd_list);
if (wait)
list_add_tail(&conn->ibc_list,
&kiblnd_data.kib_connd_waits);
if (wait)
list_add_tail(&conn->ibc_list,
&kiblnd_data.kib_connd_waits);
- /* careful with the jiffy wrap... */
- timeout = (int)(deadline - jiffies);
- if (timeout <= 0) {
- const int n = 4;
- const int p = 1;
- int chunk = kiblnd_data.kib_peer_hash_size;
+ /* careful with the jiffy wrap... */
+ timeout = (int)(deadline - jiffies);
+ if (timeout <= 0) {
+ const int n = 4;
+ const int p = 1;
+ int chunk = HASH_SIZE(kiblnd_data.kib_peers);
unsigned int lnd_timeout;
spin_unlock_irqrestore(lock, flags);
unsigned int lnd_timeout;
spin_unlock_irqrestore(lock, flags);
- /* Time to check for RDMA timeouts on a few more
- * peers: I do checks every 'p' seconds on a
- * proportion of the peer_ni table and I need to check
- * every connection 'n' times within a timeout
- * interval, to ensure I detect a timeout on any
- * connection within (n+1)/n times the timeout
- * interval. */
+ /* Time to check for RDMA timeouts on a few more
+ * peers: I do checks every 'p' seconds on a
+ * proportion of the peer_ni table and I need to check
+ * every connection 'n' times within a timeout
+ * interval, to ensure I detect a timeout on any
+ * connection within (n+1)/n times the timeout
+ * interval.
+ */
for (i = 0; i < chunk; i++) {
kiblnd_check_conns(peer_index);
peer_index = (peer_index + 1) %
for (i = 0; i < chunk; i++) {
kiblnd_check_conns(peer_index);
peer_index = (peer_index + 1) %