Author: sephe
Date: Fri Oct 14 03:26:24 2016
New Revision: 307255
URL: https://svnweb.freebsd.org/changeset/base/307255

Log:
  MFC 306431,306432
  
  306431
      hyperv/hn: Move TX tasks' draining into hn_suspend().
  
      This prepares to consolidate hn_stop() and netvsc_detach().
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D8055
  
  306432
      hyperv/hn: Consolidate hn_init() and hn_stop()
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D8056

Modified:
  stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c     Fri Oct 14 
03:22:19 2016        (r307254)
+++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c     Fri Oct 14 
03:26:24 2016        (r307255)
@@ -336,7 +336,6 @@ static void hn_fixup_tx_data(struct hn_s
 static void hn_destroy_tx_data(struct hn_softc *);
 static void hn_start_taskfunc(void *, int);
 static void hn_start_txeof_taskfunc(void *, int);
-static void hn_stop_tx_tasks(struct hn_softc *);
 static int hn_encap(struct hn_tx_ring *, struct hn_txdesc *, struct mbuf **);
 static int hn_create_rx_data(struct hn_softc *sc, int);
 static void hn_destroy_rx_data(struct hn_softc *sc);
@@ -352,6 +351,8 @@ static void hn_synth_detach(struct hn_so
 static bool hn_tx_ring_pending(struct hn_tx_ring *);
 static void hn_suspend(struct hn_softc *);
 static void hn_resume(struct hn_softc *);
+static void hn_rx_drain(struct vmbus_channel *);
+static void hn_tx_resume(struct hn_softc *, int);
 static void hn_tx_ring_qflush(struct hn_tx_ring *);
 
 static void hn_nvs_handle_notify(struct hn_softc *sc,
@@ -773,8 +774,6 @@ netvsc_detach(device_t dev)
        hn_synth_detach(sc);
        HN_UNLOCK(sc);
 
-       hn_stop_tx_tasks(sc);
-
        ifmedia_removeall(&sc->hn_media);
        hn_destroy_rx_data(sc);
        hn_destroy_tx_data(sc);
@@ -1796,25 +1795,19 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, 
 static void
 hn_stop(struct hn_softc *sc)
 {
-       struct ifnet *ifp;
+       struct ifnet *ifp = sc->hn_ifp;
        int i;
 
        HN_LOCK_ASSERT(sc);
 
-       ifp = sc->hn_ifp;
-
-       if (bootverbose)
-               printf(" Closing Device ...\n");
+       /* Clear RUNNING bit _before_ hn_suspend() */
+       atomic_clear_int(&ifp->if_drv_flags, IFF_DRV_RUNNING);
+       hn_suspend(sc);
 
-       atomic_clear_int(&ifp->if_drv_flags,
-           (IFF_DRV_RUNNING | IFF_DRV_OACTIVE));
+       /* Clear OACTIVE bit. */
+       atomic_clear_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE);
        for (i = 0; i < sc->hn_tx_ring_inuse; ++i)
                sc->hn_tx_ring[i].hn_oactive = 0;
-
-       if_link_state_change(ifp, LINK_STATE_DOWN);
-
-       /* Disable RX by clearing RX filter. */
-       hn_rndis_set_rxfilter(sc, 0);
 }
 
 /*
@@ -1878,27 +1871,29 @@ do_sched:
 static void
 hn_init_locked(struct hn_softc *sc)
 {
-       struct ifnet *ifp;
-       int ret, i;
+       struct ifnet *ifp = sc->hn_ifp;
+       int i;
 
        HN_LOCK_ASSERT(sc);
 
-       ifp = sc->hn_ifp;
-
-       if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+       if (ifp->if_drv_flags & IFF_DRV_RUNNING)
                return;
-       }
 
        /* TODO: add hn_rx_filter */
-       ret = hn_rndis_set_rxfilter(sc, NDIS_PACKET_TYPE_PROMISCUOUS);
-       if (ret != 0)
-               return;
+       hn_rndis_set_rxfilter(sc, NDIS_PACKET_TYPE_PROMISCUOUS);
 
+       /* Clear OACTIVE bit. */
        atomic_clear_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE);
        for (i = 0; i < sc->hn_tx_ring_inuse; ++i)
                sc->hn_tx_ring[i].hn_oactive = 0;
 
+       /* Clear TX 'suspended' bit. */
+       hn_tx_resume(sc, sc->hn_tx_ring_inuse);
+
+       /* Everything is ready; unleash! */
        atomic_set_int(&ifp->if_drv_flags, IFF_DRV_RUNNING);
+
+       /* TODO: check RNDIS link status. */
        if_link_state_change(ifp, LINK_STATE_UP);
 }
 
