xref: /dpdk/lib/graph/graph_populate.c (revision 070db97e017b7ed9a5320b2f624f05562a632bd3)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(C) 2020 Marvell International Ltd.
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
599a2dd95SBruce Richardson 
699a2dd95SBruce Richardson #include <rte_common.h>
799a2dd95SBruce Richardson #include <rte_errno.h>
899a2dd95SBruce Richardson #include <rte_malloc.h>
999a2dd95SBruce Richardson #include <rte_memzone.h>
1099a2dd95SBruce Richardson 
1199a2dd95SBruce Richardson #include "graph_private.h"
129b72ea1fSAmit Prakash Shukla #include "graph_pcap_private.h"
1399a2dd95SBruce Richardson 
1499a2dd95SBruce Richardson static size_t
1599a2dd95SBruce Richardson graph_fp_mem_calc_size(struct graph *graph)
1699a2dd95SBruce Richardson {
1799a2dd95SBruce Richardson 	struct graph_node *graph_node;
1899a2dd95SBruce Richardson 	rte_node_t val;
1999a2dd95SBruce Richardson 	size_t sz;
2099a2dd95SBruce Richardson 
2199a2dd95SBruce Richardson 	/* Graph header */
2299a2dd95SBruce Richardson 	sz = sizeof(struct rte_graph);
2399a2dd95SBruce Richardson 	/* Source nodes list */
2499a2dd95SBruce Richardson 	sz += sizeof(rte_graph_off_t) * graph->src_node_count;
2599a2dd95SBruce Richardson 	/* Circular buffer for pending streams of size number of nodes */
2699a2dd95SBruce Richardson 	val = rte_align32pow2(graph->node_count * sizeof(rte_graph_off_t));
2799a2dd95SBruce Richardson 	sz = RTE_ALIGN(sz, val);
2899a2dd95SBruce Richardson 	graph->cir_start = sz;
2999a2dd95SBruce Richardson 	graph->cir_mask = rte_align32pow2(graph->node_count) - 1;
3099a2dd95SBruce Richardson 	sz += val;
3199a2dd95SBruce Richardson 	/* Fence */
3299a2dd95SBruce Richardson 	sz += sizeof(RTE_GRAPH_FENCE);
3399a2dd95SBruce Richardson 	sz = RTE_ALIGN(sz, RTE_CACHE_LINE_SIZE);
3499a2dd95SBruce Richardson 	graph->nodes_start = sz;
3599a2dd95SBruce Richardson 	/* For 0..N node objects with fence */
3699a2dd95SBruce Richardson 	STAILQ_FOREACH(graph_node, &graph->node_list, next) {
3799a2dd95SBruce Richardson 		sz = RTE_ALIGN(sz, RTE_CACHE_LINE_SIZE);
3899a2dd95SBruce Richardson 		sz += sizeof(struct rte_node);
3999a2dd95SBruce Richardson 		/* Pointer to next nodes(edges) */
4099a2dd95SBruce Richardson 		sz += sizeof(struct rte_node *) * graph_node->node->nb_edges;
4199a2dd95SBruce Richardson 	}
42*070db97eSPavan Nikhilesh 	sz = RTE_ALIGN(sz, RTE_CACHE_LINE_SIZE);
43*070db97eSPavan Nikhilesh 	graph->xstats_start = sz;
44*070db97eSPavan Nikhilesh 	/* For 0..N node objects with xstats */
45*070db97eSPavan Nikhilesh 	STAILQ_FOREACH(graph_node, &graph->node_list, next) {
46*070db97eSPavan Nikhilesh 		if (graph_node->node->xstats == NULL)
47*070db97eSPavan Nikhilesh 			continue;
48*070db97eSPavan Nikhilesh 		sz = RTE_ALIGN(sz, RTE_CACHE_LINE_SIZE);
49*070db97eSPavan Nikhilesh 		sz += sizeof(uint64_t) * graph_node->node->xstats->nb_xstats;
50*070db97eSPavan Nikhilesh 	}
5199a2dd95SBruce Richardson 
5299a2dd95SBruce Richardson 	graph->mem_sz = sz;
5399a2dd95SBruce Richardson 	return sz;
5499a2dd95SBruce Richardson }
5599a2dd95SBruce Richardson 
5699a2dd95SBruce Richardson static void
5799a2dd95SBruce Richardson graph_header_popluate(struct graph *_graph)
5899a2dd95SBruce Richardson {
5999a2dd95SBruce Richardson 	struct rte_graph *graph = _graph->graph;
6099a2dd95SBruce Richardson 
6199a2dd95SBruce Richardson 	graph->tail = 0;
6299a2dd95SBruce Richardson 	graph->head = (int32_t)-_graph->src_node_count;
6399a2dd95SBruce Richardson 	graph->cir_mask = _graph->cir_mask;
6499a2dd95SBruce Richardson 	graph->nb_nodes = _graph->node_count;
6599a2dd95SBruce Richardson 	graph->cir_start = RTE_PTR_ADD(graph, _graph->cir_start);
6699a2dd95SBruce Richardson 	graph->nodes_start = _graph->nodes_start;
6799a2dd95SBruce Richardson 	graph->socket = _graph->socket;
6899a2dd95SBruce Richardson 	graph->id = _graph->id;
6999a2dd95SBruce Richardson 	memcpy(graph->name, _graph->name, RTE_GRAPH_NAMESIZE);
7099a2dd95SBruce Richardson 	graph->fence = RTE_GRAPH_FENCE;
7199a2dd95SBruce Richardson }
7299a2dd95SBruce Richardson 
7399a2dd95SBruce Richardson static void
7499a2dd95SBruce Richardson graph_nodes_populate(struct graph *_graph)
7599a2dd95SBruce Richardson {
76*070db97eSPavan Nikhilesh 	rte_graph_off_t xstat_off = _graph->xstats_start;
7799a2dd95SBruce Richardson 	rte_graph_off_t off = _graph->nodes_start;
7899a2dd95SBruce Richardson 	struct rte_graph *graph = _graph->graph;
7999a2dd95SBruce Richardson 	struct graph_node *graph_node;
8099a2dd95SBruce Richardson 	rte_edge_t count, nb_edges;
8199a2dd95SBruce Richardson 	const char *parent;
8299a2dd95SBruce Richardson 	rte_node_t pid;
8399a2dd95SBruce Richardson 
8499a2dd95SBruce Richardson 	STAILQ_FOREACH(graph_node, &_graph->node_list, next) {
8599a2dd95SBruce Richardson 		struct rte_node *node = RTE_PTR_ADD(graph, off);
8699a2dd95SBruce Richardson 		memset(node, 0, sizeof(*node));
8799a2dd95SBruce Richardson 		node->fence = RTE_GRAPH_FENCE;
8899a2dd95SBruce Richardson 		node->off = off;
899b72ea1fSAmit Prakash Shukla 		if (graph_pcap_is_enable()) {
909b72ea1fSAmit Prakash Shukla 			node->process = graph_pcap_dispatch;
919b72ea1fSAmit Prakash Shukla 			node->original_process = graph_node->node->process;
929b72ea1fSAmit Prakash Shukla 		} else
9399a2dd95SBruce Richardson 			node->process = graph_node->node->process;
9499a2dd95SBruce Richardson 		memcpy(node->name, graph_node->node->name, RTE_GRAPH_NAMESIZE);
9599a2dd95SBruce Richardson 		pid = graph_node->node->parent_id;
9699a2dd95SBruce Richardson 		if (pid != RTE_NODE_ID_INVALID) { /* Cloned node */
9799a2dd95SBruce Richardson 			parent = rte_node_id_to_name(pid);
9899a2dd95SBruce Richardson 			memcpy(node->parent, parent, RTE_GRAPH_NAMESIZE);
9999a2dd95SBruce Richardson 		}
10099a2dd95SBruce Richardson 		node->id = graph_node->node->id;
10199a2dd95SBruce Richardson 		node->parent_id = pid;
102e6c67c9eSZhirun Yan 		node->dispatch.lcore_id = graph_node->node->lcore_id;
10399a2dd95SBruce Richardson 		nb_edges = graph_node->node->nb_edges;
10499a2dd95SBruce Richardson 		node->nb_edges = nb_edges;
10599a2dd95SBruce Richardson 		off += sizeof(struct rte_node);
10699a2dd95SBruce Richardson 		/* Copy the name in first pass to replace with rte_node* later*/
10799a2dd95SBruce Richardson 		for (count = 0; count < nb_edges; count++)
10899a2dd95SBruce Richardson 			node->nodes[count] = (struct rte_node *)&graph_node
10999a2dd95SBruce Richardson 						     ->adjacency_list[count]
11099a2dd95SBruce Richardson 						     ->node->name[0];
11199a2dd95SBruce Richardson 
112*070db97eSPavan Nikhilesh 		if (graph_node->node->xstats != NULL) {
113*070db97eSPavan Nikhilesh 			node->xstat_off = xstat_off - off;
114*070db97eSPavan Nikhilesh 			xstat_off += sizeof(uint64_t) * graph_node->node->xstats->nb_xstats;
115*070db97eSPavan Nikhilesh 			xstat_off = RTE_ALIGN(xstat_off, RTE_CACHE_LINE_SIZE);
116*070db97eSPavan Nikhilesh 		}
117*070db97eSPavan Nikhilesh 
11899a2dd95SBruce Richardson 		off += sizeof(struct rte_node *) * nb_edges;
11999a2dd95SBruce Richardson 		off = RTE_ALIGN(off, RTE_CACHE_LINE_SIZE);
12099a2dd95SBruce Richardson 		node->next = off;
12199a2dd95SBruce Richardson 		__rte_node_stream_alloc(graph, node);
12299a2dd95SBruce Richardson 	}
12399a2dd95SBruce Richardson }
12499a2dd95SBruce Richardson 
12599a2dd95SBruce Richardson struct rte_node *
12699a2dd95SBruce Richardson graph_node_id_to_ptr(const struct rte_graph *graph, rte_node_t id)
12799a2dd95SBruce Richardson {
12899a2dd95SBruce Richardson 	rte_node_t count;
12999a2dd95SBruce Richardson 	rte_graph_off_t off;
13099a2dd95SBruce Richardson 	struct rte_node *node;
13199a2dd95SBruce Richardson 
13299a2dd95SBruce Richardson 	rte_graph_foreach_node(count, off, graph, node)
13399a2dd95SBruce Richardson 		if (unlikely(node->id == id))
13499a2dd95SBruce Richardson 			return node;
13599a2dd95SBruce Richardson 
13699a2dd95SBruce Richardson 	return NULL;
13799a2dd95SBruce Richardson }
13899a2dd95SBruce Richardson 
13999a2dd95SBruce Richardson struct rte_node *
14099a2dd95SBruce Richardson graph_node_name_to_ptr(const struct rte_graph *graph, const char *name)
14199a2dd95SBruce Richardson {
14299a2dd95SBruce Richardson 	rte_node_t count;
14399a2dd95SBruce Richardson 	rte_graph_off_t off;
14499a2dd95SBruce Richardson 	struct rte_node *node;
14599a2dd95SBruce Richardson 
14699a2dd95SBruce Richardson 	rte_graph_foreach_node(count, off, graph, node)
14799a2dd95SBruce Richardson 		if (strncmp(name, node->name, RTE_NODE_NAMESIZE) == 0)
14899a2dd95SBruce Richardson 			return node;
14999a2dd95SBruce Richardson 
15099a2dd95SBruce Richardson 	return NULL;
15199a2dd95SBruce Richardson }
15299a2dd95SBruce Richardson 
15399a2dd95SBruce Richardson static int
15499a2dd95SBruce Richardson graph_node_nexts_populate(struct graph *_graph)
15599a2dd95SBruce Richardson {
15699a2dd95SBruce Richardson 	rte_node_t count, val;
15799a2dd95SBruce Richardson 	rte_graph_off_t off;
15899a2dd95SBruce Richardson 	struct rte_node *node;
15999a2dd95SBruce Richardson 	const struct rte_graph *graph = _graph->graph;
16099a2dd95SBruce Richardson 	const char *name;
16199a2dd95SBruce Richardson 
16299a2dd95SBruce Richardson 	rte_graph_foreach_node(count, off, graph, node) {
16399a2dd95SBruce Richardson 		for (val = 0; val < node->nb_edges; val++) {
16499a2dd95SBruce Richardson 			name = (const char *)node->nodes[val];
16599a2dd95SBruce Richardson 			node->nodes[val] = graph_node_name_to_ptr(graph, name);
16699a2dd95SBruce Richardson 			if (node->nodes[val] == NULL)
16799a2dd95SBruce Richardson 				SET_ERR_JMP(EINVAL, fail, "%s not found", name);
16899a2dd95SBruce Richardson 		}
16999a2dd95SBruce Richardson 	}
17099a2dd95SBruce Richardson 
17199a2dd95SBruce Richardson 	return 0;
17299a2dd95SBruce Richardson fail:
17399a2dd95SBruce Richardson 	return -rte_errno;
17499a2dd95SBruce Richardson }
17599a2dd95SBruce Richardson 
17699a2dd95SBruce Richardson static int
177*070db97eSPavan Nikhilesh graph_src_nodes_offset_populate(struct graph *_graph)
17899a2dd95SBruce Richardson {
17999a2dd95SBruce Richardson 	struct rte_graph *graph = _graph->graph;
18099a2dd95SBruce Richardson 	struct graph_node *graph_node;
18199a2dd95SBruce Richardson 	struct rte_node *node;
18299a2dd95SBruce Richardson 	int32_t head = -1;
18399a2dd95SBruce Richardson 	const char *name;
18499a2dd95SBruce Richardson 
18599a2dd95SBruce Richardson 	STAILQ_FOREACH(graph_node, &_graph->node_list, next) {
18699a2dd95SBruce Richardson 		if (graph_node->node->flags & RTE_NODE_SOURCE_F) {
18799a2dd95SBruce Richardson 			name = graph_node->node->name;
18899a2dd95SBruce Richardson 			node = graph_node_name_to_ptr(graph, name);
18999a2dd95SBruce Richardson 			if (node == NULL)
19099a2dd95SBruce Richardson 				SET_ERR_JMP(EINVAL, fail, "%s not found", name);
19199a2dd95SBruce Richardson 
19299a2dd95SBruce Richardson 			__rte_node_stream_alloc(graph, node);
19399a2dd95SBruce Richardson 			graph->cir_start[head--] = node->off;
19499a2dd95SBruce Richardson 		}
19599a2dd95SBruce Richardson 	}
19699a2dd95SBruce Richardson 
19799a2dd95SBruce Richardson 	return 0;
19899a2dd95SBruce Richardson fail:
19999a2dd95SBruce Richardson 	return -rte_errno;
20099a2dd95SBruce Richardson }
20199a2dd95SBruce Richardson 
20299a2dd95SBruce Richardson static int
20399a2dd95SBruce Richardson graph_fp_mem_populate(struct graph *graph)
20499a2dd95SBruce Richardson {
20599a2dd95SBruce Richardson 	int rc;
20699a2dd95SBruce Richardson 
20799a2dd95SBruce Richardson 	graph_header_popluate(graph);
2089b72ea1fSAmit Prakash Shukla 	if (graph_pcap_is_enable())
2099b72ea1fSAmit Prakash Shukla 		graph_pcap_init(graph);
21099a2dd95SBruce Richardson 	graph_nodes_populate(graph);
21199a2dd95SBruce Richardson 	rc = graph_node_nexts_populate(graph);
212*070db97eSPavan Nikhilesh 	rc |= graph_src_nodes_offset_populate(graph);
21399a2dd95SBruce Richardson 
21499a2dd95SBruce Richardson 	return rc;
21599a2dd95SBruce Richardson }
21699a2dd95SBruce Richardson 
21799a2dd95SBruce Richardson int
21899a2dd95SBruce Richardson graph_fp_mem_create(struct graph *graph)
21999a2dd95SBruce Richardson {
22099a2dd95SBruce Richardson 	const struct rte_memzone *mz;
22199a2dd95SBruce Richardson 	size_t sz;
22299a2dd95SBruce Richardson 
22399a2dd95SBruce Richardson 	sz = graph_fp_mem_calc_size(graph);
22499a2dd95SBruce Richardson 	mz = rte_memzone_reserve(graph->name, sz, graph->socket, 0);
22599a2dd95SBruce Richardson 	if (mz == NULL)
22699a2dd95SBruce Richardson 		SET_ERR_JMP(ENOMEM, fail, "Memzone %s reserve failed",
22799a2dd95SBruce Richardson 			    graph->name);
22899a2dd95SBruce Richardson 
22999a2dd95SBruce Richardson 	graph->graph = mz->addr;
23099a2dd95SBruce Richardson 	graph->mz = mz;
23199a2dd95SBruce Richardson 
23299a2dd95SBruce Richardson 	return graph_fp_mem_populate(graph);
23399a2dd95SBruce Richardson fail:
23499a2dd95SBruce Richardson 	return -rte_errno;
23599a2dd95SBruce Richardson }
23699a2dd95SBruce Richardson 
23799a2dd95SBruce Richardson static void
23899a2dd95SBruce Richardson graph_nodes_mem_destroy(struct rte_graph *graph)
23999a2dd95SBruce Richardson {
24099a2dd95SBruce Richardson 	rte_node_t count;
24199a2dd95SBruce Richardson 	rte_graph_off_t off;
24299a2dd95SBruce Richardson 	struct rte_node *node;
24399a2dd95SBruce Richardson 
24499a2dd95SBruce Richardson 	if (graph == NULL)
24599a2dd95SBruce Richardson 		return;
24699a2dd95SBruce Richardson 
24799a2dd95SBruce Richardson 	rte_graph_foreach_node(count, off, graph, node)
24899a2dd95SBruce Richardson 		rte_free(node->objs);
24999a2dd95SBruce Richardson }
25099a2dd95SBruce Richardson 
25199a2dd95SBruce Richardson int
25299a2dd95SBruce Richardson graph_fp_mem_destroy(struct graph *graph)
25399a2dd95SBruce Richardson {
2549b72ea1fSAmit Prakash Shukla 	if (graph_pcap_is_enable())
2559b72ea1fSAmit Prakash Shukla 		graph_pcap_exit(graph->graph);
2569b72ea1fSAmit Prakash Shukla 
25799a2dd95SBruce Richardson 	graph_nodes_mem_destroy(graph->graph);
25899a2dd95SBruce Richardson 	return rte_memzone_free(graph->mz);
25999a2dd95SBruce Richardson }
260