From 60df29581f67e06791a176641c774515ec1634e5 Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Mon, 7 Mar 2016 11:35:30 -0800 Subject: 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 Signed-off-by: Mike Marciniszyn Signed-off-by: Doug Ledford --- drivers/staging/rdma/hfi1/pio.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers/staging') 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++) -- cgit v1.2.3