From owner-dev-commits-src-all@freebsd.org Tue Jan 19 05:08:27 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 520AD4E54A0; Tue, 19 Jan 2021 05:08:27 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4DKcB15pjpz4XKm; Tue, 19 Jan 2021 05:08:25 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 1998820BA4; Tue, 19 Jan 2021 05:08:21 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 10J58KIM085932; Tue, 19 Jan 2021 05:08:20 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 10J58KOG085931; Tue, 19 Jan 2021 05:08:20 GMT (envelope-from git) Date: Tue, 19 Jan 2021 05:08:20 GMT Message-Id: <202101190508.10J58KOG085931@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Bryan Venteicher Subject: git: 44559b26af14 - main - if_vtnet: Cleanup the reinit process MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bryanv X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 44559b26af1403513dabc0f15e23649aaf40d5d9 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Jan 2021 05:08:27 -0000 The branch main has been updated by bryanv: URL: https://cgit.FreeBSD.org/src/commit/?id=44559b26af1403513dabc0f15e23649aaf40d5d9 commit 44559b26af1403513dabc0f15e23649aaf40d5d9 Author: Bryan Venteicher AuthorDate: 2021-01-19 04:55:25 +0000 Commit: Bryan Venteicher 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;