[dpdk-dev,10/16] vhost: export vid as the only interface to applications

Message ID 1462227927-22853-11-git-send-email-yuanhan.liu@linux.intel.com (mailing list archive)
State Changes Requested, archived
Delegated to: Yuanhan Liu
Headers

Commit Message

Yuanhan Liu May 2, 2016, 10:25 p.m. UTC
  With all the previous prepare works, we are just one step away from
the final ABI refactoring. That is, to change current API to let them
stick to vid instead of the old virtio_net dev.

Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
 drivers/net/vhost/rte_eth_vhost.c             | 61 ++++++++++-----------------
 examples/vhost/main.c                         | 41 ++++++++++++------
 lib/librte_vhost/rte_virtio_net.h             | 30 +++++--------
 lib/librte_vhost/vhost_rxtx.c                 | 15 ++++++-
 lib/librte_vhost/vhost_user/virtio-net-user.c | 14 +++---
 lib/librte_vhost/virtio-net.c                 | 17 +++++---
 6 files changed, 91 insertions(+), 87 deletions(-)
  

Comments

Rich Lane May 10, 2016, 4:17 p.m. UTC | #1
On Mon, May 2, 2016 at 3:25 PM, Yuanhan Liu <yuanhan.liu@linux.intel.com>
wrote:

> With all the previous prepare works, we are just one step away from
> the final ABI refactoring. That is, to change current API to let them
> stick to vid instead of the old virtio_net dev.
>

This patch removes the only assignment to internal->vid in the PMD. It's
initialized to zero, so only the first vhost connection will work.
  
Yuanhan Liu May 10, 2016, 4:39 p.m. UTC | #2
On Tue, May 10, 2016 at 09:17:23AM -0700, Rich Lane wrote:
> On Mon, May 2, 2016 at 3:25 PM, Yuanhan Liu <yuanhan.liu@linux.intel.com>
> wrote:
> 
>     With all the previous prepare works, we are just one step away from
>     the final ABI refactoring. That is, to change current API to let them
>     stick to vid instead of the old virtio_net dev.
> 
> 
> This patch removes the only assignment to internal->vid in the PMD. It's
> initialized to zero, so only the first vhost connection will work.

I assume you meant to following diff:

-       if (dev == NULL) {
-               RTE_LOG(INFO, PMD, "Invalid argument\n");
-               return -1;
-       }
-
-       list = find_internal_resource(dev->vid);
+       list = find_internal_resource(vid);
        if (list == NULL) {
-               RTE_LOG(INFO, PMD, "Invalid vid %d\n", dev->vid);
+               RTE_LOG(INFO, PMD, "Invalid vid %d\n", vid);
                return -1;
        }

        eth_dev = list->eth_dev;
        internal = eth_dev->data->dev_private;
-       internal->vid = dev->vid;

Then yes, I have no idea why I did that; it's a careless and
hard-to-catch issue. So, thanks a lot for catching it!

Rich, would you help try by adding following line there and
do a test? It would be great if this patch has your Tested-by :)

    internal->vid = vid;

Thanks.

	--yliu
  
Rich Lane May 10, 2016, 5:13 p.m. UTC | #3
On Tue, May 10, 2016 at 9:39 AM, Yuanhan Liu <yuanhan.liu@linux.intel.com>
wrote:
>
> Rich, would you help try by adding following line there and
> do a test? It would be great if this patch has your Tested-by :)
>
>     internal->vid = vid;
>

The problem is new_device has already returned before that point because
find_internal_resource failed.

I suggest adding a cookie parameter to rte_vhost_driver_register and
passing the cookie to each of the vhost_ops. The PMD can use pmd_internals
for the cookie and the whole internal_list can go away.

ps. Could you push git branches somewhere for these larger vhost patch
series? That would make it a lot easier to test than getting patches
individually from patchwork.
  
