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;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to