}
}
+/**
+ * iowait_packet_queued() - determine if a packet is already built
+ * @wait: the wait structure
+ */
+static inline bool iowait_packet_queued(struct iowait *wait)
+{
+ return !list_empty(&wait->tx_head);
+}
+
#endif
if (qp->s_ack_queue)
e = &qp->s_ack_queue[qp->s_tail_ack_queue];
seq_printf(s,
- "N %d %s QP %x R %u %s %u %u %u f=%x %u %u %u %u %u %u SPSN %x %x %x %x %x RPSN %x S(%u %u %u %u %u %u %u) R(%u %u %u) RQP %x LID %x SL %u MTU %u %u %u %u %u SDE %p,%u SC %p,%u SCQ %u %u PID %d OS %x %x E %x %x %x RNR %d %s %d\n",
+ "N %d %s QP %x R %u %s %u %u f=%x %u %u %u %u %u %u SPSN %x %x %x %x %x RPSN %x S(%u %u %u %u %u %u %u) R(%u %u %u) RQP %x LID %x SL %u MTU %u %u %u %u %u SDE %p,%u SC %p,%u SCQ %u %u PID %d OS %x %x E %x %x %x RNR %d %s %d\n",
iter->n,
qp_idle(qp) ? "I" : "B",
qp->ibqp.qp_num,
qp_type_str[qp->ibqp.qp_type],
qp->state,
wqe ? wqe->wr.opcode : 0,
- qp->s_hdrwords,
qp->s_flags,
iowait_sdma_pending(&priv->s_iowait),
iowait_pio_pending(&priv->s_iowait),
}
if (!(qp->s_flags & RVT_S_BUSY)) {
- qp->s_hdrwords = 0;
if (qp->s_rdma_mr) {
rvt_put_mr(qp->s_rdma_mr);
qp->s_rdma_mr = NULL;
#include <rdma/rdmavt_qp.h>
#include "verbs.h"
#include "sdma.h"
+#include "verbs_txreq.h"
extern unsigned int hfi1_qp_table_size;
extern const struct rvt_operation_params hfi1_post_parms[];
/*
+ * Send if not busy or waiting for I/O and either
+ * a RC response is pending or we can process send work requests.
+ */
+static inline int hfi1_send_ok(struct rvt_qp *qp)
+{
+ return !(qp->s_flags & (RVT_S_BUSY | RVT_S_ANY_WAIT_IO)) &&
+ (verbs_txreq_queued(qp) ||
+ (qp->s_flags & RVT_S_RESP_PENDING) ||
+ !(qp->s_flags & RVT_S_ANY_WAIT_SEND));
+}
+
+/*
* free_ahg - clear ahg from QP
*/
static inline void clear_ahg(struct rvt_qp *qp)
bth2 = mask_psn(qp->s_ack_psn);
}
qp->s_rdma_ack_cnt++;
- qp->s_hdrwords = hwords;
ps->s_txreq->sde = priv->s_sde;
ps->s_txreq->s_cur_size = len;
+ ps->s_txreq->hdr_dwords = hwords;
hfi1_make_ruc_header(qp, ohdr, bth0, bth2, middle, ps);
- /* pbc */
- ps->s_txreq->hdr_dwords = qp->s_hdrwords + 2;
return 1;
bail:
: IB_WC_SUCCESS);
if (local_ops)
atomic_dec(&qp->local_ops_pending);
- qp->s_hdrwords = 0;
goto done_free_tx;
}
bth2 |= IB_BTH_REQ_ACK;
}
qp->s_len -= len;
- qp->s_hdrwords = hwords;
+ ps->s_txreq->hdr_dwords = hwords;
ps->s_txreq->sde = priv->s_sde;
ps->s_txreq->ss = ss;
ps->s_txreq->s_cur_size = len;
bth2,
middle,
ps);
- /* pbc */
- ps->s_txreq->hdr_dwords = qp->s_hdrwords + 2;
return 1;
done_free_tx:
bail_no_tx:
ps->s_txreq = NULL;
qp->s_flags &= ~RVT_S_BUSY;
- qp->s_hdrwords = 0;
return 0;
}
u32 slid;
u16 pkey = hfi1_get_pkey(ibp, qp->s_pkey_index);
u8 l4 = OPA_16B_L4_IB_LOCAL;
- u8 extra_bytes = hfi1_get_16b_padding((qp->s_hdrwords << 2),
- ps->s_txreq->s_cur_size);
+ u8 extra_bytes = hfi1_get_16b_padding(
+ (ps->s_txreq->hdr_dwords << 2),
+ ps->s_txreq->s_cur_size);
u32 nwords = SIZE_OF_CRC + ((ps->s_txreq->s_cur_size +
extra_bytes + SIZE_OF_LT) >> 2);
u8 becn = 0;
grd->sgid_index = 0;
grh = &ps->s_txreq->phdr.hdr.opah.u.l.grh;
l4 = OPA_16B_L4_IB_GLOBAL;
- hdrwords = qp->s_hdrwords - 4;
- qp->s_hdrwords += hfi1_make_grh(ibp, grh, grd,
- hdrwords, nwords);
+ hdrwords = ps->s_txreq->hdr_dwords - 4;
+ ps->s_txreq->hdr_dwords += hfi1_make_grh(ibp, grh, grd,
+ hdrwords, nwords);
middle = 0;
}
slid,
opa_get_lid(rdma_ah_get_dlid(&qp->remote_ah_attr),
16B),
- (qp->s_hdrwords + nwords) >> 1,
+ (ps->s_txreq->hdr_dwords + nwords) >> 1,
pkey, becn, 0, l4, priv->s_sc);
}
if (unlikely(rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH)) {
struct ib_grh *grh = &ps->s_txreq->phdr.hdr.ibh.u.l.grh;
- int hdrwords = qp->s_hdrwords - 2;
+ int hdrwords = ps->s_txreq->hdr_dwords - 2;
lrh0 = HFI1_LRH_GRH;
- qp->s_hdrwords +=
+ ps->s_txreq->hdr_dwords +=
hfi1_make_grh(ibp, grh,
rdma_ah_read_grh(&qp->remote_ah_attr),
hdrwords, nwords);
hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2);
hfi1_make_ib_hdr(&ps->s_txreq->phdr.hdr.ibh,
lrh0,
- qp->s_hdrwords + nwords,
+ ps->s_txreq->hdr_dwords + nwords,
opa_get_lid(rdma_ah_get_dlid(&qp->remote_ah_attr), 9B),
ppd_from_ibp(ibp)->lid |
rdma_ah_get_path_bits(&qp->remote_ah_attr));
ps.s_txreq = get_waiting_verbs_txreq(qp);
do {
/* Check for a constructed packet to be sent. */
- if (qp->s_hdrwords != 0) {
+ if (ps.s_txreq) {
spin_unlock_irqrestore(&qp->s_lock, ps.flags);
/*
* If the packet cannot be sent now, return and
*/
if (hfi1_verbs_send(qp, &ps))
return;
- /* Record that s_ahg is empty. */
- qp->s_hdrwords = 0;
/* allow other tasks to run */
if (schedule_send_yield(qp, &ps))
return;
: IB_WC_SUCCESS);
if (local_ops)
atomic_dec(&qp->local_ops_pending);
- qp->s_hdrwords = 0;
goto done_free_tx;
}
/*
break;
}
qp->s_len -= len;
- qp->s_hdrwords = hwords;
+ ps->s_txreq->hdr_dwords = hwords;
ps->s_txreq->sde = priv->s_sde;
ps->s_txreq->ss = &qp->s_sge;
ps->s_txreq->s_cur_size = len;
hfi1_make_ruc_header(qp, ohdr, bth0 | (qp->s_state << 24),
mask_psn(qp->s_psn++), middle, ps);
- /* pbc */
- ps->s_txreq->hdr_dwords = qp->s_hdrwords + 2;
return 1;
done_free_tx:
bail_no_tx:
ps->s_txreq = NULL;
qp->s_flags &= ~RVT_S_BUSY;
- qp->s_hdrwords = 0;
return 0;
}
extra_bytes = -wqe->length & 3;
nwords = ((wqe->length + extra_bytes) >> 2) + SIZE_OF_CRC;
/* header size in dwords LRH+BTH+DETH = (8+12+8)/4. */
- qp->s_hdrwords = 7;
+ ps->s_txreq->hdr_dwords = 7;
if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM)
- qp->s_hdrwords++;
+ ps->s_txreq->hdr_dwords++;
if (rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH) {
grh = &ps->s_txreq->phdr.hdr.ibh.u.l.grh;
- qp->s_hdrwords += hfi1_make_grh(ibp, grh,
- rdma_ah_read_grh(ah_attr),
- qp->s_hdrwords - 2, nwords);
+ ps->s_txreq->hdr_dwords +=
+ hfi1_make_grh(ibp, grh, rdma_ah_read_grh(ah_attr),
+ ps->s_txreq->hdr_dwords - 2, nwords);
lrh0 = HFI1_LRH_GRH;
ohdr = &ps->s_txreq->phdr.hdr.ibh.u.l.oth;
} else {
}
}
hfi1_make_bth_deth(qp, wqe, ohdr, &pkey, extra_bytes, false);
- len = qp->s_hdrwords + nwords;
+ len = ps->s_txreq->hdr_dwords + nwords;
/* Setup the packet */
ps->s_txreq->phdr.hdr.hdr_type = HFI1_PKT_TYPE_9B;
ppd = ppd_from_ibp(ibp);
ah_attr = &ibah_to_rvtah(wqe->ud_wr.ah)->attr;
/* header size in dwords 16B LRH+BTH+DETH = (16+12+8)/4. */
- qp->s_hdrwords = 9;
+ ps->s_txreq->hdr_dwords = 9;
if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM)
- qp->s_hdrwords++;
+ ps->s_txreq->hdr_dwords++;
/* SW provides space for CRC and LT for bypass packets. */
- extra_bytes = hfi1_get_16b_padding((qp->s_hdrwords << 2),
+ extra_bytes = hfi1_get_16b_padding((ps->s_txreq->hdr_dwords << 2),
wqe->length);
nwords = ((wqe->length + extra_bytes + SIZE_OF_LT) >> 2) + SIZE_OF_CRC;
grd->sgid_index = 0;
}
grh = &ps->s_txreq->phdr.hdr.opah.u.l.grh;
- qp->s_hdrwords += hfi1_make_grh(ibp, grh, grd,
- qp->s_hdrwords - 4, nwords);
+ ps->s_txreq->hdr_dwords += hfi1_make_grh(ibp, grh, grd,
+ ps->s_txreq->hdr_dwords - 4, nwords);
ohdr = &ps->s_txreq->phdr.hdr.opah.u.l.oth;
l4 = OPA_16B_L4_IB_GLOBAL;
} else {
hfi1_make_bth_deth(qp, wqe, ohdr, &pkey, extra_bytes, true);
/* Convert dwords to flits */
- len = (qp->s_hdrwords + nwords) >> 1;
+ len = (ps->s_txreq->hdr_dwords + nwords) >> 1;
/* Setup the packet */
ps->s_txreq->phdr.hdr.hdr_type = HFI1_PKT_TYPE_16B;
priv->s_ahg->ahgcount = 0;
priv->s_ahg->ahgidx = 0;
priv->s_ahg->tx_flags = 0;
- /* pbc */
- ps->s_txreq->hdr_dwords = qp->s_hdrwords + 2;
return 1;
bail_no_tx:
ps->s_txreq = NULL;
qp->s_flags &= ~RVT_S_BUSY;
- qp->s_hdrwords = 0;
return 0;
}
{
int ret = 0;
struct hfi1_sdma_header *phdr = &tx->phdr;
- u16 hdrbytes = tx->hdr_dwords << 2;
+ u16 hdrbytes = (tx->hdr_dwords + sizeof(pbc) / 4) << 2;
u8 extra_bytes = 0;
if (tx->phdr.hdr.hdr_type) {
{
struct hfi1_qp_priv *priv = qp->priv;
struct hfi1_ahg_info *ahg_info = priv->s_ahg;
- u32 hdrwords = qp->s_hdrwords;
+ u32 hdrwords = ps->s_txreq->hdr_dwords;
u32 len = ps->s_txreq->s_cur_size;
u32 plen;
struct hfi1_ibdev *dev = ps->dev;
} else {
dwords = (len + 3) >> 2;
}
- plen = hdrwords + dwords + 2;
+ plen = hdrwords + dwords + sizeof(pbc) / 4;
tx = ps->s_txreq;
if (!sdma_txreq_built(&tx->txreq)) {
u64 pbc)
{
struct hfi1_qp_priv *priv = qp->priv;
- u32 hdrwords = qp->s_hdrwords;
+ u32 hdrwords = ps->s_txreq->hdr_dwords;
struct rvt_sge_state *ss = ps->s_txreq->ss;
u32 len = ps->s_txreq->s_cur_size;
u32 dwords;
dwords = (len + 3) >> 2;
hdr = (u32 *)&ps->s_txreq->phdr.hdr.ibh;
}
- plen = hdrwords + dwords + 2;
+ plen = hdrwords + dwords + sizeof(pbc) / 4;
/* only RC/UC use complete */
switch (qp->ibqp.qp_type) {
}
/*
- * Send if not busy or waiting for I/O and either
- * a RC response is pending or we can process send work requests.
- */
-static inline int hfi1_send_ok(struct rvt_qp *qp)
-{
- return !(qp->s_flags & (RVT_S_BUSY | RVT_S_ANY_WAIT_IO)) &&
- (qp->s_hdrwords || (qp->s_flags & RVT_S_RESP_PENDING) ||
- !(qp->s_flags & RVT_S_ANY_WAIT_SEND));
-}
-
-/*
* This must be called with s_lock held.
*/
void hfi1_bad_pkey(struct hfi1_ibport *ibp, u32 key, u32 sl,
return NULL;
}
+static inline bool verbs_txreq_queued(struct rvt_qp *qp)
+{
+ struct hfi1_qp_priv *priv = qp->priv;
+
+ return iowait_packet_queued(&priv->s_iowait);
+}
+
void hfi1_put_txreq(struct verbs_txreq *tx);
int verbs_txreq_init(struct hfi1_ibdev *dev);
void verbs_txreq_exit(struct hfi1_ibdev *dev);