IB/hfi1: Fix PIO wakeup timing hole
authorMike Marciniszyn <mike.marciniszyn@intel.com>
Mon, 7 Mar 2016 19:35:30 +0000 (11:35 -0800)
committerDoug Ledford <dledford@redhat.com>
Thu, 17 Mar 2016 19:55:20 +0000 (15:55 -0400)
There is a timing hole if there had been greater than
PIO_WAIT_BATCH_SIZE waiters.  This code will dispatch the first
batch but leave the others in the queue.   If the restarted waiters
don't in turn wait on a buffer, there is a hang.

Fix by forcing a return when the QP queue is non-empty.

Reviewed-by: Vennila Megavannan <vennila.megavannan@intel.com>
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/staging/rdma/hfi1/pio.c

index e888e21..c6849ce 100644 (file)
@@ -1545,7 +1545,7 @@ static void sc_piobufavail(struct send_context *sc)
                struct iowait *wait;
 
                if (n == ARRAY_SIZE(qps))
-                       goto full;
+                       break;
                wait = list_first_entry(list, struct iowait, list);
                qp = iowait_to_qp(wait);
                priv = qp->priv;
@@ -1554,12 +1554,14 @@ static void sc_piobufavail(struct send_context *sc)
                qps[n++] = qp;
        }
        /*
-        * Counting: only call wantpiobuf_intr() if there were waiters and they
-        * are now all gone.
+        * If there had been waiters and there are more
+        * insure that we redo the force to avoid a potential hang.
         */
-       if (n)
+       if (n) {
                hfi1_sc_wantpiobuf_intr(sc, 0);
-full:
+               if (!list_empty(list))
+                       hfi1_sc_wantpiobuf_intr(sc, 1);
+       }
        write_sequnlock_irqrestore(&dev->iowait_lock, flags);
 
        for (i = 0; i < n; i++)