Commit dbcf24d1 authored by Jason Wang's avatar Jason Wang Committed by David S. Miller

virtio-net: use NETIF_F_GRO_HW instead of NETIF_F_LRO

Commit a02e8964 ("virtio-net: ethtool configurable LRO")
maps LRO to virtio guest offloading features and allows the
administrator to enable and disable those features via ethtool.

This leads to several issues:

- For a device that doesn't support control guest offloads, the "LRO"
  can't be disabled triggering WARN in dev_disable_lro() when turning
  off LRO or when enabling forwarding bridging etc.

- For a device that supports control guest offloads, the guest
  offloads are disabled in cases of bridging, forwarding etc slowing
  down the traffic.

Fix this by using NETIF_F_GRO_HW instead. Though the spec does not
guarantee packets to be re-segmented as the original ones,
we can add that to the spec, possibly with a flag for devices to
differentiate between GRO and LRO.

Further, we never advertised LRO historically before a02e8964
("virtio-net: ethtool configurable LRO") and so bridged/forwarded
configs effectively always relied on virtio receive offloads behaving
like GRO - thus even if this breaks any configs it is at least not
a regression.

Fixes: a02e8964 ("virtio-net: ethtool configurable LRO")
Acked-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Reported-by: default avatarIvan <ivan@prestigetransportation.com>
Tested-by: default avatarIvan <ivan@prestigetransportation.com>
Signed-off-by: default avatarJason Wang <jasowang@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 09e856d5
...@@ -63,7 +63,7 @@ static const unsigned long guest_offloads[] = { ...@@ -63,7 +63,7 @@ static const unsigned long guest_offloads[] = {
VIRTIO_NET_F_GUEST_CSUM VIRTIO_NET_F_GUEST_CSUM
}; };
#define GUEST_OFFLOAD_LRO_MASK ((1ULL << VIRTIO_NET_F_GUEST_TSO4) | \ #define GUEST_OFFLOAD_GRO_HW_MASK ((1ULL << VIRTIO_NET_F_GUEST_TSO4) | \
(1ULL << VIRTIO_NET_F_GUEST_TSO6) | \ (1ULL << VIRTIO_NET_F_GUEST_TSO6) | \
(1ULL << VIRTIO_NET_F_GUEST_ECN) | \ (1ULL << VIRTIO_NET_F_GUEST_ECN) | \
(1ULL << VIRTIO_NET_F_GUEST_UFO)) (1ULL << VIRTIO_NET_F_GUEST_UFO))
...@@ -2515,7 +2515,7 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog, ...@@ -2515,7 +2515,7 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) || virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) ||
virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO) || virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO) ||
virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM))) { virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM))) {
NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing LRO/CSUM, disable LRO/CSUM first"); NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW/CSUM, disable GRO_HW/CSUM first");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -2646,15 +2646,15 @@ static int virtnet_set_features(struct net_device *dev, ...@@ -2646,15 +2646,15 @@ static int virtnet_set_features(struct net_device *dev,
u64 offloads; u64 offloads;
int err; int err;
if ((dev->features ^ features) & NETIF_F_LRO) { if ((dev->features ^ features) & NETIF_F_GRO_HW) {
if (vi->xdp_enabled) if (vi->xdp_enabled)
return -EBUSY; return -EBUSY;
if (features & NETIF_F_LRO) if (features & NETIF_F_GRO_HW)
offloads = vi->guest_offloads_capable; offloads = vi->guest_offloads_capable;
else else
offloads = vi->guest_offloads_capable & offloads = vi->guest_offloads_capable &
~GUEST_OFFLOAD_LRO_MASK; ~GUEST_OFFLOAD_GRO_HW_MASK;
err = virtnet_set_guest_offloads(vi, offloads); err = virtnet_set_guest_offloads(vi, offloads);
if (err) if (err)
...@@ -3134,9 +3134,9 @@ static int virtnet_probe(struct virtio_device *vdev) ...@@ -3134,9 +3134,9 @@ static int virtnet_probe(struct virtio_device *vdev)
dev->features |= NETIF_F_RXCSUM; dev->features |= NETIF_F_RXCSUM;
if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||
virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6)) virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6))
dev->features |= NETIF_F_LRO; dev->features |= NETIF_F_GRO_HW;
if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS))
dev->hw_features |= NETIF_F_LRO; dev->hw_features |= NETIF_F_GRO_HW;
dev->vlan_features = dev->features; dev->vlan_features = dev->features;
......
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