Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 60df2958 authored by Mike Marciniszyn's avatar Mike Marciniszyn Committed by Doug Ledford
Browse files

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: default avatarVennila Megavannan <vennila.megavannan@intel.com>
Signed-off-by: default avatarMike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 5326dfbf
Loading
Loading
Loading
Loading
+7 −5
Original line number Original line Diff line number Diff line
@@ -1545,7 +1545,7 @@ static void sc_piobufavail(struct send_context *sc)
		struct iowait *wait;
		struct iowait *wait;


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


	for (i = 0; i < n; i++)
	for (i = 0; i < n; i++)