- }
-
- LASSERT (tx->tx_queued);
- /* We rely on this for QP sizing */
- LASSERT (tx->tx_nwrq > 0 &&
- tx->tx_nwrq <= 1 + IBLND_MAX_RDMA_FRAGS);
-
- LASSERT (conn->ibc_outstanding_credits >= 0);
- LASSERT (conn->ibc_outstanding_credits <= IBLND_MSG_QUEUE_SIZE);
- LASSERT (conn->ibc_credits >= 0);
- LASSERT (conn->ibc_credits <= IBLND_MSG_QUEUE_SIZE);
-
- if (conn->ibc_nsends_posted ==
- *kiblnd_tunables.kib_concurrent_sends) {
- /* tx completions outstanding... */
- CDEBUG(D_NET, "%s: posted enough\n",
- libcfs_nid2str(conn->ibc_peer->ibp_nid));
- break;
- }
-
- if (consume_cred) {
- if (conn->ibc_credits == 0) { /* no credits */
- CDEBUG(D_NET, "%s: no credits\n",
- libcfs_nid2str(conn->ibc_peer->ibp_nid));
- break;
- }
-
- if (conn->ibc_credits == 1 && /* last credit reserved for */
- conn->ibc_outstanding_credits == 0) { /* giving back credits */
- CDEBUG(D_NET, "%s: not using last credit\n",
- libcfs_nid2str(conn->ibc_peer->ibp_nid));
- break;
- }
- }
-
- list_del (&tx->tx_list);
- tx->tx_queued = 0;
-
- /* NB don't drop ibc_lock before bumping tx_sending */
-
- if (tx->tx_msg->ibm_type == IBLND_MSG_NOOP &&
- (!list_empty(&conn->ibc_tx_queue) ||
- !list_empty(&conn->ibc_tx_queue_nocred) ||
- (conn->ibc_outstanding_credits < IBLND_CREDIT_HIGHWATER &&
- !kiblnd_send_keepalive(conn)))) {
- /* redundant NOOP */
- spin_unlock(&conn->ibc_lock);
- kiblnd_tx_done(ni, tx);
- spin_lock(&conn->ibc_lock);
- CDEBUG(D_NET, "%s: redundant noop\n",
- libcfs_nid2str(conn->ibc_peer->ibp_nid));
- continue;
- }
-
- kiblnd_pack_msg(ni, tx->tx_msg, conn->ibc_outstanding_credits,
- conn->ibc_peer->ibp_nid, conn->ibc_incarnation);
-
- conn->ibc_outstanding_credits = 0;
- conn->ibc_nsends_posted++;
- if (consume_cred)
- conn->ibc_credits--;
-
- /* CAVEAT EMPTOR! This tx could be the PUT_DONE of an RDMA
- * PUT. If so, it was first queued here as a PUT_REQ, sent and
- * stashed on ibc_active_txs, matched by an incoming PUT_ACK,
- * and then re-queued here. It's (just) possible that
- * tx_sending is non-zero if we've not done the tx_complete() from
- * the first send; hence the ++ rather than = below. */
- tx->tx_sending++;
-
- list_add (&tx->tx_list, &conn->ibc_active_txs);
-#if 0
- {
- int i;
-
- for (i = 0; i < tx->tx_nwrq - 1; i++) {
- LASSERT (tx->tx_wrq[i].opcode == IB_WR_RDMA_WRITE);
- LASSERT (tx->tx_wrq[i].next == &tx->tx_wrq[i+1]);
- LASSERT (tx->tx_wrq[i].sg_list == &tx->tx_sge[i]);
-
- CDEBUG(D_WARNING, "WORK[%d]: RDMA "LPX64
- " for %d k %x -> "LPX64" k %x\n", i,
- tx->tx_wrq[i].sg_list->addr,
- tx->tx_wrq[i].sg_list->length,
- tx->tx_wrq[i].sg_list->lkey,
- tx->tx_wrq[i].wr.rdma.remote_addr,
- tx->tx_wrq[i].wr.rdma.rkey);
- }
-
- LASSERT (tx->tx_wrq[i].opcode == IB_WR_SEND);
- LASSERT (tx->tx_wrq[i].next == NULL);
- LASSERT (tx->tx_wrq[i].sg_list == &tx->tx_sge[i]);
-
- CDEBUG(D_WARNING, "WORK[%d]: SEND "LPX64" for %d k %x\n", i,
- tx->tx_wrq[i].sg_list->addr,
- tx->tx_wrq[i].sg_list->length,
- tx->tx_wrq[i].sg_list->lkey);
- }
-#endif
- /* I'm still holding ibc_lock! */
- if (conn->ibc_state != IBLND_CONN_ESTABLISHED)
- rc = -ECONNABORTED;
- else
- rc = ib_post_send(conn->ibc_cmid->qp, tx->tx_wrq, &bad_wrq);
-
- conn->ibc_last_send = jiffies;
-
- if (rc != 0) {
- /* NB credits are transferred in the actual
- * message, which can only be the last work item */
- conn->ibc_outstanding_credits += tx->tx_msg->ibm_credits;
- if (consume_cred)
- conn->ibc_credits++;
- conn->ibc_nsends_posted--;
-
- tx->tx_status = rc;
- tx->tx_waiting = 0;
- tx->tx_sending--;
-
- done = (tx->tx_sending == 0);
- if (done)
- list_del (&tx->tx_list);
-
- spin_unlock(&conn->ibc_lock);