summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2019-07-30 12:11:43 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2019-07-30 12:11:43 +0000
commitb0c4777b4dd02e928b62ac0b2be79a88acd33c1d (patch)
tree70c27a6b51827b8e7cf0aa6394c408a44a9241e1 /sys
parent425d13d54354426bea6b6e14f76f676a8b9f7524 (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.c29
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);