Yuanhan Liu May 10, 2016, 5:29 p.m. UTC | #4
On Tue, May 10, 2016 at 10:13:18AM -0700, Rich Lane wrote:
> On Tue, May 10, 2016 at 9:39 AM, Yuanhan Liu <yuanhan.liu@linux.intel.com>
> wrote:
> 
>     Rich, would you help try by adding following line there and
>     do a test? It would be great if this patch has your Tested-by :)
> 
>         internal->vid = vid;
> 
>  
> The problem is new_device has already returned before that point because
> find_internal_resource failed.

Oh. right.

> I suggest adding a cookie parameter to rte_vhost_driver_register and passing
> the cookie to each of the vhost_ops. The PMD can use pmd_internals for the
> cookie and the whole internal_list can go away.

TBH, I don't quite like messing rte_vhost_driver_register here.

Maybe I could switch back to the old way to find_internal_resource by
ifname. In such case, I need introduce an API to expose that field
from vhost lib.

> ps. Could you push git branches somewhere for these larger vhost patch series?
> That would make it a lot easier to test than getting patches individually from
> patchwork.

Yes, indeeded. And I have a tree on dpdk.org, but that is mainly for
holding patches for the mainline. I'm thinking I may could add a new
branch there, say staging, just for testing. Thomas, will it work for
you? Or, should I push it to github?

	--yliu
  
Thomas Monjalon May 10, 2016, 7:22 p.m. UTC | #5
2016-05-10 10:29, Yuanhan Liu:
> On Tue, May 10, 2016 at 10:13:18AM -0700, Rich Lane wrote:
> > ps. Could you push git branches somewhere for these larger vhost patch series?
> > That would make it a lot easier to test than getting patches individually from
> > patchwork.
> 
> Yes, indeeded. And I have a tree on dpdk.org, but that is mainly for
> holding patches for the mainline. I'm thinking I may could add a new
> branch there, say staging, just for testing. Thomas, will it work for
> you? Or, should I push it to github?

You are free to create the branches you like on dpdk.org.
  

Patch

diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index 9763cd4..a9dada5 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -68,9 +68,9 @@  static struct ether_addr base_eth_addr = {
 };
 
 struct vhost_queue {
+	int vid;
 	rte_atomic32_t allow_queuing;
 	rte_atomic32_t while_queuing;
-	struct virtio_net *device;
 	struct pmd_internal *internal;
 	struct rte_mempool *mb_pool;
 	uint8_t port;
@@ -137,7 +137,7 @@  eth_vhost_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
 		goto out;
 
 	/* Dequeue packets from guest TX queue */
-	nb_rx = rte_vhost_dequeue_burst(r->device,
+	nb_rx = rte_vhost_dequeue_burst(r->vid,
 			r->virtqueue_id, r->mb_pool, bufs, nb_bufs);
 
 	r->rx_pkts += nb_rx;
@@ -168,7 +168,7 @@  eth_vhost_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
 		goto out;
 
 	/* Enqueue packets to guest RX queue */
-	nb_tx = rte_vhost_enqueue_burst(r->device,
+	nb_tx = rte_vhost_enqueue_burst(r->vid,
 			r->virtqueue_id, bufs, nb_bufs);
 
 	r->tx_pkts += nb_tx;
@@ -217,7 +217,7 @@  find_internal_resource(int vid)
 }
 
 static int
-new_device(struct virtio_net *dev)
+new_device(int vid)
 {
 	struct rte_eth_dev *eth_dev;
 	struct internal_list *list;
@@ -228,23 +228,17 @@  new_device(struct virtio_net *dev)
 	int newnode;
 #endif
 
-	if (dev == NULL) {
-		RTE_LOG(INFO, PMD, "Invalid argument\n");
-		return -1;
-	}
-
-	list = find_internal_resource(dev->vid);
+	list = find_internal_resource(vid);
 	if (list == NULL) {
-		RTE_LOG(INFO, PMD, "Invalid vid %d\n", dev->vid);
+		RTE_LOG(INFO, PMD, "Invalid vid %d\n", vid);
 		return -1;
 	}
 
 	eth_dev = list->eth_dev;
 	internal = eth_dev->data->dev_private;
-	internal->vid = dev->vid;
 
 #ifdef RTE_LIBRTE_VHOST_NUMA
-	newnode = rte_vhost_get_numa_node(dev->vid);
+	newnode = rte_vhost_get_numa_node(vid);
 	if (newnode > 0)
 		eth_dev->data->numa_node = newnode;
 #endif
@@ -253,7 +247,7 @@  new_device(struct virtio_net *dev)
 		vq = eth_dev->data->rx_queues[i];
 		if (vq == NULL)
 			continue;
-		vq->device = dev;
+		vq->vid = vid;
 		vq->internal = internal;
 		vq->port = eth_dev->data->port_id;
 	}
@@ -261,15 +255,14 @@  new_device(struct virtio_net *dev)
 		vq = eth_dev->data->tx_queues[i];
 		if (vq == NULL)
 			continue;
-		vq->device = dev;
+		vq->vid = vid;
 		vq->internal = internal;
 		vq->port = eth_dev->data->port_id;
 	}
 
-	for (i = 0; i < rte_vhost_get_queue_num(dev->vid) * VIRTIO_QNUM; i++)
-		rte_vhost_enable_guest_notification(dev, i, 0);
+	for (i = 0; i < rte_vhost_get_queue_num(vid) * VIRTIO_QNUM; i++)
+		rte_vhost_enable_guest_notification(vid, i, 0);
 
-	dev->priv = eth_dev;
 	eth_dev->data->dev_link.link_status = ETH_LINK_UP;
 
 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
@@ -293,22 +286,19 @@  new_device(struct virtio_net *dev)
 }
 
 static void
