DPDK patches and discussions
 help / color / mirror / Atom feed
From: Maxime Coquelin <maxime.coquelin@redhat.com>
To: dev@dpdk.org, matan@mellanox.com, xiao.w.wang@intel.com,
	zhihong.wang@intel.com, xiaolong.ye@intel.com,
	chenbo.xia@intel.com, david.marchand@redhat.com,
	amorenoz@redhat.com, shreyansh.jain@nxp.com,
	viacheslavo@mellanox.com, hemant.agrawal@nxp.com,
	sachin.saxena@nxp.com
Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
Subject: [dpdk-dev] [PATCH 09/14] vhost: use linked-list for vDPA devices
Date: Thu, 11 Jun 2020 23:37:43 +0200
Message-ID: <20200611213748.1967029-10-maxime.coquelin@redhat.com> (raw)
In-Reply-To: <20200611213748.1967029-1-maxime.coquelin@redhat.com>

There is no more notion of device ID outside of vdpa.c.
We can now move from array to linked-list model for keeping
track of the vDPA devices.

There is no point in using array here, as all vDPA API are
used from the control path, so no performance concerns.

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 lib/librte_vhost/rte_vdpa.h |   1 +
 lib/librte_vhost/vdpa.c     | 135 ++++++++++++++++++------------------
 2 files changed, 70 insertions(+), 66 deletions(-)

