if_vtnet: Support VIRTIO_NET_F_MTU

This feature lets the guest driver know the maximum MTU size
supported by the host device. If set, use this to limit the
acceptable MTUs, and improve how the receive mbuf cluster size
then is selected.

Reviewed by: grehan (mentor)
Differential Revision: https://reviews.freebsd.org/D27907
This commit is contained in:
Bryan Venteicher 2021-01-19 04:55:24 +00:00
parent fa7ca1e332
commit aabdf5b6e8
2 changed files with 12 additions and 5 deletions

View File

@ -668,6 +668,12 @@ vtnet_setup_features(struct vtnet_softc *sc)
sc->vtnet_flags |= VTNET_FLAG_MAC;
}
if (virtio_with_feature(dev, VIRTIO_NET_F_MTU)) {
sc->vtnet_max_mtu = virtio_read_dev_config_2(dev,
offsetof(struct virtio_net_config, mtu));
} else
sc->vtnet_max_mtu = VTNET_MAX_MTU;
if (virtio_with_feature(dev, VIRTIO_NET_F_MRG_RXBUF)) {
sc->vtnet_flags |= VTNET_FLAG_MRG_RXBUFS;
sc->vtnet_hdr_size = sizeof(struct virtio_net_hdr_mrg_rxbuf);
@ -1094,10 +1100,9 @@ vtnet_rx_cluster_size(struct vtnet_softc *sc, int mtu)
return (MCLBYTES);
/*
* Try to scale the receive mbuf cluster size from the MTU. Without
* the GUEST_TSO[46] features, the VirtIO specification says the
* driver must only be able to receive ~1500 byte frames. But if
* jumbo frames can be transmitted then try to receive jumbo.
* Try to scale the receive mbuf cluster size from the MTU. We
* could also use the VQ size to influence the selected size,
* but that would only matter for very small queues.
*/
if (vtnet_modern(sc)) {
MPASS(sc->vtnet_hdr_size == sizeof(struct virtio_net_hdr_v1));
@ -1128,7 +1133,7 @@ vtnet_ioctl_mtu(struct vtnet_softc *sc, int mtu)
if (ifp->if_mtu == mtu)
return (0);
else if (mtu < ETHERMIN || mtu > VTNET_MAX_MTU)
else if (mtu < ETHERMIN || mtu > sc->vtnet_max_mtu)
return (EINVAL);
ifp->if_mtu = mtu;

View File

@ -164,6 +164,7 @@ struct vtnet_softc {
int vtnet_tx_intr_thresh;
int vtnet_tx_nsegs;
int vtnet_if_flags;
int vtnet_max_mtu;
int vtnet_act_vq_pairs;
int vtnet_max_vq_pairs;
int vtnet_requested_vq_pairs;
@ -297,6 +298,7 @@ CTASSERT(sizeof(struct vtnet_mac_filter) <= PAGE_SIZE);
#define VTNET_COMMON_FEATURES \
(VIRTIO_NET_F_MAC | \
VIRTIO_NET_F_STATUS | \
VIRTIO_NET_F_MTU | \
VIRTIO_NET_F_CTRL_VQ | \
VIRTIO_NET_F_CTRL_RX | \
VIRTIO_NET_F_CTRL_MAC_ADDR | \