Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 59312
b: refs/heads/master
c: 06ee109
h: refs/heads/master
v: v3
  • Loading branch information
Ralph Campbell authored and Roland Dreier committed Jul 10, 2007
1 parent fe45b18 commit d47aaa8
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 20 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9380068fc2f230e7840ff87d3f1e6030ae2ee5e8
refs/heads/master: 06ee109002672ac875558ec699b53cf08a865bd3
57 changes: 38 additions & 19 deletions trunk/drivers/infiniband/hw/ipath/ipath_rc.c
Original file line number Diff line number Diff line change
Expand Up @@ -806,13 +806,15 @@ static inline void update_last_psn(struct ipath_qp *qp, u32 psn)
* Called at interrupt level with the QP s_lock held and interrupts disabled.
* Returns 1 if OK, 0 if current operation should be aborted (NAK).
*/
static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode,
u64 val)
{
struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
struct ib_wc wc;
struct ipath_swqe *wqe;
int ret = 0;
u32 ack_psn;
int diff;

/*
* Remove the QP from the timeout queue (or RNR timeout queue).
Expand Down Expand Up @@ -840,7 +842,19 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
* The MSN might be for a later WQE than the PSN indicates so
* only complete WQEs that the PSN finishes.
*/
while (ipath_cmp24(ack_psn, wqe->lpsn) >= 0) {
while ((diff = ipath_cmp24(ack_psn, wqe->lpsn)) >= 0) {
/*
* RDMA_READ_RESPONSE_ONLY is a special case since
* we want to generate completion events for everything
* before the RDMA read, copy the data, then generate
* the completion for the read.
*/
if (wqe->wr.opcode == IB_WR_RDMA_READ &&
opcode == OP(RDMA_READ_RESPONSE_ONLY) &&
diff == 0) {
ret = 1;
goto bail;
}
/*
* If this request is a RDMA read or atomic, and the ACK is
* for a later operation, this ACK NAKs the RDMA read or
Expand All @@ -851,12 +865,10 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
* is sent but before the response is received.
*/
if ((wqe->wr.opcode == IB_WR_RDMA_READ &&
(opcode != OP(RDMA_READ_RESPONSE_LAST) ||
ipath_cmp24(ack_psn, wqe->lpsn) != 0)) ||
(opcode != OP(RDMA_READ_RESPONSE_LAST) || diff != 0)) ||
((wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) &&
(opcode != OP(ATOMIC_ACKNOWLEDGE) ||
ipath_cmp24(wqe->psn, psn) != 0))) {
(opcode != OP(ATOMIC_ACKNOWLEDGE) || diff != 0))) {
/*
* The last valid PSN seen is the previous
* request's.
Expand All @@ -870,6 +882,9 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
*/
goto bail;
}
if (wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD)
*(u64 *) wqe->sg_list[0].vaddr = val;
if (qp->s_num_rd_atomic &&
(wqe->wr.opcode == IB_WR_RDMA_READ ||
wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
Expand Down Expand Up @@ -1079,6 +1094,7 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
int diff;
u32 pad;
u32 aeth;
u64 val;

spin_lock_irqsave(&qp->s_lock, flags);

Expand Down Expand Up @@ -1118,21 +1134,20 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
data += sizeof(__be32);
}
if (opcode == OP(ATOMIC_ACKNOWLEDGE)) {
u64 val;

if (!header_in_data) {
__be32 *p = ohdr->u.at.atomic_ack_eth;

val = ((u64) be32_to_cpu(p[0]) << 32) |
be32_to_cpu(p[1]);
} else
val = be64_to_cpu(((__be64 *) data)[0]);
*(u64 *) wqe->sg_list[0].vaddr = val;
}
if (!do_rc_ack(qp, aeth, psn, opcode) ||
} else
val = 0;
if (!do_rc_ack(qp, aeth, psn, opcode, val) ||
opcode != OP(RDMA_READ_RESPONSE_FIRST))
goto ack_done;
hdrsize += 4;
wqe = get_swqe_ptr(qp, qp->s_last);
if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ))
goto ack_op_err;
/*
Expand Down Expand Up @@ -1176,13 +1191,12 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
goto bail;

case OP(RDMA_READ_RESPONSE_ONLY):
if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) {
dev->n_rdma_seq++;
ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
if (!header_in_data)
aeth = be32_to_cpu(ohdr->u.aeth);
else
aeth = be32_to_cpu(((__be32 *) data)[0]);
if (!do_rc_ack(qp, aeth, psn, opcode, 0))
goto ack_done;
}
if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ))
goto ack_op_err;
/* Get the number of bytes the message was padded by. */
pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3;
/*
Expand All @@ -1197,6 +1211,7 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
* have to be careful to copy the data to the right
* location.
*/
wqe = get_swqe_ptr(qp, qp->s_last);
qp->s_rdma_read_len = restart_sge(&qp->s_rdma_read_sge,
wqe, psn, pmtu);
goto read_last;
Expand Down Expand Up @@ -1230,7 +1245,8 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
data += sizeof(__be32);
}
ipath_copy_sge(&qp->s_rdma_read_sge, data, tlen);
(void) do_rc_ack(qp, aeth, psn, OP(RDMA_READ_RESPONSE_LAST));
(void) do_rc_ack(qp, aeth, psn,
OP(RDMA_READ_RESPONSE_LAST), 0);
goto ack_done;
}

Expand Down Expand Up @@ -1344,8 +1360,11 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev,
e = NULL;
break;
}
if (ipath_cmp24(psn, e->psn) >= 0)
if (ipath_cmp24(psn, e->psn) >= 0) {
if (prev == qp->s_tail_ack_queue)
old_req = 0;
break;
}
}
switch (opcode) {
case OP(RDMA_READ_REQUEST): {
Expand Down

0 comments on commit d47aaa8

Please sign in to comment.