From c7c995cc58b3b3892baf6461e1db26413877580d Mon Sep 17 00:00:00 2001 From: Jerin Jacob Date: Sat, 11 Apr 2020 19:44:01 +0530 Subject: [PATCH] graph: implement node registration 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 Signed-off-by: Kiran Kumar K Signed-off-by: Pavan Nikhilesh Signed-off-by: Nithin Dabilpuram --- lib/librte_graph/Makefile | 1 + lib/librte_graph/graph.c | 18 +++- lib/librte_graph/graph_private.h | 75 ++++++++++++++++ lib/librte_graph/meson.build | 2 +- lib/librte_graph/node.c | 113 +++++++++++++++++++++++++ lib/librte_graph/rte_graph_version.map | 4 + 6 files changed, 211 insertions(+), 2 deletions(-) create mode 100644 lib/librte_graph/graph_private.h create mode 100644 lib/librte_graph/node.c diff --git a/lib/librte_graph/Makefile b/lib/librte_graph/Makefile index 50afc51f48..f59d910475 100644 --- a/lib/librte_graph/Makefile +++ b/lib/librte_graph/Makefile @@ -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 diff --git a/lib/librte_graph/graph.c b/lib/librte_graph/graph.c index a55bf443ac..a9c124896a 100644 --- a/lib/librte_graph/graph.c +++ b/lib/librte_graph/graph.c @@ -2,4 +2,20 @@ * Copyright(C) 2020 Marvell International Ltd. */ -#include "rte_graph.h" +#include + +#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 index 0000000000..8b9ff5292d --- /dev/null +++ b/lib/librte_graph/graph_private.h @@ -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 +#include + +#include +#include + +#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_ */ diff --git a/lib/librte_graph/meson.build b/lib/librte_graph/meson.build index 703b07f6e1..ed7c33f596 100644 --- a/lib/librte_graph/meson.build +++ b/lib/librte_graph/meson.build @@ -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 index 0000000000..336cd1c946 --- /dev/null +++ b/lib/librte_graph/node.c @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2020 Marvell International Ltd. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#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; +} + diff --git a/lib/librte_graph/rte_graph_version.map b/lib/librte_graph/rte_graph_version.map index 55ef35df50..0884c09f1a 100644 --- a/lib/librte_graph/rte_graph_version.map +++ b/lib/librte_graph/rte_graph_version.map @@ -1,3 +1,7 @@ EXPERIMENTAL { + global: + __rte_node_register; + + local: *; }; -- 2.20.1