Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F156627633
D27919.id81542.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D27919.id81542.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D27919: if_vtnet: Initial support for software LRO
Attached
Detach File
Event Timeline
Log In to Comment