@@ -2991,19 +2986,6 @@ hn_start_txeof_taskfunc(void *xtxr, int 
        mtx_unlock(&txr->hn_tx_lock);
 }
 
-static void
-hn_stop_tx_tasks(struct hn_softc *sc)
-{
-       int i;
-
-       for (i = 0; i < sc->hn_tx_ring_inuse; ++i) {
-               struct hn_tx_ring *txr = &sc->hn_tx_ring[i];
-
-               taskqueue_drain(txr->hn_tx_taskq, &txr->hn_tx_task);
-               taskqueue_drain(txr->hn_tx_taskq, &txr->hn_txeof_task);
-       }
-}
-
 static int
 hn_xmit(struct hn_tx_ring *txr, int len)
 {
@@ -3591,6 +3573,9 @@ hn_suspend(struct hn_softc *sc)
                /* Wait for all pending sends to finish. */
                while (hn_tx_ring_pending(txr))
                        pause("hnwtx", 1 /* 1 tick */);
+
+               taskqueue_drain(txr->hn_tx_taskq, &txr->hn_tx_task);
+               taskqueue_drain(txr->hn_tx_taskq, &txr->hn_txeof_task);
        }
 
        /*
@@ -3621,9 +3606,25 @@ hn_suspend(struct hn_softc *sc)
 }
 
 static void
+hn_tx_resume(struct hn_softc *sc, int tx_ring_cnt)
+{
+       int i;
+
+       KASSERT(tx_ring_cnt <= sc->hn_tx_ring_cnt,
+           ("invalid TX ring count %d", tx_ring_cnt));
+
+       for (i = 0; i < tx_ring_cnt; ++i) {
+               struct hn_tx_ring *txr = &sc->hn_tx_ring[i];
+
+               mtx_lock(&txr->hn_tx_lock);
+               txr->hn_suspended = 0;
+               mtx_unlock(&txr->hn_tx_lock);
+       }
+}
+
+static void
 hn_resume(struct hn_softc *sc)
 {
-       struct hn_tx_ring *txr;
        int i;
 
        HN_LOCK_ASSERT(sc);
@@ -3638,13 +3639,7 @@ hn_resume(struct hn_softc *sc)
         * Make sure to clear suspend status on "all" TX rings,
         * since hn_tx_ring_inuse can be changed after hn_suspend().
         */
-       for (i = 0; i < sc->hn_tx_ring_cnt; ++i) {
-               txr = &sc->hn_tx_ring[i];
-
-               mtx_lock(&txr->hn_tx_lock);
-               txr->hn_suspended = 0;
-               mtx_unlock(&txr->hn_tx_lock);
-       }
+       hn_tx_resume(sc, sc->hn_tx_ring_cnt);
 
        if (!hn_use_if_start) {
                /*
@@ -3659,7 +3654,8 @@ hn_resume(struct hn_softc *sc)
         * Kick start TX.
         */
        for (i = 0; i < sc->hn_tx_ring_inuse; ++i) {
-               txr = &sc->hn_tx_ring[i];
+               struct hn_tx_ring *txr = &sc->hn_tx_ring[i];
+
                /*
                 * Use txeof task, so that any pending oactive can be
                 * cleared properly.
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to