hyperv: Enable sendbuf mechanism on the send path
Subsystems (3)
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
@@ -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
@@ -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
David Miller
maintainerFrom: "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;