]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sif: cq: sif_poll_cq might not drain cq completely
authorWei Lin Guay <wei.lin.guay@oracle.com>
Thu, 3 Nov 2016 09:46:22 +0000 (10:46 +0100)
committerKnut Omang <knut.omang@oracle.com>
Fri, 11 Nov 2016 16:36:59 +0000 (17:36 +0100)
In a scenario where a duplicate completion is detected, the sif_poll_cq
skips the remaining cqes in the cq. This code bug is introduced in
commit "sif: sqflush: Handle duplicate completions in poll_cq".

Orabug: 25038711

Signed-off-by: Wei Lin Guay <wei.lin.guay@oracle.com>
Reviewed-by: Knut Omang <knut.omang@oracle.com>
drivers/infiniband/hw/sif/sif_cq.c

index 92204edbdb753cd68ee72044517d528c549067e1..545a7fe702fcf2bd00d82f5f9ff8405e865486da 100644 (file)
@@ -871,25 +871,23 @@ int sif_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
 
                polled_value = get_psif_cq_entry__seq_num(cqe);
 
-               if (seqno == polled_value)
-                       npolled++;
-               else
+               if (seqno != polled_value)
                        break;
 
                if (likely(wc)) {
-                       if (unlikely(handle_wc(sdev, cq, cqe, wc) < 0)) {
-                               /* poll_cq should not return < 0. Thus, ignore
-                                * the CQE if it is duplicate, unexpected or wrong
-                                * CQE.
-                                */
-                               seqno = ++cq_sw->next_seq;
-                               npolled--;
-                               continue;
+                        /* handle_wc == 0 means that it's a valid cqe.
+                         * Thus, increments the npolled and the wc pointer.
+                         */
+                       if (likely(handle_wc(sdev, cq, cqe, wc) == 0)) {
+                               ++wc;
+                               ++npolled;
                        }
-                       wc++;
                        seqno = ++cq_sw->next_seq;
-               } else /* peek_cq semantics */
+               } else {
+                       /* peek_cq semantics */
                        ++seqno;
+                       ++npolled;
+               }
 
                cqe = get_cq_entry(cq, seqno);
        }