Date: Wed, 24 Jun 2009 21:09:56 +0000 (UTC) From: Andrew Gallatin <gallatin@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r194909 - head/sys/dev/mxge Message-ID: <200906242109.n5OL9uVb029380@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gallatin Date: Wed Jun 24 21:09:56 2009 New Revision: 194909 URL: http://svn.freebsd.org/changeset/base/194909 Log: Add a dying flag to prevent races at detach. I tried re-ordering ether_ifdetach(), but this created a new race where sometimes, when under heavy receive load (>1Mpps) and running tcpdump, the machine would panic. At panic, the ithread was still in the original (not dead) if_input() path, and was accessing stale BPF data structs. By using a dying flag, I can close the interface prior to if_detach() to be certain the interface cannot send packets up in the middle of ether_ifdetach. Modified: head/sys/dev/mxge/if_mxge.c head/sys/dev/mxge/if_mxge_var.h Modified: head/sys/dev/mxge/if_mxge.c ============================================================================== --- head/sys/dev/mxge/if_mxge.c Wed Jun 24 21:03:59 2009 (r194908) +++ head/sys/dev/mxge/if_mxge.c Wed Jun 24 21:09:56 2009 (r194909) @@ -3906,6 +3906,10 @@ mxge_ioctl(struct ifnet *ifp, u_long com case SIOCSIFFLAGS: mtx_lock(&sc->driver_mtx); + if (sc->dying) { + mtx_unlock(&sc->driver_mtx); + return EINVAL; + } if (ifp->if_flags & IFF_UP) { if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { err = mxge_open(sc); @@ -4590,6 +4594,7 @@ mxge_attach(device_t dev) mxge_media_status); mxge_set_media(sc, IFM_ETHER | IFM_AUTO); mxge_media_probe(sc); + sc->dying = 0; ether_ifattach(ifp, sc->mac_addr); /* ether_ifattach sets mtu to ETHERMTU */ if (mxge_initial_mtu != ETHERMTU) @@ -4637,6 +4642,7 @@ mxge_detach(device_t dev) return EBUSY; } mtx_lock(&sc->driver_mtx); + sc->dying = 1; if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING) mxge_close(sc); mtx_unlock(&sc->driver_mtx); Modified: head/sys/dev/mxge/if_mxge_var.h ============================================================================== --- head/sys/dev/mxge/if_mxge_var.h Wed Jun 24 21:03:59 2009 (r194908) +++ head/sys/dev/mxge/if_mxge_var.h Wed Jun 24 21:09:56 2009 (r194909) @@ -266,6 +266,7 @@ struct mxge_softc { int need_media_probe; int num_slices; int rx_ring_size; + int dying; mxge_dma_t dmabench_dma; struct callout co_hdl; struct sysctl_oid *slice_sysctl_tree;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906242109.n5OL9uVb029380>