From: Matthew Dillon Date: Tue, 3 Jan 2012 17:18:28 +0000 (-0800) Subject: kernel - Fix a case in if_re which could lockup the system X-Git-Tag: v3.0.0~191 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/3c7587607776f143f9793ad05356ba5ac0941a0e?hp=e43987e0d95a259c9e35a3d70b8875d290b89af6 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. --- diff --git a/sys/dev/netif/re/if_re.c b/sys/dev/netif/re/if_re.c index 6231be43c8..34d7b9a9a4 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;