graph: implement node registration
authorJerin Jacob <jerinj@marvell.com>
Sat, 11 Apr 2020 14:14:01 +0000 (19:44 +0530)
committerThomas Monjalon <thomas@monjalon.net>
Tue, 5 May 2020 21:28:03 +0000 (23:28 +0200)
Adding rte_node_register() API implementation includes allocating
memory for node object, check for duplicate node name and
add the allocated node to STAILQ node_list for future use.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
lib/librte_graph/Makefile
lib/librte_graph/graph.c
lib/librte_graph/graph_private.h [new file with mode: 0644]
lib/librte_graph/meson.build
lib/librte_graph/node.c [new file with mode: 0644]
lib/librte_graph/rte_graph_version.map

index 50afc51..f59d910 100644 (file)
@@ -14,6 +14,7 @@ LDLIBS += -lrte_eal
 EXPORT_MAP := rte_graph_version.map
 
 # all source are stored in SRCS-y
+SRCS-$(CONFIG_RTE_LIBRTE_GRAPH) += node.c
 SRCS-$(CONFIG_RTE_LIBRTE_GRAPH) += graph.c
 
 # install header files
index a55bf44..a9c1248 100644 (file)
@@ -2,4 +2,20 @@
  * Copyright(C) 2020 Marvell International Ltd.
  */
 
-#include "rte_graph.h"
+#include <rte_spinlock.h>
+
+#include "graph_private.h"
+
+static rte_spinlock_t graph_lock = RTE_SPINLOCK_INITIALIZER;
+
+void
+graph_spinlock_lock(void)
+{
+       rte_spinlock_lock(&graph_lock);
+}
+
+void
+graph_spinlock_unlock(void)
+{
+       rte_spinlock_unlock(&graph_lock);
+}
diff --git a/lib/librte_graph/graph_private.h b/lib/librte_graph/graph_private.h
new file mode 100644 (file)
index 0000000..8b9ff52
--- /dev/null
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#ifndef _RTE_GRAPH_PRIVATE_H_
+#define _RTE_GRAPH_PRIVATE_H_
+
+#include <inttypes.h>
+#include <sys/queue.h>
+
+#include <rte_common.h>
+#include <rte_eal.h>
+
+#include "rte_graph.h"
+
+/**
+ * @internal
+ *
+ * Structure that holds node internal data.
+ */
+struct node {
+       STAILQ_ENTRY(node) next;      /**< Next node in the list. */
+       char name[RTE_NODE_NAMESIZE]; /**< Name of the node. */
+       uint64_t flags;               /**< Node configuration flag. */
+       rte_node_process_t process;   /**< Node process function. */
+       rte_node_init_t init;         /**< Node init function. */
+       rte_node_fini_t fini;         /**< Node fini function. */
+       rte_node_t id;                /**< Allocated identifier for the node. */
+       rte_node_t parent_id;         /**< Parent node identifier. */
+       rte_edge_t nb_edges;          /**< Number of edges from this node. */
+       char next_nodes[][RTE_NODE_NAMESIZE]; /**< Names of next nodes. */
+};
+
+/* Node functions */
+STAILQ_HEAD(node_head, node);
+
+/**
+ * @internal
+ *
+ * Get the head of the node list.
+ *
+ * @return
+ *   Pointer to the node head.
+ */
+struct node_head *node_list_head_get(void);
+
+/**
+ * @internal
+ *
+ * Get node pointer from node name.
+ *
+ * @param name
+ *   Pointer to character string containing the node name.
+ *
+ * @return
+ *   Pointer to the node.
+ */
+struct node *node_from_name(const char *name);
+
+/* Lock functions */
+/**
+ * @internal
+ *
+ * Take a lock on the graph internal spin lock.
+ */
+void graph_spinlock_lock(void);
+
+/**
+ * @internal
+ *
+ * Release a lock on the graph internal spin lock.
+ */
+void graph_spinlock_unlock(void);
+
+#endif /* _RTE_GRAPH_PRIVATE_H_ */
index 703b07f..ed7c33f 100644 (file)
@@ -3,7 +3,7 @@
 
 name = 'graph'
 
-sources = files('graph.c')
+sources = files('node.c', 'graph.c')
 headers = files('rte_graph.h')
 
 deps += ['eal']
diff --git a/lib/librte_graph/node.c b/lib/librte_graph/node.c
new file mode 100644 (file)
index 0000000..336cd1c
--- /dev/null
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2020 Marvell International Ltd.
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <rte_common.h>
+#include <rte_debug.h>
+#include <rte_eal.h>
+#include <rte_errno.h>
+#include <rte_string_fns.h>
+
+#include "graph_private.h"
+
+static struct node_head node_list = STAILQ_HEAD_INITIALIZER(node_list);
+static rte_node_t node_id;
+
+/* Private functions */
+struct node_head *
+node_list_head_get(void)
+{
+       return &node_list;
+}
+
+struct node *
+node_from_name(const char *name)
+{
+       struct node *node;
+
+       STAILQ_FOREACH(node, &node_list, next)
+               if (strncmp(node->name, name, RTE_NODE_NAMESIZE) == 0)
+                       return node;
+
+       return NULL;
+}
+
+static bool
+node_has_duplicate_entry(const char *name)
+{
+       struct node *node;
+
+       /* Is duplicate name registered */
+       STAILQ_FOREACH(node, &node_list, next) {
+               if (strncmp(node->name, name, RTE_NODE_NAMESIZE) == 0) {
+                       rte_errno = EEXIST;
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+/* Public functions */
+rte_node_t
+__rte_node_register(const struct rte_node_register *reg)
+{
+       struct node *node;
+       rte_edge_t i;
+       size_t sz;
+
+       graph_spinlock_lock();
+
+       /* Check sanity */
+       if (reg == NULL || reg->process == NULL) {
+               rte_errno = EINVAL;
+               goto fail;
+       }
+
+       /* Check for duplicate name */
+       if (node_has_duplicate_entry(reg->name))
+               goto fail;
+
+       sz = sizeof(struct node) + (reg->nb_edges * RTE_NODE_NAMESIZE);
+       node = calloc(1, sz);
+       if (node == NULL) {
+               rte_errno = ENOMEM;
+               goto fail;
+       }
+
+       /* Initialize the node */
+       if (rte_strscpy(node->name, reg->name, RTE_NODE_NAMESIZE) < 0) {
+               rte_errno = E2BIG;
+               goto free;
+       }
+       node->flags = reg->flags;
+       node->process = reg->process;
+       node->init = reg->init;
+       node->fini = reg->fini;
+       node->nb_edges = reg->nb_edges;
+       node->parent_id = reg->parent_id;
+       for (i = 0; i < reg->nb_edges; i++) {
+               if (rte_strscpy(node->next_nodes[i], reg->next_nodes[i],
+                               RTE_NODE_NAMESIZE) < 0) {
+                       rte_errno = E2BIG;
+                       goto free;
+               }
+       }
+
+       node->id = node_id++;
+
+       /* Add the node at tail */
+       STAILQ_INSERT_TAIL(&node_list, node, next);
+       graph_spinlock_unlock();
+
+       return node->id;
+free:
+       free(node);
+fail:
+       graph_spinlock_unlock();
+       return RTE_NODE_ID_INVALID;
+}
+
index 55ef35d..0884c09 100644 (file)
@@ -1,3 +1,7 @@
 EXPERIMENTAL {
+       global:
 
+       __rte_node_register;
+
+       local: *;
 };