svn commit: r194909 - head/sys/dev/mxge
Andrew Gallatin
gallatin at FreeBSD.org
Wed Jun 24 21:09:58 UTC 2009
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;
More information about the svn-src-head
mailing list