summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2017-01-04 01:47:33 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2017-01-04 01:47:33 +0000
commitadc9980a597ff6f92068d01260fb720e5b06ebe2 (patch)
treecaf338f06707fb8a2315206acd14068da6227242 /sys/dev
parent8996527be20dee64915a18af947e1178231e5c78 (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/dev')
-rw-r--r--sys/dev/ic/re.c8
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;
}