svn commit: r252451 - in user/bryanv/vtnetmq/sys/dev/virtio: . network pci
Bryan Venteicher
bryanv at FreeBSD.org
Mon Jul 1 06:44:28 UTC 2013
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);
More information about the svn-src-user
mailing list