]> git.droids-corp.org - dpdk.git/commitdiff
net/virtio: support MTU feature
authorMaxime Coquelin <maxime.coquelin@redhat.com>
Sun, 12 Mar 2017 16:34:04 +0000 (17:34 +0100)
committerYuanhan Liu <yuanhan.liu@linux.intel.com>
Sat, 1 Apr 2017 08:36:17 +0000 (10:36 +0200)
This patch implements support for the Virtio MTU feature.
When negotiated, the host shares its maximum supported MTU,
which is used as initial MTU and as maximum MTU the application
can set.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Acked-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
doc/guides/nics/features/virtio.ini
doc/guides/rel_notes/release_17_05.rst
drivers/net/virtio/virtio_ethdev.c
drivers/net/virtio/virtio_ethdev.h
drivers/net/virtio/virtio_pci.h

index 84d201236d997848a59a8c6450afd198cf727457..8e3aca1d99b1a4e7143b19499058e60ef71aa98a 100644 (file)
@@ -25,3 +25,4 @@ ARMv8                = Y
 x86-32               = Y
 x86-64               = Y
 Usage doc            = Y
+MTU update           = Y
index 28fbeabaceca7317531f629954745708ea13f76d..ee8eb6bbb60858c1882af88b31cc05fe73b71400 100644 (file)
@@ -153,6 +153,14 @@ New Features
   * Generic flow API support for Ethernet, VLAN, IPv4, IPv6, UDP and TCP pattern
     items with DROP, QUEUE and PASSTHRU actions for ingress traffic.
 
+* **Added MTU feature support to Virtio and Vhost.**
+
+  Implemented new Virtio MTU feature into Vhost and Virtio:
+
+  * Add ``rte_vhost_mtu_get()`` API to Vhost library.
+  * Enable Vhost PMD's MTU get feature.
+  * Get max MTU value from host in Virtio PMD
+
 
 Resolved Issues
 ---------------
index 66770fc5a9a8a78f8a3aca7cf334fa32c20be738..d9986ab52e0ae1afc9717bd19995a8ae53839243 100644 (file)
@@ -721,10 +721,13 @@ virtio_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
        uint32_t ether_hdr_len = ETHER_HDR_LEN + VLAN_TAG_LEN +
                                 hw->vtnet_hdr_size;
        uint32_t frame_size = mtu + ether_hdr_len;
+       uint32_t max_frame_size = hw->max_mtu + ether_hdr_len;
 
-       if (mtu < ETHER_MIN_MTU || frame_size > VIRTIO_MAX_RX_PKTLEN) {
+       max_frame_size = RTE_MIN(max_frame_size, VIRTIO_MAX_RX_PKTLEN);
+
+       if (mtu < ETHER_MIN_MTU || frame_size > max_frame_size) {
                PMD_INIT_LOG(ERR, "MTU should be between %d and %d",
-                       ETHER_MIN_MTU, VIRTIO_MAX_RX_PKTLEN - ether_hdr_len);
+                       ETHER_MIN_MTU, max_frame_size - ether_hdr_len);
                return -EINVAL;
        }
        return 0;
@@ -1158,6 +1161,18 @@ virtio_negotiate_features(struct virtio_hw *hw, uint64_t req_features)
        PMD_INIT_LOG(DEBUG, "host_features before negotiate = %" PRIx64,
                host_features);
 