-destroy_device(volatile struct virtio_net *dev)
+destroy_device(int vid)
 {
+	struct internal_list *list;
 	struct rte_eth_dev *eth_dev;
 	struct vhost_queue *vq;
 	unsigned i;
 
-	if (dev == NULL) {
-		RTE_LOG(INFO, PMD, "Invalid argument\n");
-		return;
-	}
-
-	eth_dev = (struct rte_eth_dev *)dev->priv;
-	if (eth_dev == NULL) {
-		RTE_LOG(INFO, PMD, "Failed to find a ethdev\n");
+	list = find_internal_resource(vid);
+	if (list == NULL) {
+		RTE_LOG(INFO, PMD, "Invalid vid %d\n", vid);
 		return;
 	}
+	eth_dev = list->eth_dev;
 
 	/* Wait until rx/tx_pkt_burst stops accessing vhost device */
 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
@@ -330,19 +320,17 @@  destroy_device(volatile struct virtio_net *dev)
 
 	eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
 
-	dev->priv = NULL;
-
 	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
 		vq = eth_dev->data->rx_queues[i];
 		if (vq == NULL)
 			continue;
-		vq->device = NULL;
+		vq->vid = -1;
 	}
 	for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
 		vq = eth_dev->data->tx_queues[i];
 		if (vq == NULL)
 			continue;
-		vq->device = NULL;
+		vq->vid = -1;
 	}
 
 	RTE_LOG(INFO, PMD, "Connection closed\n");
@@ -351,20 +339,15 @@  destroy_device(volatile struct virtio_net *dev)
 }
 
 static int
-vring_state_changed(struct virtio_net *dev, uint16_t vring, int enable)
+vring_state_changed(int vid, uint16_t vring, int enable)
 {
 	struct rte_vhost_vring_state *state;
 	struct rte_eth_dev *eth_dev;
 	struct internal_list *list;
 
-	if (dev == NULL) {
-		RTE_LOG(ERR, PMD, "Invalid argument\n");
-		return -1;
-	}
-
-	list = find_internal_resource(dev->vid);
+	list = find_internal_resource(vid);
 	if (list == NULL) {
-		RTE_LOG(ERR, PMD, "Invalid vid %d\n", dev->vid);
+		RTE_LOG(ERR, PMD, "Invalid vid %d\n", vid);
 		return -1;
 	}
 
diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 145fa6f..bbf0d28 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -701,6 +701,19 @@  find_vhost_dev(struct ether_addr *mac)
 	return NULL;
 }
 
