diff options
| author | Di Zhu <zhud@hygon.cn> | 2026-03-23 07:17:30 +0300 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-03-27 06:28:49 +0300 |
| commit | f8844dfeeae88db074146e3f8a865b5565f61b40 (patch) | |
| tree | 9a3b1d9d85b8db0440f2164919ded41eed4be65a | |
| parent | 6a539eee855cbfe9c32507c70003b7710604fcfb (diff) | |
| download | linux-f8844dfeeae88db074146e3f8a865b5565f61b40.tar.xz | |
virtio-net: enable NETIF_F_GRO_HW only if GRO-related offloads are supported
Negotiating VIRTIO_NET_F_CTRL_GUEST_OFFLOADS indicates the device
allows control over offload support, but the offloads that can be
controlled may have nothing to do with GRO (e.g., if neither GUEST_TSO4
nor GUEST_TSO6 is supported).
In such a setup, reporting NETIF_F_GRO_HW as available for the device
is too optimistic and misleading to the user.
Improve the situation by masking off NETIF_F_GRO_HW unless the device
possesses actual GRO-related offload capabilities. Out of an abundance
of caution, this does not change the current behaviour for hardware with
just v6 or just v4 GRO: current interfaces do not allow distinguishing
between v6/v4 GRO, so we can't expose them to userspace precisely.
Signed-off-by: Di Zhu <zhud@hygon.cn>
Acked-by: Jason Wang <jasowang@redhat.com>
Link: https://patch.msgid.link/20260323041730.986351-1-zhud@hygon.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | drivers/net/virtio_net.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 9cf240afe81e..0fcb3f8486c3 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -6800,8 +6800,6 @@ static int virtnet_probe(struct virtio_device *vdev) if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6)) dev->features |= NETIF_F_GRO_HW; - if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) - dev->hw_features |= NETIF_F_GRO_HW; dev->vlan_features = dev->features; dev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT | @@ -6994,6 +6992,19 @@ static int virtnet_probe(struct virtio_device *vdev) enable_rx_mode_work(vi); + for (i = 0; i < ARRAY_SIZE(guest_offloads); i++) { + unsigned int fbit; + + fbit = virtio_offload_to_feature(guest_offloads[i]); + if (virtio_has_feature(vi->vdev, fbit)) + set_bit(guest_offloads[i], &vi->guest_offloads); + } + vi->guest_offloads_capable = vi->guest_offloads; + + if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) && + (vi->guest_offloads_capable & GUEST_OFFLOAD_GRO_HW_MASK)) + dev->hw_features |= NETIF_F_GRO_HW; + /* serialize netdev register + virtio_device_ready() with ndo_open() */ rtnl_lock(); @@ -7076,15 +7087,6 @@ static int virtnet_probe(struct virtio_device *vdev) netif_carrier_on(dev); } - for (i = 0; i < ARRAY_SIZE(guest_offloads); i++) { - unsigned int fbit; - - fbit = virtio_offload_to_feature(guest_offloads[i]); - if (virtio_has_feature(vi->vdev, fbit)) - set_bit(guest_offloads[i], &vi->guest_offloads); - } - vi->guest_offloads_capable = vi->guest_offloads; - rtnl_unlock(); err = virtnet_cpu_notif_add(vi); |
