svn commit: r293721 - head/sys/dev/hyperv/netvsc

Sepherosa Ziehau sephe at FreeBSD.org
Tue Jan 12 01:50:58 UTC 2016


Author: sephe
Date: Tue Jan 12 01:50:56 2016
New Revision: 293721
URL: https://svnweb.freebsd.org/changeset/base/293721

Log:
  hyperv/hn: Avoid mbuf cluster allocation, if the packet is small.
  
  This one mainly avoids mbuf cluster allocation for TCP ACKs during
  TCP sending tests.  And it gives me ~200Mbps improvement (4.7Gbps
  -> 4.9Gbps), when running iperf3 TCP sending test w/ 16 connections.
  
  While I'm here, nuke the unnecessary zeroing out pkthdr.csum_flags.
  
  Reviewed by:		adrain
  Approved by:		adrian (mentor)
  Sponsored by:		Microsoft OSTC
  Differential Revision:	https://reviews.freebsd.org/D4853

Modified:
  head/sys/dev/hyperv/netvsc/hv_net_vsc.h
  head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c

Modified: head/sys/dev/hyperv/netvsc/hv_net_vsc.h
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_net_vsc.h	Tue Jan 12 01:41:34 2016	(r293720)
+++ head/sys/dev/hyperv/netvsc/hv_net_vsc.h	Tue Jan 12 01:50:56 2016	(r293721)
@@ -1011,6 +1011,7 @@ typedef struct hn_softc {
 	u_long		hn_csum_tcp;
 	u_long		hn_csum_trusted;
 	u_long		hn_lro_tried;
+	u_long		hn_small_pkts;
 } hn_softc_t;
 
 

Modified: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c	Tue Jan 12 01:41:34 2016	(r293720)
+++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c	Tue Jan 12 01:50:56 2016	(r293721)
@@ -469,6 +469,8 @@ netvsc_attach(device_t dev)
 	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "csum_trusted",
 	    CTLFLAG_RW, &sc->hn_csum_trusted,
 	    "# of TCP segements that we trust host's csum verification");
+	SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "small_pkts",
+	    CTLFLAG_RW, &sc->hn_small_pkts, "# of small packets received");
 
 	if (unit == 0) {
 		struct sysctl_ctx_list *dc_ctx;
@@ -1022,35 +1024,38 @@ netvsc_recv(struct hv_device *device_ctx
 	 */
 	if (packet->tot_data_buf_len > (ifp->if_mtu + ETHER_HDR_LEN)) {
 		return (0);
-	}
-
-	/*
-	 * Get an mbuf with a cluster.  For packets 2K or less,
-	 * get a standard 2K cluster.  For anything larger, get a
-	 * 4K cluster.  Any buffers larger than 4K can cause problems
-	 * if looped around to the Hyper-V TX channel, so avoid them.
-	 */
-	size = MCLBYTES;
-
-	if (packet->tot_data_buf_len > MCLBYTES) {
-		/* 4096 */
-		size = MJUMPAGESIZE;
-	}
+	} else if (packet->tot_data_buf_len <= MHLEN) {
+		m_new = m_gethdr(M_NOWAIT, MT_DATA);
+		if (m_new == NULL)
+			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;
+		sc->hn_small_pkts++;
+	} else {
+		/*
+		 * Get an mbuf with a cluster.  For packets 2K or less,
+		 * get a standard 2K cluster.  For anything larger, get a
+		 * 4K cluster.  Any buffers larger than 4K can cause problems
+		 * if looped around to the Hyper-V TX channel, so avoid them.
+		 */
+		size = MCLBYTES;
+		if (packet->tot_data_buf_len > MCLBYTES) {
+			/* 4096 */
+			size = MJUMPAGESIZE;
+		}
 
-	m_new = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, size);
+		m_new = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, size);
+		if (m_new == NULL) {
+			device_printf(dev, "alloc mbuf failed.\n");
+			return (0);
+		}
 
-	if (m_new == NULL) {
-		device_printf(dev, "alloc mbuf failed.\n");
-		return (0);
+		hv_m_append(m_new, packet->tot_data_buf_len, packet->data);
 	}
-
-	hv_m_append(m_new, packet->tot_data_buf_len,
-			packet->data);
-
 	m_new->m_pkthdr.rcvif = ifp;
 
 	/* receive side checksum offload */
-	m_new->m_pkthdr.csum_flags = 0;
 	if (NULL != csum_info) {
 		/* IP csum offload */
 		if (csum_info->receive.ip_csum_succeeded) {


More information about the svn-src-head mailing list