IB/qib: Avoid duplicate writes to the rcv head register
authorMike Marciniszyn <mike.marciniszyn@qlogic.com>
Tue, 11 Jan 2011 01:42:21 +0000 (17:42 -0800)
committerRoland Dreier <rolandd@cisco.com>
Tue, 11 Jan 2011 01:42:21 +0000 (17:42 -0800)
Avoid duplicate writes to the head register as this can lead to lost
interrupts if the context goes full before the second write is done.

Signed-off-by: Mike Marciniszyn <mike.marciniszyn@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/hw/qib/qib_driver.c

index 9cd1936..3ed0d5a 100644 (file)
@@ -71,6 +71,11 @@ MODULE_DESCRIPTION("QLogic IB driver");
  */
 #define QIB_PIO_MAXIBHDR 128
 
+/*
+ * QIB_MAX_PKT_RCV is the max # if packets processed per receive interrupt.
+ */
+#define QIB_MAX_PKT_RECV 64
+
 struct qlogic_ib_stats qib_stats;
 
 const char *qib_get_unit_name(int unit)
@@ -335,7 +340,7 @@ u32 qib_kreceive(struct qib_ctxtdata *rcd, u32 *llic, u32 *npkts)
                smp_rmb();  /* prevent speculative reads of dma'ed hdrq */
        }
 
-       for (last = 0, i = 1; !last && i <= 64; i += !last) {
+       for (last = 0, i = 1; !last; i += !last) {
                hdr = dd->f_get_msgheader(dd, rhf_addr);
                eflags = qib_hdrget_err_flags(rhf_addr);
                etype = qib_hdrget_rcv_type(rhf_addr);
@@ -384,6 +389,9 @@ move_along:
                l += rsize;
                if (l >= maxcnt)
                        l = 0;
+               if (i == QIB_MAX_PKT_RECV)
+                       last = 1;
+
                rhf_addr = (__le32 *) rcd->rcvhdrq + l + dd->rhf_offset;
                if (dd->flags & QIB_NODMA_RTAIL) {
                        u32 seq = qib_hdrget_seq(rhf_addr);