All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yuanhan Liu <yuanhan.liu@linux.intel.com>
To: dev@dpdk.org
Subject: [PATCH v3 1/3] vhost: get rid of linked list dev
Date: Thu, 10 Mar 2016 12:19:59 +0800	[thread overview]
Message-ID: <1457583601-27365-2-git-send-email-yuanhan.liu@linux.intel.com> (raw)
In-Reply-To: <1457583601-27365-1-git-send-email-yuanhan.liu@linux.intel.com>

While we use a single linked list to maintain all devices, we could
use a static array to achieve the same goal, just like what we did
to maintain the eth devices with rte_eth_devices array. This could
simplifies the code a bit.

Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Acked-by: Huawei Xie <huawei.xie@intel.com>
---
 lib/librte_vhost/virtio-net.c | 209 ++++++++++--------------------------------
 1 file changed, 50 insertions(+), 159 deletions(-)

diff --git a/lib/librte_vhost/virtio-net.c b/lib/librte_vhost/virtio-net.c
index fe1a77e..be91e5f 100644
--- a/lib/librte_vhost/virtio-net.c
+++ b/lib/librte_vhost/virtio-net.c
@@ -55,18 +55,11 @@
 #include "vhost-net.h"
 #include "virtio-net.h"
 
-/*
- * Device linked list structure for configuration.
- */
-struct virtio_net_config_ll {
-	struct virtio_net dev;			/* Virtio device.*/
-	struct virtio_net_config_ll *next;	/* Next dev on linked list.*/
-};
+#define MAX_VHOST_DEVICE	1024
+static struct virtio_net *vhost_devices[MAX_VHOST_DEVICE];
 
 /* device ops to add/remove device to/from data core. */
 struct virtio_net_device_ops const *notify_ops;
-/* root address of the linked list of managed virtio devices */
-static struct virtio_net_config_ll *ll_root;
 
 #define VHOST_USER_F_PROTOCOL_FEATURES	30
 
@@ -116,77 +109,17 @@ qva_to_vva(struct virtio_net *dev, uint64_t qemu_va)
 }
 
 
