From owner-svn-src-user@FreeBSD.ORG Mon Jul 1 06:44:28 2013 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id AD62ECF9; Mon, 1 Jul 2013 06:44:28 +0000 (UTC) (envelope-from bryanv@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 9F90F111F; Mon, 1 Jul 2013 06:44:28 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r616iSir003505; Mon, 1 Jul 2013 06:44:28 GMT (envelope-from bryanv@svn.freebsd.org) Received: (from bryanv@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r616iRla003497; Mon, 1 Jul 2013 06:44:27 GMT (envelope-from bryanv@svn.freebsd.org) Message-Id: <201307010644.r616iRla003497@svn.freebsd.org> From: Bryan Venteicher Date: Mon, 1 Jul 2013 06:44:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r252451 - in user/bryanv/vtnetmq/sys/dev/virtio: . network pci X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Jul 2013 06:44:28 -0000 Author: bryanv Date: Mon Jul 1 06:44:27 2013 New Revision: 252451 URL: http://svnweb.freebsd.org/changeset/base/252451 Log: More minor changes to the multiqueue driver - Add new VirtIO device method for device drivers to perform some action after the device status has been set to OK. - Honor VIRTIO_NET_F_GSO option. It seems most host implementations also set the TSO IPv4/6 features so this is mostly a noop. - For Rx frames with VIRTIO_NET_HDR_F_DATA_VALID set, do not bump an error counter if the L4 protocol is unsupported. This just means we'll be forced to recompute the checksum higher in the stack. - Start all the Tx queues when the link is upped. - Do not add our MAC address to the Rx MAC filter table; it is not required. - Use the VIRTIO_NET_F_CTRL_MAC_ADDR feature to set MAC address if available. - Pass correct number of desc segments of the MQ control message. Modified: user/bryanv/vtnetmq/sys/dev/virtio/network/if_vtnet.c user/bryanv/vtnetmq/sys/dev/virtio/network/if_vtnetvar.h user/bryanv/vtnetmq/sys/dev/virtio/pci/virtio_pci.c user/bryanv/vtnetmq/sys/dev/virtio/virtio_if.m Modified: user/bryanv/vtnetmq/sys/dev/virtio/network/if_vtnet.c ============================================================================== --- user/bryanv/vtnetmq/sys/dev/virtio/network/if_vtnet.c Mon Jul 1 06:33:35 2013 (r252450) +++ user/bryanv/vtnetmq/sys/dev/virtio/network/if_vtnet.c Mon Jul 1 06:44:27 2013 (r252451) @@ -90,6 +90,7 @@ static int vtnet_detach(device_t); static int vtnet_suspend(device_t); static int vtnet_resume(device_t); static int vtnet_shutdown(device_t); +static int vtnet_attach_completed(device_t); static int vtnet_config_change(device_t); static void vtnet_negotiate_features(struct vtnet_softc *); @@ -147,6 +148,7 @@ static void vtnet_txq_tq_deferred(void * static void vtnet_txq_tq_intr(void *, int); static void vtnet_txq_eof(struct vtnet_txq *); static void vtnet_tx_vq_intr(void *); +static void vtnet_tx_start_all(struct vtnet_softc *); #ifndef VTNET_LEGACY_TX static void vtnet_qflush(struct ifnet *); @@ -278,15 +280,16 @@ static struct virtio_feature_desc vtnet_ static device_method_t vtnet_methods[] = { /* Device methods. */ - DEVMETHOD(device_probe, vtnet_probe), - DEVMETHOD(device_attach, vtnet_attach), - DEVMETHOD(device_detach, vtnet_detach), - DEVMETHOD(device_suspend, vtnet_suspend), - DEVMETHOD(device_resume, vtnet_resume), - DEVMETHOD(device_shutdown, vtnet_shutdown), + DEVMETHOD(device_probe, vtnet_probe), + DEVMETHOD(device_attach, vtnet_attach), + DEVMETHOD(device_detach, vtnet_detach), + DEVMETHOD(device_suspend, vtnet_suspend), + DEVMETHOD(device_resume, vtnet_resume), + DEVMETHOD(device_shutdown, vtnet_shutdown), /* VirtIO methods. */ - DEVMETHOD(virtio_config_change, vtnet_config_change), + DEVMETHOD(virtio_attach_completed, vtnet_attach_completed), + DEVMETHOD(virtio_config_change, vtnet_config_change), DEVMETHOD_END }; @@ -397,8 +400,6 @@ vtnet_attach(device_t dev) goto fail; } - vtnet_attach_disable_promisc(sc); - vtnet_start_taskqueues(sc); fail: @@ -502,6 +503,15 @@ vtnet_shutdown(device_t dev) } static int +vtnet_attach_completed(device_t dev) +{ + + vtnet_attach_disable_promisc(device_get_softc(dev)); + + return (0); +} + +static int vtnet_config_change(device_t dev) { struct vtnet_softc *sc; @@ -510,6 +520,8 @@ vtnet_config_change(device_t dev) VTNET_CORE_LOCK(sc); vtnet_update_link_status(sc); + if (sc->vtnet_link_active != 0) + vtnet_tx_start_all(sc); VTNET_CORE_UNLOCK(sc); return (0); @@ -538,6 +550,9 @@ vtnet_negotiate_features(struct vtnet_so mask |= VTNET_LRO_FEATURES; if (vtnet_tunable_int(sc, "mq_disable", vtnet_mq_disable)) mask |= VIRTIO_NET_F_MQ; +#ifdef VTNET_LEGACY_TX + mask |= VIRTIO_NET_F_MQ; +#endif features = VTNET_FEATURES & ~mask; sc->vtnet_features = virtio_negotiate_features(dev, features); @@ -884,6 +899,7 @@ vtnet_setup_interface(struct vtnet_softc struct virtqueue *vq = sc->vtnet_txqs[0].vtntx_vq; ifp->if_start = vtnet_start; IFQ_SET_MAXLEN(&ifp->if_snd, virtqueue_size(vq) - 1); + ifp->if_snd.ifq_drv_maxlen = virtqueue_size(vq) - 1; IFQ_SET_READY(&ifp->if_snd); #endif @@ -907,15 +923,20 @@ vtnet_setup_interface(struct vtnet_softc if (virtio_with_feature(dev, VIRTIO_NET_F_CSUM)) { ifp->if_capabilities |= IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6; - if (virtio_with_feature(dev, VIRTIO_NET_F_HOST_TSO4)) - ifp->if_capabilities |= IFCAP_TSO4; - if (virtio_with_feature(dev, VIRTIO_NET_F_HOST_TSO6)) - ifp->if_capabilities |= IFCAP_TSO6; + if (virtio_with_feature(dev, VIRTIO_NET_F_GSO)) { + ifp->if_capabilities |= IFCAP_TSO4 | IFCAP_TSO6; + sc->vtnet_flags |= VTNET_FLAG_TSO_ECN; + } else { + if (virtio_with_feature(dev, VIRTIO_NET_F_HOST_TSO4)) + ifp->if_capabilities |= IFCAP_TSO4; + if (virtio_with_feature(dev, VIRTIO_NET_F_HOST_TSO6)) + ifp->if_capabilities |= IFCAP_TSO6; + if (virtio_with_feature(dev, VIRTIO_NET_F_HOST_ECN)) + sc->vtnet_flags |= VTNET_FLAG_TSO_ECN; + } + if (ifp->if_capabilities & IFCAP_TSO) ifp->if_capabilities |= IFCAP_VLAN_HWTSO; - - if (virtio_with_feature(dev, VIRTIO_NET_F_HOST_ECN)) - sc->vtnet_flags |= VTNET_FLAG_TSO_ECN; } if (virtio_with_feature(dev, VIRTIO_NET_F_GUEST_CSUM)) @@ -1059,23 +1080,16 @@ vtnet_ioctl(struct ifnet *ifp, u_long cm ifp->if_capenable ^= IFCAP_TXCSUM; if (mask & IFCAP_TXCSUM_IPV6) ifp->if_capenable ^= IFCAP_TXCSUM_IPV6; - if (mask & IFCAP_TSO) { - if (mask & IFCAP_TSO4) - ifp->if_capenable ^= IFCAP_TSO4; - if (mask & IFCAP_TSO6) - ifp->if_capenable ^= IFCAP_TSO6; - } + if (mask & IFCAP_TSO4) + ifp->if_capenable ^= IFCAP_TSO4; + if (mask & IFCAP_TSO6) + ifp->if_capenable ^= IFCAP_TSO6; if (mask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6 | IFCAP_LRO | IFCAP_VLAN_HWFILTER)) { /* These Rx features require us to renegotiate. */ reinit = 1; - /* - * VirtIO does not distinguish between IPv4 and IPv6 - * checksum offloading. Both must be enabled for us - * to negotiate it with the host. - */ if (mask & IFCAP_RXCSUM) ifp->if_capenable ^= IFCAP_RXCSUM; if (mask & IFCAP_RXCSUM_IPV6) @@ -1503,8 +1517,17 @@ vtnet_rxq_csum_by_parse(struct vtnet_rxq m->m_pkthdr.csum_flags |= CSUM_SCTP_VALID; break; default: - sc->vtnet_stats.rx_csum_bad_proto++; - return (1); + /* + * For the remaining protocols, FreeBSD does not support + * checksum offloading, so the checksum will be recomputed. + */ +#if 0 + if_printf(sc->vtnet_ifp, "cksum offload of unsupported " + "protocol eth_type=%#x proto=%d csum_start=%d + "csum_offset=%d\n", __func__, eth_type, proto, + hdr->csum_start, hdr->csum_offset); +#endif + break; } return (0); @@ -1674,19 +1697,17 @@ vtnet_rxq_input(struct vtnet_rxq *rxq, s static int vtnet_rxq_eof(struct vtnet_rxq *rxq) { - struct virtio_net_hdr lhdr; + struct virtio_net_hdr lhdr, *hdr; struct vtnet_softc *sc; struct ifnet *ifp; struct virtqueue *vq; struct mbuf *m; - struct virtio_net_hdr *hdr; struct virtio_net_hdr_mrg_rxbuf *mhdr; int len, deq, nbufs, adjsz, count; sc = rxq->vtnrx_sc; vq = rxq->vtnrx_vq; ifp = sc->vtnet_ifp; - hdr = &lhdr; deq = 0; count = sc->vtnet_rx_process_limit; @@ -1899,7 +1920,7 @@ vtnet_txq_offload_ctx(struct vtnet_txq * case ETHERTYPE_IPV6: *proto = -1; *start = ip6_lasthdr(m, offset, IPPROTO_IPV6, proto); - /* Assert the network stack sends us a valid packet. */ + /* Assert the network stack sent us a valid packet. */ KASSERT(*start > offset, ("%s: mbuf %p start %d offset %d proto %d", __func__, m, *start, offset, *proto)); @@ -2382,6 +2403,31 @@ again: VTNET_TXQ_UNLOCK(txq); } +static void +vtnet_tx_start_all(struct vtnet_softc *sc) +{ + struct ifnet *ifp; + struct vtnet_txq *txq; + int i; + + ifp = sc->vtnet_ifp; + VTNET_CORE_LOCK_ASSERT(sc); + + for (i = 0; i < sc->vtnet_act_vq_pairs; i++) { + txq = &sc->vtnet_txqs[i]; + + VTNET_TXQ_LOCK(txq); +#ifdef VTNET_LEGACY_TX + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + vtnet_start_locked(txq, ifp); +#else + if (!drbr_empty(ifp, txq->vtntx_br)) + vtnet_txq_mq_start_locked(txq, NULL); +#endif + VTNET_TXQ_UNLOCK(txq); + } +} + #ifndef VTNET_LEGACY_TX static void vtnet_qflush(struct ifnet *ifp) @@ -3034,7 +3080,7 @@ vtnet_ctrl_mq_cmd(struct vtnet_softc *sc KASSERT(error == 0 && sg.sg_nseg == 3, ("%s: error %d adding MQ message to sglist", __func__, error)); - vtnet_exec_ctrl_cmd(sc, &s.ack, &sg, 1, 1); + vtnet_exec_ctrl_cmd(sc, &s.ack, &sg, sg.sg_nseg - 1, 1); return (s.ack == VIRTIO_NET_OK ? 0 : EIO); } @@ -3105,7 +3151,6 @@ vtnet_attach_disable_promisc(struct vtne return; } - /* Hold the lock to satisfy asserts. */ VTNET_CORE_LOCK(sc); error = vtnet_set_promisc(sc, 0); VTNET_CORE_UNLOCK(sc); @@ -3166,6 +3211,9 @@ vtnet_rx_filter_mac(struct vtnet_softc * TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { if (ifa->ifa_addr->sa_family != AF_LINK) continue; + else if (memcmp(LLADDR((struct sockaddr_dl *)ifa->ifa_addr), + sc->vtnet_hwaddr, ETHER_ADDR_LEN) == 0) + continue; else if (ucnt == VTNET_MAX_MAC_ENTRIES) break; @@ -3672,7 +3720,6 @@ vtnet_txq_enable_intr(struct vtnet_txq * { return (virtqueue_postpone_intr(txq->vtntx_vq, VQ_POSTPONE_LONG)); - return (virtqueue_enable_intr(txq->vtntx_vq)); } static void Modified: user/bryanv/vtnetmq/sys/dev/virtio/network/if_vtnetvar.h ============================================================================== --- user/bryanv/vtnetmq/sys/dev/virtio/network/if_vtnetvar.h Mon Jul 1 06:33:35 2013 (r252450) +++ user/bryanv/vtnetmq/sys/dev/virtio/network/if_vtnetvar.h Mon Jul 1 06:44:27 2013 (r252451) @@ -256,8 +256,10 @@ CTASSERT(sizeof(struct vtnet_mac_filter) VIRTIO_NET_F_STATUS | \ VIRTIO_NET_F_CTRL_VQ | \ VIRTIO_NET_F_CTRL_RX | \ + VIRTIO_NET_F_CTRL_MAC_ADDR | \ VIRTIO_NET_F_CTRL_VLAN | \ VIRTIO_NET_F_CSUM | \ + VIRTIO_NET_F_GSO | \ VIRTIO_NET_F_HOST_TSO4 | \ VIRTIO_NET_F_HOST_TSO6 | \ VIRTIO_NET_F_HOST_ECN | \ @@ -274,7 +276,7 @@ CTASSERT(sizeof(struct vtnet_mac_filter) * The VIRTIO_NET_F_HOST_TSO[46] features permit us to send the host * frames larger than 1514 bytes. */ -#define VTNET_TSO_FEATURES (VIRTIO_NET_F_HOST_TSO4 | \ +#define VTNET_TSO_FEATURES (VIRTIO_NET_F_GSO | VIRTIO_NET_F_HOST_TSO4 | \ VIRTIO_NET_F_HOST_TSO6 | VIRTIO_NET_F_HOST_ECN) /* Modified: user/bryanv/vtnetmq/sys/dev/virtio/pci/virtio_pci.c ============================================================================== --- user/bryanv/vtnetmq/sys/dev/virtio/pci/virtio_pci.c Mon Jul 1 06:33:35 2013 (r252450) +++ user/bryanv/vtnetmq/sys/dev/virtio/pci/virtio_pci.c Mon Jul 1 06:44:27 2013 (r252451) @@ -757,8 +757,10 @@ vtpci_probe_and_attach_child(struct vtpc vtpci_release_child_resources(sc); /* Reset status for future attempt. */ vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_ACK); - } else + } else { vtpci_set_status(dev, VIRTIO_CONFIG_STATUS_DRIVER_OK); + VIRTIO_ATTACH_COMPLETED(child); + } } static int Modified: user/bryanv/vtnetmq/sys/dev/virtio/virtio_if.m ============================================================================== --- user/bryanv/vtnetmq/sys/dev/virtio/virtio_if.m Mon Jul 1 06:33:35 2013 (r252450) +++ user/bryanv/vtnetmq/sys/dev/virtio/virtio_if.m Mon Jul 1 06:44:27 2013 (r252451) @@ -31,6 +31,18 @@ INTERFACE virtio; CODE { static int + virtio_default_attach_completed(device_t dev) + { + return (0); + } +}; + +METHOD int attach_completed { + device_t dev; +} DEFAULT virtio_default_attach_completed; + +CODE { + static int virtio_default_config_change(device_t dev) { return (0);