Skip to content

Commit eaea34b

Browse files
Paolo Abenidavem330
authored andcommitted
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>
1 parent 3a927bc commit eaea34b

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

drivers/net/tun.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ struct tun_struct {
187187
#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
188188
NETIF_F_TSO6|NETIF_F_UFO)
189189

190+
int align;
190191
int vnet_hdr_sz;
191192
int sndbuf;
192193
struct tap_filter txflt;
@@ -934,6 +935,17 @@ static void tun_poll_controller(struct net_device *dev)
934935
return;
935936
}
936937
#endif
938+
939+
static 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+
937949
static const struct net_device_ops tun_netdev_ops = {
938950
.ndo_uninit = tun_net_uninit,
939951
.ndo_open = tun_net_open,
@@ -945,6 +957,7 @@ static const struct net_device_ops tun_netdev_ops = {
945957
#ifdef CONFIG_NET_POLL_CONTROLLER
946958
.ndo_poll_controller = tun_poll_controller,
947959
#endif
960+
.ndo_set_rx_headroom = tun_set_headroom,
948961
};
949962

950963
static const struct net_device_ops tap_netdev_ops = {
@@ -962,6 +975,7 @@ static const struct net_device_ops tap_netdev_ops = {
962975
.ndo_poll_controller = tun_poll_controller,
963976
#endif
964977
.ndo_features_check = passthru_features_check,
978+
.ndo_set_rx_headroom = tun_set_headroom,
965979
};
966980

967981
static 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,
10861100
struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) };
10871101
struct sk_buff *skb;
10881102
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;
10901104
struct virtio_net_hdr gso = { 0 };
10911105
int good_linear;
10921106
int copylen;
@@ -1694,6 +1708,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
16941708
tun->txflt.count = 0;
16951709
tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr);
16961710

1711+
tun->align = NET_SKB_PAD;
16971712
tun->filter_attached = false;
16981713
tun->sndbuf = tfile->socket.sk->sk_sndbuf;
16991714

0 commit comments

Comments
 (0)