From e9ace2571cdd02fe56a731a744a03c74a1294d8b Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Fri, 20 May 2005 07:16:09 +0000 Subject: [PATCH] Calling xl_rxeof() at the end of xl_start_locked() leads to recursion in case of IP fast forwarding. Enqueue a taskqueue(9) task instead of calling xl_rxeof() directly. Reported & tested by: Slava Alpatov Reviewed by: wpaul MFC after: 1 week --- sys/pci/if_xl.c | 20 +++++++++++++++++++- sys/pci/if_xlreg.h | 1 + 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/sys/pci/if_xl.c b/sys/pci/if_xl.c index 498e1c4548b6..074166793101 100644 --- a/sys/pci/if_xl.c +++ b/sys/pci/if_xl.c @@ -109,6 +109,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -228,6 +229,7 @@ static void xl_stats_update(void *); static void xl_stats_update_locked(struct xl_softc *); static int xl_encap(struct xl_softc *, struct xl_chain *, struct mbuf *); static void xl_rxeof(struct xl_softc *); +static void xl_rxeof_task(void *, int); static int xl_rx_resync(struct xl_softc *); static void xl_txeof(struct xl_softc *); static void xl_txeof_90xB(struct xl_softc *); @@ -1368,6 +1370,7 @@ xl_attach(device_t dev) sc->xl_unit = unit; callout_handle_init(&sc->xl_stat_ch); + TASK_INIT(&sc->xl_task, 0, xl_rxeof_task, sc); bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); /* @@ -2084,6 +2087,19 @@ xl_rxeof(struct xl_softc *sc) } } +/* + * Taskqueue wrapper for xl_rxeof(). + */ +static void +xl_rxeof_task(void *arg, int pending) +{ + struct xl_softc *sc = (struct xl_softc *)arg; + + XL_LOCK(sc); + xl_rxeof(sc); + XL_UNLOCK(sc); +} + /* * A frame was downloaded to the chip. It's safe for us to clean up * the list buffers. @@ -2683,7 +2699,7 @@ xl_start_locked(struct ifnet *ifp) * nature of their chips in all their marketing literature; * we may as well take advantage of it. :) */ - xl_rxeof(sc); + taskqueue_enqueue(taskqueue_swi, &sc->xl_task); } static void @@ -3254,6 +3270,8 @@ xl_stop(struct xl_softc *sc) ether_poll_deregister(ifp); #endif /* DEVICE_POLLING */ + taskqueue_drain(taskqueue_swi, &sc->xl_task); + CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_DISABLE); CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_DISABLE); CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB); diff --git a/sys/pci/if_xlreg.h b/sys/pci/if_xlreg.h index 8fbcc53fe7dd..6b2829f333ec 100644 --- a/sys/pci/if_xlreg.h +++ b/sys/pci/if_xlreg.h @@ -607,6 +607,7 @@ struct xl_softc { bus_space_handle_t xl_fhandle; bus_space_tag_t xl_ftag; struct mtx xl_mtx; + struct task xl_task; #ifdef DEVICE_POLLING int rxcycles; #endif