On Thu, Dec 20, 2018 at 05:14:54PM -0500, Willem de Bruijn wrote: > From: Willem de Bruijn <will...@google.com> > > Virtio-net devices negotiate LRO support with the host. > Display the initially negotiated state with ethtool -k. > > Also allow configuring it with ethtool -K, reusing the existing > virtnet_set_guest_offloads helper that configures LRO for XDP. > This is conditional on VIRTIO_NET_F_CTRL_GUEST_OFFLOADS. > > Virtio-net negotiates TSO4 and TSO6 separately, but ethtool does not > distinguish between the two. Display LRO as on only if any offload > is active. > > RTNL is held while calling virtnet_set_features, same as on the path > from virtnet_xdp_set. > > Changes v1 -> v2 > - allow ethtool config (-K) only if VIRTIO_NET_F_CTRL_GUEST_OFFLOADS > - show LRO as enabled if any LRO variant is enabled > - do not allow configuration while XDP is active > - differentiate current features from the capable set, to restore > on XDP down only those features that were active on XDP up > - move test out of VIRTIO_NET_F_CSUM/TSO branch, which is tx only
This part shouldn't be in the commit log, right? Should be after "---". > Signed-off-by: Willem de Bruijn <will...@google.com> Acked-by: Michael S. Tsirkin <m...@redhat.com> > --- > drivers/net/virtio_net.c | 33 +++++++++++++++++++++++++++++++++ > 1 file changed, 33 insertions(+) > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > index ea672145f6a66..0237250860467 100644 > --- a/drivers/net/virtio_net.c > +++ b/drivers/net/virtio_net.c > @@ -236,6 +236,7 @@ struct virtnet_info { > u32 speed; > > unsigned long guest_offloads; > + unsigned long guest_offloads_capable; > > /* failover when STANDBY feature enabled */ > struct failover *failover; > @@ -2479,6 +2480,31 @@ static int virtnet_get_phys_port_name(struct > net_device *dev, char *buf, > return 0; > } > > +static int virtnet_set_features(struct net_device *dev, > + netdev_features_t features) > +{ > + struct virtnet_info *vi = netdev_priv(dev); > + u64 offloads; > + int err; > + > + if ((dev->features ^ features) & NETIF_F_LRO) { > + if (vi->xdp_queue_pairs) > + return -EBUSY; > + > + if (features & NETIF_F_LRO) > + offloads = vi->guest_offloads_capable; > + else > + offloads = 0; > + > + err = virtnet_set_guest_offloads(vi, offloads); > + if (err) > + return err; > + vi->guest_offloads = offloads; > + } > + > + return 0; > +} > + > static const struct net_device_ops virtnet_netdev = { > .ndo_open = virtnet_open, > .ndo_stop = virtnet_close, > @@ -2493,6 +2519,7 @@ static const struct net_device_ops virtnet_netdev = { > .ndo_xdp_xmit = virtnet_xdp_xmit, > .ndo_features_check = passthru_features_check, > .ndo_get_phys_port_name = virtnet_get_phys_port_name, > + .ndo_set_features = virtnet_set_features, > }; > > static void virtnet_config_changed_work(struct work_struct *work) > @@ -2951,6 +2978,11 @@ static int virtnet_probe(struct virtio_device *vdev) > } > if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM)) > dev->features |= NETIF_F_RXCSUM; > + if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || > + virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6)) > + dev->features |= NETIF_F_LRO; > + if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) > + dev->hw_features |= NETIF_F_LRO; > > dev->vlan_features = dev->features; > > @@ -3080,6 +3112,7 @@ static int virtnet_probe(struct virtio_device *vdev) > for (i = 0; i < ARRAY_SIZE(guest_offloads); i++) > if (virtio_has_feature(vi->vdev, guest_offloads[i])) > set_bit(guest_offloads[i], &vi->guest_offloads); > + vi->guest_offloads_capable = vi->guest_offloads; > > pr_debug("virtnet: registered device %s with %d RX and TX vq's\n", > dev->name, max_queue_pairs); > -- > 2.20.1.415.g653613c723-goog