[v4,3/4] regexdev: add regexdev core functions

Message ID 1593675963-13317-4-git-send-email-orika@mellanox.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series add RegEx class |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Ori Kam July 2, 2020, 7:46 a.m. UTC
  This commit introduce the API that is needed by the RegEx devices in
order to work with the RegEX lib.

During the probe of a RegEx device, the device should configure itself,
and allocate the resources it requires.
On completion of the device init, it should call the
rte_regex_dev_register in order to register itself as a RegEx device.

Signed-off-by: Ori Kam <orika@mellanox.com>
Signed-off-by: Parav Pandit <parav@mellanox.com>
Acked-by: Guy Kaneti <guyk@marvell.com>
---
v4:
* No changes.

v3:
* Add function to get device by name.

v2:
* Changes resulted from previous patch update.
---
 config/common_base                        |   3 +-
 config/meson.build                        |   1 +
 lib/librte_regexdev/Makefile              |   1 +
 lib/librte_regexdev/meson.build           |   5 +-
 lib/librte_regexdev/rte_regexdev.c        | 139 +++++++++++++++++++++++++++++-
 lib/librte_regexdev/rte_regexdev.h        |   7 ++
 lib/librte_regexdev/rte_regexdev_core.h   |  16 +++-
 lib/librte_regexdev/rte_regexdev_driver.h |  59 +++++++++++++
 meson_options.txt                         |   2 +
 9 files changed, 229 insertions(+), 4 deletions(-)
 create mode 100644 lib/librte_regexdev/rte_regexdev_driver.h
  

Comments

Thomas Monjalon July 5, 2020, 9:08 p.m. UTC | #1
02/07/2020 09:46, Ori Kam:
> --- a/meson_options.txt
> +++ b/meson_options.txt
> @@ -30,6 +30,8 @@ option('max_lcores', type: 'integer', value: 128,
>  	description: 'maximum number of cores/threads supported by EAL')
>  option('max_numa_nodes', type: 'integer', value: 4,
>  	description: 'maximum number of NUMA nodes supported by EAL')
> +option('max_regexdev_devs', type: 'integer', value: 32,
> +	description: 'maximum number of RegEx devices')

Do we really want to add such option in meson?
Some other classes do not expose any option here.
I tend to think it should be hidden.
If the max is really varying, it should be dynamic.
By the way, the maximum number of ethdev ports should be made infinite
with a dynamic array.

Bruce, any opinion please?
  
Ori Kam July 6, 2020, 6:07 a.m. UTC | #2
> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Monday, July 6, 2020 12:08 AM
> Subject: Re: [dpdk-dev] [PATCH v4 3/4] regexdev: add regexdev core functions
> 
> 02/07/2020 09:46, Ori Kam:
> > --- a/meson_options.txt
> > +++ b/meson_options.txt
> > @@ -30,6 +30,8 @@ option('max_lcores', type: 'integer', value: 128,
> >  	description: 'maximum number of cores/threads supported by EAL')
> >  option('max_numa_nodes', type: 'integer', value: 4,
> >  	description: 'maximum number of NUMA nodes supported by EAL')
> > +option('max_regexdev_devs', type: 'integer', value: 32,
> > +	description: 'maximum number of RegEx devices')
> 
> Do we really want to add such option in meson?
> Some other classes do not expose any option here.
> I tend to think it should be hidden.
> If the max is really varying, it should be dynamic.
> By the way, the maximum number of ethdev ports should be made infinite
> with a dynamic array.
> 
> Bruce, any opinion please?
> 
Why this is just like ethdev:
option('max_ethports', type: 'integer', value: 32,
description: 'maximum number of Ethernet devices')
Best,
Ori
  
