git: 44559b26af14 - main - if_vtnet: Cleanup the reinit process

Bryan Venteicher bryanv at FreeBSD.org
Tue Jan 19 05:08:27 UTC 2021


The branch main has been updated by bryanv:

URL: https://cgit.FreeBSD.org/src/commit/?id=44559b26af1403513dabc0f15e23649aaf40d5d9

commit 44559b26af1403513dabc0f15e23649aaf40d5d9
Author:     Bryan Venteicher <bryanv at FreeBSD.org>
AuthorDate: 2021-01-19 04:55:25 +0000
Commit:     Bryan Venteicher <bryanv at FreeBSD.org>
CommitDate: 2021-01-19 04:55:25 +0000

    if_vtnet: Cleanup the reinit process
    
    In modern VirtIO, the virtqueues cannot be notified before setting
    DRIVER_OK status.
    
    Reviewed by: grehan (mentor)
    Differential Revision: https://reviews.freebsd.org/D27932
---
 sys/dev/virtio/network/if_vtnet.c    | 91 ++++++++++++++++++------------------
 sys/dev/virtio/network/if_vtnetvar.h |  1 +
 2 files changed, 46 insertions(+), 46 deletions(-)

diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c
index 33d421b32b1f..d0c98afe5b20 100644
--- a/sys/dev/virtio/network/if_vtnet.c
+++ b/sys/dev/virtio/network/if_vtnet.c
@@ -600,7 +600,7 @@ static void
 vtnet_negotiate_features(struct vtnet_softc *sc)
 {
 	device_t dev;
-	uint64_t features;
+	uint64_t features, negotiated_features;
 	int no_csum;
 
 	dev = sc->vtnet_dev;
@@ -626,7 +626,7 @@ vtnet_negotiate_features(struct vtnet_softc *sc)
 	features &= ~VIRTIO_NET_F_MQ;
 #endif
 
-	sc->vtnet_features = virtio_negotiate_features(dev, features);
+	negotiated_features = virtio_negotiate_features(dev, features);
 
 	if (virtio_with_feature(dev, VTNET_LRO_FEATURES) &&
 	    virtio_with_feature(dev, VIRTIO_NET_F_MRG_RXBUF) == 0) {
@@ -644,12 +644,15 @@ vtnet_negotiate_features(struct vtnet_softc *sc)
 			    "LRO disabled since both mergeable buffers and "
 			    "indirect descriptors were not negotiated\n");
 			features &= ~VTNET_LRO_FEATURES;
-			sc->vtnet_features =
+			negotiated_features =
 			    virtio_negotiate_features(dev, features);
 		} else
 			sc->vtnet_flags |= VTNET_FLAG_LRO_NOMRG;
 	}
 
+	sc->vtnet_features = negotiated_features;
+	sc->vtnet_negotiated_features = negotiated_features;
+
 	virtio_finalize_features(dev);
 }
 
@@ -2964,19 +2967,11 @@ vtnet_virtio_reinit(struct vtnet_softc *sc)
 	device_t dev;
 	struct ifnet *ifp;
 	uint64_t features;
-	int mask, error;
+	int error;
 
 	dev = sc->vtnet_dev;
 	ifp = sc->vtnet_ifp;
-	features = sc->vtnet_features;
-
-	mask = 0;
-#if defined(INET)
-	mask |= IFCAP_RXCSUM;
-#endif
-#if defined (INET6)
-	mask |= IFCAP_RXCSUM_IPV6;
-#endif
+	features = sc->vtnet_negotiated_features;
 
 	/*
 	 * Re-negotiate with the host, removing any disabled receive
@@ -2984,14 +2979,17 @@ vtnet_virtio_reinit(struct vtnet_softc *sc)
 	 * via if_capenable and if_hwassist.
 	 */
 
