Commit 5e8d3dc7 authored by Heng Qi's avatar Heng Qi Committed by Jakub Kicinski

Revert "veth: Avoid drop packets when xdp_redirect performs"

This reverts commit 2e0de636.

Based on the issues reported by John and Paolo and their comments,
this patch and the corresponding fix 5e5dc33d are reverted, and
we'll remake it.
Signed-off-by: default avatarHeng Qi <hengqi@linux.alibaba.com>
Reviewed-by: default avatarXuan Zhuo <xuanzhuo@linux.alibaba.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent b535d681
...@@ -1119,14 +1119,10 @@ static void veth_disable_xdp_range(struct net_device *dev, int start, int end, ...@@ -1119,14 +1119,10 @@ static void veth_disable_xdp_range(struct net_device *dev, int start, int end,
static int veth_enable_xdp(struct net_device *dev) static int veth_enable_xdp(struct net_device *dev)
{ {
bool napi_already_on = veth_gro_requested(dev) && (dev->flags & IFF_UP);
struct veth_priv *priv = netdev_priv(dev); struct veth_priv *priv = netdev_priv(dev);
bool napi_already_on;
struct veth_rq *rq;
int err, i; int err, i;
rq = &priv->rq[0];
napi_already_on = (dev->flags & IFF_UP) && rcu_access_pointer(rq->napi);
if (!xdp_rxq_info_is_reg(&priv->rq[0].xdp_rxq)) { if (!xdp_rxq_info_is_reg(&priv->rq[0].xdp_rxq)) {
err = veth_enable_xdp_range(dev, 0, dev->real_num_rx_queues, napi_already_on); err = veth_enable_xdp_range(dev, 0, dev->real_num_rx_queues, napi_already_on);
if (err) if (err)
...@@ -1327,28 +1323,18 @@ static int veth_set_channels(struct net_device *dev, ...@@ -1327,28 +1323,18 @@ static int veth_set_channels(struct net_device *dev,
static int veth_open(struct net_device *dev) static int veth_open(struct net_device *dev)
{ {
struct veth_priv *peer_priv, *priv = netdev_priv(dev); struct veth_priv *priv = netdev_priv(dev);
struct net_device *peer = rtnl_dereference(priv->peer); struct net_device *peer = rtnl_dereference(priv->peer);
struct veth_rq *peer_rq;
int err; int err;
if (!peer) if (!peer)
return -ENOTCONN; return -ENOTCONN;
peer_priv = netdev_priv(peer);
peer_rq = &peer_priv->rq[0];
if (priv->_xdp_prog) { if (priv->_xdp_prog) {
err = veth_enable_xdp(dev); err = veth_enable_xdp(dev);
if (err) if (err)
return err; return err;
/* refer to the logic in veth_xdp_set() */ } else if (veth_gro_requested(dev)) {
if (!rtnl_dereference(peer_rq->napi)) {
err = veth_napi_enable(peer);
if (err)
return err;
}
} else if (veth_gro_requested(dev) || peer_priv->_xdp_prog) {
err = veth_napi_enable(dev); err = veth_napi_enable(dev);
if (err) if (err)
return err; return err;
...@@ -1364,29 +1350,17 @@ static int veth_open(struct net_device *dev) ...@@ -1364,29 +1350,17 @@ static int veth_open(struct net_device *dev)
static int veth_close(struct net_device *dev) static int veth_close(struct net_device *dev)
{ {
struct veth_priv *peer_priv, *priv = netdev_priv(dev); struct veth_priv *priv = netdev_priv(dev);
struct net_device *peer = rtnl_dereference(priv->peer); struct net_device *peer = rtnl_dereference(priv->peer);
struct veth_rq *peer_rq;
netif_carrier_off(dev); netif_carrier_off(dev);
if (peer) { if (peer)
peer_priv = netdev_priv(peer); netif_carrier_off(peer);
peer_rq = &peer_priv->rq[0];
}
if (priv->_xdp_prog) { if (priv->_xdp_prog)
veth_disable_xdp(dev); veth_disable_xdp(dev);
/* refer to the logic in veth_xdp_set */ else if (veth_gro_requested(dev))
if (peer && rtnl_dereference(peer_rq->napi)) {
if (!veth_gro_requested(peer) && !peer_priv->_xdp_prog)
veth_napi_del(peer);
}
} else if (veth_gro_requested(dev) || (peer && peer_priv->_xdp_prog)) {
veth_napi_del(dev); veth_napi_del(dev);
}
if (peer)
netif_carrier_off(peer);
return 0; return 0;
} }
...@@ -1496,20 +1470,16 @@ static int veth_set_features(struct net_device *dev, ...@@ -1496,20 +1470,16 @@ static int veth_set_features(struct net_device *dev,
{ {
netdev_features_t changed = features ^ dev->features; netdev_features_t changed = features ^ dev->features;
struct veth_priv *priv = netdev_priv(dev); struct veth_priv *priv = netdev_priv(dev);
struct veth_rq *rq = &priv->rq[0];
int err; int err;
if (!(changed & NETIF_F_GRO) || !(dev->flags & IFF_UP) || priv->_xdp_prog) if (!(changed & NETIF_F_GRO) || !(dev->flags & IFF_UP) || priv->_xdp_prog)
return 0; return 0;
if (features & NETIF_F_GRO) { if (features & NETIF_F_GRO) {
if (!rtnl_dereference(rq->napi)) {
err = veth_napi_enable(dev); err = veth_napi_enable(dev);
if (err) if (err)
return err; return err;
}
} else { } else {
if (rtnl_dereference(rq->napi))
veth_napi_del(dev); veth_napi_del(dev);
} }
return 0; return 0;
...@@ -1542,19 +1512,14 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog, ...@@ -1542,19 +1512,14 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct veth_priv *priv = netdev_priv(dev); struct veth_priv *priv = netdev_priv(dev);
struct veth_priv *peer_priv;
struct bpf_prog *old_prog; struct bpf_prog *old_prog;
struct veth_rq *peer_rq;
struct net_device *peer; struct net_device *peer;
bool napi_already_off;
unsigned int max_mtu; unsigned int max_mtu;
bool noreq_napi;
int err; int err;
old_prog = priv->_xdp_prog; old_prog = priv->_xdp_prog;
priv->_xdp_prog = prog; priv->_xdp_prog = prog;
peer = rtnl_dereference(priv->peer); peer = rtnl_dereference(priv->peer);
peer_priv = netdev_priv(peer);
if (prog) { if (prog) {
if (!peer) { if (!peer) {
...@@ -1591,24 +1556,6 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog, ...@@ -1591,24 +1556,6 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog,
} }
} }
if (peer && (peer->flags & IFF_UP)) {
peer_rq = &peer_priv->rq[0];
/* If the peer hasn't enabled GRO and loaded xdp,
* then we enable napi automatically if its napi
* is not ready.
*/
napi_already_off = !rtnl_dereference(peer_rq->napi);
if (napi_already_off) {
err = veth_napi_enable(peer);
if (err) {
NL_SET_ERR_MSG_MOD(extack,
"Failed to automatically enable napi of peer");
goto err;
}
}
}
if (!old_prog) { if (!old_prog) {
peer->hw_features &= ~NETIF_F_GSO_SOFTWARE; peer->hw_features &= ~NETIF_F_GSO_SOFTWARE;
peer->max_mtu = max_mtu; peer->max_mtu = max_mtu;
...@@ -1623,17 +1570,6 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog, ...@@ -1623,17 +1570,6 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog,
if (peer) { if (peer) {
peer->hw_features |= NETIF_F_GSO_SOFTWARE; peer->hw_features |= NETIF_F_GSO_SOFTWARE;
peer->max_mtu = ETH_MAX_MTU; peer->max_mtu = ETH_MAX_MTU;
peer_rq = &peer_priv->rq[0];
/* If the peer doesn't has its xdp and enabled
* GRO, then we disable napi if its napi is ready;
*/
if (rtnl_dereference(peer_rq->napi)) {
noreq_napi = !veth_gro_requested(peer) &&
!peer_priv->_xdp_prog;
if (noreq_napi && (peer->flags & IFF_UP))
veth_napi_del(peer);
}
} }
} }
bpf_prog_put(old_prog); bpf_prog_put(old_prog);
......
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