summaryrefslogtreecommitdiffstats
path: root/drivers/net/hyperv/netvsc_drv.c
diff options
context:
space:
mode:
authorHaiyang Zhang <haiyangz@microsoft.com>2018-09-21 18:20:35 +0000
committerDavid S. Miller <davem@davemloft.net>2018-09-22 17:23:15 -0700
commitc8e4eff4675f22ad1110141ed9e62102d4d77e1c (patch)
treeb5b80a632a4034d0f9e2cbae9f748bb90a9eb50f /drivers/net/hyperv/netvsc_drv.c
parentbd4d08daeb959234a9f8365037b0fefa6ae790c6 (diff)
downloadlinux-c8e4eff4675f22ad1110141ed9e62102d4d77e1c.tar.bz2
hv_netvsc: Add support for LRO/RSC in the vSwitch
LRO/RSC in the vSwitch is a feature available in Windows Server 2019 hosts and later. It reduces the per packet processing overhead by coalescing multiple TCP segments when possible. This patch adds netvsc driver support for this feature. Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/hyperv/netvsc_drv.c')
-rw-r--r--drivers/net/hyperv/netvsc_drv.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 3af6d8d15233..f8c18370d9d1 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -744,14 +744,16 @@ void netvsc_linkstatus_callback(struct net_device *net,
}
static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net,
- struct napi_struct *napi,
- const struct ndis_tcp_ip_checksum_info *csum_info,
- const struct ndis_pkt_8021q_info *vlan,
- void *data, u32 buflen)
+ struct netvsc_channel *nvchan)
{
+ struct napi_struct *napi = &nvchan->napi;
+ const struct ndis_pkt_8021q_info *vlan = nvchan->rsc.vlan;
+ const struct ndis_tcp_ip_checksum_info *csum_info =
+ nvchan->rsc.csum_info;
struct sk_buff *skb;
+ int i;
- skb = napi_alloc_skb(napi, buflen);
+ skb = napi_alloc_skb(napi, nvchan->rsc.pktlen);
if (!skb)
return skb;
@@ -759,7 +761,8 @@ static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net,
* Copy to skb. This copy is needed here since the memory pointed by
* hv_netvsc_packet cannot be deallocated
*/
- skb_put_data(skb, data, buflen);
+ for (i = 0; i < nvchan->rsc.cnt; i++)
+ skb_put_data(skb, nvchan->rsc.data[i], nvchan->rsc.len[i]);
skb->protocol = eth_type_trans(skb, net);
@@ -792,14 +795,11 @@ static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net,
*/
int netvsc_recv_callback(struct net_device *net,
struct netvsc_device *net_device,
- struct vmbus_channel *channel,
- void *data, u32 len,
- const struct ndis_tcp_ip_checksum_info *csum_info,
- const struct ndis_pkt_8021q_info *vlan)
+ struct netvsc_channel *nvchan)
{
struct net_device_context *net_device_ctx = netdev_priv(net);
+ struct vmbus_channel *channel = nvchan->channel;
u16 q_idx = channel->offermsg.offer.sub_channel_index;
- struct netvsc_channel *nvchan = &net_device->chan_table[q_idx];
struct sk_buff *skb;
struct netvsc_stats *rx_stats;
@@ -807,8 +807,8 @@ int netvsc_recv_callback(struct net_device *net,
return NVSP_STAT_FAIL;
/* Allocate a skb - TODO direct I/O to pages? */
- skb = netvsc_alloc_recv_skb(net, &nvchan->napi,
- csum_info, vlan, data, len);
+ skb = netvsc_alloc_recv_skb(net, nvchan);
+
if (unlikely(!skb)) {
++net_device_ctx->eth_stats.rx_no_memory;
rcu_read_unlock();
@@ -825,7 +825,7 @@ int netvsc_recv_callback(struct net_device *net,
rx_stats = &nvchan->rx_stats;
u64_stats_update_begin(&rx_stats->syncp);
rx_stats->packets++;
- rx_stats->bytes += len;
+ rx_stats->bytes += nvchan->rsc.pktlen;
if (skb->pkt_type == PACKET_BROADCAST)
++rx_stats->broadcast;