]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
[IB] mthca: fix wraparound handling in mthca_cq_clean()
authorRoland Dreier <rolandd@cisco.com>
Wed, 9 Nov 2005 20:23:17 +0000 (12:23 -0800)
committerRoland Dreier <rolandd@cisco.com>
Thu, 10 Nov 2005 18:22:51 +0000 (10:22 -0800)
Handle case where prod_index has wrapped around and become less than
cq->cons_index by checking that their difference as a signed int is
positive rather than comparing directly.

Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/hw/mthca/mthca_cq.c

index f98e23555826e07b8eda0e7a8d47190805174cb7..4a8adcef2079cd5c118c41c40f6a87a94ab98ffe 100644 (file)
@@ -258,7 +258,7 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
 {
        struct mthca_cq *cq;
        struct mthca_cqe *cqe;
-       int prod_index;
+       u32 prod_index;
        int nfreed = 0;
 
        spin_lock_irq(&dev->cq_table.lock);
@@ -293,19 +293,15 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
         * Now sweep backwards through the CQ, removing CQ entries
         * that match our QP by copying older entries on top of them.
         */
-       while (prod_index > cq->cons_index) {
-               cqe = get_cqe(cq, (prod_index - 1) & cq->ibcq.cqe);
+       while ((int) --prod_index - (int) cq->cons_index >= 0) {
+               cqe = get_cqe(cq, prod_index & cq->ibcq.cqe);
                if (cqe->my_qpn == cpu_to_be32(qpn)) {
                        if (srq)
                                mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe));
                        ++nfreed;
-               }
-               else if (nfreed)
-                       memcpy(get_cqe(cq, (prod_index - 1 + nfreed) &
-                                      cq->ibcq.cqe),
-                              cqe,
-                              MTHCA_CQ_ENTRY_SIZE);
-               --prod_index;
+               } else if (nfreed)
+                       memcpy(get_cqe(cq, (prod_index + nfreed) & cq->ibcq.cqe),
+                              cqe, MTHCA_CQ_ENTRY_SIZE);
        }
 
        if (nfreed) {