Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Nov 2016 05:21:15 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r308907 - head/sys/dev/hyperv/netvsc
Message-ID:  <201611210521.uAL5LFeP071731@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Mon Nov 21 05:21:15 2016
New Revision: 308907
URL: https://svnweb.freebsd.org/changeset/base/308907

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

Modified:
  head/sys/dev/hyperv/netvsc/hn_nvs.c
  head/sys/dev/hyperv/netvsc/hn_rndis.c
  head/sys/dev/hyperv/netvsc/if_hn.c
  head/sys/dev/hyperv/netvsc/if_hnvar.h

Modified: head/sys/dev/hyperv/netvsc/hn_nvs.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hn_nvs.c	Mon Nov 21 05:09:43 2016	(r308906)
+++ head/sys/dev/hyperv/netvsc/hn_nvs.c	Mon Nov 21 05:21:15 2016	(r308907)
@@ -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: head/sys/dev/hyperv/netvsc/hn_rndis.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hn_rndis.c	Mon Nov 21 05:09:43 2016	(r308906)
+++ head/sys/dev/hyperv/netvsc/hn_rndis.c	Mon Nov 21 05:21:15 2016	(r308907)
@@ -232,7 +232,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: head/sys/dev/hyperv/netvsc/if_hn.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/if_hn.c	Mon Nov 21 05:09:43 2016	(r308906)
+++ head/sys/dev/hyperv/netvsc/if_hn.c	Mon Nov 21 05:21:15 2016	(r308907)
@@ -149,7 +149,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)
@@ -667,18 +671,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) {
@@ -2338,10 +2334,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);
@@ -2402,27 +2406,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: head/sys/dev/hyperv/netvsc/if_hnvar.h
==============================================================================
--- head/sys/dev/hyperv/netvsc/if_hnvar.h	Mon Nov 21 05:09:43 2016	(r308906)
+++ head/sys/dev/hyperv/netvsc/if_hnvar.h	Mon Nov 21 05:21:15 2016	(r308907)
@@ -236,6 +236,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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611210521.uAL5LFeP071731>