-/*
- * Retrieves an entry from the devices configuration linked list.
- */
-static struct virtio_net_config_ll *
-get_config_ll_entry(struct vhost_device_ctx ctx)
-{
-	struct virtio_net_config_ll *ll_dev = ll_root;
-
-	/* Loop through linked list until the device_fh is found. */
-	while (ll_dev != NULL) {
-		if (ll_dev->dev.device_fh == ctx.fh)
-			return ll_dev;
-		ll_dev = ll_dev->next;
-	}
-
-	return NULL;
-}
-
-/*
- * Searches the configuration core linked list and
- * retrieves the device if it exists.
- */
 struct virtio_net *
 get_device(struct vhost_device_ctx ctx)
 {
-	struct virtio_net_config_ll *ll_dev;
+	struct virtio_net *dev = vhost_devices[ctx.fh];
 
-	ll_dev = get_config_ll_entry(ctx);
-
-	if (ll_dev)
-		return &ll_dev->dev;
-
-	RTE_LOG(ERR, VHOST_CONFIG,
-		"(%"PRIu64") Device not found in linked list.\n", ctx.fh);
-	return NULL;
-}
-
-/*
- * Add entry containing a device to the device configuration linked list.
- */
-static void
-add_config_ll_entry(struct virtio_net_config_ll *new_ll_dev)
-{
-	struct virtio_net_config_ll *ll_dev = ll_root;
-
-	/* If ll_dev == NULL then this is the first device so go to else */
-	if (ll_dev) {
-		/* If the 1st device_fh != 0 then we insert our device here. */
-		if (ll_dev->dev.device_fh != 0) {
-			new_ll_dev->dev.device_fh = 0;
-			new_ll_dev->next = ll_dev;
-			ll_root = new_ll_dev;
-		} else {
-			/*
-			 * Increment through the ll until we find un unused
-			 * device_fh. Insert the device at that entry.
-			 */
-			while ((ll_dev->next != NULL) &&
-				(ll_dev->dev.device_fh ==
-					(ll_dev->next->dev.device_fh - 1)))
-				ll_dev = ll_dev->next;
-
-			new_ll_dev->dev.device_fh = ll_dev->dev.device_fh + 1;
-			new_ll_dev->next = ll_dev->next;
-			ll_dev->next = new_ll_dev;
-		}
-	} else {
-		ll_root = new_ll_dev;
-		ll_root->dev.device_fh = 0;
+	if (unlikely(!dev)) {
+		RTE_LOG(ERR, VHOST_CONFIG,
+			"(%"PRIu64") device not found.\n", ctx.fh);
 	}
 
+	return dev;
 }
 
 static void
@@ -219,43 +152,14 @@ cleanup_device(struct virtio_net *dev, int destroy)
  * Release virtqueues and device memory.
  */
 static void
-free_device(struct virtio_net_config_ll *ll_dev)
+free_device(struct virtio_net *dev)
 {
 	uint32_t i;
 
-	for (i = 0; i < ll_dev->dev.virt_qp_nb; i++)
-		rte_free(ll_dev->dev.virtqueue[i * VIRTIO_QNUM]);
-
-	rte_free(ll_dev);
-}
+	for (i = 0; i < dev->virt_qp_nb; i++)
+		rte_free(dev->virtqueue[i * VIRTIO_QNUM]);
 
-/*
- * Remove an entry from the device configuration linked list.
- */
-static struct virtio_net_config_ll *
-rm_config_ll_entry(struct virtio_net_config_ll *ll_dev,
-	struct virtio_net_config_ll *ll_dev_last)
-{
-	/* First remove the device and then clean it up. */
-	if (ll_dev == ll_root) {
-		ll_root = ll_dev->next;
-		cleanup_device(&ll_dev->dev, 1);
-		free_device(ll_dev);
-		return ll_root;
-	} else {
-		if (likely(ll_dev_last != NULL)) {
-			ll_dev_last->next = ll_dev->next;
-			cleanup_device(&ll_dev->dev, 1);
-			free_device(ll_dev);
-			return ll_dev_last->next;
-		} else {
-			cleanup_device(&ll_dev->dev, 1);
-			free_device(ll_dev);
-			RTE_LOG(ERR, VHOST_CONFIG,
-				"Remove entry from config_ll failed\n");
-			return NULL;
-		}
-	}
+	rte_free(dev);
 }
 
 static void
@@ -353,23 +257,31 @@ reset_device(struct virtio_net *dev)
 int
 vhost_new_device(struct vhost_device_ctx ctx)
 {
-	struct virtio_net_config_ll *new_ll_dev;
+	struct virtio_net *dev;
+	int i;
 
-	/* Setup device and virtqueues. */
-	new_ll_dev = rte_zmalloc(NULL, sizeof(struct virtio_net_config_ll), 0);
-	if (new_ll_dev == NULL) {
+	dev = rte_zmalloc(NULL, sizeof(struct virtio_net), 0);
+	if (dev == NULL) {
 		RTE_LOG(ERR, VHOST_CONFIG,
 			"(%"PRIu64") Failed to allocate memory for dev.\n",
 			ctx.fh);
 		return -1;
 	}
 
-	new_ll_dev->next = NULL;
+	for (i = 0; i < MAX_VHOST_DEVICE; i++) {
+		if (vhost_devices[i] == NULL)
+			break;
+	}
+	if (i == MAX_VHOST_DEVICE) {
+		RTE_LOG(ERR, VHOST_CONFIG,
+			"Failed to find a free slot for new device.\n");
+		return -1;
+	}
 
-	/* Add entry to device configuration linked list. */
-	add_config_ll_entry(new_ll_dev);
+	vhost_devices[i] = dev;
+	dev->device_fh   = i;
 
-	return new_ll_dev->dev.device_fh;
+	return i;
 }
 
 /*
@@ -379,30 +291,15 @@ vhost_new_device(struct vhost_device_ctx ctx)
 void
 vhost_destroy_device(struct vhost_device_ctx ctx)
 {
-	struct virtio_net_config_ll *ll_dev_cur_ctx, *ll_dev_last = NULL;
-	struct virtio_net_config_ll *ll_dev_cur = ll_root;
-
-	/* Find the linked list entry for the device to be removed. */
-	ll_dev_cur_ctx = get_config_ll_entry(ctx);
-	while (ll_dev_cur != NULL) {
-		/*
-		 * If the device is found or
-		 * a device that doesn't exist is found then it is removed.
-		 */
-		if (ll_dev_cur == ll_dev_cur_ctx) {
-			/*
-			 * If the device is running on a data core then call
-			 * the function to remove it from the data core.
-			 */
-			if ((ll_dev_cur->dev.flags & VIRTIO_DEV_RUNNING))
-				notify_ops->destroy_device(&(ll_dev_cur->dev));
-			ll_dev_cur = rm_config_ll_entry(ll_dev_cur,
-					ll_dev_last);
-		} else {
-			ll_dev_last = ll_dev_cur;
-			ll_dev_cur = ll_dev_cur->next;
-		}
-	}
+	struct virtio_net *dev = get_device(ctx);
+
+	if (dev->flags & VIRTIO_DEV_RUNNING)
+		notify_ops->destroy_device(dev);
+
+	cleanup_device(dev, 1);
+	free_device(dev);
+
+	vhost_devices[ctx.fh] = NULL;
 }
 
 void
@@ -547,17 +444,17 @@ static struct virtio_net*
 numa_realloc(struct virtio_net *dev, int index)
 {
 	int oldnode, newnode;
-	struct virtio_net_config_ll *old_ll_dev, *new_ll_dev = NULL;
+	struct virtio_net *old_dev, *new_dev = NULL;
 	struct vhost_virtqueue *old_vq, *new_vq = NULL;
 	int ret;
 	int realloc_dev = 0, realloc_vq = 0;
 
-	old_ll_dev = (struct virtio_net_config_ll *)dev;
-	old_vq = dev->virtqueue[index];
+	old_dev = dev;
+	old_vq  = dev->virtqueue[index];
 
 	ret  = get_mempolicy(&newnode, NULL, 0, old_vq->desc,
 			MPOL_F_NODE | MPOL_F_ADDR);
-	ret = ret | get_mempolicy(&oldnode, NULL, 0, old_ll_dev,
+	ret = ret | get_mempolicy(&oldnode, NULL, 0, old_dev,
 			MPOL_F_NODE | MPOL_F_ADDR);
 	if (ret) {
 		RTE_LOG(ERR, VHOST_CONFIG,
@@ -581,36 +478,30 @@ numa_realloc(struct virtio_net *dev, int index)
 		return dev;
 
 	if (realloc_dev)
-		new_ll_dev = rte_malloc_socket(NULL,
-			sizeof(struct virtio_net_config_ll), 0, newnode);
+		new_dev = rte_malloc_socket(NULL,
+			sizeof(struct virtio_net), 0, newnode);
 	if (realloc_vq)
 		new_vq = rte_malloc_socket(NULL,
 			sizeof(struct vhost_virtqueue), 0, newnode);
-	if (!new_ll_dev && !new_vq)
+	if (!new_dev && !new_vq)
 		return dev;
 
 	if (realloc_vq)
 		memcpy(new_vq, old_vq, sizeof(*new_vq));
 	if (realloc_dev)
-		memcpy(new_ll_dev, old_ll_dev, sizeof(*new_ll_dev));
-	(new_ll_dev ? new_ll_dev : old_ll_dev)->dev.virtqueue[index] =
+		memcpy(new_dev, old_dev, sizeof(*new_dev));
+
+	(new_dev ? new_dev : old_dev)->virtqueue[index] =
 		new_vq ? new_vq : old_vq;
 	if (realloc_vq)
 		rte_free(old_vq);
 	if (realloc_dev) {
-		if (ll_root == old_ll_dev)
-			ll_root = new_ll_dev;
-		else {
-			struct virtio_net_config_ll *prev = ll_root;
-			while (prev->next != old_ll_dev)
-				prev = prev->next;
-			prev->next = new_ll_dev;
-			new_ll_dev->next = old_ll_dev->next;
-		}
-		rte_free(old_ll_dev);
+		rte_free(old_dev);
+
+		vhost_devices[new_dev->device_fh] = new_dev;
 	}
 
-	return realloc_dev ? &new_ll_dev->dev : dev;
+	return realloc_dev ? new_dev : dev;
 }
 #else
 static struct virtio_net*
-- 
1.9.0

  reply	other threads:[~2016-03-10  4:17 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-18  7:04 [PATCH 1/3] vhost: get rid of linked list dev Yuanhan Liu
2015-12-18  7:04 ` [PATCH 2/3] vhost: simplify numa_realloc Yuanhan Liu
2015-12-22  6:46   ` Xie, Huawei
2015-12-22  6:52     ` Yuanhan Liu
2015-12-18  7:04 ` [PATCH 3/3] vhost: fix vq realloc at numa_realloc Yuanhan Liu
2015-12-22  6:56   ` Xie, Huawei
2015-12-22  3:33 ` [PATCH 1/3] vhost: get rid of linked list dev Xie, Huawei
2015-12-22  6:21 ` Xie, Huawei
2015-12-22  7:28 ` [PATCH v2 " Yuanhan Liu
2015-12-22  7:28   ` [PATCH v2 2/3] vhost: simplify numa_realloc Yuanhan Liu
2015-12-22 14:40     ` Xie, Huawei
2015-12-22  7:28   ` [PATCH v2 3/3] vhost: fix vq realloc at numa_realloc Yuanhan Liu
2016-03-07 13:49     ` Loftus, Ciara
2016-03-08 11:54       ` Yuanhan Liu
2016-03-10  4:19 ` [PATCH v3 0/3] vhost: virtio-net.c cleanups and fixes Yuanhan Liu
2016-03-10  4:19   ` Yuanhan Liu [this message]
2016-03-10  4:20   ` [PATCH v3 2/3] vhost: simplify numa_realloc Yuanhan Liu
2016-03-10  4:20   ` [PATCH v3 3/3] vhost: fix vq realloc at numa_realloc Yuanhan Liu
2016-03-11 15:35   ` [PATCH v3 0/3] vhost: virtio-net.c cleanups and fixes Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1457583601-27365-2-git-send-email-yuanhan.liu@linux.intel.com \
    --to=yuanhan.liu@linux.intel.com \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.