diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2017-01-04 01:47:33 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2017-01-04 01:47:33 +0000 |
commit | adc9980a597ff6f92068d01260fb720e5b06ebe2 (patch) | |
tree | caf338f06707fb8a2315206acd14068da6227242 /sys | |
parent | 8996527be20dee64915a18af947e1178231e5c78 (diff) |
better handle empty or full rx rings.
currently re appears to end up spinning on landisk. the most obvious
cause of this would be an inability to add entries on the rx ring
when we run out of mbufs. cope with this by calling rxeof from the
isr when the FIFO_OVERFLOW status bit is set. rxeof in turn
unconditionally tries to fill the rx ring, even if it doesnt dequeue
any packets off the ring.
while here limit the number of entries that can go on the rx ring
to 1 less than the size of the ring. a full ring looks the same as
an empty ring (cos the producer and consumer are the same in both
cases), so avoid letting this happen.
ok deraadt@ who hit problems on his landisk and tested this diff
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ic/re.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/sys/dev/ic/re.c b/sys/dev/ic/re.c index f7f6fa24306..4a9c7b28059 100644 --- a/sys/dev/ic/re.c +++ b/sys/dev/ic/re.c @@ -1,4 +1,4 @@ -/* $OpenBSD: re.c,v 1.198 2016/11/16 06:06:04 dlg Exp $ */ +/* $OpenBSD: re.c,v 1.199 2017/01/04 01:47:32 dlg Exp $ */ /* $FreeBSD: if_re.c,v 1.31 2004/09/04 07:54:05 ru Exp $ */ /* * Copyright (c) 1997, 1998-2003 @@ -1213,7 +1213,8 @@ re_rx_list_init(struct rl_softc *sc) sc->rl_ldata.rl_rx_considx = 0; sc->rl_head = sc->rl_tail = NULL; - if_rxr_init(&sc->rl_ldata.rl_rx_ring, 2, sc->rl_ldata.rl_rx_desc_cnt); + if_rxr_init(&sc->rl_ldata.rl_rx_ring, 2, + sc->rl_ldata.rl_rx_desc_cnt - 1); re_rx_list_fill(sc); return (0); @@ -1520,7 +1521,8 @@ re_intr(void *arg) claimed = 1; if (status & RL_INTRS_CPLUS) { - if (status & (sc->rl_rx_ack | RL_ISR_RX_ERR)) { + if (status & + (sc->rl_rx_ack | RL_ISR_RX_ERR | RL_ISR_FIFO_OFLOW)) { rx |= re_rxeof(sc); claimed = 1; } |