Author: sephe
Date: Thu Dec 29 06:13:00 2016
New Revision: 310738
URL: https://svnweb.freebsd.org/changeset/base/310738

Log:
  MFC 308907
  
      hyperv/hn: Fix WITNESS warnings
  
      And re-enable SIOCADDMULTI/SIOCDELMULTI, after WITNESS warning is fixed.
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D8489

Modified:
  stable/10/sys/dev/hyperv/netvsc/hn_nvs.c
  stable/10/sys/dev/hyperv/netvsc/hn_rndis.c
  stable/10/sys/dev/hyperv/netvsc/if_hn.c
  stable/10/sys/dev/hyperv/netvsc/if_hnvar.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/hyperv/netvsc/hn_nvs.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hn_nvs.c    Thu Dec 29 06:10:38 2016        
(r310737)
+++ stable/10/sys/dev/hyperv/netvsc/hn_nvs.c    Thu Dec 29 06:13:00 2016        
(r310738)
@@ -109,7 +109,10 @@ hn_nvs_xact_execute(struct hn_softc *sc,
                vmbus_xact_deactivate(xact);
                return (NULL);
        }
-       hdr = vmbus_xact_wait(xact, &resplen);
+       if (HN_CAN_SLEEP(sc))
+               hdr = vmbus_xact_wait(xact, &resplen);
+       else
+               hdr = vmbus_xact_busywait(xact, &resplen);
 
        /*
         * Check this NVS response message.

Modified: stable/10/sys/dev/hyperv/netvsc/hn_rndis.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hn_rndis.c  Thu Dec 29 06:10:38 2016        
(r310737)
+++ stable/10/sys/dev/hyperv/netvsc/hn_rndis.c  Thu Dec 29 06:13:00 2016        
(r310738)
@@ -233,7 +233,10 @@ hn_rndis_xact_exec1(struct hn_softc *sc,
                if_printf(sc->hn_ifp, "RNDIS ctrl send failed: %d\n", error);
                return (NULL);
        }
-       return (vmbus_xact_wait(xact, comp_len));
+       if (HN_CAN_SLEEP(sc))
+               return (vmbus_xact_wait(xact, comp_len));
+       else
+               return (vmbus_xact_busywait(xact, comp_len));
 }
 
 static const void *

Modified: stable/10/sys/dev/hyperv/netvsc/if_hn.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/if_hn.c     Thu Dec 29 06:10:38 2016        
(r310737)
+++ stable/10/sys/dev/hyperv/netvsc/if_hn.c     Thu Dec 29 06:13:00 2016        
(r310738)
@@ -152,7 +152,11 @@ __FBSDID("$FreeBSD$");
        sx_init(&(sc)->hn_lock, device_get_nameunit((sc)->hn_dev))
 #define HN_LOCK_DESTROY(sc)            sx_destroy(&(sc)->hn_lock)
 #define HN_LOCK_ASSERT(sc)             sx_assert(&(sc)->hn_lock, SA_XLOCKED)
-#define HN_LOCK(sc)                    sx_xlock(&(sc)->hn_lock)
+#define HN_LOCK(sc)                                    \
+do {                                                   \
+       while (sx_try_xlock(&(sc)->hn_lock) == 0)       \
+               DELAY(1000);                            \
+} while (0)
 #define HN_UNLOCK(sc)                  sx_xunlock(&(sc)->hn_lock)
 
 #define HN_CSUM_IP_MASK                        (CSUM_IP | CSUM_IP_TCP | 
CSUM_IP_UDP)
@@ -670,18 +674,10 @@ hn_set_rxfilter(struct hn_softc *sc)
                filter = NDIS_PACKET_TYPE_DIRECTED;
                if (ifp->if_flags & IFF_BROADCAST)
                        filter |= NDIS_PACKET_TYPE_BROADCAST;
-#ifdef notyet
-               /*
-                * See the comment in SIOCADDMULTI/SIOCDELMULTI.
-                */
                /* TODO: support multicast list */
                if ((ifp->if_flags & IFF_ALLMULTI) ||
                    !TAILQ_EMPTY(&ifp->if_multiaddrs))
                        filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
-#else
-               /* Always enable ALLMULTI */
-               filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
-#endif
        }
 
        if (sc->hn_rx_filter != filter) {
@@ -2364,10 +2360,18 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, 
                }
 
                if (ifp->if_flags & IFF_UP) {
-                       if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+                       if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+                               /*
+                                * Caller meight hold mutex, e.g.
+                                * bpf; use busy-wait for the RNDIS
+                                * reply.
+                                */
+                               HN_NO_SLEEPING(sc);
                                hn_set_rxfilter(sc);
-                       else
+                               HN_SLEEPING_OK(sc);
+                       } else {
                                hn_init_locked(sc);
+                       }
                } else {
                        if (ifp->if_drv_flags & IFF_DRV_RUNNING)
                                hn_stop(sc);
@@ -2428,27 +2432,23 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, 
 
        case SIOCADDMULTI:
        case SIOCDELMULTI:
-#ifdef notyet
-               /*
-                * XXX
-                * Multicast uses mutex, while RNDIS RX filter setting
-                * sleeps.  We workaround this by always enabling
-                * ALLMULTI.  ALLMULTI would actually always be on, even
-                * if we supported the SIOCADDMULTI/SIOCDELMULTI, since
-                * we don't support multicast address list configuration
-                * for this driver.
-                */
                HN_LOCK(sc);
 
                if ((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0) {
                        HN_UNLOCK(sc);
                        break;
                }
-               if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+               if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+                       /*
+                        * Multicast uses mutex; use busy-wait for
+                        * the RNDIS reply.
+                        */
+                       HN_NO_SLEEPING(sc);
                        hn_set_rxfilter(sc);
+                       HN_SLEEPING_OK(sc);
+               }
 
                HN_UNLOCK(sc);
-#endif
                break;
 
        case SIOCSIFMEDIA:

Modified: stable/10/sys/dev/hyperv/netvsc/if_hnvar.h
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/if_hnvar.h  Thu Dec 29 06:10:38 2016        
(r310737)
+++ stable/10/sys/dev/hyperv/netvsc/if_hnvar.h  Thu Dec 29 06:13:00 2016        
(r310738)
@@ -237,6 +237,20 @@ struct hn_softc {
 #define HN_FLAG_HAS_RSSKEY             0x0004
 #define HN_FLAG_HAS_RSSIND             0x0008
 #define HN_FLAG_SYNTH_ATTACHED         0x0010
+#define HN_FLAG_NO_SLEEPING            0x0020
+
+#define HN_NO_SLEEPING(sc)                     \
+do {                                           \
+       (sc)->hn_flags |= HN_FLAG_NO_SLEEPING;  \
+} while (0)
+
+#define HN_SLEEPING_OK(sc)                     \
+do {                                           \
+       (sc)->hn_flags &= ~HN_FLAG_NO_SLEEPING; \
+} while (0)
+
+#define HN_CAN_SLEEP(sc)               \
+       (((sc)->hn_flags & HN_FLAG_NO_SLEEPING) == 0)
 
 #define HN_CAP_VLAN                    0x0001
 #define HN_CAP_MTU                     0x0002
_______________________________________________
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