From adc9980a597ff6f92068d01260fb720e5b06ebe2 Mon Sep 17 00:00:00 2001 From: David Gwynne Date: Wed, 4 Jan 2017 01:47:33 +0000 Subject: 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 --- sys/dev/ic/re.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'sys') 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; } -- cgit v1.2.3