IB/hfi1: Add a function to build TID RDMA WRITE response

This patch adds the function to build TID RDMA WRITE response. The
main role of the TID RDMA WRITE RESP packet is to send TID entries
to the requester so that they can be used to encode TID RDMA WRITE
DATA packet.

Signed-off-by: Mitko Haralanov <mitko.haralanov@intel.com>
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Signed-off-by: Kaike Wan <kaike.wan@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
Kaike Wan 2019-01-23 21:49:09 -08:00 committed by Doug Ledford
parent 07b923701e
commit 38d46d3676
3 changed files with 101 additions and 0 deletions

View File

@ -3583,3 +3583,98 @@ nack_acc:
send_ack:
hfi1_send_rc_ack(packet, is_fecn);
}
u32 hfi1_build_tid_rdma_write_resp(struct rvt_qp *qp, struct rvt_ack_entry *e,
struct ib_other_headers *ohdr, u32 *bth1,
u32 bth2, u32 *len,
struct rvt_sge_state **ss)
{
struct hfi1_ack_priv *epriv = e->priv;
struct tid_rdma_request *req = &epriv->tid_req;
struct hfi1_qp_priv *qpriv = qp->priv;
struct tid_rdma_flow *flow = NULL;
u32 resp_len = 0, hdwords = 0;
void *resp_addr = NULL;
struct tid_rdma_params *remote;
flow = &req->flows[req->flow_idx];
switch (req->state) {
default:
/*
* Try to allocate resources here in case QP was queued and was
* later scheduled when resources became available
*/
hfi1_tid_write_alloc_resources(qp, false);
/* We've already sent everything which is ready */
if (req->cur_seg >= req->alloc_seg)
goto done;
/*
* Resources can be assigned but responses cannot be sent in
* rnr_nak state, till the resent request is received
*/
if (qpriv->rnr_nak_state == TID_RNR_NAK_SENT)
goto done;
req->state = TID_REQUEST_ACTIVE;
req->flow_idx = CIRC_NEXT(req->flow_idx, MAX_FLOWS);
break;
case TID_REQUEST_RESEND_ACTIVE:
case TID_REQUEST_RESEND:
req->flow_idx = CIRC_NEXT(req->flow_idx, MAX_FLOWS);
if (!CIRC_CNT(req->setup_head, req->flow_idx, MAX_FLOWS))
req->state = TID_REQUEST_ACTIVE;
break;
}
flow->flow_state.resp_ib_psn = bth2;
resp_addr = (void *)flow->tid_entry;
resp_len = sizeof(*flow->tid_entry) * flow->tidcnt;
req->cur_seg++;
memset(&ohdr->u.tid_rdma.w_rsp, 0, sizeof(ohdr->u.tid_rdma.w_rsp));
epriv->ss.sge.vaddr = resp_addr;
epriv->ss.sge.sge_length = resp_len;
epriv->ss.sge.length = epriv->ss.sge.sge_length;
/*
* We can safely zero these out. Since the first SGE covers the
* entire packet, nothing else should even look at the MR.
*/
epriv->ss.sge.mr = NULL;
epriv->ss.sge.m = 0;
epriv->ss.sge.n = 0;
epriv->ss.sg_list = NULL;
epriv->ss.total_len = epriv->ss.sge.sge_length;
epriv->ss.num_sge = 1;
*ss = &epriv->ss;
*len = epriv->ss.total_len;
/* Construct the TID RDMA WRITE RESP packet header */
rcu_read_lock();
remote = rcu_dereference(qpriv->tid_rdma.remote);
KDETH_RESET(ohdr->u.tid_rdma.w_rsp.kdeth0, KVER, 0x1);
KDETH_RESET(ohdr->u.tid_rdma.w_rsp.kdeth1, JKEY, remote->jkey);
ohdr->u.tid_rdma.w_rsp.aeth = rvt_compute_aeth(qp);
ohdr->u.tid_rdma.w_rsp.tid_flow_psn =
cpu_to_be32((flow->flow_state.generation <<
HFI1_KDETH_BTH_SEQ_SHIFT) |
(flow->flow_state.spsn &
HFI1_KDETH_BTH_SEQ_MASK));
ohdr->u.tid_rdma.w_rsp.tid_flow_qp =
cpu_to_be32(qpriv->tid_rdma.local.qp |
((flow->idx & TID_RDMA_DESTQP_FLOW_MASK) <<
TID_RDMA_DESTQP_FLOW_SHIFT) |
qpriv->rcd->ctxt);
ohdr->u.tid_rdma.w_rsp.verbs_qp = cpu_to_be32(qp->remote_qpn);
*bth1 = remote->qp;
rcu_read_unlock();
hdwords = sizeof(ohdr->u.tid_rdma.w_rsp) / sizeof(u32);
qpriv->pending_tid_w_segs++;
done:
return hdwords;
}

View File

@ -263,4 +263,9 @@ void hfi1_compute_tid_rdma_flow_wt(void);
void hfi1_rc_rcv_tid_rdma_write_req(struct hfi1_packet *packet);
u32 hfi1_build_tid_rdma_write_resp(struct rvt_qp *qp, struct rvt_ack_entry *e,
struct ib_other_headers *ohdr, u32 *bth1,
u32 bth2, u32 *len,
struct rvt_sge_state **ss);
#endif /* HFI1_TID_RDMA_H */

View File

@ -200,6 +200,7 @@ struct hfi1_swqe_priv {
};
struct hfi1_ack_priv {
struct rvt_sge_state ss; /* used for TID WRITE RESP */
struct tid_rdma_request tid_req;
};