veth: implement ndo_set_rx_headroom
The rx headroom for veth dev is the peer device needed_headroom. Avoid ping-pong updates setting the private flag IFF_PHONY_HEADROOM. This avoids skb head reallocation when forwarding from a veth dev towards a device adding some kind of encapsulation. When transmitting frames below the MTU size towards a vxlan device, this gives about 10% performance speed-up when OVS is used to connect the veth and the vxlan device and a little more when using a plain Linux bridge. Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
eaea34b23c
Коммит
163e529200
|
@ -35,6 +35,7 @@ struct pcpu_vstats {
|
|||
struct veth_priv {
|
||||
struct net_device __rcu *peer;
|
||||
atomic64_t dropped;
|
||||
unsigned requested_headroom;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -271,6 +272,29 @@ static int veth_get_iflink(const struct net_device *dev)
|
|||
return iflink;
|
||||
}
|
||||
|
||||
static void veth_set_rx_headroom(struct net_device *dev, int new_hr)
|
||||
{
|
||||
struct veth_priv *peer_priv, *priv = netdev_priv(dev);
|
||||
struct net_device *peer;
|
||||
|
||||
if (new_hr < 0)
|
||||
new_hr = 0;
|
||||
|
||||
rcu_read_lock();
|
||||
peer = rcu_dereference(priv->peer);
|
||||
if (unlikely(!peer))
|
||||
goto out;
|
||||
|
||||
peer_priv = netdev_priv(peer);
|
||||
priv->requested_headroom = new_hr;
|
||||
new_hr = max(priv->requested_headroom, peer_priv->requested_headroom);
|
||||
dev->needed_headroom = new_hr;
|
||||
peer->needed_headroom = new_hr;
|
||||
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static const struct net_device_ops veth_netdev_ops = {
|
||||
.ndo_init = veth_dev_init,
|
||||
.ndo_open = veth_open,
|
||||
|
@ -285,6 +309,7 @@ static const struct net_device_ops veth_netdev_ops = {
|
|||
#endif
|
||||
.ndo_get_iflink = veth_get_iflink,
|
||||
.ndo_features_check = passthru_features_check,
|
||||
.ndo_set_rx_headroom = veth_set_rx_headroom,
|
||||
};
|
||||
|
||||
#define VETH_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
|
||||
|
@ -301,6 +326,7 @@ static void veth_setup(struct net_device *dev)
|
|||
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
||||
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
|
||||
dev->priv_flags |= IFF_NO_QUEUE;
|
||||
dev->priv_flags |= IFF_PHONY_HEADROOM;
|
||||
|
||||
dev->netdev_ops = &veth_netdev_ops;
|
||||
dev->ethtool_ops = &veth_ethtool_ops;
|
||||
|
|
Загрузка…
Ссылка в новой задаче