From 431cf92001509037ebe29bb3def0b68cb763b1ba Mon Sep 17 00:00:00 2001 From: nwhitehorn Date: Thu, 12 Mar 2015 17:01:30 +0000 Subject: The H_VIO_SIGNAL hypercall only enables interrupts for future received packets and does not schedule interrupts for any packets currently enqueued. Close two races where enqueued packets may not ever trigger interrupts. The first of these, at adapter initialization time, was especially severe since a rush of enqueued packets could actually fill the receive buffer completely, stalling the interface forever. MFC after: 2 weeks --- sys/powerpc/pseries/phyp_llan.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'sys/powerpc/pseries') diff --git a/sys/powerpc/pseries/phyp_llan.c b/sys/powerpc/pseries/phyp_llan.c index 0b25f39..26dbcc0 100644 --- a/sys/powerpc/pseries/phyp_llan.c +++ b/sys/powerpc/pseries/phyp_llan.c @@ -273,6 +273,9 @@ llan_init(void *xsc) sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; mtx_unlock(&sc->io_lock); + + /* Check for pending receives scheduled before interrupt enable */ + llan_intr(sc); } static int @@ -335,6 +338,7 @@ llan_intr(void *xsc) struct mbuf *m; mtx_lock(&sc->io_lock); +restart: phyp_hcall(H_VIO_SIGNAL, sc->unit, 0); while ((sc->rx_buf[sc->rx_dma_slot].control >> 7) == sc->rx_valid_val) { @@ -369,6 +373,15 @@ llan_intr(void *xsc) } phyp_hcall(H_VIO_SIGNAL, sc->unit, 1); + + /* + * H_VIO_SIGNAL enables interrupts for future packets only. + * Make sure none were queued between the end of the loop and the + * enable interrupts call. + */ + if ((sc->rx_buf[sc->rx_dma_slot].control >> 7) == sc->rx_valid_val) + goto restart; + mtx_unlock(&sc->io_lock); } -- cgit v1.1