[V5,01/17] pipeline: add pipeline name

Message ID 20220727230132.601114-1-cristian.dumitrescu@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series [V5,01/17] pipeline: add pipeline name |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Cristian Dumitrescu July 27, 2022, 11:01 p.m. UTC
  Add an unique name to every pipeline. This enables the library to
maintain a list of the existing pipeline objects, which can be
queried by the application.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Kamalakannan R. <kamalakannan.r@intel.com>
---
 examples/pipeline/obj.c                  |   2 +-
 lib/pipeline/rte_swx_ctl.c               |  99 +++++++++++++++++++++
 lib/pipeline/rte_swx_ctl.h               |  15 ++++
 lib/pipeline/rte_swx_pipeline.c          | 107 ++++++++++++++++++++++-
 lib/pipeline/rte_swx_pipeline.h          |  18 +++-
 lib/pipeline/rte_swx_pipeline_internal.h |   2 +
 lib/pipeline/version.map                 |   4 +
 7 files changed, 244 insertions(+), 3 deletions(-)
  

Comments

Bruce Richardson July 28, 2022, 8:22 a.m. UTC | #1
On Wed, Jul 27, 2022 at 11:01:16PM +0000, Cristian Dumitrescu wrote:
> Add an unique name to every pipeline. This enables the library to
> maintain a list of the existing pipeline objects, which can be
> queried by the application.
> 
> Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> Signed-off-by: Kamalakannan R. <kamalakannan.r@intel.com>
> ---
I really think this patchset could do with a cover letter. Since you are
now on v5, it would be nice to have a cover-letter where the differences
between each of the patch versions are called out. A cover-letter is also
nice to outline the overall scope of the changes rather than asking
reviewers to go through the set patch by patch to see what is in there.

Thanks,
/Bruce
  
Cristian Dumitrescu July 28, 2022, 3:17 p.m. UTC | #2
> -----Original Message-----
> From: Richardson, Bruce <bruce.richardson@intel.com>
> Sent: Thursday, July 28, 2022 9:22 AM
> To: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
> Cc: dev@dpdk.org; R, Kamalakannan <kamalakannan.r@intel.com>
> Subject: Re: [PATCH V5 01/17] pipeline: add pipeline name
> 
> On Wed, Jul 27, 2022 at 11:01:16PM +0000, Cristian Dumitrescu wrote:
> > Add an unique name to every pipeline. This enables the library to
> > maintain a list of the existing pipeline objects, which can be
> > queried by the application.
> >
> > Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> > Signed-off-by: Kamalakannan R. <kamalakannan.r@intel.com>
> > ---
> I really think this patchset could do with a cover letter. Since you are
> now on v5, it would be nice to have a cover-letter where the differences
> between each of the patch versions are called out. A cover-letter is also
> nice to outline the overall scope of the changes rather than asking
> reviewers to go through the set patch by patch to see what is in there.
> 
> Thanks,
> /Bruce

Just sent the cover letter with V6, thanks.
  

Patch

diff --git a/examples/pipeline/obj.c b/examples/pipeline/obj.c
index b79f044ac7..967342c580 100644
--- a/examples/pipeline/obj.c
+++ b/examples/pipeline/obj.c
@@ -533,7 +533,7 @@  pipeline_create(struct obj *obj, const char *name, int numa_node)
 		return NULL;
 
 	/* Resource create */
-	status = rte_swx_pipeline_config(&p, numa_node);
+	status = rte_swx_pipeline_config(&p, name, numa_node);
 	if (status)
 		goto error;
 
diff --git a/lib/pipeline/rte_swx_ctl.c b/lib/pipeline/rte_swx_ctl.c
index 710e89a46a..1b776fc543 100644
--- a/lib/pipeline/rte_swx_ctl.c
+++ b/lib/pipeline/rte_swx_ctl.c
@@ -9,6 +9,8 @@ 
 
 #include <rte_common.h>
 #include <rte_byteorder.h>
+#include <rte_tailq.h>
+#include <rte_eal_memconfig.h>
 
 #include <rte_swx_table_selector.h>
 
@@ -1157,12 +1159,103 @@  table_state_create(struct rte_swx_ctl_pipeline *ctl)
 	return status;
 }
 
