]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
IB/hfi1: Add a function to build TID RDMA WRITE response
authorKaike Wan <kaike.wan@intel.com>
Thu, 24 Jan 2019 05:49:09 +0000 (21:49 -0800)
committerDoug Ledford <dledford@redhat.com>
Tue, 5 Feb 2019 23:07:43 +0000 (18:07 -0500)
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>
drivers/infiniband/hw/hfi1/tid_rdma.c
drivers/infiniband/hw/hfi1/tid_rdma.h
drivers/infiniband/hw/hfi1/verbs.h

index 516dca9f497edc7116f97a82ed77f4456240db42..78828f9f7592ba8f38f529a9b1dc2e0314fa5315 100644 (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;
+}
index 7780a28db3168e93be3c86ea17d45991ba295a7d..19f4dd89680f54b62a35a43be699b88c81ff4c33 100644 (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 */
index 9ced8a4a7b769f5dfe58fb2576919b1515129027..3a501b09621e9b1dd7923e3c1909e7bf6d9446cc 100644 (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;
 };