+       /* If supported, ensure MTU value is valid before acknowledging it. */
+       if (host_features & req_features & (1ULL << VIRTIO_NET_F_MTU)) {
+               struct virtio_net_config config;
+
+               vtpci_read_dev_config(hw,
+                       offsetof(struct virtio_net_config, mtu),
+                       &config.mtu, sizeof(config.mtu));
+
+               if (config.mtu < ETHER_MIN_MTU)
+                       req_features &= ~(1ULL << VIRTIO_NET_F_MTU);
+       }
+
        /*
         * Negotiate features: Subset of device feature bits are written back
         * guest feature bits.
@@ -1392,6 +1407,32 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 
                hw->max_queue_pairs = config->max_virtqueue_pairs;
 
+               if (vtpci_with_feature(hw, VIRTIO_NET_F_MTU)) {
+                       vtpci_read_dev_config(hw,
+                               offsetof(struct virtio_net_config, mtu),
+                               &config->mtu,
+                               sizeof(config->mtu));
+
+                       /*
+                        * MTU value has already been checked at negotiation
+                        * time, but check again in case it has changed since
+                        * then, which should not happen.
+                        */
+                       if (config->mtu < ETHER_MIN_MTU) {
+                               PMD_INIT_LOG(ERR, "invalid max MTU value (%u)",
+                                               config->mtu);
+                               return -1;
+                       }
+
+                       hw->max_mtu = config->mtu;
+                       /* Set initial MTU to maximum one supported by vhost */
+                       eth_dev->data->mtu = config->mtu;
+
+               } else {
+                       hw->max_mtu = VIRTIO_MAX_RX_PKTLEN - ETHER_HDR_LEN -
+                               VLAN_TAG_LEN - hw->vtnet_hdr_size;
+               }
+
                PMD_INIT_LOG(DEBUG, "config->max_virtqueue_pairs=%d",
                                config->max_virtqueue_pairs);
                PMD_INIT_LOG(DEBUG, "config->status=%d", config->status);
index 777a14be0b44f13daf5f3abbd61323ad1589d921..aa78adc2b85bf1ada8998b45926c016ee5bf84e2 100644 (file)
@@ -51,7 +51,7 @@
 #define VIRTIO_MAX_TX_QUEUES 128U
 #define VIRTIO_MAX_MAC_ADDRS 64
 #define VIRTIO_MIN_RX_BUFSIZE 64
-#define VIRTIO_MAX_RX_PKTLEN  9728
+#define VIRTIO_MAX_RX_PKTLEN  9728U
 
 /* Features desired/implemented by this driver. */
 #define VIRTIO_PMD_DEFAULT_GUEST_FEATURES      \
@@ -66,6 +66,7 @@
         1u << VIRTIO_NET_F_HOST_TSO4     |     \
         1u << VIRTIO_NET_F_HOST_TSO6     |     \
         1u << VIRTIO_NET_F_MRG_RXBUF     |     \
+        1u << VIRTIO_NET_F_MTU | \
         1u << VIRTIO_RING_F_INDIRECT_DESC |    \
         1ULL << VIRTIO_F_VERSION_1       |     \
         1ULL << VIRTIO_F_IOMMU_PLATFORM)
index 1302556ebc6057ff81582a138b8ac9224b4b13d8..0362acd5ee038c55f608e1267d9ed0552cd1246f 100644 (file)
@@ -106,6 +106,7 @@ struct virtnet_ctl;
 /* The feature bitmap for virtio net */
 #define VIRTIO_NET_F_CSUM      0       /* Host handles pkts w/ partial csum */
 #define VIRTIO_NET_F_GUEST_CSUM        1       /* Guest handles pkts w/ partial csum */
+#define VIRTIO_NET_F_MTU       3       /* Initial MTU advice. */
 #define VIRTIO_NET_F_MAC       5       /* Host has given MAC address. */
 #define VIRTIO_NET_F_GUEST_TSO4        7       /* Guest can handle TSOv4 in. */
 #define VIRTIO_NET_F_GUEST_TSO6        8       /* Guest can handle TSOv6 in. */
@@ -252,6 +253,7 @@ struct virtio_hw {
        uint64_t    req_guest_features;
        uint64_t    guest_features;
        uint32_t    max_queue_pairs;
+       uint16_t        max_mtu;
        uint16_t    vtnet_hdr_size;
        uint8_t     vlan_strip;
        uint8_t     use_msix;
@@ -297,6 +299,7 @@ struct virtio_net_config {
        /* See VIRTIO_NET_F_STATUS and VIRTIO_NET_S_* above */
        uint16_t   status;
        uint16_t   max_virtqueue_pairs;
+       uint16_t   mtu;
 } __attribute__((packed));
 
 /*