svn commit: r305763 - head/sys/dev/hyperv/netvsc

Sepherosa Ziehau sephe at FreeBSD.org
Tue Sep 13 05:54:33 UTC 2016


Author: sephe
Date: Tue Sep 13 05:54:31 2016
New Revision: 305763
URL: https://svnweb.freebsd.org/changeset/base/305763

Log:
  hyperv/hn: Reorganize synthetic parts attach code.
  
  MFC after:	1 week
  Sponsored by:	Microsoft
  Differential Revision:	https://reviews.freebsd.org/D7860

Modified:
  head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
  head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
  head/sys/dev/hyperv/netvsc/hv_rndis_filter.h
  head/sys/dev/hyperv/netvsc/if_hnvar.h

Modified: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c	Tue Sep 13 05:47:59 2016	(r305762)
+++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c	Tue Sep 13 05:54:31 2016	(r305763)
@@ -350,6 +350,7 @@ static int hn_attach_subchans(struct hn_
 static void hn_detach_allchans(struct hn_softc *);
 static void hn_chan_callback(struct vmbus_channel *chan, void *xrxr);
 static void hn_set_ring_inuse(struct hn_softc *, int);
+static int hn_synth_attach(struct hn_softc *, int);
 
 static void hn_nvs_handle_notify(struct hn_softc *sc,
 		const struct vmbus_chanpkt_hdr *pkt);
@@ -531,29 +532,9 @@ netvsc_attach(device_t dev)
 		goto failed;
 
 	/*
-	 * Attach the primary channel before attaching NVS and RNDIS.
+	 * Attach the synthetic parts, i.e. NVS and RNDIS.
 	 */
-	error = hn_chan_attach(sc, sc->hn_prichan);
-	if (error)
-		goto failed;
-
-	/*
-	 * Attach NVS and RNDIS (synthetic parts).
-	 */
-	error = hv_rf_on_device_add(sc, &ring_cnt, ETHERMTU);
-	if (error)
-		goto failed;
-
-	/*
-	 * Set the # of TX/RX rings that could be used according to
-	 * the # of channels that host offered.
-	 */
-	hn_set_ring_inuse(sc, ring_cnt);
-
-	/*
-	 * Attach the sub-channels, if any.
-	 */
-	error = hn_attach_subchans(sc);
+	error = hn_synth_attach(sc, ETHERMTU);
 	if (error)
 		goto failed;
 
@@ -1513,7 +1494,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, 
 #ifdef INET
 	struct ifaddr *ifa = (struct ifaddr *)data;
 #endif
-	int mask, error = 0, ring_cnt;
+	int mask, error = 0;
 	int retry_cnt = 500;
 	
 	switch(cmd) {
@@ -1590,29 +1571,10 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, 
 		hn_detach_allchans(sc);
 
 		/*
-		 * Attach the primary channel before attaching NVS and RNDIS.
-		 */
-		hn_chan_attach(sc, sc->hn_prichan);
-
-		ring_cnt = sc->hn_rx_ring_cnt;
-		error = hv_rf_on_device_add(sc, &ring_cnt, ifr->ifr_mtu);
-		if (error) {
-			NV_LOCK(sc);
-			sc->temp_unusable = FALSE;
-			NV_UNLOCK(sc);
-			break;
-		}
-
-		/*
-		 * Set the # of TX/RX rings that could be used according to
-		 * the # of channels that host offered.
+		 * Attach the synthetic parts, i.e. NVS and RNDIS.
+		 * XXX check error.
 		 */
-		hn_set_ring_inuse(sc, ring_cnt);
-
-		/*
-		 * Attach the sub-channels, if any.
-		 */
-		hn_attach_subchans(sc); /* XXX check error */
+		hn_synth_attach(sc, ifr->ifr_mtu);
 
 		if (sc->hn_tx_ring[0].hn_chim_size > sc->hn_chim_szmax)
 			hn_set_chim_size(sc, sc->hn_chim_szmax);
@@ -3065,17 +3027,13 @@ hn_attach_subchans(struct hn_softc *sc)
 	if (subchan_cnt == 0)
 		return (0);
 
-	/* Wait for sub-channels setup to complete. */
-	subchans = vmbus_subchan_get(sc->hn_prichan, subchan_cnt);
-
 	/* Attach the sub-channels. */
+	subchans = vmbus_subchan_get(sc->hn_prichan, subchan_cnt);
 	for (i = 0; i < subchan_cnt; ++i) {
 		error = hn_chan_attach(sc, subchans[i]);
 		if (error)
 			break;
 	}
-
-	/* Release the sub-channels */
 	vmbus_subchan_rel(subchans, subchan_cnt);
 
 	if (error) {
@@ -3129,6 +3087,132 @@ back:
 #endif
 }
 
+static int
+hn_synth_alloc_subchans(struct hn_softc *sc, int *nsubch)
+{
+	struct vmbus_channel **subchans;
+	int nchan, rxr_cnt, error;
+
+	nchan = *nsubch + 1;
+	if (sc->hn_ndis_ver < HN_NDIS_VERSION_6_30 || nchan == 1) {
+		/*
+		 * Either RSS is not supported, or multiple RX/TX rings
+		 * are not requested.
+		 */
+		*nsubch = 0;
+		return (0);
+	}
+
+	/*
+	 * Get RSS capabilities, e.g. # of RX rings, and # of indirect
+	 * table entries.
+	 */
+	error = hn_rndis_get_rsscaps(sc, &rxr_cnt);
+	if (error) {
+		/* No RSS; this is benign. */
+		*nsubch = 0;
+		return (0);
+	}
+	if_printf(sc->hn_ifp, "RX rings offered %u, requested %d\n",
+	    rxr_cnt, nchan);
+
+	if (nchan > rxr_cnt)
+		nchan = rxr_cnt;
+	if (nchan == 1) {
+		if_printf(sc->hn_ifp, "only 1 channel is supported, no vRSS\n");
+		*nsubch = 0;
+		return (0);
+	}
+	
+	/*
+	 * Allocate sub-channels from NVS.
+	 */
+	*nsubch = nchan - 1;
+	error = hn_nvs_alloc_subchans(sc, nsubch);
+	if (error || *nsubch == 0) {
+		/* Failed to allocate sub-channels. */
+		*nsubch = 0;
+		return (0);
+	}
+
+	/*
+	 * Wait for all sub-channels to become ready before moving on.
+	 */
+	subchans = vmbus_subchan_get(sc->hn_prichan, *nsubch);
+	vmbus_subchan_rel(subchans, *nsubch);
+	return (0);
+}
+
+static int
+hn_synth_attach(struct hn_softc *sc, int mtu)
+{
+	int error, nsubch;
+
+	/*
+	 * Attach the primary channel _before_ attaching NVS and RNDIS.
+	 */
+	error = hn_chan_attach(sc, sc->hn_prichan);
+	if (error)
+		return (error);
+
+	/*
+	 * Attach NVS.
+	 */
+	error = hn_nvs_attach(sc, mtu);
+	if (error)
+		return (error);
+
+	/*
+	 * Attach RNDIS _after_ NVS is attached.
+	 */
+	error = hn_rndis_attach(sc);
+	if (error)
+		return (error);
+
+	/*
+	 * Allocate sub-channels for multi-TX/RX rings.
+	 *
+	 * NOTE:
+	 * The # of RX rings that can be used is equivalent to the # of
+	 * channels to be requested.
+	 */
+	nsubch = sc->hn_rx_ring_cnt - 1;
+	error = hn_synth_alloc_subchans(sc, &nsubch);
+	if (error)
+		return (error);
+	if (nsubch == 0) {
+		/* Only the primary channel can be used; done */
+		goto back;
+	}
+
+	/*
+	 * Configure RSS key and indirect table _after_ all sub-channels
+	 * are allocated.
+	 */
+	error = hn_rndis_conf_rss(sc, nsubch + 1);
+	if (error) {
+		/*
+		 * Failed to configure RSS key or indirect table; only
+		 * the primary channel can be used.
+		 */
+		nsubch = 0;
+	}
+back:
+	/*
+	 * Set the # of TX/RX rings that could be used according to
+	 * the # of channels that NVS offered.
+	 */
+	hn_set_ring_inuse(sc, nsubch + 1);
+
+	/*
+	 * Attach the sub-channels, if any.
+	 */
+	error = hn_attach_subchans(sc);
+	if (error)
+		return (error);
+	return (0);
+}
+
 static void
 hn_set_ring_inuse(struct hn_softc *sc, int ring_cnt)
 {

Modified: head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_rndis_filter.c	Tue Sep 13 05:47:59 2016	(r305762)
+++ head/sys/dev/hyperv/netvsc/hv_rndis_filter.c	Tue Sep 13 05:54:31 2016	(r305763)
@@ -81,8 +81,6 @@ static int hn_rndis_query(struct hn_soft
 static int hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data,
     size_t dlen);
 static int hn_rndis_conf_offload(struct hn_softc *sc);
-static int hn_rndis_get_rsscaps(struct hn_softc *sc, int *rxr_cnt);
-static int hn_rndis_conf_rss(struct hn_softc *sc, int nchan);
 
 static __inline uint32_t
 hn_rndis_rid(struct hn_softc *sc)
@@ -711,7 +709,7 @@ done:
 	return (error);
 }
 
-static int
+int
 hn_rndis_get_rsscaps(struct hn_softc *sc, int *rxr_cnt)
 {
 	struct ndis_rss_caps in, caps;
@@ -846,7 +844,7 @@ hn_rndis_conf_offload(struct hn_softc *s
 	return (error);
 }
 
-static int
+int
 hn_rndis_conf_rss(struct hn_softc *sc, int nchan)
 {
 	struct ndis_rssprm_toeplitz *rss = &sc->hn_rss;
@@ -994,7 +992,7 @@ hv_rf_halt_device(struct hn_softc *sc)
 	return (0);
 }
 
-static int
+int
 hn_rndis_attach(struct hn_softc *sc)
 {
 	int error;
@@ -1014,76 +1012,6 @@ hn_rndis_attach(struct hn_softc *sc)
 	return (0);
 }
 
-int
-hv_rf_on_device_add(struct hn_softc *sc, int *nchan0, int mtu)
-{
-	int ret;
-	device_t dev = sc->hn_dev;
-	int nchan = *nchan0, rxr_cnt, nsubch;
-
-	ret = hn_nvs_attach(sc, mtu);
-	if (ret != 0)
-		return (ret);
-
-	ret = hn_rndis_attach(sc);
-	if (ret != 0)
-		return (ret);
-
-	if (sc->hn_ndis_ver < HN_NDIS_VERSION_6_30 || nchan == 1) {
-		/*
-		 * Either RSS is not supported, or multiple RX/TX rings
-		 * are not requested.
-		 */
-		*nchan0 = 1;
-		return (0);
-	}
-
-	/*
-	 * Get RSS capabilities, e.g. # of RX rings, and # of indirect
-	 * table entries.
-	 */
-	ret = hn_rndis_get_rsscaps(sc, &rxr_cnt);
-	if (ret) {
-		/* No RSS; this is benign. */
-		*nchan0 = 1;
-		return (0);
-	}
-	if_printf(sc->hn_ifp, "RX rings offered %u, requested %d\n",
-	    rxr_cnt, nchan);
-
-	if (nchan > rxr_cnt)
-		nchan = rxr_cnt;
-	if (nchan == 1) {
-		device_printf(dev, "only 1 channel is supported, no vRSS\n");
-		*nchan0 = 1;
-		return (0);
-	}
-	
-	/*
-	 * Allocate sub-channels from NVS.
-	 */
-	nsubch = nchan - 1;
-	ret = hn_nvs_alloc_subchans(sc, &nsubch);
-	if (ret || nsubch == 0) {
-		/* Failed to allocate sub-channels. */
-		*nchan0 = 1;
-		return (0);
-	}
-	nchan = nsubch + 1;
-
-	/*
-	 * Configure RSS key and indirect table after all sub-channels
-	 * are allocated.
-	 */
-	ret = hn_rndis_conf_rss(sc, nchan);
-	if (ret != 0) {
-		/* Failed to configure RSS key or indirect table. */
-		nchan = 1;
-	}
-	*nchan0 = nchan;
-	return (0);
-}
-
 /*
  * RNDIS filter on device remove
  */

Modified: head/sys/dev/hyperv/netvsc/hv_rndis_filter.h
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_rndis_filter.h	Tue Sep 13 05:47:59 2016	(r305762)
+++ head/sys/dev/hyperv/netvsc/hv_rndis_filter.h	Tue Sep 13 05:54:31 2016	(r305763)
@@ -43,7 +43,6 @@ struct hn_rx_ring;
 void hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr,
     const void *data, int dlen);
 void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr);
-int hv_rf_on_device_add(struct hn_softc *sc, int *nchan, int mtu);
 int hv_rf_on_device_remove(struct hn_softc *sc);
 int hv_rf_on_open(struct hn_softc *sc);
 int hv_rf_on_close(struct hn_softc *sc);

Modified: head/sys/dev/hyperv/netvsc/if_hnvar.h
==============================================================================
--- head/sys/dev/hyperv/netvsc/if_hnvar.h	Tue Sep 13 05:47:59 2016	(r305762)
+++ head/sys/dev/hyperv/netvsc/if_hnvar.h	Tue Sep 13 05:54:31 2016	(r305763)
@@ -114,18 +114,23 @@ hn_nvs_send_sglist(struct vmbus_channel 
 struct vmbus_xact;
 struct rndis_packet_msg;
 
-void		hn_nvs_sent_xact(struct hn_send_ctx *sndc, struct hn_softc *sc,
-		    struct vmbus_channel *chan, const void *data, int dlen);
 uint32_t	hn_chim_alloc(struct hn_softc *sc);
 void		hn_chim_free(struct hn_softc *sc, uint32_t chim_idx);
 
+int		hn_rndis_attach(struct hn_softc *sc);
+int		hn_rndis_conf_rss(struct hn_softc *sc, int nchan);
 void		*hn_rndis_pktinfo_append(struct rndis_packet_msg *,
 		    size_t pktsize, size_t pi_dlen, uint32_t pi_type);
-
+int		hn_rndis_get_rsscaps(struct hn_softc *sc, int *rxr_cnt);
 int		hn_rndis_get_eaddr(struct hn_softc *sc, uint8_t *eaddr);
 int		hn_rndis_get_linkstatus(struct hn_softc *sc,
 		    uint32_t *link_status);
+
+int		hn_nvs_attach(struct hn_softc *sc, int mtu);
 int		hn_nvs_alloc_subchans(struct hn_softc *sc, int *nsubch);
+void		hn_nvs_sent_xact(struct hn_send_ctx *sndc, struct hn_softc *sc,
+		    struct vmbus_channel *chan, const void *data, int dlen);
+
 int		hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen,
 		    const struct hn_recvinfo *info);
 void		hn_chan_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr);


More information about the svn-src-head mailing list