Commit 58ce31cc authored by Tom Herbert's avatar Tom Herbert Committed by David S. Miller

vxlan: GRO support at tunnel layer

Add calls to gro_cells infrastructure to do GRO when receiving on a tunnel.

Testing:

Ran 200 netperf TCP_STREAM instance

  - With fix (GRO enabled on VXLAN interface)

    Verify GRO is happening.

    9084 MBps tput
    3.44% CPU utilization

  - Without fix (GRO disabled on VXLAN interface)

    Verified no GRO is happening.

    9084 MBps tput
    5.54% CPU utilization
Signed-off-by: default avatarTom Herbert <tom@herbertland.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b7fe10e5
...@@ -1208,7 +1208,7 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb, ...@@ -1208,7 +1208,7 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,
stats->rx_bytes += skb->len; stats->rx_bytes += skb->len;
u64_stats_update_end(&stats->syncp); u64_stats_update_end(&stats->syncp);
netif_rx(skb); gro_cells_receive(&vxlan->gro_cells, skb);
return; return;
drop: drop:
...@@ -2446,6 +2446,8 @@ static void vxlan_setup(struct net_device *dev) ...@@ -2446,6 +2446,8 @@ static void vxlan_setup(struct net_device *dev)
vxlan->dev = dev; vxlan->dev = dev;
gro_cells_init(&vxlan->gro_cells, dev);
for (h = 0; h < FDB_HASH_SIZE; ++h) for (h = 0; h < FDB_HASH_SIZE; ++h)
INIT_HLIST_HEAD(&vxlan->fdb_head[h]); INIT_HLIST_HEAD(&vxlan->fdb_head[h]);
} }
...@@ -2885,6 +2887,7 @@ static void vxlan_dellink(struct net_device *dev, struct list_head *head) ...@@ -2885,6 +2887,7 @@ static void vxlan_dellink(struct net_device *dev, struct list_head *head)
hlist_del_rcu(&vxlan->hlist); hlist_del_rcu(&vxlan->hlist);
spin_unlock(&vn->sock_lock); spin_unlock(&vn->sock_lock);
gro_cells_destroy(&vxlan->gro_cells);
list_del(&vxlan->next); list_del(&vxlan->next);
unregister_netdevice_queue(dev, head); unregister_netdevice_queue(dev, head);
} }
...@@ -3093,9 +3096,11 @@ static void __net_exit vxlan_exit_net(struct net *net) ...@@ -3093,9 +3096,11 @@ static void __net_exit vxlan_exit_net(struct net *net)
/* If vxlan->dev is in the same netns, it has already been added /* If vxlan->dev is in the same netns, it has already been added
* to the list by the previous loop. * to the list by the previous loop.
*/ */
if (!net_eq(dev_net(vxlan->dev), net)) if (!net_eq(dev_net(vxlan->dev), net)) {
gro_cells_destroy(&vxlan->gro_cells);
unregister_netdevice_queue(vxlan->dev, &list); unregister_netdevice_queue(vxlan->dev, &list);
} }
}
unregister_netdevice_many(&list); unregister_netdevice_many(&list);
rtnl_unlock(); rtnl_unlock();
......
...@@ -161,6 +161,7 @@ struct vxlan_dev { ...@@ -161,6 +161,7 @@ struct vxlan_dev {
struct timer_list age_timer; struct timer_list age_timer;
spinlock_t hash_lock; spinlock_t hash_lock;
unsigned int addrcnt; unsigned int addrcnt;
struct gro_cells gro_cells;
struct vxlan_config cfg; struct vxlan_config cfg;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment