diff mbox

[ovs-dev,RFC,1/1] netdev-dpdk: Add support for DPDK 16.07

Message ID 1467627167-24440-2-git-send-email-ciara.loftus@intel.com
State Superseded
Delegated to: Daniele Di Proietto
Headers show

Commit Message

Ciara Loftus July 4, 2016, 10:12 a.m. UTC
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.loftus@intel.com>
---
 .travis/linux-build.sh |   2 +-
 INSTALL.DPDK.md        |  12 +--
 lib/netdev-dpdk.c      | 247 ++++++++++++++++++++++++-------------------------
 3 files changed, 128 insertions(+), 133 deletions(-)

Comments

Aaron Conole July 5, 2016, 12:35 p.m. UTC | #1
Hi Ciara,

Ciara Loftus <ciara.loftus@intel.com> writes:

> 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.loftus@intel.com>
> ---

Thanks for this patch - I started work on a similar patchset.  Have you
considered changing the stats lookup design so that we only strcmp once
at initialization and then use the stats id to do the actual stats
processing?  If thing it's worthwhile, I would gladly donate some code to
the cause :-)

Otherwise it looks good.  Thanks for posting it ahead of the DPDK
release, so we can evaluate it!

Reviewed-by: Aaron Conole <aconole@redhat.com>

-Aaron
Ciara Loftus July 5, 2016, 12:41 p.m. UTC | #2
> 
> Hi Ciara,
> 
> Ciara Loftus <ciara.loftus@intel.com> writes:
> 
> > 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.loftus@intel.com>
> > ---
> 
> Thanks for this patch - I started work on a similar patchset.  Have you
> considered changing the stats lookup design so that we only strcmp once
> at initialization and then use the stats id to do the actual stats
> processing?  If thing it's worthwhile, I would gladly donate some code to
> the cause :-)

Hi Aaron,

You're welcome. Certainly, I thought there must be a better way to handle the new xstats but since we're at RFC I didn't pursue much of an investigation.
If you have some code to donate I'll happily merge it into the patch and add you as co-author :-)
I will probably wait until another release candidate to upload a v2.

Thanks,
Ciara

> 
> Otherwise it looks good.  Thanks for posting it ahead of the DPDK
> release, so we can evaluate it!
> 
> Reviewed-by: Aaron Conole <aconole@redhat.com>
> 
> -Aaron
diff mbox

Patch

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)
 {