Page MenuHomeFreeBSD

D27919.id81542.diff
No OneTemporary

D27919.id81542.diff

Index: sys/dev/virtio/network/if_vtnet.c
===================================================================
--- sys/dev/virtio/network/if_vtnet.c
+++ sys/dev/virtio/network/if_vtnet.c
@@ -71,6 +71,7 @@
#include <netinet6/ip6_var.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
+#include <netinet/tcp_lro.h>
#include <machine/bus.h>
#include <machine/resource.h>
@@ -110,6 +111,7 @@
static int vtnet_alloc_rx_filters(struct vtnet_softc *);
static void vtnet_free_rx_filters(struct vtnet_softc *);
static int vtnet_alloc_virtqueues(struct vtnet_softc *);
+static int vtnet_alloc_interface(struct vtnet_softc *);
static int vtnet_setup_interface(struct vtnet_softc *);
static int vtnet_ioctl_mtu(struct vtnet_softc *, int);
static int vtnet_ioctl_ifflags(struct vtnet_softc *);
@@ -434,6 +436,12 @@
VTNET_CORE_LOCK_INIT(sc);
callout_init_mtx(&sc->vtnet_tick_ch, VTNET_CORE_MTX(sc), 0);
+ error = vtnet_alloc_interface(sc);
+ if (error) {
+ device_printf(dev, "cannot allocate interface\n");
+ goto fail;
+ }
+
vtnet_setup_sysctl(sc);
vtnet_setup_features(sc);
@@ -775,6 +783,12 @@
if (rxq->vtnrx_sg == NULL)
return (ENOMEM);
+#if defined(INET) || defined(INET6)
+ if (tcp_lro_init(&rxq->vtnrx_lro) != 0)
+ return (ENOMEM);
+ rxq->vtnrx_lro.ifp = sc->vtnet_ifp;
+#endif
+
NET_TASK_INIT(&rxq->vtnrx_intrtask, 0, vtnet_rxq_tq_intr, rxq);
rxq->vtnrx_tq = taskqueue_create(rxq->vtnrx_name, M_NOWAIT,
taskqueue_thread_enqueue, &rxq->vtnrx_tq);
@@ -853,6 +867,10 @@
rxq->vtnrx_sc = NULL;
rxq->vtnrx_id = -1;
+#if defined(INET) || defined(INET6)
+ tcp_lro_free(&rxq->vtnrx_lro);
+#endif
+
if (rxq->vtnrx_sg != NULL) {
sglist_free(rxq->vtnrx_sg);
rxq->vtnrx_sg = NULL;
@@ -992,22 +1010,34 @@
}
static int
-vtnet_setup_interface(struct vtnet_softc *sc)
+vtnet_alloc_interface(struct vtnet_softc *sc)
{
device_t dev;
- struct pfil_head_args pa;
struct ifnet *ifp;
dev = sc->vtnet_dev;
- ifp = sc->vtnet_ifp = if_alloc(IFT_ETHER);
- if (ifp == NULL) {
- device_printf(dev, "cannot allocate ifnet structure\n");
- return (ENOSPC);
- }
+ ifp = if_alloc(IFT_ETHER);
+ if (ifp == NULL)
+ return (ENOMEM);
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+ sc->vtnet_ifp = ifp;
ifp->if_softc = sc;
+ if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+
+ return (0);
+}
+
+static int
+vtnet_setup_interface(struct vtnet_softc *sc)
+{
+ device_t dev;
+ struct pfil_head_args pa;
+ struct ifnet *ifp;
+
+ dev = sc->vtnet_dev;
+ ifp = sc->vtnet_ifp;
+
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
IFF_KNOWSEPOCH;
ifp->if_baudrate = IF_Gbps(10);
@@ -1906,9 +1936,14 @@
rxq->vtnrx_stats.vrxs_ipackets++;
rxq->vtnrx_stats.vrxs_ibytes += m->m_pkthdr.len;
- VTNET_RXQ_UNLOCK(rxq);
+#if defined(INET) || defined(INET6)
+ if (ifp->if_capenable & IFCAP_LRO && rxq->vtnrx_lro.lro_cnt != 0) {
+ if (tcp_lro_rx(&rxq->vtnrx_lro, m, 0) == 0)
+ return;
+ }
+#endif
+
(*ifp->if_input)(ifp, m);
- VTNET_RXQ_LOCK(rxq);
}
static int
@@ -2013,14 +2048,14 @@
}
vtnet_rxq_input(rxq, m, &lhdr);
-
- /* Must recheck after dropping the Rx lock. */
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- break;
}
- if (deq > 0)
+ if (deq > 0) {
+#if defined(INET) || defined(INET6)
+ tcp_lro_flush_all(&rxq->vtnrx_lro);
+#endif
virtqueue_notify(vq);
+ }
return (count > 0 ? 0 : EAGAIN);
}
Index: sys/dev/virtio/network/if_vtnetvar.h
===================================================================
--- sys/dev/virtio/network/if_vtnetvar.h
+++ sys/dev/virtio/network/if_vtnetvar.h
@@ -79,6 +79,7 @@
struct vtnet_rxq_stats vtnrx_stats;
struct taskqueue *vtnrx_tq;
struct task vtnrx_intrtask;
+ struct lro_ctrl vtnrx_lro;
#ifdef DEV_NETMAP
uint32_t vtnrx_nm_refill;
struct virtio_net_hdr_mrg_rxbuf vtnrx_shrhdr;
@@ -325,8 +326,7 @@
/*
* The VIRTIO_NET_F_GUEST_TSO[46] features permit the host to send us
- * frames larger than 1514 bytes. We do not yet support software LRO
- * via tcp_lro_rx().
+ * frames larger than 1514 bytes.
*/
#define VTNET_LRO_FEATURES (VIRTIO_NET_F_GUEST_TSO4 | \
VIRTIO_NET_F_GUEST_TSO6 | VIRTIO_NET_F_GUEST_ECN)

File Metadata

Mime Type
text/plain
Expires
Sat, May 16, 5:41 AM (12 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33116482
Default Alt Text
D27919.id81542.diff (4 KB)

Event Timeline