Thomas Monjalon July 6, 2020, 7:03 a.m. UTC | #3
06/07/2020 08:07, Ori Kam:
> From: Thomas Monjalon <thomas@monjalon.net>
> > 02/07/2020 09:46, Ori Kam:
> > > --- a/meson_options.txt
> > > +++ b/meson_options.txt
> > > @@ -30,6 +30,8 @@ option('max_lcores', type: 'integer', value: 128,
> > >  	description: 'maximum number of cores/threads supported by EAL')
> > >  option('max_numa_nodes', type: 'integer', value: 4,
> > >  	description: 'maximum number of NUMA nodes supported by EAL')
> > > +option('max_regexdev_devs', type: 'integer', value: 32,
> > > +	description: 'maximum number of RegEx devices')
> > 
> > Do we really want to add such option in meson?
> > Some other classes do not expose any option here.
> > I tend to think it should be hidden.
> > If the max is really varying, it should be dynamic.
> > By the way, the maximum number of ethdev ports should be made infinite
> > with a dynamic array.
> > 
> > Bruce, any opinion please?
> > 
> Why this is just like ethdev:
> option('max_ethports', type: 'integer', value: 32,
> description: 'maximum number of Ethernet devices')

Ethdev is the only class exposing such option.
And we already have some requests to replace it with
on-demand runtime dynamic size.
That's why it's better not exposing such bad config.
Anyway we are probably not going to need more than 32 regex engines
in the near future. It gives us time to switch to a dynamic model.
  
Bruce Richardson July 6, 2020, 8 a.m. UTC | #4
On Mon, Jul 06, 2020 at 09:03:49AM +0200, Thomas Monjalon wrote:
> 06/07/2020 08:07, Ori Kam:
> > From: Thomas Monjalon <thomas@monjalon.net>
> > > 02/07/2020 09:46, Ori Kam:
> > > > --- a/meson_options.txt
> > > > +++ b/meson_options.txt
> > > > @@ -30,6 +30,8 @@ option('max_lcores', type: 'integer', value: 128,
> > > >  	description: 'maximum number of cores/threads supported by EAL')
> > > >  option('max_numa_nodes', type: 'integer', value: 4,
> > > >  	description: 'maximum number of NUMA nodes supported by EAL')
> > > > +option('max_regexdev_devs', type: 'integer', value: 32,
> > > > +	description: 'maximum number of RegEx devices')
> > > 
> > > Do we really want to add such option in meson?
> > > Some other classes do not expose any option here.
> > > I tend to think it should be hidden.
> > > If the max is really varying, it should be dynamic.
> > > By the way, the maximum number of ethdev ports should be made infinite
> > > with a dynamic array.
> > > 
> > > Bruce, any opinion please?
> > > 
> > Why this is just like ethdev:
> > option('max_ethports', type: 'integer', value: 32,
> > description: 'maximum number of Ethernet devices')
> 
> Ethdev is the only class exposing such option.
> And we already have some requests to replace it with
> on-demand runtime dynamic size.
> That's why it's better not exposing such bad config.
> Anyway we are probably not going to need more than 32 regex engines
> in the near future. It gives us time to switch to a dynamic model.
>
I would tend to agree. In general I do not like adding new config options
so I'd prefer this not be exposed unless necessary. For ethdev, since it is
by far the mostly widely used, and since we know that people have some
varying port requirements, we have exposed this, while other classes have
not, indicating that it's probably not necessary for most device
categories.

/Bruce
  

Patch

diff --git a/config/common_base b/config/common_base
index d7f07b9..5b8dae4 100644
--- a/config/common_base
+++ b/config/common_base
@@ -832,9 +832,10 @@  CONFIG_RTE_LIBRTE_PMD_OCTEONTX2_EP_RAWDEV=y
 CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
 
 #
-# Compile regex device support
+# Compile RexEx device support
 #
 CONFIG_RTE_LIBRTE_REGEXDEV=y
+CONFIG_RTE_MAX_REGEXDEV_DEVS=32
 
 #
 # Compile librte_ring
diff --git a/config/meson.build b/config/meson.build
index 351e268..1cb86e9 100644
--- a/config/meson.build
+++ b/config/meson.build
@@ -232,6 +232,7 @@  endforeach
 dpdk_conf.set('RTE_MAX_LCORE', get_option('max_lcores'))
 dpdk_conf.set('RTE_MAX_NUMA_NODES', get_option('max_numa_nodes'))
 dpdk_conf.set('RTE_MAX_ETHPORTS', get_option('max_ethports'))
