aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorMike Marciniszyn <mike.marciniszyn@intel.com>2016-03-07 11:35:30 -0800
committerDoug Ledford <dledford@redhat.com>2016-03-17 15:55:20 -0400
commit60df29581f67e06791a176641c774515ec1634e5 (patch)
tree06c4e9587bcdd2ce69d3efd7696b4ac30d83e71f /drivers/staging
parentIB/hfi1: Fix ordering of trace for accuracy (diff)
downloadlinux-dev-60df29581f67e06791a176641c774515ec1634e5.tar.xz
linux-dev-60df29581f67e06791a176641c774515ec1634e5.zip
IB/hfi1: Fix PIO wakeup timing hole
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>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/rdma/hfi1/pio.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/staging/rdma/hfi1/pio.c b/drivers/staging/rdma/hfi1/pio.c
index e888e214356b..c6849ce9e5eb 100644
--- a/drivers/staging/rdma/hfi1/pio.c
+++ b/drivers/staging/rdma/hfi1/pio.c
@@ -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++)