diff options
author | Mike Marciniszyn <mike.marciniszyn@intel.com> | 2016-03-07 11:35:30 -0800 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2016-03-17 15:55:20 -0400 |
commit | 60df29581f67e06791a176641c774515ec1634e5 (patch) | |
tree | 06c4e9587bcdd2ce69d3efd7696b4ac30d83e71f | |
parent | 5326dfbf005ca8589d709209a81d145c5b87b23d (diff) | |
download | op-kernel-dev-60df29581f67e06791a176641c774515ec1634e5.zip op-kernel-dev-60df29581f67e06791a176641c774515ec1634e5.tar.gz |
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>
-rw-r--r-- | drivers/staging/rdma/hfi1/pio.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/staging/rdma/hfi1/pio.c b/drivers/staging/rdma/hfi1/pio.c index e888e21..c6849ce 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++) |