summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2019-03-01 10:02:45 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2019-03-01 10:02:45 +0000
commitb9da46258ed19c240e791f8696ff97a5ec4bb94a (patch)
tree80720db41a937ab0a7650f2c3ad12ae4e5d26e90
parent8b18066adb684e14a24bbf162082713266c76e62 (diff)
use a timeout to refill the rx ring when it's empty.
em had rxr, but didn't use a timeout cos it claimed to generate an RX overflow interrupt when packets fell off slots in the ring. turns out that's a lie on at least one chip, so add the timeout like other drivers. this was hit by mlarkin@, who had nfs and bufs steal all the packets and memory for packets from em, which didn't recover after the memory had been released back to the system.
-rw-r--r--sys/dev/pci/if_em.c25
-rw-r--r--sys/dev/pci/if_em.h3
2 files changed, 19 insertions, 9 deletions
diff --git a/sys/dev/pci/if_em.c b/sys/dev/pci/if_em.c
index eed5efe3fde..14a90e70ca1 100644
--- a/sys/dev/pci/if_em.c
+++ b/sys/dev/pci/if_em.c
@@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
-/* $OpenBSD: if_em.c,v 1.341 2018/04/07 11:56:40 sf Exp $ */
+/* $OpenBSD: if_em.c,v 1.342 2019/03/01 10:02:44 dlg Exp $ */
/* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */
#include <dev/pci/if_em.h>
@@ -250,6 +250,7 @@ void em_txeof(struct em_softc *);
int em_allocate_receive_structures(struct em_softc *);
int em_allocate_transmit_structures(struct em_softc *);
int em_rxfill(struct em_softc *);
+void em_rxrefill(void *);
int em_rxeof(struct em_softc *);
void em_receive_checksum(struct em_softc *, struct em_rx_desc *,
struct mbuf *);
@@ -375,6 +376,7 @@ em_attach(struct device *parent, struct device *self, void *aux)
timeout_set(&sc->timer_handle, em_local_timer, sc);
timeout_set(&sc->tx_fifo_timer_handle, em_82547_move_tail, sc);
+ timeout_set(&sc->rx_refill, em_rxrefill, sc);
/* Determine hardware revision */
em_identify_hardware(sc);
@@ -959,13 +961,8 @@ em_intr(void *arg)
if (ifp->if_flags & IFF_RUNNING) {
em_txeof(sc);
-
- if (em_rxeof(sc) || ISSET(reg_icr, E1000_ICR_RXO)) {
- if (em_rxfill(sc)) {
- E1000_WRITE_REG(&sc->hw, RDT,
- sc->sc_rx_desc_head);
- }
- }
+ if (em_rxeof(sc))
+ em_rxrefill(sc);
}
/* Link status change */
@@ -1534,6 +1531,7 @@ em_stop(void *arg, int softonly)
INIT_DEBUGOUT("em_stop: begin");
+ timeout_del(&sc->rx_refill);
timeout_del(&sc->timer_handle);
timeout_del(&sc->tx_fifo_timer_handle);
@@ -2755,6 +2753,17 @@ em_rxfill(struct em_softc *sc)
return (post);
}
+void
+em_rxrefill(void *arg)
+{
+ struct em_softc *sc = arg;
+
+ if (em_rxfill(sc))
+ E1000_WRITE_REG(&sc->hw, RDT, sc->sc_rx_desc_head);
+ else if (if_rxr_inuse(&sc->sc_rx_ring) == 0)
+ timeout_add(&sc->rx_refill, 1);
+}
+
/*********************************************************************
*
* This routine executes in interrupt context. It replenishes
diff --git a/sys/dev/pci/if_em.h b/sys/dev/pci/if_em.h
index 156a2ca1b7f..4294a133746 100644
--- a/sys/dev/pci/if_em.h
+++ b/sys/dev/pci/if_em.h
@@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
/* $FreeBSD: if_em.h,v 1.26 2004/09/01 23:22:41 pdeuskar Exp $ */
-/* $OpenBSD: if_em.h,v 1.73 2016/10/27 03:06:53 dlg Exp $ */
+/* $OpenBSD: if_em.h,v 1.74 2019/03/01 10:02:44 dlg Exp $ */
#ifndef _EM_H_DEFINED_
#define _EM_H_DEFINED_
@@ -324,6 +324,7 @@ struct em_softc {
struct timeout em_intr_enable;
struct timeout timer_handle;
struct timeout tx_fifo_timer_handle;
+ struct timeout rx_refill;
/* Info about the board itself */
u_int32_t part_num;