On Tue, Nov 22, 2022 at 3:44 PM Heng Qi <hengqi@xxxxxxxxxxxxxxxxx> wrote: > > When the xdp program sets xdp.frags, which means it can process > multi-buffer packets, so we continue to open xdp support when > features such as GRO_HW are negotiated. > > Signed-off-by: Heng Qi <hengqi@xxxxxxxxxxxxxxxxx> > Reviewed-by: Xuan Zhuo <xuanzhuo@xxxxxxxxxxxxxxxxx> > --- > drivers/net/virtio_net.c | 30 +++++++++++++++++------------- > 1 file changed, 17 insertions(+), 13 deletions(-) > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > index c5046d21b281..8f7d207d58d6 100644 > --- a/drivers/net/virtio_net.c > +++ b/drivers/net/virtio_net.c > @@ -3080,14 +3080,21 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog, > u16 xdp_qp = 0, curr_qp; > int i, err; > > - if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) > - && (virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO4) || > - virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6) || > - 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_CSUM))) { > - NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW/CSUM, disable GRO_HW/CSUM first"); > - return -EOPNOTSUPP; > + if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) { > + if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM)) { > + NL_SET_ERR_MSG_MOD(extack, "Can't set XDP without frags while guest is implementing GUEST_CSUM"); > + return -EOPNOTSUPP; > + } > + > + if (prog && !prog->aux->xdp_has_frags) { > + if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO4) || > + virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_TSO6) || > + virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) || > + virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO)) { > + NL_SET_ERR_MSG_MOD(extack, "Can't set XDP without frags while guest is implementing GUEST_GRO_HW"); > + return -EOPNOTSUPP; > + } > + } > } > > if (vi->mergeable_rx_bufs && !vi->any_header_sg) { > @@ -3095,8 +3102,8 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog, > return -EINVAL; > } > > - if (dev->mtu > max_sz) { > - NL_SET_ERR_MSG_MOD(extack, "MTU too large to enable XDP"); > + if (prog && !prog->aux->xdp_has_frags && dev->mtu > max_sz) { > + NL_SET_ERR_MSG_MOD(extack, "MTU too large to enable XDP without frags"); > netdev_warn(dev, "XDP requires MTU less than %lu\n", max_sz); > return -EINVAL; > } > @@ -3218,9 +3225,6 @@ static int virtnet_set_features(struct net_device *dev, > int err; > > if ((dev->features ^ features) & NETIF_F_GRO_HW) { > - if (vi->xdp_enabled) > - return -EBUSY; This seems suspicious, GRO_HW could be re-enabled accidentally even if it was disabled when attaching an XDP program that is not capable of doing multi-buffer XDP? Thanks > - > if (features & NETIF_F_GRO_HW) > offloads = vi->guest_offloads_capable; > else > -- > 2.19.1.6.gb485710b >