aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2016-02-26 04:45:40 -0500
committerDavid S. Miller <davem@davemloft.net>2016-03-01 15:54:30 -0500
commiteaea34b23c46bf17b4a5638be69ab3561854f34b (patch)
tree1a2182f40f905d60de941bda9513864eb22fe9ab
parent3a927bc7cf9d0fbe8f4a8189dd5f8440228f64e7 (diff)
net/tun: implement ndo_set_rx_headroom
ndo_set_rx_headroom controls the align value used by tun devices to allocate skbs on frame reception. When the xmit device adds a large encapsulation, this avoids an skb head reallocation on forwarding. The measured improvement when forwarding towards a vxlan dev with frame size below the egress device MTU is as follow: vxlan over ipv6, bridged: +6% vxlan over ipv6, ovs: +7% In case of ipv4 tunnels there is no improvement, since the tun device default alignment provides enough headroom to avoid the skb head reallocation. Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/tun.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 88bb8cc3555b..afdf950617c3 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -187,6 +187,7 @@ struct tun_struct {
187#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ 187#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
188 NETIF_F_TSO6|NETIF_F_UFO) 188 NETIF_F_TSO6|NETIF_F_UFO)
189 189
190 int align;
190 int vnet_hdr_sz; 191 int vnet_hdr_sz;
191 int sndbuf; 192 int sndbuf;
192 struct tap_filter txflt; 193 struct tap_filter txflt;
@@ -934,6 +935,17 @@ static void tun_poll_controller(struct net_device *dev)
934 return; 935 return;
935} 936}
936#endif 937#endif
938
939static void tun_set_headroom(struct net_device *dev, int new_hr)
940{
941 struct tun_struct *tun = netdev_priv(dev);
942
943 if (new_hr < NET_SKB_PAD)
944 new_hr = NET_SKB_PAD;
945
946 tun->align = new_hr;
947}
948
937static const struct net_device_ops tun_netdev_ops = { 949static const struct net_device_ops tun_netdev_ops = {
938 .ndo_uninit = tun_net_uninit, 950 .ndo_uninit = tun_net_uninit,
939 .ndo_open = tun_net_open, 951 .ndo_open = tun_net_open,
@@ -945,6 +957,7 @@ static const struct net_device_ops tun_netdev_ops = {
945#ifdef CONFIG_NET_POLL_CONTROLLER 957#ifdef CONFIG_NET_POLL_CONTROLLER
946 .ndo_poll_controller = tun_poll_controller, 958 .ndo_poll_controller = tun_poll_controller,
947#endif 959#endif
960 .ndo_set_rx_headroom = tun_set_headroom,
948}; 961};
949 962
950static const struct net_device_ops tap_netdev_ops = { 963static const struct net_device_ops tap_netdev_ops = {
@@ -962,6 +975,7 @@ static const struct net_device_ops tap_netdev_ops = {
962 .ndo_poll_controller = tun_poll_controller, 975 .ndo_poll_controller = tun_poll_controller,
963#endif 976#endif
964 .ndo_features_check = passthru_features_check, 977 .ndo_features_check = passthru_features_check,
978 .ndo_set_rx_headroom = tun_set_headroom,
965}; 979};
966 980
967static void tun_flow_init(struct tun_struct *tun) 981static void tun_flow_init(struct tun_struct *tun)
@@ -1086,7 +1100,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
1086 struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) }; 1100 struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) };
1087 struct sk_buff *skb; 1101 struct sk_buff *skb;
1088 size_t total_len = iov_iter_count(from); 1102 size_t total_len = iov_iter_count(from);
1089 size_t len = total_len, align = NET_SKB_PAD, linear; 1103 size_t len = total_len, align = tun->align, linear;
1090 struct virtio_net_hdr gso = { 0 }; 1104 struct virtio_net_hdr gso = { 0 };
1091 int good_linear; 1105 int good_linear;
1092 int copylen; 1106 int copylen;
@@ -1694,6 +1708,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
1694 tun->txflt.count = 0; 1708 tun->txflt.count = 0;
1695 tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr); 1709 tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr);
1696 1710
1711 tun->align = NET_SKB_PAD;
1697 tun->filter_attached = false; 1712 tun->filter_attached = false;
1698 tun->sndbuf = tfile->socket.sk->sk_sndbuf; 1713 tun->sndbuf = tfile->socket.sk->sk_sndbuf;
1699 1714