+/* Global list of pipeline instances. */
+TAILQ_HEAD(rte_swx_ctl_pipeline_list, rte_tailq_entry);
+
+static struct rte_tailq_elem rte_swx_ctl_pipeline_tailq = {
+	.name = "RTE_SWX_CTL_PIPELINE",
+};
+
+EAL_REGISTER_TAILQ(rte_swx_ctl_pipeline_tailq)
+
+struct rte_swx_ctl_pipeline *
+rte_swx_ctl_pipeline_find(const char *name)
+{
+	struct rte_swx_ctl_pipeline_list *ctl_list;
+	struct rte_tailq_entry *te = NULL;
+
+	if (!name || !name[0] || (strnlen(name, RTE_SWX_CTL_NAME_SIZE) >= RTE_SWX_CTL_NAME_SIZE))
+		return NULL;
+
+	ctl_list = RTE_TAILQ_CAST(rte_swx_ctl_pipeline_tailq.head, rte_swx_ctl_pipeline_list);
+
+	rte_mcfg_tailq_read_lock();
+
+	TAILQ_FOREACH(te, ctl_list, next) {
+		struct rte_swx_ctl_pipeline *ctl = (struct rte_swx_ctl_pipeline *)te->data;
+
+		if (!strncmp(name, ctl->info.name, sizeof(ctl->info.name))) {
+			rte_mcfg_tailq_read_unlock();
+			return ctl;
+		}
+	}
+
+	rte_mcfg_tailq_read_unlock();
+	return NULL;
+}
+
+static int
+ctl_register(struct rte_swx_ctl_pipeline *ctl)
+{
+	struct rte_swx_ctl_pipeline_list *ctl_list;
+	struct rte_tailq_entry *te = NULL;
+
+	ctl_list = RTE_TAILQ_CAST(rte_swx_ctl_pipeline_tailq.head, rte_swx_ctl_pipeline_list);
+
+	rte_mcfg_tailq_write_lock();
+
+	TAILQ_FOREACH(te, ctl_list, next) {
+		struct rte_swx_ctl_pipeline *ctl_crt = (struct rte_swx_ctl_pipeline *)te->data;
+
+		if (!strncmp(ctl->info.name, ctl_crt->info.name, sizeof(ctl->info.name))) {
+			rte_mcfg_tailq_write_unlock();
+			return -EEXIST;
+		}
+	}
+
+	te = calloc(1, sizeof(struct rte_tailq_entry));
+	if (!te) {
+		rte_mcfg_tailq_write_unlock();
+		return -ENOMEM;
+	}
+
+	te->data = (void *)ctl;
+	TAILQ_INSERT_TAIL(ctl_list, te, next);
+	rte_mcfg_tailq_write_unlock();
+	return 0;
+}
+
+static void
+ctl_unregister(struct rte_swx_ctl_pipeline *ctl)
+{
+	struct rte_swx_ctl_pipeline_list *ctl_list;
+	struct rte_tailq_entry *te = NULL;
+
+	ctl_list = RTE_TAILQ_CAST(rte_swx_ctl_pipeline_tailq.head, rte_swx_ctl_pipeline_list);
+
+	rte_mcfg_tailq_write_lock();
+
+	TAILQ_FOREACH(te, ctl_list, next) {
+		if (te->data == (void *)ctl) {
+			TAILQ_REMOVE(ctl_list, te, next);
+			rte_mcfg_tailq_write_unlock();
+			free(te);
+			return;
+		}
+	}
+
+	rte_mcfg_tailq_write_unlock();
+}
+
 void
 rte_swx_ctl_pipeline_free(struct rte_swx_ctl_pipeline *ctl)
 {
 	if (!ctl)
 		return;
 
+	if (ctl->info.name[0])
+		ctl_unregister(ctl);
+
 	action_free(ctl);
 
 	table_state_free(ctl);
@@ -1441,6 +1534,12 @@  rte_swx_ctl_pipeline_create(struct rte_swx_pipeline *p)
 	if (status)
 		goto error;
 
+	if (ctl->info.name[0]) {
+		status = ctl_register(ctl);
+		if (status)
+			goto error;
+	}
+
 	return ctl;
 
 error:
diff --git a/lib/pipeline/rte_swx_ctl.h b/lib/pipeline/rte_swx_ctl.h
index d771389d26..63ee479e47 100644
--- a/lib/pipeline/rte_swx_ctl.h
+++ b/lib/pipeline/rte_swx_ctl.h
@@ -35,6 +35,9 @@  struct rte_swx_pipeline;
 
 /** Pipeline info. */
 struct rte_swx_ctl_pipeline_info {
+	/** Pipeline name. */
+	char name[RTE_SWX_CTL_NAME_SIZE];
+
 	/** Number of input ports. */
 	uint32_t n_ports_in;
 
@@ -812,6 +815,18 @@  rte_swx_pipeline_table_state_set(struct rte_swx_pipeline *p,
 /** Pipeline control opaque data structure. */
 struct rte_swx_ctl_pipeline;
 
+/**
+ * Pipeline control find
+ *
+ * @param[in] name
+ *   Pipeline name.
+ * @return
+ *   Valid pipeline control handle if found or NULL otherwise.
+ */
+__rte_experimental
+struct rte_swx_ctl_pipeline *
+rte_swx_ctl_pipeline_find(const char *name);
+
 /**
  * Pipeline control create
  *
diff --git a/lib/pipeline/rte_swx_pipeline.c b/lib/pipeline/rte_swx_pipeline.c
index 3e1c6e9edb..c8ccded4f8 100644
--- a/lib/pipeline/rte_swx_pipeline.c
+++ b/lib/pipeline/rte_swx_pipeline.c
@@ -6,6 +6,8 @@ 
 #include <errno.h>
 #include <dlfcn.h>
 
+#include <rte_tailq.h>
+#include <rte_eal_memconfig.h>
 #include <rte_jhash.h>
 #include <rte_hash_crc.h>
 
@@ -9578,6 +9580,95 @@  metarray_free(struct rte_swx_pipeline *p)
 /*
  * Pipeline.
  */
+
+/* Global list of pipeline instances. */
+TAILQ_HEAD(rte_swx_pipeline_list, rte_tailq_entry);
+
+static struct rte_tailq_elem rte_swx_pipeline_tailq = {
+	.name = "RTE_SWX_PIPELINE",
+};
+
+EAL_REGISTER_TAILQ(rte_swx_pipeline_tailq)
+
+struct rte_swx_pipeline *
+rte_swx_pipeline_find(const char *name)
+{
+	struct rte_swx_pipeline_list *pipeline_list;
+	struct rte_tailq_entry *te = NULL;
+
+	if (!name || !name[0] || (strnlen(name, RTE_SWX_NAME_SIZE) >= RTE_SWX_NAME_SIZE))
+		return NULL;
+
+	pipeline_list = RTE_TAILQ_CAST(rte_swx_pipeline_tailq.head, rte_swx_pipeline_list);
+
+	rte_mcfg_tailq_read_lock();
+
+	TAILQ_FOREACH(te, pipeline_list, next) {
+		struct rte_swx_pipeline *p = (struct rte_swx_pipeline *)te->data;
+
+		if (!strncmp(name, p->name, sizeof(p->name))) {
+			rte_mcfg_tailq_read_unlock();
+			return p;
+		}
+	}
+
+	rte_mcfg_tailq_read_unlock();
+	return NULL;
+}
+
+static int
+pipeline_register(struct rte_swx_pipeline *p)
+{
+	struct rte_swx_pipeline_list *pipeline_list;
+	struct rte_tailq_entry *te = NULL;
+
+	pipeline_list = RTE_TAILQ_CAST(rte_swx_pipeline_tailq.head, rte_swx_pipeline_list);
+
+	rte_mcfg_tailq_write_lock();
+
+	TAILQ_FOREACH(te, pipeline_list, next) {
+		struct rte_swx_pipeline *pipeline = (struct rte_swx_pipeline *)te->data;
+
+		if (!strncmp(p->name, pipeline->name, sizeof(p->name))) {
+			rte_mcfg_tailq_write_unlock();
+			return -EEXIST;
+		}
+	}
+
+	te = calloc(1, sizeof(struct rte_tailq_entry));
+	if (!te) {
+		rte_mcfg_tailq_write_unlock();
+		return -ENOMEM;
+	}
+
+	te->data = (void *)p;
+	TAILQ_INSERT_TAIL(pipeline_list, te, next);
+	rte_mcfg_tailq_write_unlock();
+	return 0;
+}
+
+static void
+pipeline_unregister(struct rte_swx_pipeline *p)
+{
+	struct rte_swx_pipeline_list *pipeline_list;
+	struct rte_tailq_entry *te = NULL;
+
+	pipeline_list = RTE_TAILQ_CAST(rte_swx_pipeline_tailq.head, rte_swx_pipeline_list);
+
+	rte_mcfg_tailq_write_lock();
+
+	TAILQ_FOREACH(te, pipeline_list, next) {
+		if (te->data == (void *)p) {
+			TAILQ_REMOVE(pipeline_list, te, next);
+			rte_mcfg_tailq_write_unlock();
+			free(te);
+			return;
+		}
+	}
+
+	rte_mcfg_tailq_write_unlock();
+}
+
 void
 rte_swx_pipeline_free(struct rte_swx_pipeline *p)
 {
@@ -9586,6 +9677,9 @@  rte_swx_pipeline_free(struct rte_swx_pipeline *p)
 	if (!p)
 		return;
 
+	if (p->name[0])
+		pipeline_unregister(p);
+
 	lib = p->lib;
 
 	free(p->instruction_data);
@@ -9720,13 +9814,14 @@  hash_funcs_register(struct rte_swx_pipeline *p)
 }
 
 int
-rte_swx_pipeline_config(struct rte_swx_pipeline **p, int numa_node)
+rte_swx_pipeline_config(struct rte_swx_pipeline **p, const char *name, int numa_node)
 {
 	struct rte_swx_pipeline *pipeline = NULL;
 	int status = 0;
 
 	/* Check input parameters. */
 	CHECK(p, EINVAL);
+	CHECK(!name || (strnlen(name, RTE_SWX_NAME_SIZE) < RTE_SWX_NAME_SIZE), EINVAL);
 
 	/* Memory allocation. */
 	pipeline = calloc(1, sizeof(struct rte_swx_pipeline));
@@ -9736,6 +9831,9 @@  rte_swx_pipeline_config(struct rte_swx_pipeline **p, int numa_node)
 	}
 
 	/* Initialization. */
+	if (name)
+		strcpy(pipeline->name, name);
+
 	TAILQ_INIT(&pipeline->struct_types);
 	TAILQ_INIT(&pipeline->port_in_types);
 	TAILQ_INIT(&pipeline->ports_in);
@@ -9776,6 +9874,12 @@  rte_swx_pipeline_config(struct rte_swx_pipeline **p, int numa_node)
 	if (status)
 		goto error;
 
+	if (pipeline->name[0]) {
+		status = pipeline_register(pipeline);
+		if (status)
+			goto error;
+	}
+
 	*p = pipeline;
 	return 0;
 
@@ -9966,6 +10070,7 @@  rte_swx_ctl_pipeline_info_get(struct rte_swx_pipeline *p,
 	TAILQ_FOREACH(table, &p->tables, node)
 		n_tables++;
 
+	strcpy(pipeline->name, p->name);
 	pipeline->n_ports_in = p->n_ports_in;
 	pipeline->n_ports_out = p->n_ports_out;
 	pipeline->n_mirroring_slots = p->n_mirroring_slots;
diff --git a/lib/pipeline/rte_swx_pipeline.h b/lib/pipeline/rte_swx_pipeline.h
index c41ca5cb15..ef50a0fa70 100644
--- a/lib/pipeline/rte_swx_pipeline.h
+++ b/lib/pipeline/rte_swx_pipeline.h
@@ -44,22 +44,38 @@  extern "C" {
 /** Pipeline opaque data structure. */
 struct rte_swx_pipeline;
 
+/**
+ * Pipeline find
+ *
+ * @param[in] name
+ *   Pipeline name.
+ * @return
+ *   Valid pipeline handle if found or NULL otherwise.
+ */
+__rte_experimental
+struct rte_swx_pipeline *
+rte_swx_pipeline_find(const char *name);
+
 /**
  * Pipeline configure
  *
  * @param[out] p
  *   Pipeline handle. Must point to valid memory. Contains valid pipeline handle
  *   when the function returns successfully.
+ * @param[in] name
+ *   Pipeline unique name.
  * @param[in] numa_node
  *   Non-Uniform Memory Access (NUMA) node.
  * @return
  *   0 on success or the following error codes otherwise:
  *   -EINVAL: Invalid argument;
- *   -ENOMEM: Not enough space/cannot allocate memory.
+ *   -ENOMEM: Not enough space/cannot allocate memory;
+ *   -EEXIST: Pipeline with this name already exists.
  */
 __rte_experimental
 int
 rte_swx_pipeline_config(struct rte_swx_pipeline **p,
+			const char *name,
 			int numa_node);
 
 /*
diff --git a/lib/pipeline/rte_swx_pipeline_internal.h b/lib/pipeline/rte_swx_pipeline_internal.h
index a35635efb7..588cad62b5 100644
--- a/lib/pipeline/rte_swx_pipeline_internal.h
+++ b/lib/pipeline/rte_swx_pipeline_internal.h
@@ -1459,6 +1459,8 @@  instr_operand_nbo(struct thread *t, const struct instr_operand *x)
 #endif
 
 struct rte_swx_pipeline {
+	char name[RTE_SWX_NAME_SIZE];
+
 	struct struct_type_tailq struct_types;
 	struct port_in_type_tailq port_in_types;
 	struct port_in_tailq ports_in;
diff --git a/lib/pipeline/version.map b/lib/pipeline/version.map
index 8312307a7a..50029aadcf 100644
--- a/lib/pipeline/version.map
+++ b/lib/pipeline/version.map
@@ -145,4 +145,8 @@  EXPERIMENTAL {
 	rte_swx_ctl_pipeline_learner_timeout_get;
 	rte_swx_ctl_pipeline_learner_timeout_set;
 	rte_swx_pipeline_hash_func_register;
+
+	#added in 22.11
+	rte_swx_ctl_pipeline_find;
+	rte_swx_pipeline_find;
 };