+static inline struct vhost_dev *__attribute__((always_inline))
+find_vhost_dev_by_vid(int vid)
+{
+	struct vhost_dev *vdev;
+
+	TAILQ_FOREACH(vdev, &vhost_dev_list, next) {
+		if (vdev->ready == DEVICE_RX && vdev->vid == vid)
+			return vdev;
+	}
+
+	return NULL;
+}
+
 /*
  * This function learns the MAC address of the device and registers this along with a
  * vlan tag to a VMDQ.
@@ -796,7 +809,7 @@  virtio_xmit(struct vhost_dev *dst_vdev, struct vhost_dev *src_vdev,
 {
 	uint16_t ret;
 
-	ret = rte_vhost_enqueue_burst(dst_vdev->dev, VIRTIO_RXQ, &m, 1);
+	ret = rte_vhost_enqueue_burst(dst_vdev->vid, VIRTIO_RXQ, &m, 1);
 	if (enable_stats) {
 		rte_atomic64_inc(&dst_vdev->stats.rx_total_atomic);
 		rte_atomic64_add(&dst_vdev->stats.rx_atomic, ret);
@@ -1042,7 +1055,6 @@  static inline void __attribute__((always_inline))
 drain_eth_rx(struct vhost_dev *vdev)
 {
 	uint16_t rx_count, enqueue_count;
-	struct virtio_net *dev = vdev->dev;
 	struct rte_mbuf *pkts[MAX_PKT_BURST];
 
 	rx_count = rte_eth_rx_burst(ports[0], vdev->vmdq_rx_q,
@@ -1068,7 +1080,7 @@  drain_eth_rx(struct vhost_dev *vdev)
 		}
 	}
 
-	enqueue_count = rte_vhost_enqueue_burst(dev, VIRTIO_RXQ,
+	enqueue_count = rte_vhost_enqueue_burst(vdev->vid, VIRTIO_RXQ,
 						pkts, rx_count);
 	if (enable_stats) {
 		rte_atomic64_add(&vdev->stats.rx_total_atomic, rx_count);
@@ -1085,7 +1097,7 @@  drain_virtio_tx(struct vhost_dev *vdev)
 	uint16_t count;
 	uint16_t i;
 
-	count = rte_vhost_dequeue_burst(vdev->dev, VIRTIO_TXQ, mbuf_pool,
+	count = rte_vhost_dequeue_burst(vdev->vid, VIRTIO_TXQ, mbuf_pool,
 					pkts, MAX_PKT_BURST);
 
 	/* setup VMDq for the first packet */
@@ -1171,13 +1183,17 @@  switch_worker(void *arg __rte_unused)
  * of dev->remove=1 which can cause an infinite loop in the rte_pause loop.
  */
 static void
