net/virtio: remove unnecessary read memory barrier
[dpdk.git] / drivers / net / virtio / virtio_ethdev.c
index b6ed582..9600624 100644 (file)
@@ -23,6 +23,7 @@
 #include <rte_common.h>
 #include <rte_errno.h>
 #include <rte_cpuflags.h>
+#include <rte_vect.h>
 
 #include <rte_memory.h>
 #include <rte_eal.h>
@@ -40,7 +41,7 @@
 static int eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev);
 static int  virtio_dev_configure(struct rte_eth_dev *dev);
 static int  virtio_dev_start(struct rte_eth_dev *dev);
-static void virtio_dev_stop(struct rte_eth_dev *dev);
+static int  virtio_dev_stop(struct rte_eth_dev *dev);
 static int virtio_dev_promiscuous_enable(struct rte_eth_dev *dev);
 static int virtio_dev_promiscuous_disable(struct rte_eth_dev *dev);
 static int virtio_dev_allmulticast_enable(struct rte_eth_dev *dev);
@@ -208,12 +209,12 @@ virtio_send_command_packed(struct virtnet_ctl *cvq,
        virtio_wmb(vq->hw->weak_barriers);
        virtqueue_notify(vq);
 
-       /* wait for used descriptors in virtqueue */
+       /* wait for used desc in virtqueue
+        * desc_is_used has a load-acquire or rte_io_rmb inside
+        */
        while (!desc_is_used(&desc[head], vq))
                usleep(100);
 
-       virtio_rmb(vq->hw->weak_barriers);
-
        /* now get used descriptors */
        vq->vq_free_cnt += nb_descs;
        vq->vq_used_cons_idx += nb_descs;
@@ -609,10 +610,9 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
                txr = hdr_mz->addr;
                memset(txr, 0, vq_size * sizeof(*txr));
                for (i = 0; i < vq_size; i++) {
-                       struct vring_desc *start_dp = txr[i].tx_indir;
-
                        /* first indirect descriptor is always the tx header */
                        if (!vtpci_packed_queue(hw)) {
+                               struct vring_desc *start_dp = txr[i].tx_indir;
                                vring_desc_init_split(start_dp,
                                                      RTE_DIM(txr[i].tx_indir));
                                start_dp->addr = txvq->virtio_net_hdr_mem
@@ -621,6 +621,16 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
                                                   tx_hdr);
                                start_dp->len = hw->vtnet_hdr_size;
                                start_dp->flags = VRING_DESC_F_NEXT;
+                       } else {
+                               struct vring_packed_desc *start_dp =
+                                       txr[i].tx_packed_indir;
+                               vring_desc_init_indirect_packed(start_dp,
+                                     RTE_DIM(txr[i].tx_packed_indir));
+                               start_dp->addr = txvq->virtio_net_hdr_mem
+                                       + i * sizeof(*txr)
+                                       + offsetof(struct virtio_tx_region,
+                                                  tx_hdr);
+                               start_dp->len = hw->vtnet_hdr_size;
                        }
                }
        }
@@ -711,6 +721,8 @@ virtio_dev_close(struct rte_eth_dev *dev)
        struct rte_intr_conf *intr_conf = &dev->data->dev_conf.intr_conf;
 
        PMD_INIT_LOG(DEBUG, "virtio_dev_close");
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return 0;
 
        if (!hw->opened)
                return 0;
@@ -1668,7 +1680,6 @@ virtio_configure_intr(struct rte_eth_dev *dev)
 
        return 0;
 }
-#define SPEED_UNKNOWN    0xffffffff
 #define DUPLEX_UNKNOWN   0xff
 /* reset device and renegotiate features if needed */
 static int
@@ -1708,6 +1719,8 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
        else
                eth_dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC;
 
+       eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
+
        /* Setting up rx_header size for the device */
        if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF) ||
            vtpci_with_feature(hw, VIRTIO_F_VERSION_1) ||
@@ -1725,7 +1738,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
                     hw->mac_addr[0], hw->mac_addr[1], hw->mac_addr[2],
                     hw->mac_addr[3], hw->mac_addr[4], hw->mac_addr[5]);
 
