IB/ipath: Fix RDMA read response sequence checking
authorRalph Campbell <ralph.campbell@qlogic.com>
Tue, 13 May 2008 18:42:20 +0000 (11:42 -0700)
committerRoland Dreier <rolandd@cisco.com>
Tue, 13 May 2008 18:42:20 +0000 (11:42 -0700)
If an out of sequence RDMA read response middle or last packet is
received, we should only resend the RDMA read request on the first
out of sequence packet and drop subsequent out of sequence packets
otherwise, we get "too many retries".

Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/hw/ipath/ipath_rc.c
drivers/infiniband/hw/ipath/ipath_verbs.h

index 5b5276a270bcca9aabeec32995cfaaae84f6665c..108df667d2eeff235fb7d5a9d7939b755504d551 100644 (file)
@@ -1189,6 +1189,7 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
                wqe = get_swqe_ptr(qp, qp->s_last);
                if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ))
                        goto ack_op_err;
+               qp->r_flags &= ~IPATH_R_RDMAR_SEQ;
                /*
                 * If this is a response to a resent RDMA read, we
                 * have to be careful to copy the data to the right
@@ -1202,6 +1203,9 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
                /* no AETH, no ACK */
                if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) {
                        dev->n_rdma_seq++;
+                       if (qp->r_flags & IPATH_R_RDMAR_SEQ)
+                               goto ack_done;
+                       qp->r_flags |= IPATH_R_RDMAR_SEQ;
                        ipath_restart_rc(qp, qp->s_last_psn + 1);
                        goto ack_done;
                }
@@ -1263,6 +1267,9 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
                /* ACKs READ req. */
                if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) {
                        dev->n_rdma_seq++;
+                       if (qp->r_flags & IPATH_R_RDMAR_SEQ)
+                               goto ack_done;
+                       qp->r_flags |= IPATH_R_RDMAR_SEQ;
                        ipath_restart_rc(qp, qp->s_last_psn + 1);
                        goto ack_done;
                }
index deee02ca7ca410b67a4e1d6c35505b7c86da8c9b..9d12ae8a778eba131e5936e9e37e22a3390bfe10 100644 (file)
@@ -444,6 +444,7 @@ struct ipath_qp {
  * Bit definitions for r_flags.
  */
 #define IPATH_R_REUSE_SGE      0x01
+#define IPATH_R_RDMAR_SEQ      0x02
 
 /*
  * Bit definitions for s_flags.