This commit introduces support for DPDK 16.07 and consequently breaks
compatibility with DPDK 16.04.

DPDK 16.07 introduces some changes to various APIs. These have been
updated in OVS, including:
* xstats API: changes to structure of xstats
* vhost API:  replace virtio-net references with 'vid'

Signed-off-by: Ciara Loftus <ciara.lof...@intel.com>
---
 .travis/linux-build.sh |   2 +-
 INSTALL.DPDK.md        |  12 +--
 lib/netdev-dpdk.c      | 247 ++++++++++++++++++++++++-------------------------
 3 files changed, 128 insertions(+), 133 deletions(-)

diff --git a/.travis/linux-build.sh b/.travis/linux-build.sh
index 065de39..1b3d43d 100755
--- a/.travis/linux-build.sh
+++ b/.travis/linux-build.sh
@@ -68,7 +68,7 @@ fi
 
 if [ "$DPDK" ]; then
     if [ -z "$DPDK_VER" ]; then
-        DPDK_VER="16.04"
+        DPDK_VER="16.07"
     fi
     install_dpdk $DPDK_VER
     if [ "$CC" = "clang" ]; then
diff --git a/INSTALL.DPDK.md b/INSTALL.DPDK.md
index 00e75bd..5e63365 100644
--- a/INSTALL.DPDK.md
+++ b/INSTALL.DPDK.md
@@ -16,7 +16,7 @@ OVS needs a system with 1GB hugepages support.
 Building and Installing:
 ------------------------
 
-Required: DPDK 16.04, libnuma
+Required: DPDK 16.07, libnuma
 Optional (if building with vhost-cuse): `fuse`, `fuse-devel` (`libfuse-dev`
 on Debian/Ubuntu)
 
@@ -24,7 +24,7 @@ on Debian/Ubuntu)
   1. Set `$DPDK_DIR`
 
      ```
-     export DPDK_DIR=/usr/src/dpdk-16.04
+     export DPDK_DIR=/usr/src/dpdk-16.07
      cd $DPDK_DIR
      ```
 
@@ -563,7 +563,7 @@ the vswitchd.
 DPDK vhost:
 -----------
 
-DPDK 16.04 supports two types of vhost:
+DPDK 16.07 supports two types of vhost:
 
 1. vhost-user
 2. vhost-cuse
@@ -584,7 +584,7 @@ with OVS.
 DPDK vhost-user Prerequisites:
 -------------------------
 
-1. DPDK 16.04 with vhost support enabled as documented in the "Building and
+1. DPDK 16.07 with vhost support enabled as documented in the "Building and
    Installing section"
 
 2. QEMU version v2.1.0+
@@ -703,7 +703,7 @@ with OVS.
 DPDK vhost-cuse Prerequisites:
 -------------------------
 
-1. DPDK 16.04 with vhost support enabled as documented in the "Building and
+1. DPDK 16.07 with vhost support enabled as documented in the "Building and
    Installing section"
    As an additional step, you must enable vhost-cuse in DPDK by setting the
    following additional flag in `config/common_base`:
@@ -1005,7 +1005,7 @@ Restrictions:
     this with smaller page sizes.
 
   Platform and Network Interface:
-  - By default with DPDK 16.04, a maximum of 64 TX queues can be used with an
+  - By default with DPDK 16.07, a maximum of 64 TX queues can be used with an
     Intel XL710 Network Interface on a platform with more than 64 logical
     cores. If a user attempts to add an XL710 interface as a DPDK port type to
     a system as described above, an error will be reported that initialization
diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index 02e2c58..4968d80 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -364,8 +364,8 @@ struct netdev_dpdk {
     int real_n_rxq;
     bool txq_needs_locking;
 
-    /* virtio-net structure for vhost device */
-    OVSRCU_TYPE(struct virtio_net *) virtio_dev;
+    /* virtio identifier for vhost devices */
+    int vid;
 
     /* Identifier used to distinguish vhost devices from each other */
     char vhost_id[PATH_MAX];
@@ -401,8 +401,6 @@ static bool dpdk_thread_is_pmd(void);
 
 static int netdev_dpdk_construct(struct netdev *);
 
-struct virtio_net * netdev_dpdk_get_virtio(const struct netdev_dpdk *dev);
-
 struct ingress_policer *
 netdev_dpdk_get_ingress_policer(const struct netdev_dpdk *dev);
 
@@ -770,6 +768,7 @@ netdev_dpdk_init(struct netdev *netdev, unsigned int 
port_no,
     dev->flags = 0;
     dev->mtu = ETHER_MTU;
     dev->max_packet_len = MTU_TO_FRAME_LEN(dev->mtu);
+    dev->vid = -1;
 
     buf_size = dpdk_buf_size(dev->mtu);
     dev->dpdk_mp = dpdk_mp_get(dev->socket_id, FRAME_LEN_TO_MTU(buf_size));
@@ -869,6 +868,7 @@ netdev_dpdk_vhost_user_construct(struct netdev *netdev)
     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
     const char *name = netdev->name;
     int err;
+    uint64_t flags = 0;
 
     /* 'name' is appended to 'vhost_sock_dir' and used to create a socket in
      * the file system. '/' or '\' would traverse directories, so they're not
@@ -891,7 +891,7 @@ netdev_dpdk_vhost_user_construct(struct netdev *netdev)
     snprintf(dev->vhost_id, sizeof(dev->vhost_id), "%s/%s",
              vhost_sock_dir, name);
 
-    err = rte_vhost_driver_register(dev->vhost_id);
+    err = rte_vhost_driver_register(dev->vhost_id, flags);
     if (err) {
         VLOG_ERR("vhost-user socket device setup failure for socket %s\n",
                  dev->vhost_id);
@@ -946,13 +946,19 @@ netdev_dpdk_destruct(struct netdev *netdev)
     ovs_mutex_unlock(&dpdk_mutex);
 }
 
+static bool
+is_vhost_running(int vid)
+{
+    return vid >= 0;
+}
+
 static void
 netdev_dpdk_vhost_destruct(struct netdev *netdev)
 {
     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
 
     /* Guest becomes an orphan if still attached. */
-    if (netdev_dpdk_get_virtio(dev) != NULL) {
+    if (is_vhost_running(dev->vid)) {
         VLOG_ERR("Removing port '%s' while vhost device still attached.",
                  netdev->name);
         VLOG_ERR("To restore connectivity after re-adding of port, VM on 
socket"
@@ -1181,12 +1187,6 @@ ingress_policer_run(struct ingress_policer *policer, 
struct rte_mbuf **pkts,
     return cnt;
 }
 
-static bool
-is_vhost_running(struct virtio_net *virtio_dev)
-{
-    return (virtio_dev != NULL && (virtio_dev->flags & VIRTIO_DEV_RUNNING));
-}
-
 static inline void
 netdev_dpdk_vhost_update_rx_size_counters(struct netdev_stats *stats,
                                           unsigned int packet_size)
@@ -1256,13 +1256,12 @@ netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq,
                            struct dp_packet **packets, int *c)
 {
     struct netdev_dpdk *dev = netdev_dpdk_cast(rxq->netdev);
-    struct virtio_net *virtio_dev = netdev_dpdk_get_virtio(dev);
     int qid = rxq->queue_id;
     struct ingress_policer *policer = netdev_dpdk_get_ingress_policer(dev);
     uint16_t nb_rx = 0;
     uint16_t dropped = 0;
 
-    if (OVS_UNLIKELY(!is_vhost_running(virtio_dev)
+    if (OVS_UNLIKELY(!is_vhost_running(dev->vid)
                      || !(dev->flags & NETDEV_UP))) {
         return EAGAIN;
     }
@@ -1271,7 +1270,7 @@ netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq,
         return EOPNOTSUPP;
     }
 
-    nb_rx = rte_vhost_dequeue_burst(virtio_dev, qid * VIRTIO_QNUM + VIRTIO_TXQ,
+    nb_rx = rte_vhost_dequeue_burst(dev->vid, qid * VIRTIO_QNUM + VIRTIO_TXQ,
                                     dev->dpdk_mp->mp,
                                     (struct rte_mbuf **)packets,
                                     NETDEV_MAX_BURST);
@@ -1377,7 +1376,6 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid,
                          bool may_steal)
 {
     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
-    struct virtio_net *virtio_dev = netdev_dpdk_get_virtio(dev);
     struct rte_mbuf **cur_pkts = (struct rte_mbuf **) pkts;
     unsigned int total_pkts = cnt;
     unsigned int qos_pkts = cnt;
@@ -1385,7 +1383,7 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid,
 
     qid = dev->tx_q[qid % dev->real_n_txq].map;
 
-    if (OVS_UNLIKELY(!is_vhost_running(virtio_dev) || qid < 0
+    if (OVS_UNLIKELY(!is_vhost_running(dev->vid) || qid < 0
                      || !(dev->flags & NETDEV_UP))) {
         rte_spinlock_lock(&dev->stats_lock);
         dev->stats.tx_dropped+= cnt;
@@ -1403,7 +1401,7 @@ __netdev_dpdk_vhost_send(struct netdev *netdev, int qid,
         int vhost_qid = qid * VIRTIO_QNUM + VIRTIO_RXQ;
         unsigned int tx_pkts;
 
-        tx_pkts = rte_vhost_enqueue_burst(virtio_dev, vhost_qid,
+        tx_pkts = rte_vhost_enqueue_burst(dev->vid, vhost_qid,
                                           cur_pkts, cnt);
         if (OVS_LIKELY(tx_pkts)) {
             /* Packets have been sent.*/
@@ -1787,60 +1785,50 @@ netdev_dpdk_vhost_get_stats(const struct netdev *netdev,
 
 static void
 netdev_dpdk_convert_xstats(struct netdev_stats *stats,
-                           const struct rte_eth_xstats *xstats,
+                           const struct rte_eth_xstat *xstats,
+                           const struct rte_eth_xstat_name *names,
                            const unsigned int size)
 {
-    /* XXX Current implementation is simple search through an array
-     * to find hardcoded counter names. In future DPDK release (TBD)
-     * XSTATS API will change so each counter will be represented by
-     * unique ID instead of String. */
-
     for (unsigned int i = 0; i < size; i++) {
-        if (strcmp(XSTAT_RX_64_PACKETS, xstats[i].name) == 0) {
+        if (strcmp(XSTAT_RX_64_PACKETS, names[i].name) == 0) {
             stats->rx_1_to_64_packets = xstats[i].value;
-        } else if (strcmp(XSTAT_RX_65_TO_127_PACKETS, xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_RX_65_TO_127_PACKETS, names[i].name) == 0) {
             stats->rx_65_to_127_packets = xstats[i].value;
-        } else if (strcmp(XSTAT_RX_128_TO_255_PACKETS, xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_RX_128_TO_255_PACKETS, names[i].name) == 0) {
             stats->rx_128_to_255_packets = xstats[i].value;
-        } else if (strcmp(XSTAT_RX_256_TO_511_PACKETS, xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_RX_256_TO_511_PACKETS, names[i].name) == 0) {
             stats->rx_256_to_511_packets = xstats[i].value;
-        } else if (strcmp(XSTAT_RX_512_TO_1023_PACKETS,
-                          xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_RX_512_TO_1023_PACKETS, names[i].name) == 0) {
             stats->rx_512_to_1023_packets = xstats[i].value;
-        } else if (strcmp(XSTAT_RX_1024_TO_1522_PACKETS,
-                          xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_RX_1024_TO_1522_PACKETS, names[i].name) == 0) {
             stats->rx_1024_to_1522_packets = xstats[i].value;
-        } else if (strcmp(XSTAT_RX_1523_TO_MAX_PACKETS,
-                          xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_RX_1523_TO_MAX_PACKETS, names[i].name) == 0) {
             stats->rx_1523_to_max_packets = xstats[i].value;
-        } else if (strcmp(XSTAT_TX_64_PACKETS, xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_TX_64_PACKETS, names[i].name) == 0) {
             stats->tx_1_to_64_packets = xstats[i].value;
-        } else if (strcmp(XSTAT_TX_65_TO_127_PACKETS, xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_TX_65_TO_127_PACKETS, names[i].name) == 0) {
             stats->tx_65_to_127_packets = xstats[i].value;
-        } else if (strcmp(XSTAT_TX_128_TO_255_PACKETS, xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_TX_128_TO_255_PACKETS, names[i].name) == 0) {
             stats->tx_128_to_255_packets = xstats[i].value;
-        } else if (strcmp(XSTAT_TX_256_TO_511_PACKETS, xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_TX_256_TO_511_PACKETS, names[i].name) == 0) {
             stats->tx_256_to_511_packets = xstats[i].value;
-        } else if (strcmp(XSTAT_TX_512_TO_1023_PACKETS,
-                          xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_TX_512_TO_1023_PACKETS, names[i].name) == 0) {
             stats->tx_512_to_1023_packets = xstats[i].value;
-        } else if (strcmp(XSTAT_TX_1024_TO_1522_PACKETS,
-                          xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_TX_1024_TO_1522_PACKETS, names[i].name) == 0) {
             stats->tx_1024_to_1522_packets = xstats[i].value;
-        } else if (strcmp(XSTAT_TX_1523_TO_MAX_PACKETS,
-                          xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_TX_1523_TO_MAX_PACKETS, names[i].name) == 0) {
             stats->tx_1523_to_max_packets = xstats[i].value;
-        } else if (strcmp(XSTAT_TX_MULTICAST_PACKETS, xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_TX_MULTICAST_PACKETS, names[i].name) == 0) {
             stats->tx_multicast_packets = xstats[i].value;
-        } else if (strcmp(XSTAT_RX_BROADCAST_PACKETS, xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_RX_BROADCAST_PACKETS, names[i].name) == 0) {
             stats->rx_broadcast_packets = xstats[i].value;
-        } else if (strcmp(XSTAT_TX_BROADCAST_PACKETS, xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_TX_BROADCAST_PACKETS, names[i].name) == 0) {
             stats->tx_broadcast_packets = xstats[i].value;
-        } else if (strcmp(XSTAT_RX_UNDERSIZED_ERRORS, xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_RX_UNDERSIZED_ERRORS, names[i].name) == 0) {
             stats->rx_undersized_errors = xstats[i].value;
-        } else if (strcmp(XSTAT_RX_FRAGMENTED_ERRORS, xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_RX_FRAGMENTED_ERRORS, names[i].name) == 0) {
             stats->rx_fragmented_errors = xstats[i].value;
-        } else if (strcmp(XSTAT_RX_JABBER_ERRORS, xstats[i].name) == 0) {
+        } else if (strcmp(XSTAT_RX_JABBER_ERRORS, names[i].name) == 0) {
             stats->rx_jabber_errors = xstats[i].value;
         }
     }
@@ -1856,7 +1844,8 @@ netdev_dpdk_get_stats(const struct netdev *netdev, struct 
netdev_stats *stats)
     netdev_dpdk_get_carrier(netdev, &gg);
     ovs_mutex_lock(&dev->mutex);
 
-    struct rte_eth_xstats *rte_xstats;
+    struct rte_eth_xstat *rte_xstats;
+    struct rte_eth_xstat_name *rte_xstats_names;
     int rte_xstats_len, rte_xstats_ret;
 
     if (rte_eth_stats_get(dev->port_id, &rte_stats)) {
@@ -1865,20 +1854,51 @@ netdev_dpdk_get_stats(const struct netdev *netdev, 
struct netdev_stats *stats)
         return EPROTO;
     }
 
-    rte_xstats_len = rte_eth_xstats_get(dev->port_id, NULL, 0);
-    if (rte_xstats_len > 0) {
-        rte_xstats = dpdk_rte_mzalloc(sizeof(*rte_xstats) * rte_xstats_len);
-        memset(rte_xstats, 0xff, sizeof(*rte_xstats) * rte_xstats_len);
-        rte_xstats_ret = rte_eth_xstats_get(dev->port_id, rte_xstats,
-                                            rte_xstats_len);
-        if (rte_xstats_ret > 0 && rte_xstats_ret <= rte_xstats_len) {
-            netdev_dpdk_convert_xstats(stats, rte_xstats, rte_xstats_ret);
-        }
+    /* Get length of statistics */
+    rte_xstats_len = rte_eth_xstats_get_names(dev->port_id, NULL, 0);
+    if (rte_xstats_len < 0) {
+        VLOG_WARN("Cannot get XSTATS values for port: %i", dev->port_id);
+        goto out;
+    }
+    /* Reserve memory for xstats names */
+    rte_xstats_names = dpdk_rte_mzalloc(sizeof(*rte_xstats_names)
+                                        * rte_xstats_len);
+    if (rte_xstats_names == NULL) {
+        VLOG_WARN("Cannot allocate memory for XSTATS names for port %i",
+                  dev->port_id);
+        rte_free(rte_xstats_names);
+        goto out;
+    }
+    /* Reserve memory for xstats values */
+    rte_xstats = dpdk_rte_mzalloc(sizeof(*rte_xstats) * rte_xstats_len);
+    if (rte_xstats == NULL) {
+        VLOG_WARN("Cannot allocate memory for XSTATS values for port %i",
+                  dev->port_id);
         rte_free(rte_xstats);
+        goto out;
+    }
+    /* Retreive xstats names */
+    if (rte_xstats_len != rte_eth_xstats_get_names(dev->port_id,
+                                       rte_xstats_names, rte_xstats_len)) {
+        VLOG_WARN("Cannot get XSTATS names for port: %i.", dev->port_id);
+        rte_free(rte_xstats);
+        rte_free(rte_xstats_names);
+        goto out;
+    }
+    /* Retreive xstats values */
+    memset(rte_xstats, 0xff, sizeof(*rte_xstats) * rte_xstats_len);
+    rte_xstats_ret = rte_eth_xstats_get(dev->port_id, rte_xstats,
+                                        rte_xstats_len);
+    if (rte_xstats_ret > 0 && rte_xstats_ret <= rte_xstats_len) {
+        netdev_dpdk_convert_xstats(stats, rte_xstats, rte_xstats_names,
+                                   rte_xstats_len);
     } else {
-        VLOG_WARN("Can't get XSTATS counters for port: %i.", dev->port_id);
+        VLOG_WARN("Cannot get XSTATS values for port: %i.", dev->port_id);
+        rte_free(rte_xstats);
+        rte_free(rte_xstats_names);
     }
 
+out:
     stats->rx_packets = rte_stats.ipackets;
     stats->tx_packets = rte_stats.opackets;
     stats->rx_bytes = rte_stats.ibytes;
@@ -1886,7 +1906,6 @@ netdev_dpdk_get_stats(const struct netdev *netdev, struct 
netdev_stats *stats)
     /* DPDK counts imissed as errors, but count them here as dropped instead */
     stats->rx_errors = rte_stats.ierrors - rte_stats.imissed;
     stats->tx_errors = rte_stats.oerrors;
-    stats->multicast = rte_stats.imcasts;
 
     rte_spinlock_lock(&dev->stats_lock);
     stats->tx_dropped = dev->stats.tx_dropped;
@@ -2053,11 +2072,10 @@ static int
 netdev_dpdk_vhost_get_carrier(const struct netdev *netdev, bool *carrier)
 {
     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
-    struct virtio_net *virtio_dev = netdev_dpdk_get_virtio(dev);
 
     ovs_mutex_lock(&dev->mutex);
 
-    if (is_vhost_running(virtio_dev)) {
+    if (is_vhost_running(dev->vid)) {
         *carrier = 1;
     } else {
         *carrier = 0;
@@ -2125,10 +2143,9 @@ netdev_dpdk_update_flags__(struct netdev_dpdk *dev,
         /* If DPDK_DEV_VHOST device's NETDEV_UP flag was changed and vhost is
          * running then change netdev's change_seq to trigger link state
          * update. */
-        struct virtio_net *virtio_dev = netdev_dpdk_get_virtio(dev);
 
         if ((NETDEV_UP & ((*old_flagsp ^ on) | (*old_flagsp ^ off)))
-            && is_vhost_running(virtio_dev)) {
+            && is_vhost_running(dev->vid)){
             netdev_change_seq_changed(&dev->up);
 
             /* Clear statistics if device is getting up. */
@@ -2256,15 +2273,15 @@ netdev_dpdk_set_admin_state(struct unixctl_conn *conn, 
int argc,
  * Set virtqueue flags so that we do not receive interrupts.
  */
 static void
-set_irq_status(struct virtio_net *virtio_dev)
+set_irq_status(int vid)
 {
     uint32_t i;
     uint64_t idx;
 
-    for (i = 0; i < virtio_dev->virt_qp_nb; i++) {
+    for (i = 0; i < rte_vhost_get_queue_num(vid); i++) {
         idx = i * VIRTIO_QNUM;
-        rte_vhost_enable_guest_notification(virtio_dev, idx + VIRTIO_RXQ, 0);
-        rte_vhost_enable_guest_notification(virtio_dev, idx + VIRTIO_TXQ, 0);
+        rte_vhost_enable_guest_notification(vid, idx + VIRTIO_RXQ, 0);
+        rte_vhost_enable_guest_notification(vid, idx + VIRTIO_TXQ, 0);
     }
 }
 
@@ -2310,16 +2327,15 @@ netdev_dpdk_remap_txqs(struct netdev_dpdk *dev)
 }
 
 static int
-netdev_dpdk_vhost_set_queues(struct netdev_dpdk *dev, struct virtio_net 
*virtio_dev)
+netdev_dpdk_vhost_set_queues(struct netdev_dpdk *dev, int vid)
     OVS_REQUIRES(dev->mutex)
 {
     uint32_t qp_num;
 
-    qp_num = virtio_dev->virt_qp_nb;
+    qp_num = rte_vhost_get_queue_num(vid);
     if (qp_num > dev->up.n_rxq) {
-        VLOG_ERR("vHost Device '%s' %"PRIu64" can't be added - "
-                 "too many queues %d > %d", virtio_dev->ifname, 
virtio_dev->device_fh,
-                 qp_num, dev->up.n_rxq);
+        VLOG_ERR("vHost Device '%s' can't be added - too many queues %d > %d",
+                 dev->vhost_id, qp_num, dev->up.n_rxq);
         return -1;
     }
 
@@ -2340,41 +2356,37 @@ netdev_dpdk_vhost_set_queues(struct netdev_dpdk *dev, 
struct virtio_net *virtio_
  * A new virtio-net device is added to a vhost port.
  */
 static int
-new_device(struct virtio_net *virtio_dev)
+new_device(int vid)
 {
     struct netdev_dpdk *dev;
     bool exists = false;
     int newnode = 0;
-    long err = 0;
+    char ifname[PATH_MAX];
+
+    rte_vhost_get_ifname(vid, ifname, sizeof(ifname));
 
     ovs_mutex_lock(&dpdk_mutex);
     /* Add device to the vhost port with the same name as that passed down. */
     LIST_FOR_EACH(dev, list_node, &dpdk_list) {
-        if (strncmp(virtio_dev->ifname, dev->vhost_id, IF_NAME_SZ) == 0) {
+        if (strncmp(ifname, dev->vhost_id, PATH_MAX) == 0) {
             ovs_mutex_lock(&dev->mutex);
-            if (netdev_dpdk_vhost_set_queues(dev, virtio_dev)) {
+            if (netdev_dpdk_vhost_set_queues(dev, vid)) {
                 ovs_mutex_unlock(&dev->mutex);
                 ovs_mutex_unlock(&dpdk_mutex);
                 return -1;
             }
-            ovsrcu_set(&dev->virtio_dev, virtio_dev);
+            dev->vid = vid;
             exists = true;
 
             /* Get NUMA information */
-            err = get_mempolicy(&newnode, NULL, 0, virtio_dev,
-                                MPOL_F_NODE | MPOL_F_ADDR);
-            if (err) {
-                VLOG_INFO("Error getting NUMA info for vHost Device '%s'",
-                        virtio_dev->ifname);
-                newnode = dev->socket_id;
-            } else if (newnode != dev->socket_id) {
+            newnode = rte_vhost_get_numa_node(vid);
+            if ((newnode != -1) && (newnode != dev->socket_id)) {
                 dev->requested_socket_id = newnode;
                 netdev_request_reconfigure(&dev->up);
             }
 
-            virtio_dev->flags |= VIRTIO_DEV_RUNNING;
             /* Disable notifications. */
-            set_irq_status(virtio_dev);
+            set_irq_status(dev->vid);
             netdev_change_seq_changed(&dev->up);
             ovs_mutex_unlock(&dev->mutex);
             break;
@@ -2383,14 +2395,14 @@ new_device(struct virtio_net *virtio_dev)
     ovs_mutex_unlock(&dpdk_mutex);
 
     if (!exists) {
-        VLOG_INFO("vHost Device '%s' %"PRIu64" can't be added - name not "
-                  "found", virtio_dev->ifname, virtio_dev->device_fh);
+        VLOG_INFO("vHost Device '%s' can't be added - name not found", ifname);
 
         return -1;
     }
 
-    VLOG_INFO("vHost Device '%s' %"PRIu64" has been added on numa node %i",
-              virtio_dev->ifname, virtio_dev->device_fh, newnode);
+    VLOG_INFO("vHost Device '%s' has been added on numa node %i",
+              ifname, newnode);
+
     return 0;
 }
 
@@ -2413,19 +2425,20 @@ netdev_dpdk_txq_map_clear(struct netdev_dpdk *dev)
  *  the device.
  */
 static void
-destroy_device(volatile struct virtio_net *virtio_dev)
+destroy_device(int vid)
 {
     struct netdev_dpdk *dev;
     bool exists = false;
+    char ifname[PATH_MAX];
+
+    rte_vhost_get_ifname(vid, ifname, sizeof(ifname));
 
     ovs_mutex_lock(&dpdk_mutex);
     LIST_FOR_EACH (dev, list_node, &dpdk_list) {
-        if (netdev_dpdk_get_virtio(dev) == virtio_dev) {
-
+        if (dev->vid == vid) {
             ovs_mutex_lock(&dev->mutex);
-            virtio_dev->flags &= ~VIRTIO_DEV_RUNNING;
-            ovsrcu_set(&dev->virtio_dev, NULL);
             netdev_dpdk_txq_map_clear(dev);
+            dev->vid = -1;
             exists = true;
             netdev_change_seq_changed(&dev->up);
             ovs_mutex_unlock(&dev->mutex);
@@ -2436,31 +2449,21 @@ destroy_device(volatile struct virtio_net *virtio_dev)
     ovs_mutex_unlock(&dpdk_mutex);
 
     if (exists == true) {
-        /*
-         * Wait for other threads to quiesce after setting the 'virtio_dev'
-         * to NULL, before returning.
-         */
-        ovsrcu_synchronize();
-        /*
-         * As call to ovsrcu_synchronize() will end the quiescent state,
-         * put thread back into quiescent state before returning.
-         */
-        ovsrcu_quiesce_start();
-        VLOG_INFO("vHost Device '%s' %"PRIu64" has been removed",
-                  virtio_dev->ifname, virtio_dev->device_fh);
+        VLOG_INFO("vHost Device '%s' has been removed", ifname);
     } else {
-        VLOG_INFO("vHost Device '%s' %"PRIu64" not found", virtio_dev->ifname,
-                  virtio_dev->device_fh);
+        VLOG_INFO("vHost Device '%s' not found", ifname);
     }
 }
 
 static int
-vring_state_changed(struct virtio_net *virtio_dev, uint16_t queue_id,
-                    int enable)
+vring_state_changed(int vid, uint16_t queue_id, int enable)
 {
     struct netdev_dpdk *dev;
     bool exists = false;
     int qid = queue_id / VIRTIO_QNUM;
+    char ifname[PATH_MAX];
+
+    rte_vhost_get_ifname(vid, ifname, sizeof(ifname));
 
     if (queue_id % VIRTIO_QNUM == VIRTIO_TXQ) {
         return 0;
@@ -2468,7 +2471,7 @@ vring_state_changed(struct virtio_net *virtio_dev, 
uint16_t queue_id,
 
     ovs_mutex_lock(&dpdk_mutex);
     LIST_FOR_EACH (dev, list_node, &dpdk_list) {
-        if (strncmp(virtio_dev->ifname, dev->vhost_id, IF_NAME_SZ) == 0) {
+        if (strncmp(ifname, dev->vhost_id, PATH_MAX) == 0) {
             ovs_mutex_lock(&dev->mutex);
             if (enable) {
                 dev->tx_q[qid].map = qid;
@@ -2484,25 +2487,17 @@ vring_state_changed(struct virtio_net *virtio_dev, 
uint16_t queue_id,
     ovs_mutex_unlock(&dpdk_mutex);
 
     if (exists) {
-        VLOG_INFO("State of queue %d ( tx_qid %d ) of vhost device '%s' %"
-                  PRIu64" changed to \'%s\'", queue_id, qid,
-                  virtio_dev->ifname, virtio_dev->device_fh,
+        VLOG_INFO("State of queue %d ( tx_qid %d ) of vhost device '%s'"
+                  "changed to \'%s\'", queue_id, qid, ifname,
                   (enable == 1) ? "enabled" : "disabled");
     } else {
-        VLOG_INFO("vHost Device '%s' %"PRIu64" not found", virtio_dev->ifname,
-                  virtio_dev->device_fh);
+        VLOG_INFO("vHost Device '%s' not found", ifname);
         return -1;
     }
 
     return 0;
 }
 
-struct virtio_net *
-netdev_dpdk_get_virtio(const struct netdev_dpdk *dev)
-{
-    return ovsrcu_get(struct virtio_net *, &dev->virtio_dev);
-}
-
 struct ingress_policer *
 netdev_dpdk_get_ingress_policer(const struct netdev_dpdk *dev)
 {
-- 
2.4.3

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to