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-all mailing list