mirror of
https://github.com/torvalds/linux.git
synced 2024-11-16 17:12:06 +00:00
IB/ipath: Support larger IB_QP_MAX_DEST_RD_ATOMIC and IB_QP_MAX_QP_RD_ATOMIC
This patch adds support for multiple RDMA reads and atomics to be sent before an ACK is required to be seen by the requester. Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
parent
7b21d26dda
commit
3859e39d75
@ -320,7 +320,8 @@ static void ipath_reset_qp(struct ipath_qp *qp)
|
|||||||
qp->remote_qpn = 0;
|
qp->remote_qpn = 0;
|
||||||
qp->qkey = 0;
|
qp->qkey = 0;
|
||||||
qp->qp_access_flags = 0;
|
qp->qp_access_flags = 0;
|
||||||
clear_bit(IPATH_S_BUSY, &qp->s_flags);
|
qp->s_busy = 0;
|
||||||
|
qp->s_flags &= ~IPATH_S_SIGNAL_REQ_WR;
|
||||||
qp->s_hdrwords = 0;
|
qp->s_hdrwords = 0;
|
||||||
qp->s_psn = 0;
|
qp->s_psn = 0;
|
||||||
qp->r_psn = 0;
|
qp->r_psn = 0;
|
||||||
@ -333,7 +334,6 @@ static void ipath_reset_qp(struct ipath_qp *qp)
|
|||||||
qp->r_state = IB_OPCODE_UC_SEND_LAST;
|
qp->r_state = IB_OPCODE_UC_SEND_LAST;
|
||||||
}
|
}
|
||||||
qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE;
|
qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE;
|
||||||
qp->r_ack_state = IB_OPCODE_RC_ACKNOWLEDGE;
|
|
||||||
qp->r_nak_state = 0;
|
qp->r_nak_state = 0;
|
||||||
qp->r_wrid_valid = 0;
|
qp->r_wrid_valid = 0;
|
||||||
qp->s_rnr_timeout = 0;
|
qp->s_rnr_timeout = 0;
|
||||||
@ -344,6 +344,10 @@ static void ipath_reset_qp(struct ipath_qp *qp)
|
|||||||
qp->s_ssn = 1;
|
qp->s_ssn = 1;
|
||||||
qp->s_lsn = 0;
|
qp->s_lsn = 0;
|
||||||
qp->s_wait_credit = 0;
|
qp->s_wait_credit = 0;
|
||||||
|
memset(qp->s_ack_queue, 0, sizeof(qp->s_ack_queue));
|
||||||
|
qp->r_head_ack_queue = 0;
|
||||||
|
qp->s_tail_ack_queue = 0;
|
||||||
|
qp->s_num_rd_atomic = 0;
|
||||||
if (qp->r_rq.wq) {
|
if (qp->r_rq.wq) {
|
||||||
qp->r_rq.wq->head = 0;
|
qp->r_rq.wq->head = 0;
|
||||||
qp->r_rq.wq->tail = 0;
|
qp->r_rq.wq->tail = 0;
|
||||||
@ -503,6 +507,10 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
|||||||
attr->path_mig_state != IB_MIG_REARM)
|
attr->path_mig_state != IB_MIG_REARM)
|
||||||
goto inval;
|
goto inval;
|
||||||
|
|
||||||
|
if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
|
||||||
|
if (attr->max_dest_rd_atomic > IPATH_MAX_RDMA_ATOMIC)
|
||||||
|
goto inval;
|
||||||
|
|
||||||
switch (new_state) {
|
switch (new_state) {
|
||||||
case IB_QPS_RESET:
|
case IB_QPS_RESET:
|
||||||
ipath_reset_qp(qp);
|
ipath_reset_qp(qp);
|
||||||
@ -559,6 +567,12 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
|||||||
if (attr_mask & IB_QP_QKEY)
|
if (attr_mask & IB_QP_QKEY)
|
||||||
qp->qkey = attr->qkey;
|
qp->qkey = attr->qkey;
|
||||||
|
|
||||||
|
if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
|
||||||
|
qp->r_max_rd_atomic = attr->max_dest_rd_atomic;
|
||||||
|
|
||||||
|
if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC)
|
||||||
|
qp->s_max_rd_atomic = attr->max_rd_atomic;
|
||||||
|
|
||||||
qp->state = new_state;
|
qp->state = new_state;
|
||||||
spin_unlock_irqrestore(&qp->s_lock, flags);
|
spin_unlock_irqrestore(&qp->s_lock, flags);
|
||||||
|
|
||||||
@ -598,8 +612,8 @@ int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
|||||||
attr->alt_pkey_index = 0;
|
attr->alt_pkey_index = 0;
|
||||||
attr->en_sqd_async_notify = 0;
|
attr->en_sqd_async_notify = 0;
|
||||||
attr->sq_draining = 0;
|
attr->sq_draining = 0;
|
||||||
attr->max_rd_atomic = 1;
|
attr->max_rd_atomic = qp->s_max_rd_atomic;
|
||||||
attr->max_dest_rd_atomic = 1;
|
attr->max_dest_rd_atomic = qp->r_max_rd_atomic;
|
||||||
attr->min_rnr_timer = qp->r_min_rnr_timer;
|
attr->min_rnr_timer = qp->r_min_rnr_timer;
|
||||||
attr->port_num = 1;
|
attr->port_num = 1;
|
||||||
attr->timeout = qp->timeout;
|
attr->timeout = qp->timeout;
|
||||||
@ -614,7 +628,7 @@ int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
|||||||
init_attr->recv_cq = qp->ibqp.recv_cq;
|
init_attr->recv_cq = qp->ibqp.recv_cq;
|
||||||
init_attr->srq = qp->ibqp.srq;
|
init_attr->srq = qp->ibqp.srq;
|
||||||
init_attr->cap = attr->cap;
|
init_attr->cap = attr->cap;
|
||||||
if (qp->s_flags & (1 << IPATH_S_SIGNAL_REQ_WR))
|
if (qp->s_flags & IPATH_S_SIGNAL_REQ_WR)
|
||||||
init_attr->sq_sig_type = IB_SIGNAL_REQ_WR;
|
init_attr->sq_sig_type = IB_SIGNAL_REQ_WR;
|
||||||
else
|
else
|
||||||
init_attr->sq_sig_type = IB_SIGNAL_ALL_WR;
|
init_attr->sq_sig_type = IB_SIGNAL_ALL_WR;
|
||||||
@ -786,7 +800,7 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
|
|||||||
qp->s_size = init_attr->cap.max_send_wr + 1;
|
qp->s_size = init_attr->cap.max_send_wr + 1;
|
||||||
qp->s_max_sge = init_attr->cap.max_send_sge;
|
qp->s_max_sge = init_attr->cap.max_send_sge;
|
||||||
if (init_attr->sq_sig_type == IB_SIGNAL_REQ_WR)
|
if (init_attr->sq_sig_type == IB_SIGNAL_REQ_WR)
|
||||||
qp->s_flags = 1 << IPATH_S_SIGNAL_REQ_WR;
|
qp->s_flags = IPATH_S_SIGNAL_REQ_WR;
|
||||||
else
|
else
|
||||||
qp->s_flags = 0;
|
qp->s_flags = 0;
|
||||||
dev = to_idev(ibpd->device);
|
dev = to_idev(ibpd->device);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -255,6 +255,7 @@ static void ipath_ruc_loopback(struct ipath_qp *sqp)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct ib_wc wc;
|
struct ib_wc wc;
|
||||||
u64 sdata;
|
u64 sdata;
|
||||||
|
atomic64_t *maddr;
|
||||||
|
|
||||||
qp = ipath_lookup_qpn(&dev->qp_table, sqp->remote_qpn);
|
qp = ipath_lookup_qpn(&dev->qp_table, sqp->remote_qpn);
|
||||||
if (!qp) {
|
if (!qp) {
|
||||||
@ -311,7 +312,7 @@ again:
|
|||||||
sqp->s_rnr_retry--;
|
sqp->s_rnr_retry--;
|
||||||
dev->n_rnr_naks++;
|
dev->n_rnr_naks++;
|
||||||
sqp->s_rnr_timeout =
|
sqp->s_rnr_timeout =
|
||||||
ib_ipath_rnr_table[sqp->r_min_rnr_timer];
|
ib_ipath_rnr_table[qp->r_min_rnr_timer];
|
||||||
ipath_insert_rnr_queue(sqp);
|
ipath_insert_rnr_queue(sqp);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -344,20 +345,22 @@ again:
|
|||||||
wc.sl = sqp->remote_ah_attr.sl;
|
wc.sl = sqp->remote_ah_attr.sl;
|
||||||
wc.dlid_path_bits = 0;
|
wc.dlid_path_bits = 0;
|
||||||
wc.port_num = 0;
|
wc.port_num = 0;
|
||||||
|
spin_lock_irqsave(&sqp->s_lock, flags);
|
||||||
ipath_sqerror_qp(sqp, &wc);
|
ipath_sqerror_qp(sqp, &wc);
|
||||||
|
spin_unlock_irqrestore(&sqp->s_lock, flags);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IB_WR_RDMA_READ:
|
case IB_WR_RDMA_READ:
|
||||||
|
if (unlikely(!(qp->qp_access_flags &
|
||||||
|
IB_ACCESS_REMOTE_READ)))
|
||||||
|
goto acc_err;
|
||||||
if (unlikely(!ipath_rkey_ok(qp, &sqp->s_sge, wqe->length,
|
if (unlikely(!ipath_rkey_ok(qp, &sqp->s_sge, wqe->length,
|
||||||
wqe->wr.wr.rdma.remote_addr,
|
wqe->wr.wr.rdma.remote_addr,
|
||||||
wqe->wr.wr.rdma.rkey,
|
wqe->wr.wr.rdma.rkey,
|
||||||
IB_ACCESS_REMOTE_READ)))
|
IB_ACCESS_REMOTE_READ)))
|
||||||
goto acc_err;
|
goto acc_err;
|
||||||
if (unlikely(!(qp->qp_access_flags &
|
|
||||||
IB_ACCESS_REMOTE_READ)))
|
|
||||||
goto acc_err;
|
|
||||||
qp->r_sge.sge = wqe->sg_list[0];
|
qp->r_sge.sge = wqe->sg_list[0];
|
||||||
qp->r_sge.sg_list = wqe->sg_list + 1;
|
qp->r_sge.sg_list = wqe->sg_list + 1;
|
||||||
qp->r_sge.num_sge = wqe->wr.num_sge;
|
qp->r_sge.num_sge = wqe->wr.num_sge;
|
||||||
@ -365,22 +368,22 @@ again:
|
|||||||
|
|
||||||
case IB_WR_ATOMIC_CMP_AND_SWP:
|
case IB_WR_ATOMIC_CMP_AND_SWP:
|
||||||
case IB_WR_ATOMIC_FETCH_AND_ADD:
|
case IB_WR_ATOMIC_FETCH_AND_ADD:
|
||||||
|
if (unlikely(!(qp->qp_access_flags &
|
||||||
|
IB_ACCESS_REMOTE_ATOMIC)))
|
||||||
|
goto acc_err;
|
||||||
if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, sizeof(u64),
|
if (unlikely(!ipath_rkey_ok(qp, &qp->r_sge, sizeof(u64),
|
||||||
wqe->wr.wr.rdma.remote_addr,
|
wqe->wr.wr.atomic.remote_addr,
|
||||||
wqe->wr.wr.rdma.rkey,
|
wqe->wr.wr.atomic.rkey,
|
||||||
IB_ACCESS_REMOTE_ATOMIC)))
|
IB_ACCESS_REMOTE_ATOMIC)))
|
||||||
goto acc_err;
|
goto acc_err;
|
||||||
/* Perform atomic OP and save result. */
|
/* Perform atomic OP and save result. */
|
||||||
sdata = wqe->wr.wr.atomic.swap;
|
maddr = (atomic64_t *) qp->r_sge.sge.vaddr;
|
||||||
spin_lock_irqsave(&dev->pending_lock, flags);
|
sdata = wqe->wr.wr.atomic.compare_add;
|
||||||
qp->r_atomic_data = *(u64 *) qp->r_sge.sge.vaddr;
|
*(u64 *) sqp->s_sge.sge.vaddr =
|
||||||
if (wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD)
|
(wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) ?
|
||||||
*(u64 *) qp->r_sge.sge.vaddr =
|
(u64) atomic64_add_return(sdata, maddr) - sdata :
|
||||||
qp->r_atomic_data + sdata;
|
(u64) cmpxchg((u64 *) qp->r_sge.sge.vaddr,
|
||||||
else if (qp->r_atomic_data == wqe->wr.wr.atomic.compare_add)
|
sdata, wqe->wr.wr.atomic.swap);
|
||||||
*(u64 *) qp->r_sge.sge.vaddr = sdata;
|
|
||||||
spin_unlock_irqrestore(&dev->pending_lock, flags);
|
|
||||||
*(u64 *) sqp->s_sge.sge.vaddr = qp->r_atomic_data;
|
|
||||||
goto send_comp;
|
goto send_comp;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -441,7 +444,7 @@ again:
|
|||||||
send_comp:
|
send_comp:
|
||||||
sqp->s_rnr_retry = sqp->s_rnr_retry_cnt;
|
sqp->s_rnr_retry = sqp->s_rnr_retry_cnt;
|
||||||
|
|
||||||
if (!test_bit(IPATH_S_SIGNAL_REQ_WR, &sqp->s_flags) ||
|
if (!(sqp->s_flags & IPATH_S_SIGNAL_REQ_WR) ||
|
||||||
(wqe->wr.send_flags & IB_SEND_SIGNALED)) {
|
(wqe->wr.send_flags & IB_SEND_SIGNALED)) {
|
||||||
wc.wr_id = wqe->wr.wr_id;
|
wc.wr_id = wqe->wr.wr_id;
|
||||||
wc.status = IB_WC_SUCCESS;
|
wc.status = IB_WC_SUCCESS;
|
||||||
@ -503,7 +506,7 @@ void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev)
|
|||||||
* We clear the tasklet flag now since we are committing to return
|
* We clear the tasklet flag now since we are committing to return
|
||||||
* from the tasklet function.
|
* from the tasklet function.
|
||||||
*/
|
*/
|
||||||
clear_bit(IPATH_S_BUSY, &qp->s_flags);
|
clear_bit(IPATH_S_BUSY, &qp->s_busy);
|
||||||
tasklet_unlock(&qp->s_task);
|
tasklet_unlock(&qp->s_task);
|
||||||
want_buffer(dev->dd);
|
want_buffer(dev->dd);
|
||||||
dev->n_piowait++;
|
dev->n_piowait++;
|
||||||
@ -542,6 +545,9 @@ int ipath_post_ruc_send(struct ipath_qp *qp, struct ib_send_wr *wr)
|
|||||||
wr->sg_list[0].addr & (sizeof(u64) - 1))) {
|
wr->sg_list[0].addr & (sizeof(u64) - 1))) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto bail;
|
goto bail;
|
||||||
|
} else if (wr->opcode >= IB_WR_RDMA_READ && !qp->s_max_rd_atomic) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto bail;
|
||||||
}
|
}
|
||||||
/* IB spec says that num_sge == 0 is OK. */
|
/* IB spec says that num_sge == 0 is OK. */
|
||||||
if (wr->num_sge > qp->s_max_sge) {
|
if (wr->num_sge > qp->s_max_sge) {
|
||||||
@ -648,7 +654,7 @@ void ipath_do_ruc_send(unsigned long data)
|
|||||||
u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu);
|
u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu);
|
||||||
struct ipath_other_headers *ohdr;
|
struct ipath_other_headers *ohdr;
|
||||||
|
|
||||||
if (test_and_set_bit(IPATH_S_BUSY, &qp->s_flags))
|
if (test_and_set_bit(IPATH_S_BUSY, &qp->s_busy))
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
if (unlikely(qp->remote_ah_attr.dlid == dev->dd->ipath_lid)) {
|
if (unlikely(qp->remote_ah_attr.dlid == dev->dd->ipath_lid)) {
|
||||||
@ -684,19 +690,15 @@ again:
|
|||||||
*/
|
*/
|
||||||
spin_lock_irqsave(&qp->s_lock, flags);
|
spin_lock_irqsave(&qp->s_lock, flags);
|
||||||
|
|
||||||
/* Sending responses has higher priority over sending requests. */
|
if (!((qp->ibqp.qp_type == IB_QPT_RC) ?
|
||||||
if (qp->s_ack_state != IB_OPCODE_RC_ACKNOWLEDGE &&
|
ipath_make_rc_req(qp, ohdr, pmtu, &bth0, &bth2) :
|
||||||
(bth0 = ipath_make_rc_ack(qp, ohdr, pmtu)) != 0)
|
ipath_make_uc_req(qp, ohdr, pmtu, &bth0, &bth2))) {
|
||||||
bth2 = qp->s_ack_psn++ & IPATH_PSN_MASK;
|
|
||||||
else if (!((qp->ibqp.qp_type == IB_QPT_RC) ?
|
|
||||||
ipath_make_rc_req(qp, ohdr, pmtu, &bth0, &bth2) :
|
|
||||||
ipath_make_uc_req(qp, ohdr, pmtu, &bth0, &bth2))) {
|
|
||||||
/*
|
/*
|
||||||
* Clear the busy bit before unlocking to avoid races with
|
* Clear the busy bit before unlocking to avoid races with
|
||||||
* adding new work queue items and then failing to process
|
* adding new work queue items and then failing to process
|
||||||
* them.
|
* them.
|
||||||
*/
|
*/
|
||||||
clear_bit(IPATH_S_BUSY, &qp->s_flags);
|
clear_bit(IPATH_S_BUSY, &qp->s_busy);
|
||||||
spin_unlock_irqrestore(&qp->s_lock, flags);
|
spin_unlock_irqrestore(&qp->s_lock, flags);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
@ -729,7 +731,7 @@ again:
|
|||||||
goto again;
|
goto again;
|
||||||
|
|
||||||
clear:
|
clear:
|
||||||
clear_bit(IPATH_S_BUSY, &qp->s_flags);
|
clear_bit(IPATH_S_BUSY, &qp->s_busy);
|
||||||
bail:
|
bail:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ static void complete_last_send(struct ipath_qp *qp, struct ipath_swqe *wqe,
|
|||||||
{
|
{
|
||||||
if (++qp->s_last == qp->s_size)
|
if (++qp->s_last == qp->s_size)
|
||||||
qp->s_last = 0;
|
qp->s_last = 0;
|
||||||
if (!test_bit(IPATH_S_SIGNAL_REQ_WR, &qp->s_flags) ||
|
if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) ||
|
||||||
(wqe->wr.send_flags & IB_SEND_SIGNALED)) {
|
(wqe->wr.send_flags & IB_SEND_SIGNALED)) {
|
||||||
wc->wr_id = wqe->wr.wr_id;
|
wc->wr_id = wqe->wr.wr_id;
|
||||||
wc->status = IB_WC_SUCCESS;
|
wc->status = IB_WC_SUCCESS;
|
||||||
@ -344,13 +344,13 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
|
|||||||
send_first:
|
send_first:
|
||||||
if (qp->r_reuse_sge) {
|
if (qp->r_reuse_sge) {
|
||||||
qp->r_reuse_sge = 0;
|
qp->r_reuse_sge = 0;
|
||||||
qp->r_sge = qp->s_rdma_sge;
|
qp->r_sge = qp->s_rdma_read_sge;
|
||||||
} else if (!ipath_get_rwqe(qp, 0)) {
|
} else if (!ipath_get_rwqe(qp, 0)) {
|
||||||
dev->n_pkt_drops++;
|
dev->n_pkt_drops++;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* Save the WQE so we can reuse it in case of an error. */
|
/* Save the WQE so we can reuse it in case of an error. */
|
||||||
qp->s_rdma_sge = qp->r_sge;
|
qp->s_rdma_read_sge = qp->r_sge;
|
||||||
qp->r_rcv_len = 0;
|
qp->r_rcv_len = 0;
|
||||||
if (opcode == OP(SEND_ONLY))
|
if (opcode == OP(SEND_ONLY))
|
||||||
goto send_last;
|
goto send_last;
|
||||||
|
@ -467,7 +467,7 @@ int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr)
|
|||||||
|
|
||||||
done:
|
done:
|
||||||
/* Queue the completion status entry. */
|
/* Queue the completion status entry. */
|
||||||
if (!test_bit(IPATH_S_SIGNAL_REQ_WR, &qp->s_flags) ||
|
if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) ||
|
||||||
(wr->send_flags & IB_SEND_SIGNALED)) {
|
(wr->send_flags & IB_SEND_SIGNALED)) {
|
||||||
wc.wr_id = wr->wr_id;
|
wc.wr_id = wr->wr_id;
|
||||||
wc.status = IB_WC_SUCCESS;
|
wc.status = IB_WC_SUCCESS;
|
||||||
|
@ -773,7 +773,6 @@ int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords,
|
|||||||
/* +1 is for the qword padding of pbc */
|
/* +1 is for the qword padding of pbc */
|
||||||
plen = hdrwords + ((len + 3) >> 2) + 1;
|
plen = hdrwords + ((len + 3) >> 2) + 1;
|
||||||
if (unlikely((plen << 2) > dd->ipath_ibmaxlen)) {
|
if (unlikely((plen << 2) > dd->ipath_ibmaxlen)) {
|
||||||
ipath_dbg("packet len 0x%x too long, failing\n", plen);
|
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
@ -980,14 +979,14 @@ static int ipath_query_device(struct ib_device *ibdev,
|
|||||||
props->max_cqe = ib_ipath_max_cqes;
|
props->max_cqe = ib_ipath_max_cqes;
|
||||||
props->max_mr = dev->lk_table.max;
|
props->max_mr = dev->lk_table.max;
|
||||||
props->max_pd = ib_ipath_max_pds;
|
props->max_pd = ib_ipath_max_pds;
|
||||||
props->max_qp_rd_atom = 1;
|
props->max_qp_rd_atom = IPATH_MAX_RDMA_ATOMIC;
|
||||||
props->max_qp_init_rd_atom = 1;
|
props->max_qp_init_rd_atom = 255;
|
||||||
/* props->max_res_rd_atom */
|
/* props->max_res_rd_atom */
|
||||||
props->max_srq = ib_ipath_max_srqs;
|
props->max_srq = ib_ipath_max_srqs;
|
||||||
props->max_srq_wr = ib_ipath_max_srq_wrs;
|
props->max_srq_wr = ib_ipath_max_srq_wrs;
|
||||||
props->max_srq_sge = ib_ipath_max_srq_sges;
|
props->max_srq_sge = ib_ipath_max_srq_sges;
|
||||||
/* props->local_ca_ack_delay */
|
/* props->local_ca_ack_delay */
|
||||||
props->atomic_cap = IB_ATOMIC_HCA;
|
props->atomic_cap = IB_ATOMIC_GLOB;
|
||||||
props->max_pkeys = ipath_get_npkeys(dev->dd);
|
props->max_pkeys = ipath_get_npkeys(dev->dd);
|
||||||
props->max_mcast_grp = ib_ipath_max_mcast_grps;
|
props->max_mcast_grp = ib_ipath_max_mcast_grps;
|
||||||
props->max_mcast_qp_attach = ib_ipath_max_mcast_qp_attached;
|
props->max_mcast_qp_attach = ib_ipath_max_mcast_qp_attached;
|
||||||
|
@ -43,6 +43,8 @@
|
|||||||
|
|
||||||
#include "ipath_layer.h"
|
#include "ipath_layer.h"
|
||||||
|
|
||||||
|
#define IPATH_MAX_RDMA_ATOMIC 4
|
||||||
|
|
||||||
#define QPN_MAX (1 << 24)
|
#define QPN_MAX (1 << 24)
|
||||||
#define QPNMAP_ENTRIES (QPN_MAX / PAGE_SIZE / BITS_PER_BYTE)
|
#define QPNMAP_ENTRIES (QPN_MAX / PAGE_SIZE / BITS_PER_BYTE)
|
||||||
|
|
||||||
@ -89,7 +91,7 @@ struct ib_reth {
|
|||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct ib_atomic_eth {
|
struct ib_atomic_eth {
|
||||||
__be64 vaddr;
|
__be32 vaddr[2]; /* unaligned so access as 2 32-bit words */
|
||||||
__be32 rkey;
|
__be32 rkey;
|
||||||
__be64 swap_data;
|
__be64 swap_data;
|
||||||
__be64 compare_data;
|
__be64 compare_data;
|
||||||
@ -108,7 +110,7 @@ struct ipath_other_headers {
|
|||||||
} rc;
|
} rc;
|
||||||
struct {
|
struct {
|
||||||
__be32 aeth;
|
__be32 aeth;
|
||||||
__be64 atomic_ack_eth;
|
__be32 atomic_ack_eth[2];
|
||||||
} at;
|
} at;
|
||||||
__be32 imm_data;
|
__be32 imm_data;
|
||||||
__be32 aeth;
|
__be32 aeth;
|
||||||
@ -311,6 +313,19 @@ struct ipath_sge_state {
|
|||||||
u8 num_sge;
|
u8 num_sge;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This structure holds the information that the send tasklet needs
|
||||||
|
* to send a RDMA read response or atomic operation.
|
||||||
|
*/
|
||||||
|
struct ipath_ack_entry {
|
||||||
|
u8 opcode;
|
||||||
|
u32 psn;
|
||||||
|
union {
|
||||||
|
struct ipath_sge_state rdma_sge;
|
||||||
|
u64 atomic_data;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Variables prefixed with s_ are for the requester (sender).
|
* Variables prefixed with s_ are for the requester (sender).
|
||||||
* Variables prefixed with r_ are for the responder (receiver).
|
* Variables prefixed with r_ are for the responder (receiver).
|
||||||
@ -333,24 +348,24 @@ struct ipath_qp {
|
|||||||
struct ipath_mmap_info *ip;
|
struct ipath_mmap_info *ip;
|
||||||
struct ipath_sge_state *s_cur_sge;
|
struct ipath_sge_state *s_cur_sge;
|
||||||
struct ipath_sge_state s_sge; /* current send request data */
|
struct ipath_sge_state s_sge; /* current send request data */
|
||||||
/* current RDMA read send data */
|
struct ipath_ack_entry s_ack_queue[IPATH_MAX_RDMA_ATOMIC + 1];
|
||||||
struct ipath_sge_state s_rdma_sge;
|
struct ipath_sge_state s_ack_rdma_sge;
|
||||||
|
struct ipath_sge_state s_rdma_read_sge;
|
||||||
struct ipath_sge_state r_sge; /* current receive data */
|
struct ipath_sge_state r_sge; /* current receive data */
|
||||||
spinlock_t s_lock;
|
spinlock_t s_lock;
|
||||||
unsigned long s_flags;
|
unsigned long s_busy;
|
||||||
u32 s_hdrwords; /* size of s_hdr in 32 bit words */
|
u32 s_hdrwords; /* size of s_hdr in 32 bit words */
|
||||||
u32 s_cur_size; /* size of send packet in bytes */
|
u32 s_cur_size; /* size of send packet in bytes */
|
||||||
u32 s_len; /* total length of s_sge */
|
u32 s_len; /* total length of s_sge */
|
||||||
u32 s_rdma_len; /* total length of s_rdma_sge */
|
u32 s_rdma_read_len; /* total length of s_rdma_read_sge */
|
||||||
u32 s_next_psn; /* PSN for next request */
|
u32 s_next_psn; /* PSN for next request */
|
||||||
u32 s_last_psn; /* last response PSN processed */
|
u32 s_last_psn; /* last response PSN processed */
|
||||||
u32 s_psn; /* current packet sequence number */
|
u32 s_psn; /* current packet sequence number */
|
||||||
u32 s_ack_psn; /* PSN for RDMA_READ */
|
u32 s_ack_rdma_psn; /* PSN for sending RDMA read responses */
|
||||||
|
u32 s_ack_psn; /* PSN for acking sends and RDMA writes */
|
||||||
u32 s_rnr_timeout; /* number of milliseconds for RNR timeout */
|
u32 s_rnr_timeout; /* number of milliseconds for RNR timeout */
|
||||||
u32 r_ack_psn; /* PSN for next ACK or atomic ACK */
|
u32 r_ack_psn; /* PSN for next ACK or atomic ACK */
|
||||||
u64 r_wr_id; /* ID for current receive WQE */
|
u64 r_wr_id; /* ID for current receive WQE */
|
||||||
u64 r_atomic_data; /* data for last atomic op */
|
|
||||||
u32 r_atomic_psn; /* PSN of last atomic op */
|
|
||||||
u32 r_len; /* total length of r_sge */
|
u32 r_len; /* total length of r_sge */
|
||||||
u32 r_rcv_len; /* receive data len processed */
|
u32 r_rcv_len; /* receive data len processed */
|
||||||
u32 r_psn; /* expected rcv packet sequence number */
|
u32 r_psn; /* expected rcv packet sequence number */
|
||||||
@ -360,12 +375,13 @@ struct ipath_qp {
|
|||||||
u8 s_ack_state; /* opcode of packet to ACK */
|
u8 s_ack_state; /* opcode of packet to ACK */
|
||||||
u8 s_nak_state; /* non-zero if NAK is pending */
|
u8 s_nak_state; /* non-zero if NAK is pending */
|
||||||
u8 r_state; /* opcode of last packet received */
|
u8 r_state; /* opcode of last packet received */
|
||||||
u8 r_ack_state; /* opcode of packet to ACK */
|
|
||||||
u8 r_nak_state; /* non-zero if NAK is pending */
|
u8 r_nak_state; /* non-zero if NAK is pending */
|
||||||
u8 r_min_rnr_timer; /* retry timeout value for RNR NAKs */
|
u8 r_min_rnr_timer; /* retry timeout value for RNR NAKs */
|
||||||
u8 r_reuse_sge; /* for UC receive errors */
|
u8 r_reuse_sge; /* for UC receive errors */
|
||||||
u8 r_sge_inx; /* current index into sg_list */
|
u8 r_sge_inx; /* current index into sg_list */
|
||||||
u8 r_wrid_valid; /* r_wrid set but CQ entry not yet made */
|
u8 r_wrid_valid; /* r_wrid set but CQ entry not yet made */
|
||||||
|
u8 r_max_rd_atomic; /* max number of RDMA read/atomic to receive */
|
||||||
|
u8 r_head_ack_queue; /* index into s_ack_queue[] */
|
||||||
u8 qp_access_flags;
|
u8 qp_access_flags;
|
||||||
u8 s_max_sge; /* size of s_wq->sg_list */
|
u8 s_max_sge; /* size of s_wq->sg_list */
|
||||||
u8 s_retry_cnt; /* number of times to retry */
|
u8 s_retry_cnt; /* number of times to retry */
|
||||||
@ -374,6 +390,10 @@ struct ipath_qp {
|
|||||||
u8 s_rnr_retry; /* requester RNR retry counter */
|
u8 s_rnr_retry; /* requester RNR retry counter */
|
||||||
u8 s_wait_credit; /* limit number of unacked packets sent */
|
u8 s_wait_credit; /* limit number of unacked packets sent */
|
||||||
u8 s_pkey_index; /* PKEY index to use */
|
u8 s_pkey_index; /* PKEY index to use */
|
||||||
|
u8 s_max_rd_atomic; /* max number of RDMA read/atomic to send */
|
||||||
|
u8 s_num_rd_atomic; /* number of RDMA read/atomic pending */
|
||||||
|
u8 s_tail_ack_queue; /* index into s_ack_queue[] */
|
||||||
|
u8 s_flags;
|
||||||
u8 timeout; /* Timeout for this QP */
|
u8 timeout; /* Timeout for this QP */
|
||||||
enum ib_mtu path_mtu;
|
enum ib_mtu path_mtu;
|
||||||
u32 remote_qpn;
|
u32 remote_qpn;
|
||||||
@ -390,11 +410,16 @@ struct ipath_qp {
|
|||||||
struct ipath_sge r_sg_list[0]; /* verified SGEs */
|
struct ipath_sge r_sg_list[0]; /* verified SGEs */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Bit definition for s_busy. */
|
||||||
|
#define IPATH_S_BUSY 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bit definitions for s_flags.
|
* Bit definitions for s_flags.
|
||||||
*/
|
*/
|
||||||
#define IPATH_S_BUSY 0
|
#define IPATH_S_SIGNAL_REQ_WR 0x01
|
||||||
#define IPATH_S_SIGNAL_REQ_WR 1
|
#define IPATH_S_FENCE_PENDING 0x02
|
||||||
|
#define IPATH_S_RDMAR_PENDING 0x04
|
||||||
|
#define IPATH_S_ACK_PENDING 0x08
|
||||||
|
|
||||||
#define IPATH_PSN_CREDIT 2048
|
#define IPATH_PSN_CREDIT 2048
|
||||||
|
|
||||||
@ -757,9 +782,6 @@ u32 ipath_make_grh(struct ipath_ibdev *dev, struct ib_grh *hdr,
|
|||||||
|
|
||||||
void ipath_do_ruc_send(unsigned long data);
|
void ipath_do_ruc_send(unsigned long data);
|
||||||
|
|
||||||
u32 ipath_make_rc_ack(struct ipath_qp *qp, struct ipath_other_headers *ohdr,
|
|
||||||
u32 pmtu);
|
|
||||||
|
|
||||||
int ipath_make_rc_req(struct ipath_qp *qp, struct ipath_other_headers *ohdr,
|
int ipath_make_rc_req(struct ipath_qp *qp, struct ipath_other_headers *ohdr,
|
||||||
u32 pmtu, u32 *bth0p, u32 *bth2p);
|
u32 pmtu, u32 *bth0p, u32 *bth2p);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user