+dpdk_conf.set('RTE_MAX_REGEXDEV_DEVS', get_option('max_regexdev_devs'))
 dpdk_conf.set('RTE_LIBEAL_USE_HPET', get_option('use_hpet'))
 dpdk_conf.set('RTE_ENABLE_TRACE_FP', get_option('enable_trace_fp'))
 # values which have defaults which may be overridden
diff --git a/lib/librte_regexdev/Makefile b/lib/librte_regexdev/Makefile
index 9012d29..6ba09f0 100644
--- a/lib/librte_regexdev/Makefile
+++ b/lib/librte_regexdev/Makefile
@@ -25,6 +25,7 @@  SRCS-$(CONFIG_RTE_LIBRTE_REGEXDEV) := rte_regexdev.c
 # export include files
 SYMLINK-$(CONFIG_RTE_LIBRTE_REGEXDEV)-include += rte_regexdev.h
 SYMLINK-$(CONFIG_RTE_LIBRTE_REGEXDEV)-include += rte_regexdev_core.h
+SYMLINK-$(CONFIG_RTE_LIBRTE_REGEXDEV)-include += rte_regexdev_driver.h
 
 # versioning export map
 EXPORT_MAP := rte_regexdev_version.map
diff --git a/lib/librte_regexdev/meson.build b/lib/librte_regexdev/meson.build
index 1816754..719ee82 100644
--- a/lib/librte_regexdev/meson.build
+++ b/lib/librte_regexdev/meson.build
@@ -1,7 +1,10 @@ 
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2020 Mellanox Corporation
 
+name = 'regexdev'
 allow_experimental_apis = true
 sources = files('rte_regexdev.c')
-headers = files('rte_regexdev.h', 'rte_regexdev_core.h')
+headers = files('rte_regexdev.h',
+	'rte_regexdev_core.h',
+	'rte_regexdev_driver.h')
 deps += ['mbuf']
diff --git a/lib/librte_regexdev/rte_regexdev.c b/lib/librte_regexdev/rte_regexdev.c
index b901877..2014b22 100644
--- a/lib/librte_regexdev/rte_regexdev.c
+++ b/lib/librte_regexdev/rte_regexdev.c
@@ -3,4 +3,141 @@ 
  * Copyright(C) 2020 Mellanox International Ltd.
  */
 