-destroy_device (volatile struct virtio_net *dev)
+destroy_device(int vid)
 {
 	struct vhost_dev *vdev;
 	int lcore;
 
-	vdev = (struct vhost_dev *)dev->priv;
-	/*set the remove flag. */
+	vdev = find_vhost_dev_by_vid(vid);
+	if (!vdev) {
+		RTE_LOG(ERR, VHOST_CONFIG, "(%d) failed to find device\n", vid);
+		return;
+	}
+
 	vdev->remove = 1;
 	while(vdev->ready != DEVICE_SAFE_REMOVE) {
 		rte_pause();
@@ -1214,12 +1230,11 @@  destroy_device (volatile struct virtio_net *dev)
  * and the allocated to a specific data core.
  */
 static int
-new_device (struct virtio_net *dev)
+new_device(int vid)
 {
 	int lcore, core_add = 0;
 	uint32_t device_num_min = num_devices;
 	struct vhost_dev *vdev;
-	int vid = dev->vid;
 
 	vdev = rte_zmalloc("vhost device", sizeof(*vdev), RTE_CACHE_LINE_SIZE);
 	if (vdev == NULL) {
@@ -1228,8 +1243,6 @@  new_device (struct virtio_net *dev)
 			vid);
 		return -1;
 	}
-	vdev->dev = dev;
-	dev->priv = vdev;
 	vdev->vid = vid;
 
 	TAILQ_INSERT_TAIL(&vhost_dev_list, vdev, next);
@@ -1252,8 +1265,8 @@  new_device (struct virtio_net *dev)
 	lcore_info[vdev->coreid].device_num++;
 
 	/* Disable notifications. */
-	rte_vhost_enable_guest_notification(dev, VIRTIO_RXQ, 0);
-	rte_vhost_enable_guest_notification(dev, VIRTIO_TXQ, 0);
+	rte_vhost_enable_guest_notification(vid, VIRTIO_RXQ, 0);
+	rte_vhost_enable_guest_notification(vid, VIRTIO_TXQ, 0);
 
 	RTE_LOG(INFO, VHOST_DATA,
 		"(%d) device has been added to data core %d\n",
@@ -1309,7 +1322,7 @@  print_stats(void)
 				"RX total:              %" PRIu64 "\n"
 				"RX dropped:            %" PRIu64 "\n"
 				"RX successful:         %" PRIu64 "\n",
-				vdev->dev->vid,
+				vdev->vid,
 				tx_total, tx_dropped, tx,
 				rx_total, rx_dropped, rx);
 		}
diff --git a/lib/librte_vhost/rte_virtio_net.h b/lib/librte_vhost/rte_virtio_net.h
index 27f6847..0a26df9 100644
--- a/lib/librte_vhost/rte_virtio_net.h
+++ b/lib/librte_vhost/rte_virtio_net.h
@@ -178,23 +178,12 @@  struct virtio_memory {
  *
  */
 struct virtio_net_device_ops {
-	int (*new_device)(struct virtio_net *);	/**< Add device. */
-	void (*destroy_device)(volatile struct virtio_net *);	/**< Remove device. */
+	int (*new_device)(int vid);		/**< Add device. */
+	void (*destroy_device)(int vid);	/**< Remove device. */
 
-	int (*vring_state_changed)(struct virtio_net *dev, uint16_t queue_id, int enable);	/**< triggered when a vring is enabled or disabled */
+	int (*vring_state_changed)(int vid, uint16_t queue_id, int enable);	/**< triggered when a vring is enabled or disabled */
 };
 
-static inline uint16_t __attribute__((always_inline))
-rte_vring_available_entries(struct virtio_net *dev, uint16_t queue_id)
-{
-	struct vhost_virtqueue *vq = dev->virtqueue[queue_id];
-
-	if (!vq->enabled)
-		return 0;
-
-	return *(volatile uint16_t *)&vq->avail->idx - vq->last_used_idx_res;
-}
-
 /**
  * Function to convert guest physical addresses to vhost virtual addresses.
  * This is used to convert guest virtio buffer addresses.
@@ -231,7 +220,7 @@  int rte_vhost_feature_enable(uint64_t feature_mask);
 /* Returns currently supported vhost features */
 uint64_t rte_vhost_feature_get(void);
 
-int rte_vhost_enable_guest_notification(struct virtio_net *dev, uint16_t queue_id, int enable);
+int rte_vhost_enable_guest_notification(int vid, uint16_t queue_id, int enable);
 
 /* Register vhost driver. dev_name could be different for multiple instance support. */
 int rte_vhost_driver_register(const char *dev_name);
@@ -286,8 +275,8 @@  int rte_vhost_get_numa_node(int vid);
  * be received from the physical port or from another virtual device. A packet
  * count is returned to indicate the number of packets that were succesfully
  * added to the RX queue.
- * @param dev
- *  virtio-net device
+ * @param vid
+ *  virtio-net device ID
  * @param queue_id
  *  virtio queue index in mq case
  * @param pkts
@@ -297,14 +286,14 @@  int rte_vhost_get_numa_node(int vid);
  * @return
  *  num of packets enqueued
  */
-uint16_t rte_vhost_enqueue_burst(struct virtio_net *dev, uint16_t queue_id,
+uint16_t rte_vhost_enqueue_burst(int vid, uint16_t queue_id,
 	struct rte_mbuf **pkts, uint16_t count);
 
 /**
  * This function gets guest buffers from the virtio device TX virtqueue,
  * construct host mbufs, copies guest buffer content to host mbufs and
  * store them in pkts to be processed.
- * @param dev
+ * @param vid
  *  virtio-net device
  * @param queue_id
  *  virtio queue index in mq case
@@ -317,7 +306,8 @@  uint16_t rte_vhost_enqueue_burst(struct virtio_net *dev, uint16_t queue_id,
  * @return
  *  num of packets dequeued
  */
-uint16_t rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
+uint16_t rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
 	struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count);
 
+
 #endif /* _VIRTIO_NET_H_ */
diff --git a/lib/librte_vhost/vhost_rxtx.c b/lib/librte_vhost/vhost_rxtx.c
index 8d87508..08cab08 100644
--- a/lib/librte_vhost/vhost_rxtx.c
+++ b/lib/librte_vhost/vhost_rxtx.c
@@ -46,6 +46,7 @@ 
 #include <rte_arp.h>
 
 #include "vhost-net.h"
+#include "virtio-net.h"
 
 #define MAX_PKT_BURST 32
 #define VHOST_LOG_PAGE	4096
@@ -587,9 +588,14 @@  virtio_dev_merge_rx(struct virtio_net *dev, uint16_t queue_id,
 }
 
 uint16_t
-rte_vhost_enqueue_burst(struct virtio_net *dev, uint16_t queue_id,
+rte_vhost_enqueue_burst(int vid, uint16_t queue_id,
 	struct rte_mbuf **pkts, uint16_t count)
 {
+	struct virtio_net *dev = get_device(vid);
+
+	if (!dev)
+		return 0;
+
 	if (dev->features & (1 << VIRTIO_NET_F_MRG_RXBUF))
 		return virtio_dev_merge_rx(dev, queue_id, pkts, count);
 	else
@@ -815,9 +821,10 @@  copy_desc_to_mbuf(struct virtio_net *dev, struct vhost_virtqueue *vq,
 }
 
 uint16_t
-rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
+rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
 	struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count)
 {
+	struct virtio_net *dev;
 	struct rte_mbuf *rarp_mbuf = NULL;
 	struct vhost_virtqueue *vq;
 	uint32_t desc_indexes[MAX_PKT_BURST];
@@ -826,6 +833,10 @@  rte_vhost_dequeue_burst(struct virtio_net *dev, uint16_t queue_id,
 	uint16_t free_entries;
 	uint16_t avail_idx;
 
+	dev = get_device(vid);
+	if (!dev)
+		return 0;
+
 	if (unlikely(!is_valid_virt_queue_idx(queue_id, 1, dev->virt_qp_nb))) {
 		RTE_LOG(ERR, VHOST_DATA, "(%d) %s: invalid virtqueue idx %d.\n",
 			dev->vid, __func__, queue_id);
diff --git a/lib/librte_vhost/vhost_user/virtio-net-user.c b/lib/librte_vhost/vhost_user/virtio-net-user.c
index 9385af1..7fa69a7 100644
--- a/lib/librte_vhost/vhost_user/virtio-net-user.c
+++ b/lib/librte_vhost/vhost_user/virtio-net-user.c
@@ -117,7 +117,7 @@  user_set_mem_table(int vid, struct VhostUserMsg *pmsg)
 	/* Remove from the data plane. */
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
-		notify_ops->destroy_device(dev);
+		notify_ops->destroy_device(vid);
 	}
 
 	if (dev->mem) {
@@ -279,6 +279,9 @@  user_set_vring_kick(int vid, struct VhostUserMsg *pmsg)
 	struct vhost_vring_file file;
 	struct virtio_net *dev = get_device(vid);
 
+	if (!dev)
+		return;
+
 	file.index = pmsg->payload.u64 & VHOST_USER_VRING_IDX_MASK;
 	if (pmsg->payload.u64 & VHOST_USER_VRING_NOFD_MASK)
 		file.fd = VIRTIO_INVALID_EVENTFD;
@@ -289,7 +292,7 @@  user_set_vring_kick(int vid, struct VhostUserMsg *pmsg)
 	vhost_set_vring_kick(vid, &file);
 
 	if (virtio_is_ready(dev) && !(dev->flags & VIRTIO_DEV_RUNNING)) {
-		if (notify_ops->new_device(dev) == 0)
+		if (notify_ops->new_device(vid) == 0)
 			dev->flags |= VIRTIO_DEV_RUNNING;
 	}
 }
@@ -307,7 +310,7 @@  user_get_vring_base(int vid,
 		return -1;
 	/* We have to stop the queue (virtio) if it is running. */
 	if (dev->flags & VIRTIO_DEV_RUNNING)
-		notify_ops->destroy_device(dev);
+		notify_ops->destroy_device(vid);
 
 	/* Here we are safe to get the last used index */
 	vhost_get_vring_base(vid, state->index, state);
@@ -342,9 +345,8 @@  user_set_vring_enable(int vid,
 		"set queue enable: %d to qp idx: %d\n",
 		enable, state->index);
 
-	if (notify_ops->vring_state_changed) {
-		notify_ops->vring_state_changed(dev, state->index, enable);
-	}
+	if (notify_ops->vring_state_changed)
+		notify_ops->vring_state_changed(vid, state->index, enable);
 
 	dev->virtqueue[state->index]->enabled = enable;
 
diff --git a/lib/librte_vhost/virtio-net.c b/lib/librte_vhost/virtio-net.c
index 6bf4d87..9fd80a8 100644
--- a/lib/librte_vhost/virtio-net.c
+++ b/lib/librte_vhost/virtio-net.c
@@ -296,7 +296,7 @@  vhost_destroy_device(int vid)
 
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
-		notify_ops->destroy_device(dev);
+		notify_ops->destroy_device(vid);
 	}
 
 	cleanup_device(dev, 1);
@@ -353,7 +353,7 @@  vhost_reset_owner(int vid)
 
 	if (dev->flags & VIRTIO_DEV_RUNNING) {
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
-		notify_ops->destroy_device(dev);
+		notify_ops->destroy_device(vid);
 	}
 
 	cleanup_device(dev, 0);
@@ -717,21 +717,26 @@  vhost_set_backend(int vid, struct vhost_vring_file *file)
 	if (!(dev->flags & VIRTIO_DEV_RUNNING)) {
 		if (dev->virtqueue[VIRTIO_TXQ]->backend != VIRTIO_DEV_STOPPED &&
 		    dev->virtqueue[VIRTIO_RXQ]->backend != VIRTIO_DEV_STOPPED) {
-			if (notify_ops->new_device(dev) < 0)
+			if (notify_ops->new_device(vid) < 0)
 				return -1;
 			dev->flags |= VIRTIO_DEV_RUNNING;
 		}
 	} else if (file->fd == VIRTIO_DEV_STOPPED) {
 		dev->flags &= ~VIRTIO_DEV_RUNNING;
-		notify_ops->destroy_device(dev);
+		notify_ops->destroy_device(vid);
 	}
 
 	return 0;
 }
 
-int rte_vhost_enable_guest_notification(struct virtio_net *dev,
-	uint16_t queue_id, int enable)
+int
+rte_vhost_enable_guest_notification(int vid, uint16_t queue_id, int enable)
 {
+	struct virtio_net *dev = get_device(vid);
+
+	if (!dev)
+		return -1;
+
 	if (enable) {
 		RTE_LOG(ERR, VHOST_CONFIG,
 			"guest notification isn't supported.\n");