summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsephe <sephe@FreeBSD.org>2016-06-16 03:16:43 +0000
committersephe <sephe@FreeBSD.org>2016-06-16 03:16:43 +0000
commit6a585fbdca889986b227564e0f049e4e88f46c7c (patch)
tree4e1d9e4e62817c7fb0460934ebddc8e3af613b53
parent300587787c826af654539252057d278d0034eed8 (diff)
downloadFreeBSD-src-6a585fbdca889986b227564e0f049e4e88f46c7c.zip
FreeBSD-src-6a585fbdca889986b227564e0f049e4e88f46c7c.tar.gz
MFC 297180,297181,297182
297180 hyperv/hn: Reduce TCP segment aggregation limit for multiple RX rings This mainly used to improve ACK timeliness when multiple RX rings are enabled. This value gives the best performance in both Azure and Hyper-V environment, w/ both 10Ge and 40Ge using non-{INVARIANTS,WITNESS} kernel. MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5691 297181 hyperv/hn: Factor out hn_set_lro_lenlim() MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5692 297182 hyperv/hn: When short of mbufs on the RX path, don't spam the console. Instead, increase the IQDROPS counter. MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5693
-rw-r--r--sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
index b00f8c3..156a76d 100644
--- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
+++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
@@ -183,6 +183,7 @@ struct hn_txdesc {
#define HN_CSUM_ASSIST_WIN8 (CSUM_IP | CSUM_TCP)
#define HN_CSUM_ASSIST (CSUM_IP | CSUM_UDP | CSUM_TCP)
+#define HN_LRO_LENLIM_MULTIRX_DEF (12 * ETHERMTU)
#define HN_LRO_LENLIM_DEF (25 * ETHERMTU)
/* YYY 2*MTU is a bit rough, but should be good enough. */
#define HN_LRO_LENLIM_MIN(ifp) (2 * (ifp)->if_mtu)
@@ -339,6 +340,17 @@ static void hn_xmit_txeof(struct hn_tx_ring *);
static void hn_xmit_taskfunc(void *, int);
static void hn_xmit_txeof_taskfunc(void *, int);
+#if __FreeBSD_version >= 1100099
+static void
+hn_set_lro_lenlim(struct hn_softc *sc, int lenlim)
+{
+ int i;
+
+ for (i = 0; i < sc->hn_rx_ring_inuse; ++i)
+ sc->hn_rx_ring[i].hn_lro.lro_length_lim = lenlim;
+}
+#endif
+
static int
hn_ifmedia_upd(struct ifnet *ifp __unused)
{
@@ -550,6 +562,16 @@ netvsc_attach(device_t dev)
device_printf(dev, "%d TX ring, %d RX ring\n",
sc->hn_tx_ring_inuse, sc->hn_rx_ring_inuse);
+#if __FreeBSD_version >= 1100099
+ if (sc->hn_rx_ring_inuse > 1) {
+ /*
+ * Reduce TCP segment aggregation limit for multiple
+ * RX rings to increase ACK timeliness.
+ */
+ hn_set_lro_lenlim(sc, HN_LRO_LENLIM_MULTIRX_DEF);
+ }
+#endif
+
if (device_info.link_state == 0) {
sc->hn_carrier = 1;
}
@@ -1258,8 +1280,10 @@ netvsc_recv(struct hv_vmbus_channel *chan, netvsc_packet *packet,
return (0);
} else if (packet->tot_data_buf_len <= MHLEN) {
m_new = m_gethdr(M_NOWAIT, MT_DATA);
- if (m_new == NULL)
+ if (m_new == NULL) {
+ if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
return (0);
+ }
memcpy(mtod(m_new, void *), packet->data,
packet->tot_data_buf_len);
m_new->m_pkthdr.len = m_new->m_len = packet->tot_data_buf_len;
@@ -1279,7 +1303,7 @@ netvsc_recv(struct hv_vmbus_channel *chan, netvsc_packet *packet,
m_new = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, size);
if (m_new == NULL) {
- if_printf(ifp, "alloc mbuf failed.\n");
+ if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
return (0);
}
@@ -1469,13 +1493,8 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
*/
NV_LOCK(sc);
if (sc->hn_rx_ring[0].hn_lro.lro_length_lim <
- HN_LRO_LENLIM_MIN(ifp)) {
- int i;
- for (i = 0; i < sc->hn_rx_ring_inuse; ++i) {
- sc->hn_rx_ring[i].hn_lro.lro_length_lim =
- HN_LRO_LENLIM_MIN(ifp);
- }
- }
+ HN_LRO_LENLIM_MIN(ifp))
+ hn_set_lro_lenlim(sc, HN_LRO_LENLIM_MIN(ifp));
NV_UNLOCK(sc);
#endif
@@ -1808,7 +1827,7 @@ hn_lro_lenlim_sysctl(SYSCTL_HANDLER_ARGS)
{
struct hn_softc *sc = arg1;
unsigned int lenlim;
- int error, i;
+ int error;
lenlim = sc->hn_rx_ring[0].hn_lro.lro_length_lim;
error = sysctl_handle_int(oidp, &lenlim, 0, req);
@@ -1820,8 +1839,7 @@ hn_lro_lenlim_sysctl(SYSCTL_HANDLER_ARGS)
return EINVAL;
NV_LOCK(sc);
- for (i = 0; i < sc->hn_rx_ring_inuse; ++i)
- sc->hn_rx_ring[i].hn_lro.lro_length_lim = lenlim;
+ hn_set_lro_lenlim(sc, lenlim);
NV_UNLOCK(sc);
return 0;
}
OpenPOWER on IntegriCloud