-#include <rte_regexdev.h>
+#include <string.h>
+
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_memzone.h>
+#include <rte_string_fns.h>
+
+#include "rte_regexdev.h"
+#include "rte_regexdev_core.h"
+#include "rte_regexdev_driver.h"
+
+static const char *MZ_RTE_REGEXDEV_DATA = "rte_regexdev_data";
+static struct rte_regexdev regex_devices[RTE_MAX_REGEXDEV_DEVS];
+/* Shared memory between primary and secondary processes. */
+static struct {
+	struct rte_regexdev_data data[RTE_MAX_REGEXDEV_DEVS];
+} *rte_regexdev_shared_data;
+
+int rte_regexdev_logtype;
+
+static uint16_t
+regexdev_find_free_dev(void)
+{
+	uint16_t i;
+
+	for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
+		if (regex_devices[i].state == RTE_REGEXDEV_UNUSED)
+			return i;
+	}
+	return RTE_MAX_REGEXDEV_DEVS;
+}
+
+static struct rte_regexdev*
+regexdev_allocated(const char *name)
+{
+	uint16_t i;
+
+	for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
+		if (regex_devices[i].state != RTE_REGEXDEV_UNUSED)
+			if (!strcmp(name, regex_devices[i].data->dev_name))
+				return &regex_devices[i];
+	}
+	return NULL;
+}
+
+static int
+regexdev_shared_data_prepare(void)
+{
+	const unsigned int flags = 0;
+	const struct rte_memzone *mz;
+
+	if (rte_regexdev_shared_data == NULL) {
+		/* Allocate port data and ownership shared memory. */
+		mz = rte_memzone_reserve(MZ_RTE_REGEXDEV_DATA,
+					 sizeof(*rte_regexdev_shared_data),
+					 rte_socket_id(), flags);
+		if (mz == NULL)
+			return -ENOMEM;
+
+		rte_regexdev_shared_data = mz->addr;
+		memset(rte_regexdev_shared_data->data, 0,
+		       sizeof(rte_regexdev_shared_data->data));
+	}
+	return 0;
+}
+
+static int
+regexdev_check_name(const char *name)
+{
+	size_t name_len;
+
+	if (name == NULL) {
+		RTE_REGEXDEV_LOG(ERR, "Name can't be NULL\n");
+		return -EINVAL;
+	}
+	name_len = strnlen(name, RTE_REGEXDEV_NAME_MAX_LEN);
+	if (name_len == 0) {
+		RTE_REGEXDEV_LOG(ERR, "Zero length RegEx device name\n");
+		return -EINVAL;
+	}
+	if (name_len >= RTE_REGEXDEV_NAME_MAX_LEN) {
+		RTE_REGEXDEV_LOG(ERR, "RegEx device name is too long\n");
+		return -EINVAL;
+	}
+	return (int)name_len;
+
+}
+
+struct rte_regexdev *
+rte_regexdev_register(const char *name)
+{
+	uint16_t dev_id;
+	int name_len;
+	struct rte_regexdev *dev;
+
+	name_len = regexdev_check_name(name);
+	if (name_len < 0)
+		return NULL;
+	dev = regexdev_allocated(name);
+	if (dev != NULL) {
+		RTE_REGEXDEV_LOG(ERR, "RegEx device already allocated\n");
+		return NULL;
+	}
+	dev_id = regexdev_find_free_dev();
+	if (dev_id == RTE_MAX_REGEXDEV_DEVS) {
+		RTE_REGEXDEV_LOG
+			(ERR, "Reached maximum number of RegEx devices\n");
+		return NULL;
+	}
+	if (regexdev_shared_data_prepare() < 0) {
+		RTE_REGEXDEV_LOG(ERR, "Cannot allocate RegEx shared data\n");
+		return NULL;
+	}
+
+	dev = &regex_devices[dev_id];
+	dev->state = RTE_REGEXDEV_REGISTERED;
+	if (dev->data == NULL)
+		dev->data = &rte_regexdev_shared_data->data[dev_id];
+	else
+		memset(dev->data, 1, sizeof(*dev->data));
+	dev->data->dev_id = dev_id;
+	strlcpy(dev->data->dev_name, name, sizeof(dev->data->dev_name));
+	return dev;
+}
+
+void
+rte_regexdev_unregister(struct rte_regexdev *dev)
+{
+	dev->state = RTE_REGEXDEV_UNUSED;
+}
+
+struct rte_regexdev *
+rte_regexdev_get_device_by_name(const char *name)
+{
+	if (regexdev_check_name(name) < 0)
+		return NULL;
+	return regexdev_allocated(name);
+}
diff --git a/lib/librte_regexdev/rte_regexdev.h b/lib/librte_regexdev/rte_regexdev.h
index bbc56f9..1e1ba8b 100644
--- a/lib/librte_regexdev/rte_regexdev.h
+++ b/lib/librte_regexdev/rte_regexdev.h
@@ -206,6 +206,13 @@ 
 #include <rte_mbuf.h>
 #include <rte_memory.h>
 