-       if (hw->speed == SPEED_UNKNOWN) {
+       if (hw->speed == ETH_SPEED_NUM_UNKNOWN) {
                if (vtpci_with_feature(hw, VIRTIO_NET_F_SPEED_DUPLEX)) {
                        config = &local_config;
                        vtpci_read_dev_config(hw,
@@ -1738,8 +1751,6 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
                        hw->duplex = config->duplex;
                }
        }
-       if (hw->speed == SPEED_UNKNOWN)
-               hw->speed = ETH_SPEED_NUM_10G;
        if (hw->duplex == DUPLEX_UNKNOWN)
                hw->duplex = ETH_LINK_FULL_DUPLEX;
        PMD_INIT_LOG(DEBUG, "link speed = %d, duplex = %d",
@@ -1891,7 +1902,7 @@ int
 eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 {
        struct virtio_hw *hw = eth_dev->data->dev_private;
-       uint32_t speed = SPEED_UNKNOWN;
+       uint32_t speed = ETH_SPEED_NUM_UNKNOWN;
        int vectorized = 0;
        int ret;
 
@@ -1956,12 +1967,12 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
                if (!vtpci_packed_queue(hw)) {
                        hw->use_vec_rx = 1;
                } else {
-#if !defined(CC_AVX512_SUPPORT)
-                       PMD_DRV_LOG(INFO,
-                               "building environment do not support packed ring vectorized");
-#else
+#if defined(CC_AVX512_SUPPORT) || defined(RTE_ARCH_ARM)
                        hw->use_vec_rx = 1;
                        hw->use_vec_tx = 1;
+#else
+                       PMD_DRV_LOG(INFO,
+                               "building environment do not support packed ring vectorized");
 #endif
                }
        }
@@ -1985,21 +1996,18 @@ err_vtpci_init:
 static int
 eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 {
+       int ret;
        PMD_INIT_FUNC_TRACE();
 
        if (rte_eal_process_type() == RTE_PROC_SECONDARY)
                return 0;
 
-       virtio_dev_stop(eth_dev);
+       ret = virtio_dev_stop(eth_dev);
        virtio_dev_close(eth_dev);
 
-       eth_dev->dev_ops = NULL;
-       eth_dev->tx_pkt_burst = NULL;
-       eth_dev->rx_pkt_burst = NULL;
-
        PMD_INIT_LOG(DEBUG, "dev_uninit completed");
 
-       return 0;
+       return ret;
 }
 
 
@@ -2033,6 +2041,8 @@ virtio_dev_speed_capa_get(uint32_t speed)
                return ETH_LINK_SPEED_56G;
        case ETH_SPEED_NUM_100G:
                return ETH_LINK_SPEED_100G;
+       case ETH_SPEED_NUM_200G:
+               return ETH_LINK_SPEED_200G;
        default:
                return 0;
        }
@@ -2303,7 +2313,19 @@ virtio_dev_configure(struct rte_eth_dev *dev)
                if ((hw->use_vec_rx || hw->use_vec_tx) &&
                    (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512F) ||
                     !vtpci_with_feature(hw, VIRTIO_F_IN_ORDER) ||
-                    !vtpci_with_feature(hw, VIRTIO_F_VERSION_1))) {
+                    !vtpci_with_feature(hw, VIRTIO_F_VERSION_1) ||
+                    rte_vect_get_max_simd_bitwidth() < RTE_VECT_SIMD_512)) {
+                       PMD_DRV_LOG(INFO,
+                               "disabled packed ring vectorized path for requirements not met");
+                       hw->use_vec_rx = 0;
+                       hw->use_vec_tx = 0;
+               }
+#elif defined(RTE_ARCH_ARM)
+               if ((hw->use_vec_rx || hw->use_vec_tx) &&
+                   (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_NEON) ||
+                    !vtpci_with_feature(hw, VIRTIO_F_IN_ORDER) ||
+                    !vtpci_with_feature(hw, VIRTIO_F_VERSION_1) ||
+                    rte_vect_get_max_simd_bitwidth() < RTE_VECT_SIMD_128)) {
                        PMD_DRV_LOG(INFO,
                                "disabled packed ring vectorized path for requirements not met");
                        hw->use_vec_rx = 0;
@@ -2335,7 +2357,7 @@ virtio_dev_configure(struct rte_eth_dev *dev)
                }
 
                if (hw->use_vec_rx) {
-#if defined RTE_ARCH_ARM64 || defined RTE_ARCH_ARM
+#if defined RTE_ARCH_ARM
                        if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_NEON)) {
                                PMD_DRV_LOG(INFO,
                                        "disabled split ring vectorized path for requirement not met");
@@ -2356,6 +2378,12 @@ virtio_dev_configure(struct rte_eth_dev *dev)
                                        "disabled split ring vectorized rx for offloading enabled");
                                hw->use_vec_rx = 0;
                        }
+
+                       if (rte_vect_get_max_simd_bitwidth() < RTE_VECT_SIMD_128) {
+                               PMD_DRV_LOG(INFO,
+                                       "disabled split ring vectorized rx, max SIMD bitwidth too low");
+                               hw->use_vec_rx = 0;
+                       }
                }
        }
 
@@ -2505,7 +2533,7 @@ static void virtio_dev_free_mbufs(struct rte_eth_dev *dev)
 /*
  * Stop device: disable interrupt and mark link down
  */
-static void
+static int
 virtio_dev_stop(struct rte_eth_dev *dev)
 {
        struct virtio_hw *hw = dev->data->dev_private;
@@ -2513,6 +2541,7 @@ virtio_dev_stop(struct rte_eth_dev *dev)
        struct rte_intr_conf *intr_conf = &dev->data->dev_conf.intr_conf;
 
        PMD_INIT_LOG(DEBUG, "stop");
+       dev->data->dev_started = 0;
 
        rte_spinlock_lock(&hw->state_lock);
        if (!hw->started)
@@ -2534,6 +2563,8 @@ virtio_dev_stop(struct rte_eth_dev *dev)
        rte_eth_linkstatus_set(dev, &link);
 out_unlock:
        rte_spinlock_unlock(&hw->state_lock);
+
+       return 0;
 }
 
 static int
@@ -2550,6 +2581,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 
        if (!hw->started) {
                link.link_status = ETH_LINK_DOWN;
+               link.link_speed = ETH_SPEED_NUM_NONE;
        } else if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
                PMD_INIT_LOG(DEBUG, "Get link status from hw");
                vtpci_read_dev_config(hw,
@@ -2557,6 +2589,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
                                &status, sizeof(status));
                if ((status & VIRTIO_NET_S_LINK_UP) == 0) {
                        link.link_status = ETH_LINK_DOWN;
+                       link.link_speed = ETH_SPEED_NUM_NONE;
                        PMD_INIT_LOG(DEBUG, "Port %d is down",
                                     dev->data->port_id);
                } else {