diff --git a/lib/librte_vhost/rte_vdpa.h b/lib/librte_vhost/rte_vdpa.h
index ca6cb0e882..011befdc71 100644
--- a/lib/librte_vhost/rte_vdpa.h
+++ b/lib/librte_vhost/rte_vdpa.h
@@ -65,6 +65,7 @@ struct rte_vdpa_dev_ops {
  * vdpa device structure includes device address and device operations.
  */
 struct rte_vdpa_device {
+	TAILQ_ENTRY(rte_vdpa_device) next;
 	/** Generic device information */
 	struct rte_device *device;
 	/** vdpa device operations */
diff --git a/lib/librte_vhost/vdpa.c b/lib/librte_vhost/vdpa.c
index ae4df4521d..8f4778e2fa 100644
--- a/lib/librte_vhost/vdpa.c
+++ b/lib/librte_vhost/vdpa.c
@@ -9,35 +9,54 @@
  */
 
 #include <stdbool.h>
+#include <sys/queue.h>
 
 #include <rte_class.h>
 #include <rte_malloc.h>
+#include <rte_spinlock.h>
+#include <rte_tailq.h>
+
 #include "rte_vdpa.h"
 #include "vhost.h"
 
-static struct rte_vdpa_device vdpa_devices[MAX_VHOST_DEVICE];
+/** Double linked list of vDPA devices. */
+TAILQ_HEAD(vdpa_device_list, rte_vdpa_device);
+
+static struct vdpa_device_list vdpa_device_list =
+		TAILQ_HEAD_INITIALIZER(vdpa_device_list);
+static rte_spinlock_t vdpa_device_list_lock = RTE_SPINLOCK_INITIALIZER;
 static uint32_t vdpa_device_num;
 
 
-struct rte_vdpa_device *
-rte_vdpa_find_device_by_name(const char *name)
+/* Unsafe, needs to be called with vdpa_device_list_lock held */
+static struct rte_vdpa_device *
+__vdpa_find_device_by_name(const char *name)
 {
-	struct rte_vdpa_device *dev;
-	int i;
+	struct rte_vdpa_device *dev, *ret = NULL;
 
 	if (name == NULL)
 		return NULL;
 
-	for (i = 0; i < MAX_VHOST_DEVICE; ++i) {
-		dev = &vdpa_devices[i];
-		if (dev->ops == NULL)
-			continue;
-
-		if (strcmp(dev->device->name, name) == 0)
-			return dev;
+	TAILQ_FOREACH(dev, &vdpa_device_list, next) {
+		if (strcmp(dev->device->name, name) == 0) {
+			ret = dev;
+			break;
+		}
 	}
 
-	return NULL;
+	return ret;
+}
+
+struct rte_vdpa_device *
+rte_vdpa_find_device_by_name(const char *name)
+{
+	struct rte_vdpa_device *dev;
+
+	rte_spinlock_lock(&vdpa_device_list_lock);
+	dev = __vdpa_find_device_by_name(name);
+	rte_spinlock_unlock(&vdpa_device_list_lock);
+
+	return dev;
 }
 
 struct rte_device *
@@ -54,52 +73,52 @@ rte_vdpa_register_device(struct rte_device *rte_dev,
 		struct rte_vdpa_dev_ops *ops)
 {
 	struct rte_vdpa_device *dev;
-	int i;
 
-	if (vdpa_device_num >= MAX_VHOST_DEVICE || ops == NULL)
+	if (ops == NULL)
 		return NULL;
 
-	for (i = 0; i < MAX_VHOST_DEVICE; i++) {
-		dev = &vdpa_devices[i];
-		if (dev->ops == NULL)
-			continue;
-
-		if (dev->device == rte_dev)
-			return NULL;
+	rte_spinlock_lock(&vdpa_device_list_lock);
+	/* Check the device hasn't been register already */
+	dev = __vdpa_find_device_by_name(rte_dev->name);
+	if (dev) {
+		dev = NULL;
+		goto out_unlock;
 	}
 
-	for (i = 0; i < MAX_VHOST_DEVICE; i++) {
-		if (vdpa_devices[i].ops == NULL)
-			break;
-	}
-
-	if (i == MAX_VHOST_DEVICE)
-		return NULL;
+	dev = rte_zmalloc(NULL, sizeof(*dev), 0);
+	if (!dev)
+		goto out_unlock;
 
-	dev = &vdpa_devices[i];
 	dev->device = rte_dev;
 	dev->ops = ops;
+	TAILQ_INSERT_TAIL(&vdpa_device_list, dev, next);
 	vdpa_device_num++;
+out_unlock:
+	rte_spinlock_unlock(&vdpa_device_list_lock);
 
 	return dev;
 }
 
 int
-rte_vdpa_unregister_device(struct rte_vdpa_device *vdev)
+rte_vdpa_unregister_device(struct rte_vdpa_device *dev)
 {
-	int i;
+	struct rte_vdpa_device *cur_dev, *tmp_dev;
+	int ret = -1;
 
-	for (i = 0; i < MAX_VHOST_DEVICE; i++) {
-		if (vdev != &vdpa_devices[i])
+	rte_spinlock_lock(&vdpa_device_list_lock);
+	TAILQ_FOREACH_SAFE(cur_dev, &vdpa_device_list, next, tmp_dev) {
+		if (dev != cur_dev)
 			continue;
 
-		memset(vdev, 0, sizeof(struct rte_vdpa_device));
+		TAILQ_REMOVE(&vdpa_device_list, dev, next);
+		rte_free(dev);
 		vdpa_device_num--;
-
-		return 0;
+		ret = 0;
+		break;
 	}
+	rte_spinlock_lock(&vdpa_device_list_lock);
 
-	return -1;
+	return ret;
 }
 
 int
@@ -210,14 +229,6 @@ rte_vdpa_relay_vring_used(int vid, uint16_t qid, void *vring_m)
 	return -1;
 }
 
-static uint16_t
-vdpa_dev_to_id(const struct rte_vdpa_device *dev)
-{
-	if (dev == NULL)
-		return MAX_VHOST_DEVICE;
-	return dev - vdpa_devices;
-}
-
 static int
 vdpa_dev_match(struct rte_vdpa_device *dev,
 	      const struct rte_device *rte_dev)
@@ -237,30 +248,22 @@ vdpa_find_device(const struct rte_vdpa_device *start, rte_vdpa_cmp_t cmp,
 		struct rte_device *rte_dev)
 {
 	struct rte_vdpa_device *dev;
-	ptrdiff_t idx;
 
-	/* Avoid Undefined Behaviour */
-	if (start != NULL &&
-	    (start < &vdpa_devices[0] ||
-	     start >= &vdpa_devices[MAX_VHOST_DEVICE]))
-		return NULL;
-
-	if (start != NULL)
-		idx = vdpa_dev_to_id(start) + 1;
+	rte_spinlock_lock(&vdpa_device_list_lock);
+	if (start == NULL)
+		dev = TAILQ_FIRST(&vdpa_device_list);
 	else
-		idx = 0;
-	for (; idx < MAX_VHOST_DEVICE; idx++) {
-		dev = &vdpa_devices[idx];
-		/*
-		 * ToDo: Certainly better to introduce a state field,
-		 * but rely on ops being set for now.
-		 */
-		if (dev->ops == NULL)
-			continue;
+		dev = TAILQ_NEXT(start, next);
+
+	while (dev != NULL) {
 		if (cmp(dev, rte_dev) == 0)
-			return dev;
+			break;
+
+		dev = TAILQ_NEXT(dev, next);
 	}
-	return NULL;
+	rte_spinlock_unlock(&vdpa_device_list_lock);
+
+	return dev;
 }
 
 static void *
-- 
2.26.2


  parent reply	other threads:[~2020-06-11 21:39 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-11 21:37 [dpdk-dev] [PATCH 00/14] vDPA API and framework rework Maxime Coquelin
2020-06-11 21:37 ` [dpdk-dev] [PATCH 01/14] bus/dpaa: fix null pointer dereference Maxime Coquelin
2020-06-12  9:48   ` Gaëtan Rivet
2020-06-11 21:37 ` [dpdk-dev] [PATCH 02/14] bus/fslmc: " Maxime Coquelin
2020-06-11 21:37 ` [dpdk-dev] [PATCH 03/14] vhost: introduce vDPA devices class Maxime Coquelin
2020-06-12 12:37   ` Gaëtan Rivet
2020-06-15  9:15     ` Maxime Coquelin
2020-06-11 21:37 ` [dpdk-dev] [PATCH 04/14] vhost: make vDPA framework bus agnostic Maxime Coquelin
2020-06-12 12:46   ` Gaëtan Rivet
2020-06-15  9:17     ` Maxime Coquelin
2020-06-19 11:14   ` Adrian Moreno
2020-06-19 15:11     ` Maxime Coquelin
2020-06-22  9:49       ` Adrian Moreno
2020-06-22 12:34         ` Maxime Coquelin
2020-06-11 21:37 ` [dpdk-dev] [PATCH 05/14] vhost: replace device ID in vDPA ops Maxime Coquelin
2020-06-11 21:37 ` [dpdk-dev] [PATCH 06/14] vhost: replace vDPA device ID in Vhost Maxime Coquelin
2020-06-11 21:37 ` [dpdk-dev] [PATCH 07/14] vhost: replace device ID in applications Maxime Coquelin
2020-06-11 21:37 ` [dpdk-dev] [PATCH 08/14] vhost: remove useless vDPA API Maxime Coquelin
2020-06-11 21:37 ` Maxime Coquelin [this message]
2020-06-11 21:37 ` [dpdk-dev] [PATCH 10/14] vhost: introduce wrappers for some vDPA ops Maxime Coquelin
2020-06-11 21:37 ` [dpdk-dev] [PATCH 11/14] examples/vdpa: use new wrappers instead of ops Maxime Coquelin
2020-06-11 21:37 ` [dpdk-dev] [PATCH 12/14] examples/vdpa: remove useless device count Maxime Coquelin
2020-06-11 21:37 ` [dpdk-dev] [PATCH 13/14] vhost: remove vDPA device count API Maxime Coquelin
2020-06-11 21:37 ` [dpdk-dev] [PATCH 14/14] vhost: split vDPA header file Maxime Coquelin
2020-06-12  9:38 ` [dpdk-dev] [PATCH 00/14] vDPA API and framework rework Gaëtan Rivet

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=20200611213748.1967029-10-maxime.coquelin@redhat.com \
    --to=maxime.coquelin@redhat.com \
    --cc=amorenoz@redhat.com \
    --cc=chenbo.xia@intel.com \
    --cc=david.marchand@redhat.com \
    --cc=dev@dpdk.org \
    --cc=hemant.agrawal@nxp.com \
    --cc=matan@mellanox.com \
    --cc=sachin.saxena@nxp.com \
    --cc=shreyansh.jain@nxp.com \
    --cc=viacheslavo@mellanox.com \
    --cc=xiao.w.wang@intel.com \
    --cc=xiaolong.ye@intel.com \
    --cc=zhihong.wang@intel.com \
    /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

DPDK patches and discussions

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://inbox.dpdk.org/dev/0 dev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dev dev/ https://inbox.dpdk.org/dev \
		dev@dpdk.org
	public-inbox-index dev

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.dev


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git