+#define RTE_REGEXDEV_NAME_MAX_LEN RTE_DEV_NAME_MAX_LEN
+
+extern int rte_regexdev_logtype;
+
+#define RTE_REGEXDEV_LOG(level, ...) \
+	rte_log(RTE_LOG_ ## level, rte_regexdev_logtype, "" __VA_ARGS__)
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
diff --git a/lib/librte_regexdev/rte_regexdev_core.h b/lib/librte_regexdev/rte_regexdev_core.h
index fa6d297..cbf054e 100644
--- a/lib/librte_regexdev/rte_regexdev_core.h
+++ b/lib/librte_regexdev/rte_regexdev_core.h
@@ -127,7 +127,18 @@  struct rte_regexdev_ops {
 	regexdev_dump_t dev_dump;
 };
 
-#define RTE_REGEXDEV_NAME_MAX_LEN
+/**
+ * @internal
+ * Possible states of a RegEx device.
+ */
+enum rte_regexdev_state {
+	RTE_REGEXDEV_UNUSED = 0, /**< Device is unused. */
+	RTE_REGEXDEV_REGISTERED,
+	/**< Device is registered, but not ready to be used. */
+	RTE_REGEXDEV_READY,
+	/**< Device is ready for use. This is set by the PMD. */
+};
+
 /**
  * @internal
  * The data part, with no function pointers, associated with each RegEx device.
@@ -137,6 +148,8 @@  struct rte_regexdev_ops {
  */
 struct rte_regexdev_data {
 	void *dev_private; /**< PMD-specific private data. */
+	char dev_name[RTE_REGEXDEV_NAME_MAX_LEN]; /**< Unique identifier name */
+	uint16_t dev_id; /**< Device [external]  identifier. */
 } __rte_cache_aligned;
 
 /**
@@ -155,6 +168,7 @@  struct rte_regexdev {
 	const struct rte_regexdev_ops *dev_ops;
 	/**< Functions exported by PMD */
 	struct rte_device *device; /**< Backing device */
+	enum rte_regexdev_state state; /**< The device state. */
 	struct rte_regexdev_data *data;  /**< Pointer to device data. */
 } __rte_cache_aligned;
 
diff --git a/lib/librte_regexdev/rte_regexdev_driver.h b/lib/librte_regexdev/rte_regexdev_driver.h
new file mode 100644
index 0000000..1477c59
--- /dev/null
+++ b/lib/librte_regexdev/rte_regexdev_driver.h
@@ -0,0 +1,59 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Mellanox Corporation
+ */
+
+#ifndef _RTE_REGEXDEV_DRIVER_H_
+#define _RTE_REGEXDEV_DRIVER_H_
+
+/**
+ * @file
+ *
+ * RTE RegEx Device PMD API
+ *
+ * APIs that are used by the RegEx drivers, to comunicate with the
+ * RegEx lib.
+ */
+
+#include "rte_regexdev.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @internal
+ * Register a RegEx device slot for a RegEx device and return the
+ * pointer to that slot.
+ *
+ * @param name
+ *   RegEx device name.
+ *
+ * @return
+ *   A pointer to the RegEx device slot case of success,
+ *   NULL otherwise.
+ */
+struct rte_regexdev *rte_regexdev_register(const char *name);
+
+/**
+ * @internal
+ * Unregister the specified regexdev port.
+ *
+ * @param dev
+ *   Device to be released.
+ */
+void rte_regexdev_unregister(struct rte_regexdev *dev);
+
+/**
+ * @internal
+ * Return the RegEx device based on the device name.
+ *
+ * @param name
+ *   The device name.
+ */
+struct rte_regexdev *rte_regexdev_get_device_by_name(const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_REGEXDEV_DRIVER_H_ */
diff --git a/meson_options.txt b/meson_options.txt
index 9bf18ab..2a04cd6 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -30,6 +30,8 @@  option('max_lcores', type: 'integer', value: 128,
 	description: 'maximum number of cores/threads supported by EAL')
 option('max_numa_nodes', type: 'integer', value: 4,
 	description: 'maximum number of NUMA nodes supported by EAL')
+option('max_regexdev_devs', type: 'integer', value: 32,
+	description: 'maximum number of RegEx devices')
 option('enable_trace_fp', type: 'boolean', value: false,
 	description: 'enable fast path trace points.')
 option('tests', type: 'boolean', value: true,