From 3c7587607776f143f9793ad05356ba5ac0941a0e Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Tue, 3 Jan 2012 09:18:28 -0800 Subject: [PATCH] kernel - Fix a case in if_re which could lockup the system * if_re's re_start function was not always properly setting IFF_OACTIVE in situations where packets would be left on the if_snd queue, causing if_start_dispatch() to get into an endless message loop. * Add debugging to device_printf() when the case occurs. --- sys/dev/netif/re/if_re.c | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/sys/dev/netif/re/if_re.c b/sys/dev/netif/re/if_re.c index 6231be4..34d7b9a 100644 --- a/sys/dev/netif/re/if_re.c +++ b/sys/dev/netif/re/if_re.c @@ -2468,6 +2468,21 @@ re_start(struct ifnet *ifp) ETHER_BPF_MTAP(ifp, m_head); } + /* + * If sc->re_ldata.re_tx_mbuf[idx] is not NULL it is possible + * for IFF_OACTIVE to not be properly set when we also do not + * have sufficient free tx descriptors, leaving packet in + * ifp->if_send. This can cause if_start_dispatch() to loop + * infinitely so make sure IFF_OACTIVE is set properly. + */ + if (sc->re_ldata.re_tx_free <= RE_TXDESC_SPARE) { + if ((ifp->if_flags & IFF_OACTIVE) == 0) { + device_printf(sc->re_dev, + "Debug: IFF_OACTIVE was not set when" + " re_tx_free was below minimum!\n"); + ifp->if_flags |= IFF_OACTIVE; + } + } if (!need_trans) return; -- 1.7.7.2