-	if (ifp->if_capabilities & mask) {
+	if (ifp->if_capabilities & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) {
 		/*
-		 * We require both IPv4 and IPv6 offloading to be enabled
-		 * in order to negotiated it: VirtIO does not distinguish
-		 * between the two.
+		 * VirtIO does not distinguish between the IPv4 and IPv6
+		 * checksums so require both. Guest TSO (LRO) requires
+		 * Rx checksums.
 		 */
-		if ((ifp->if_capenable & mask) != mask)
+		if ((ifp->if_capenable &
+		    (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) == 0) {
 			features &= ~VIRTIO_NET_F_GUEST_CSUM;
+			features &= ~VTNET_LRO_FEATURES;
+		}
 	}
 
 	if (ifp->if_capabilities & IFCAP_LRO) {
@@ -3005,10 +3003,15 @@ vtnet_virtio_reinit(struct vtnet_softc *sc)
 	}
 
 	error = virtio_reinit(dev, features);
-	if (error)
+	if (error) {
 		device_printf(dev, "virtio reinit error %d\n", error);
+		return (error);
+	}
 
-	return (error);
+	sc->vtnet_features = features;
+	virtio_reinit_complete(dev);
+
+	return (0);
 }
 
 static void
@@ -3019,9 +3022,7 @@ vtnet_init_rx_filters(struct vtnet_softc *sc)
 	ifp = sc->vtnet_ifp;
 
 	if (sc->vtnet_flags & VTNET_FLAG_CTRL_RX) {
-		/* Restore promiscuous and all-multicast modes. */
 		vtnet_rx_filter(sc);
-		/* Restore filtered MAC addresses. */
 		vtnet_rx_filter_mac(sc);
 	}
 
@@ -3130,17 +3131,25 @@ vtnet_set_active_vq_pairs(struct vtnet_softc *sc)
 static int
 vtnet_reinit(struct vtnet_softc *sc)
 {
+	device_t dev;
 	struct ifnet *ifp;
 	int error;
 
+	dev = sc->vtnet_dev;
 	ifp = sc->vtnet_ifp;
 
-	/* Use the current MAC address. */
 	bcopy(IF_LLADDR(ifp), sc->vtnet_hwaddr, ETHER_ADDR_LEN);
-	vtnet_set_macaddr(sc);
 
+	error = vtnet_virtio_reinit(sc);
+	if (error)
+		return (error);
+
+	vtnet_set_macaddr(sc);
 	vtnet_set_active_vq_pairs(sc);
 
+	if (sc->vtnet_flags & VTNET_FLAG_CTRL_VQ)
+		vtnet_init_rx_filters(sc);
+
 	ifp->if_hwassist = 0;
 	if (ifp->if_capenable & IFCAP_TXCSUM)
 		ifp->if_hwassist |= VTNET_CSUM_OFFLOAD;
@@ -3151,16 +3160,10 @@ vtnet_reinit(struct vtnet_softc *sc)
 	if (ifp->if_capenable & IFCAP_TSO6)
 		ifp->if_hwassist |= CSUM_IP6_TSO;
 
-	if (sc->vtnet_flags & VTNET_FLAG_CTRL_VQ)
-		vtnet_init_rx_filters(sc);
-
 	error = vtnet_init_rxtx_queues(sc);
 	if (error)
 		return (error);
 
-	vtnet_enable_interrupts(sc);
-	ifp->if_drv_flags |= IFF_DRV_RUNNING;
-
 	return (0);
 }
 
@@ -3192,27 +3195,20 @@ vtnet_init_locked(struct vtnet_softc *sc, int init_mode)
 	}
 #endif /* DEV_NETMAP */
 
-	/* Reinitialize with the host. */
-	if (vtnet_virtio_reinit(sc) != 0)
-		goto fail;
-
-	if (vtnet_reinit(sc) != 0)
-		goto fail;
-
-	virtio_reinit_complete(dev);
+	if (vtnet_reinit(sc) != 0) {
+		vtnet_stop(sc);
+		return;
+	}
 
+	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	vtnet_update_link_status(sc);
+	vtnet_enable_interrupts(sc);
 	callout_reset(&sc->vtnet_tick_ch, hz, vtnet_tick, sc);
 
 #ifdef DEV_NETMAP
 	/* Re-enable txsync/rxsync. */
 	netmap_enable_all_rings(ifp);
 #endif /* DEV_NETMAP */
-
-	return;
-
-fail:
-	vtnet_stop(sc);
 }
 
 static void
@@ -3247,8 +3243,8 @@ vtnet_exec_ctrl_cmd(struct vtnet_softc *sc, void *cookie,
 
 	vq = sc->vtnet_ctrl_vq;
 
-	VTNET_CORE_LOCK_ASSERT(sc);
 	MPASS(sc->vtnet_flags & VTNET_FLAG_CTRL_VQ);
+	VTNET_CORE_LOCK_ASSERT(sc);
 
 	if (!virtqueue_empty(vq))
 		return;
@@ -3707,19 +3703,22 @@ vtnet_get_macaddr(struct vtnet_softc *sc)
 static void
 vtnet_set_macaddr(struct vtnet_softc *sc)
 {
+	device_t dev;
 	int error;
 
+	dev = sc->vtnet_dev;
+
 	if (sc->vtnet_flags & VTNET_FLAG_CTRL_MAC) {
 		error = vtnet_ctrl_mac_cmd(sc, sc->vtnet_hwaddr);
 		if (error)
-			if_printf(sc->vtnet_ifp, "unable to set MAC address\n");
+			device_printf(dev, "unable to set MAC address\n");
 		return;
 	}
 
 	/* MAC in config is read-only in modern VirtIO. */
 	if (!vtnet_modern(sc) && sc->vtnet_flags & VTNET_FLAG_MAC) {
 		for (int i = 0; i < ETHER_ADDR_LEN; i++) {
-			virtio_write_dev_config_1(sc->vtnet_dev,
+			virtio_write_dev_config_1(dev,
 			    offsetof(struct virtio_net_config, mac) + i,
 			    sc->vtnet_hwaddr[i]);
 		}
diff --git a/sys/dev/virtio/network/if_vtnetvar.h b/sys/dev/virtio/network/if_vtnetvar.h
index 82dd2514472d..0fd1238b2dcb 100644
--- a/sys/dev/virtio/network/if_vtnetvar.h
+++ b/sys/dev/virtio/network/if_vtnetvar.h
@@ -174,6 +174,7 @@ struct vtnet_softc {
 	uint32_t		*vtnet_vlan_filter;
 
 	uint64_t		 vtnet_features;
+	uint64_t		 vtnet_negotiated_features;
 	struct vtnet_statistics	 vtnet_stats;
 	struct callout		 vtnet_tick_ch;
 	struct ifmedia		 vtnet_media;


More information about the dev-commits-src-all mailing list