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