forked from Minki/linux
IB/hfi1: Enable TID RDMA READ protocol
This patch enables TID RDMA READ protocol by converting a qualified RDMA READ request into a TID RDMA READ request internally: (1) The TID RDMA capability must be enabled; (2) The request must start on a 4K page boundary and all receiving buffers must start on 4K page boundaries; (3) The request length must be a multiple of 4K and must be larger or equal to 256K. Each receiving buffer length must be a multiple of 4K. Signed-off-by: Mitko Haralanov <mitko.haralanov@intel.com> Signed-off-by: Mike Marciniszyn <mike.marciniszyn@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:
parent
a0b34f75ec
commit
f1ab4efa6d
@ -319,6 +319,7 @@ int hfi1_setup_wqe(struct rvt_qp *qp, struct rvt_swqe *wqe, bool *call_send)
|
||||
|
||||
switch (qp->ibqp.qp_type) {
|
||||
case IB_QPT_RC:
|
||||
hfi1_setup_tid_rdma_wqe(qp, wqe);
|
||||
case IB_QPT_UC:
|
||||
if (wqe->length > 0x80000000U)
|
||||
return -EINVAL;
|
||||
|
@ -2866,3 +2866,71 @@ interlock:
|
||||
priv->s_flags |= HFI1_S_TID_WAIT_INTERLCK;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Does @sge meet the alignment requirements for tid rdma? */
|
||||
static inline bool hfi1_check_sge_align(struct rvt_sge *sge, int num_sge)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_sge; i++, sge++)
|
||||
if ((u64)sge->vaddr & ~PAGE_MASK ||
|
||||
sge->sge_length & ~PAGE_MASK)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void setup_tid_rdma_wqe(struct rvt_qp *qp, struct rvt_swqe *wqe)
|
||||
{
|
||||
struct hfi1_qp_priv *qpriv = (struct hfi1_qp_priv *)qp->priv;
|
||||
struct hfi1_swqe_priv *priv = wqe->priv;
|
||||
struct tid_rdma_params *remote;
|
||||
enum ib_wr_opcode new_opcode;
|
||||
bool do_tid_rdma = false;
|
||||
struct hfi1_pportdata *ppd = qpriv->rcd->ppd;
|
||||
|
||||
if ((rdma_ah_get_dlid(&qp->remote_ah_attr) & ~((1 << ppd->lmc) - 1)) ==
|
||||
ppd->lid)
|
||||
return;
|
||||
if (qpriv->hdr_type != HFI1_PKT_TYPE_9B)
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
remote = rcu_dereference(qpriv->tid_rdma.remote);
|
||||
/*
|
||||
* If TID RDMA is disabled by the negotiation, don't
|
||||
* use it.
|
||||
*/
|
||||
if (!remote)
|
||||
goto exit;
|
||||
|
||||
if (wqe->wr.opcode == IB_WR_RDMA_READ) {
|
||||
if (hfi1_check_sge_align(&wqe->sg_list[0], wqe->wr.num_sge)) {
|
||||
new_opcode = IB_WR_TID_RDMA_READ;
|
||||
do_tid_rdma = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_tid_rdma) {
|
||||
if (hfi1_kern_exp_rcv_alloc_flows(&priv->tid_req, GFP_ATOMIC))
|
||||
goto exit;
|
||||
wqe->wr.opcode = new_opcode;
|
||||
priv->tid_req.seg_len =
|
||||
min_t(u32, remote->max_len, wqe->length);
|
||||
priv->tid_req.total_segs =
|
||||
DIV_ROUND_UP(wqe->length, priv->tid_req.seg_len);
|
||||
/* Compute the last PSN of the request */
|
||||
wqe->lpsn = wqe->psn;
|
||||
if (wqe->wr.opcode == IB_WR_TID_RDMA_READ) {
|
||||
priv->tid_req.n_flows = remote->max_read;
|
||||
qpriv->tid_r_reqs++;
|
||||
wqe->lpsn += rvt_div_round_up_mtu(qp, wqe->length) - 1;
|
||||
}
|
||||
|
||||
priv->tid_req.cur_seg = 0;
|
||||
priv->tid_req.comp_seg = 0;
|
||||
priv->tid_req.ack_seg = 0;
|
||||
priv->tid_req.state = TID_REQUEST_INACTIVE;
|
||||
}
|
||||
exit:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#define CIRC_NEXT(val, size) CIRC_ADD(val, 1, size)
|
||||
#define CIRC_PREV(val, size) CIRC_ADD(val, -1, size)
|
||||
|
||||
#define TID_RDMA_MIN_SEGMENT_SIZE BIT(18) /* 256 KiB (for now) */
|
||||
#define TID_RDMA_MAX_SEGMENT_SIZE BIT(18) /* 256 KiB (for now) */
|
||||
#define TID_RDMA_MAX_PAGES (BIT(18) >> PAGE_SHIFT)
|
||||
|
||||
@ -222,4 +223,14 @@ void hfi1_tid_rdma_restart_req(struct rvt_qp *qp, struct rvt_swqe *wqe,
|
||||
void hfi1_qp_kern_exp_rcv_clear_all(struct rvt_qp *qp);
|
||||
bool hfi1_tid_rdma_wqe_interlock(struct rvt_qp *qp, struct rvt_swqe *wqe);
|
||||
|
||||
void setup_tid_rdma_wqe(struct rvt_qp *qp, struct rvt_swqe *wqe);
|
||||
static inline void hfi1_setup_tid_rdma_wqe(struct rvt_qp *qp,
|
||||
struct rvt_swqe *wqe)
|
||||
{
|
||||
if (wqe->priv &&
|
||||
wqe->wr.opcode == IB_WR_RDMA_READ &&
|
||||
wqe->length >= TID_RDMA_MIN_SEGMENT_SIZE)
|
||||
setup_tid_rdma_wqe(qp, wqe);
|
||||
}
|
||||
|
||||
#endif /* HFI1_TID_RDMA_H */
|
||||
|
Loading…
Reference in New Issue
Block a user