Skip to contentSkip to conversation

hyperv: Enable sendbuf mechanism on the send path

PATCH In review K. Y. Srinivasan 2 participants 2 messages Apr 22, 2014 – Apr 23, 2014

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 hyperv: Enable sendbuf mechanism on the send path

We send packets using a copy-free mechanism (this is the Guest to Host transport via VMBUS). While this is obviously optimal for large packets,
it may not be optimal for small packets. Hyper-V host supports
a second mechanism for sending packets that is "copy based". We implement that mechanism in this patch.

With this patch (and all of the other offload and VRSS patches), we are now able to almost saturate a 10G interface between Linux VMs on Hyper-V
on different hosts - close to 9 Gbps as measured via iperf.

---
 drivers/net/hyperv/hyperv_net.h |   14 +++
 drivers/net/hyperv/netvsc.c     |  226 +++++++++++++++++++++++++++++++++++++--
 drivers/net/hyperv/netvsc_drv.c |    3 +-
 3 files changed, 234 insertions(+), 9 deletions(-)
drivers/net/hyperv/hyperv_net.h +14 -0
index d1f7826..4b7df5a 100644
@@ -140,6 +140,8 @@ struct hv_netvsc_packet {
 	void *send_completion_ctx;
 	void (*send_completion)(void *context);
 
+	u32 send_buf_index;
+
 	/* This points to the memory after page_buf */
 	struct rndis_message *rndis_msg;
 
@@ -582,6 +584,9 @@ struct nvsp_message {
 
 #define NETVSC_RECEIVE_BUFFER_SIZE		(1024*1024*16)	/* 16MB */
 #define NETVSC_RECEIVE_BUFFER_SIZE_LEGACY	(1024*1024*15)  /* 15MB */
+#define NETVSC_SEND_BUFFER_SIZE			(1024 * 1024)   /* 1MB */
+#define NETVSC_INVALID_INDEX			-1
+
 
 #define NETVSC_RECEIVE_BUFFER_ID		0xcafe
 
@@ -607,6 +612,15 @@ struct netvsc_device {
 	u32 recv_section_cnt;
 	struct nvsp_1_receive_buffer_section *recv_section;
 
+	/* Send buffer allocated by us */
+	void *send_buf;
+	u32 send_buf_size;
+	u32 send_buf_gpadl_handle;
+	u32 send_section_cnt;
+	u32 send_section_size;
+	unsigned long *send_section_map;
+	int map_words;
+
 	/* Used for NetVSP initialization protocol */
 	struct completion channel_init_wait;
 	struct nvsp_message channel_init_pkt;
drivers/net/hyperv/netvsc.c +218 -8

306 lines not on this page · raw message

drivers/net/hyperv/netvsc_drv.c +2 -1
index c76b665..939e3af 100644
@@ -236,10 +236,11 @@ static void netvsc_xmit_completion(void *context)
 	struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)context;
 	struct sk_buff *skb = (struct sk_buff *)
 		(unsigned long)packet->send_completion_tid;
+	u32 index = packet->send_buf_index;
 
 	kfree(packet);
 
-	if (skb)
+	if (skb && (index == NETVSC_INVALID_INDEX))
 		dev_kfree_skb_any(skb);
 }
 
Signature · 1 line
1.7.4.1
maintainer
#1 lore raw

From: "K. Y. Srinivasan" <[email protected]>
Date: Tue, 22 Apr 2014 11:03:32 -0700

drivers/net/hyperv/netvsc.c int netvsc_send(struct hv_device *device, · line 733

Quoted 2 lines
drivers/net/hyperv/netvsc.c +2 -0
+			skb = (struct sk_buff *)
+			      packet->send_completion_tid;

As in netvsc_xmit_completion() this must be coded as:

	skb = (struct sk_buff *) (unsigned long)packet->send_completion_tid;