diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2019-07-30 12:11:43 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2019-07-30 12:11:43 +0000 |
commit | b0c4777b4dd02e928b62ac0b2be79a88acd33c1d (patch) | |
tree | 70c27a6b51827b8e7cf0aa6394c408a44a9241e1 /sys | |
parent | 425d13d54354426bea6b6e14f76f676a8b9f7524 (diff) |
push rxed packets to the stack once per interrupt (per port)
pushing to the stack on every packet completion interacts badly
with the backpressure mechanism in ifiq_input when you rx more than
8 or so packets per interrupt.
while here move to ifiq_input and apply backpressure before we start
dropping in software.
the problem was found by olivier taibi and reported on bugs@
i tested this on an overdrive 1000 which uses msk for its onboard nic
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/if_msk.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/sys/dev/pci/if_msk.c b/sys/dev/pci/if_msk.c index 05c7fc9b60d..52d76518eb9 100644 --- a/sys/dev/pci/if_msk.c +++ b/sys/dev/pci/if_msk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_msk.c,v 1.131 2018/01/06 03:11:04 dlg Exp $ */ +/* $OpenBSD: if_msk.c,v 1.132 2019/07/30 12:11:42 dlg Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 @@ -134,7 +134,7 @@ int mskcprint(void *, const char *); int msk_intr(void *); void msk_intr_yukon(struct sk_if_softc *); static inline int msk_rxvalid(struct sk_softc *, u_int32_t, u_int32_t); -void msk_rxeof(struct sk_if_softc *, uint16_t, uint32_t); +void msk_rxeof(struct sk_if_softc *, struct mbuf_list *, uint16_t, uint32_t); void msk_txeof(struct sk_if_softc *); static unsigned int msk_encap(struct sk_if_softc *, struct mbuf *, uint32_t); void msk_start(struct ifnet *); @@ -1591,11 +1591,11 @@ msk_rxvalid(struct sk_softc *sc, u_int32_t stat, u_int32_t len) } void -msk_rxeof(struct sk_if_softc *sc_if, uint16_t len, uint32_t rxstat) +msk_rxeof(struct sk_if_softc *sc_if, struct mbuf_list *ml, + uint16_t len, uint32_t rxstat) { struct sk_softc *sc = sc_if->sk_softc; struct ifnet *ifp = &sc_if->arpcom.ac_if; - struct mbuf_list ml = MBUF_LIST_INITIALIZER(); struct mbuf *m = NULL; int prod, cons, tail; bus_dmamap_t map; @@ -1640,8 +1640,7 @@ msk_rxeof(struct sk_if_softc *sc_if, uint16_t len, uint32_t rxstat) m->m_pkthdr.len = m->m_len = len; - ml_enqueue(&ml, m); - if_input(ifp, &ml); + ml_enqueue(ml, m); } void @@ -1770,8 +1769,12 @@ msk_intr(void *xsc) struct sk_if_softc *sc_if; struct sk_if_softc *sc_if0 = sc->sk_if[SK_PORT_A]; struct sk_if_softc *sc_if1 = sc->sk_if[SK_PORT_B]; + struct mbuf_list ml[2] = { + MBUF_LIST_INITIALIZER(), + MBUF_LIST_INITIALIZER(), + }; struct ifnet *ifp0 = NULL, *ifp1 = NULL; - int claimed = 0, rx[2] = {0, 0}; + int claimed = 0; u_int32_t status; struct msk_status_desc *cur_st; @@ -1809,8 +1812,8 @@ msk_intr(void *xsc) switch (cur_st->sk_opcode) { case SK_Y2_STOPC_RXSTAT: sc_if = sc->sk_if[cur_st->sk_link & 0x01]; - rx[cur_st->sk_link & 0x01] = 1; - msk_rxeof(sc_if, lemtoh16(&cur_st->sk_len), + msk_rxeof(sc_if, &ml[cur_st->sk_link & 0x01], + lemtoh16(&cur_st->sk_len), lemtoh32(&cur_st->sk_status)); break; case SK_Y2_STOPC_TXSTAT: @@ -1837,12 +1840,16 @@ msk_intr(void *xsc) CSR_WRITE_4(sc, SK_Y2_ICR, 2); - if (rx[0]) { + if (!ml_empty(&ml[0])) { + if (ifiq_input(&ifp0->if_rcv, &ml[0])) + if_rxr_livelocked(&sc_if0->sk_cdata.sk_rx_ring); msk_fill_rx_ring(sc_if0); SK_IF_WRITE_2(sc_if0, 0, SK_RXQ1_Y2_PREF_PUTIDX, sc_if0->sk_cdata.sk_rx_prod); } - if (rx[1]) { + if (!ml_empty(&ml[1])) { + if (ifiq_input(&ifp1->if_rcv, &ml[1])) + if_rxr_livelocked(&sc_if1->sk_cdata.sk_rx_ring); msk_fill_rx_ring(sc_if1); SK_IF_WRITE_2(sc_if1, 0, SK_RXQ1_Y2_PREF_PUTIDX, sc_if1->sk_cdata.sk_rx_prod); |