xref: /f-stack/dpdk/lib/librte_graph/graph_stats.c (revision 2d9fd380)
1*2d9fd380Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2*2d9fd380Sjfb8856606  * Copyright(C) 2020 Marvell International Ltd.
3*2d9fd380Sjfb8856606  */
4*2d9fd380Sjfb8856606 
5*2d9fd380Sjfb8856606 #include <fnmatch.h>
6*2d9fd380Sjfb8856606 #include <stdbool.h>
7*2d9fd380Sjfb8856606 
8*2d9fd380Sjfb8856606 #include <rte_common.h>
9*2d9fd380Sjfb8856606 #include <rte_errno.h>
10*2d9fd380Sjfb8856606 #include <rte_malloc.h>
11*2d9fd380Sjfb8856606 
12*2d9fd380Sjfb8856606 #include "graph_private.h"
13*2d9fd380Sjfb8856606 
14*2d9fd380Sjfb8856606 /* Capture all graphs of cluster */
15*2d9fd380Sjfb8856606 struct cluster {
16*2d9fd380Sjfb8856606 	rte_graph_t nb_graphs;
17*2d9fd380Sjfb8856606 	rte_graph_t size;
18*2d9fd380Sjfb8856606 
19*2d9fd380Sjfb8856606 	struct graph **graphs;
20*2d9fd380Sjfb8856606 };
21*2d9fd380Sjfb8856606 
22*2d9fd380Sjfb8856606 /* Capture same node ID across cluster  */
23*2d9fd380Sjfb8856606 struct cluster_node {
24*2d9fd380Sjfb8856606 	struct rte_graph_cluster_node_stats stat;
25*2d9fd380Sjfb8856606 	rte_node_t nb_nodes;
26*2d9fd380Sjfb8856606 
27*2d9fd380Sjfb8856606 	struct rte_node *nodes[];
28*2d9fd380Sjfb8856606 };
29*2d9fd380Sjfb8856606 
30*2d9fd380Sjfb8856606 struct rte_graph_cluster_stats {
31*2d9fd380Sjfb8856606 	/* Header */
32*2d9fd380Sjfb8856606 	rte_graph_cluster_stats_cb_t fn;
33*2d9fd380Sjfb8856606 	uint32_t cluster_node_size; /* Size of struct cluster_node */
34*2d9fd380Sjfb8856606 	rte_node_t max_nodes;
35*2d9fd380Sjfb8856606 	int socket_id;
36*2d9fd380Sjfb8856606 	void *cookie;
37*2d9fd380Sjfb8856606 	size_t sz;
38*2d9fd380Sjfb8856606 
39*2d9fd380Sjfb8856606 	struct cluster_node clusters[];
40*2d9fd380Sjfb8856606 } __rte_cache_aligned;
41*2d9fd380Sjfb8856606 
42*2d9fd380Sjfb8856606 #define boarder()                                                              \
43*2d9fd380Sjfb8856606 	fprintf(f, "+-------------------------------+---------------+--------" \
44*2d9fd380Sjfb8856606 		   "-------+---------------+---------------+---------------+-" \
45*2d9fd380Sjfb8856606 		   "----------+\n")
46*2d9fd380Sjfb8856606 
47*2d9fd380Sjfb8856606 static inline void
print_banner(FILE * f)48*2d9fd380Sjfb8856606 print_banner(FILE *f)
49*2d9fd380Sjfb8856606 {
50*2d9fd380Sjfb8856606 	boarder();
51*2d9fd380Sjfb8856606 	fprintf(f, "%-32s%-16s%-16s%-16s%-16s%-16s%-16s\n", "|Node", "|calls",
52*2d9fd380Sjfb8856606 		"|objs", "|realloc_count", "|objs/call", "|objs/sec(10E6)",
53*2d9fd380Sjfb8856606 		"|cycles/call|");
54*2d9fd380Sjfb8856606 	boarder();
55*2d9fd380Sjfb8856606 }
56*2d9fd380Sjfb8856606 
57*2d9fd380Sjfb8856606 static inline void
print_node(FILE * f,const struct rte_graph_cluster_node_stats * stat)58*2d9fd380Sjfb8856606 print_node(FILE *f, const struct rte_graph_cluster_node_stats *stat)
59*2d9fd380Sjfb8856606 {
60*2d9fd380Sjfb8856606 	double objs_per_call, objs_per_sec, cycles_per_call, ts_per_hz;
61*2d9fd380Sjfb8856606 	const uint64_t prev_calls = stat->prev_calls;
62*2d9fd380Sjfb8856606 	const uint64_t prev_objs = stat->prev_objs;
63*2d9fd380Sjfb8856606 	const uint64_t cycles = stat->cycles;
64*2d9fd380Sjfb8856606 	const uint64_t calls = stat->calls;
65*2d9fd380Sjfb8856606 	const uint64_t objs = stat->objs;
66*2d9fd380Sjfb8856606 	uint64_t call_delta;
67*2d9fd380Sjfb8856606 
68*2d9fd380Sjfb8856606 	call_delta = calls - prev_calls;
69*2d9fd380Sjfb8856606 	objs_per_call =
70*2d9fd380Sjfb8856606 		call_delta ? (double)((objs - prev_objs) / call_delta) : 0;
71*2d9fd380Sjfb8856606 	cycles_per_call =
72*2d9fd380Sjfb8856606 		call_delta ? (double)((cycles - stat->prev_cycles) / call_delta)
73*2d9fd380Sjfb8856606 			   : 0;
74*2d9fd380Sjfb8856606 	ts_per_hz = (double)((stat->ts - stat->prev_ts) / stat->hz);
75*2d9fd380Sjfb8856606 	objs_per_sec = ts_per_hz ? (objs - prev_objs) / ts_per_hz : 0;
76*2d9fd380Sjfb8856606 	objs_per_sec /= 1000000;
77*2d9fd380Sjfb8856606 
78*2d9fd380Sjfb8856606 	fprintf(f,
79*2d9fd380Sjfb8856606 		"|%-31s|%-15" PRIu64 "|%-15" PRIu64 "|%-15" PRIu64
80*2d9fd380Sjfb8856606 		"|%-15.3f|%-15.6f|%-11.4f|\n",
81*2d9fd380Sjfb8856606 		stat->name, calls, objs, stat->realloc_count, objs_per_call,
82*2d9fd380Sjfb8856606 		objs_per_sec, cycles_per_call);
83*2d9fd380Sjfb8856606 }
84*2d9fd380Sjfb8856606 
85*2d9fd380Sjfb8856606 static int
graph_cluster_stats_cb(bool is_first,bool is_last,void * cookie,const struct rte_graph_cluster_node_stats * stat)86*2d9fd380Sjfb8856606 graph_cluster_stats_cb(bool is_first, bool is_last, void *cookie,
87*2d9fd380Sjfb8856606 		       const struct rte_graph_cluster_node_stats *stat)
88*2d9fd380Sjfb8856606 {
89*2d9fd380Sjfb8856606 	FILE *f = cookie;
90*2d9fd380Sjfb8856606 
91*2d9fd380Sjfb8856606 	if (unlikely(is_first))
92*2d9fd380Sjfb8856606 		print_banner(f);
93*2d9fd380Sjfb8856606 	if (stat->objs)
94*2d9fd380Sjfb8856606 		print_node(f, stat);
95*2d9fd380Sjfb8856606 	if (unlikely(is_last))
96*2d9fd380Sjfb8856606 		boarder();
97*2d9fd380Sjfb8856606 
98*2d9fd380Sjfb8856606 	return 0;
99*2d9fd380Sjfb8856606 };
100*2d9fd380Sjfb8856606 
101*2d9fd380Sjfb8856606 static struct rte_graph_cluster_stats *
stats_mem_init(struct cluster * cluster,const struct rte_graph_cluster_stats_param * prm)102*2d9fd380Sjfb8856606 stats_mem_init(struct cluster *cluster,
103*2d9fd380Sjfb8856606 	       const struct rte_graph_cluster_stats_param *prm)
104*2d9fd380Sjfb8856606 {
105*2d9fd380Sjfb8856606 	size_t sz = sizeof(struct rte_graph_cluster_stats);
106*2d9fd380Sjfb8856606 	struct rte_graph_cluster_stats *stats;
107*2d9fd380Sjfb8856606 	rte_graph_cluster_stats_cb_t fn;
108*2d9fd380Sjfb8856606 	int socket_id = prm->socket_id;
109*2d9fd380Sjfb8856606 	uint32_t cluster_node_size;
110*2d9fd380Sjfb8856606 
111*2d9fd380Sjfb8856606 	/* Fix up callback */
112*2d9fd380Sjfb8856606 	fn = prm->fn;
113*2d9fd380Sjfb8856606 	if (fn == NULL)
114*2d9fd380Sjfb8856606 		fn = graph_cluster_stats_cb;
115*2d9fd380Sjfb8856606 
116*2d9fd380Sjfb8856606 	cluster_node_size = sizeof(struct cluster_node);
117*2d9fd380Sjfb8856606 	/* For a given cluster, max nodes will be the max number of graphs */
118*2d9fd380Sjfb8856606 	cluster_node_size += cluster->nb_graphs * sizeof(struct rte_node *);
119*2d9fd380Sjfb8856606 	cluster_node_size = RTE_ALIGN(cluster_node_size, RTE_CACHE_LINE_SIZE);
120*2d9fd380Sjfb8856606 
121*2d9fd380Sjfb8856606 	stats = realloc(NULL, sz);
122*2d9fd380Sjfb8856606 	memset(stats, 0, sz);
123*2d9fd380Sjfb8856606 	if (stats) {
124*2d9fd380Sjfb8856606 		stats->fn = fn;
125*2d9fd380Sjfb8856606 		stats->cluster_node_size = cluster_node_size;
126*2d9fd380Sjfb8856606 		stats->max_nodes = 0;
127*2d9fd380Sjfb8856606 		stats->socket_id = socket_id;
128*2d9fd380Sjfb8856606 		stats->cookie = prm->cookie;
129*2d9fd380Sjfb8856606 		stats->sz = sz;
130*2d9fd380Sjfb8856606 	}
131*2d9fd380Sjfb8856606 
132*2d9fd380Sjfb8856606 	return stats;
133*2d9fd380Sjfb8856606 }
134*2d9fd380Sjfb8856606 
135*2d9fd380Sjfb8856606 static int
stats_mem_populate(struct rte_graph_cluster_stats ** stats_in,struct rte_graph * graph,struct graph_node * graph_node)136*2d9fd380Sjfb8856606 stats_mem_populate(struct rte_graph_cluster_stats **stats_in,
137*2d9fd380Sjfb8856606 		   struct rte_graph *graph, struct graph_node *graph_node)
138*2d9fd380Sjfb8856606 {
139*2d9fd380Sjfb8856606 	struct rte_graph_cluster_stats *stats = *stats_in;
140*2d9fd380Sjfb8856606 	rte_node_t id = graph_node->node->id;
141*2d9fd380Sjfb8856606 	struct cluster_node *cluster;
142*2d9fd380Sjfb8856606 	struct rte_node *node;
143*2d9fd380Sjfb8856606 	rte_node_t count;
144*2d9fd380Sjfb8856606 
145*2d9fd380Sjfb8856606 	cluster = stats->clusters;
146*2d9fd380Sjfb8856606 
147*2d9fd380Sjfb8856606 	/* Iterate over cluster node array to find node ID match */
148*2d9fd380Sjfb8856606 	for (count = 0; count < stats->max_nodes; count++) {
149*2d9fd380Sjfb8856606 		/* Found an existing node in the reel */
150*2d9fd380Sjfb8856606 		if (cluster->stat.id == id) {
151*2d9fd380Sjfb8856606 			node = graph_node_id_to_ptr(graph, id);
152*2d9fd380Sjfb8856606 			if (node == NULL)
153*2d9fd380Sjfb8856606 				SET_ERR_JMP(
154*2d9fd380Sjfb8856606 					ENOENT, err,
155*2d9fd380Sjfb8856606 					"Failed to find node %s in graph %s",
156*2d9fd380Sjfb8856606 					graph_node->node->name, graph->name);
157*2d9fd380Sjfb8856606 
158*2d9fd380Sjfb8856606 			cluster->nodes[cluster->nb_nodes++] = node;
159*2d9fd380Sjfb8856606 			return 0;
160*2d9fd380Sjfb8856606 		}
161*2d9fd380Sjfb8856606 		cluster = RTE_PTR_ADD(cluster, stats->cluster_node_size);
162*2d9fd380Sjfb8856606 	}
163*2d9fd380Sjfb8856606 
164*2d9fd380Sjfb8856606 	/* Hey, it is a new node, allocate space for it in the reel */
165*2d9fd380Sjfb8856606 	stats = realloc(stats, stats->sz + stats->cluster_node_size);
166*2d9fd380Sjfb8856606 	if (stats == NULL)
167*2d9fd380Sjfb8856606 		SET_ERR_JMP(ENOMEM, err, "Realloc failed");
168*2d9fd380Sjfb8856606 
169*2d9fd380Sjfb8856606 	/* Clear the new struct cluster_node area */
170*2d9fd380Sjfb8856606 	cluster = RTE_PTR_ADD(stats, stats->sz),
171*2d9fd380Sjfb8856606 	memset(cluster, 0, stats->cluster_node_size);
172*2d9fd380Sjfb8856606 	memcpy(cluster->stat.name, graph_node->node->name, RTE_NODE_NAMESIZE);
173*2d9fd380Sjfb8856606 	cluster->stat.id = graph_node->node->id;
174*2d9fd380Sjfb8856606 	cluster->stat.hz = rte_get_timer_hz();
175*2d9fd380Sjfb8856606 	node = graph_node_id_to_ptr(graph, id);
176*2d9fd380Sjfb8856606 	if (node == NULL)
177*2d9fd380Sjfb8856606 		SET_ERR_JMP(ENOENT, err, "Failed to find node %s in graph %s",
178*2d9fd380Sjfb8856606 			    graph_node->node->name, graph->name);
179*2d9fd380Sjfb8856606 	cluster->nodes[cluster->nb_nodes++] = node;
180*2d9fd380Sjfb8856606 
181*2d9fd380Sjfb8856606 	stats->sz += stats->cluster_node_size;
182*2d9fd380Sjfb8856606 	stats->max_nodes++;
183*2d9fd380Sjfb8856606 	*stats_in = stats;
184*2d9fd380Sjfb8856606 
185*2d9fd380Sjfb8856606 	return 0;
186*2d9fd380Sjfb8856606 err:
187*2d9fd380Sjfb8856606 	return -rte_errno;
188*2d9fd380Sjfb8856606 }
189*2d9fd380Sjfb8856606 
190*2d9fd380Sjfb8856606 static void
stats_mem_fini(struct rte_graph_cluster_stats * stats)191*2d9fd380Sjfb8856606 stats_mem_fini(struct rte_graph_cluster_stats *stats)
192*2d9fd380Sjfb8856606 {
193*2d9fd380Sjfb8856606 	free(stats);
194*2d9fd380Sjfb8856606 }
195*2d9fd380Sjfb8856606 
196*2d9fd380Sjfb8856606 static void
cluster_init(struct cluster * cluster)197*2d9fd380Sjfb8856606 cluster_init(struct cluster *cluster)
198*2d9fd380Sjfb8856606 {
199*2d9fd380Sjfb8856606 	memset(cluster, 0, sizeof(*cluster));
200*2d9fd380Sjfb8856606 }
201*2d9fd380Sjfb8856606 
202*2d9fd380Sjfb8856606 static int
cluster_add(struct cluster * cluster,struct graph * graph)203*2d9fd380Sjfb8856606 cluster_add(struct cluster *cluster, struct graph *graph)
204*2d9fd380Sjfb8856606 {
205*2d9fd380Sjfb8856606 	rte_graph_t count;
206*2d9fd380Sjfb8856606 	size_t sz;
207*2d9fd380Sjfb8856606 
208*2d9fd380Sjfb8856606 	/* Skip the if graph is already added to cluster */
209*2d9fd380Sjfb8856606 	for (count = 0; count < cluster->nb_graphs; count++)
210*2d9fd380Sjfb8856606 		if (cluster->graphs[count] == graph)
211*2d9fd380Sjfb8856606 			return 0;
212*2d9fd380Sjfb8856606 
213*2d9fd380Sjfb8856606 	/* Expand the cluster if required to store graph objects */
214*2d9fd380Sjfb8856606 	if (cluster->nb_graphs + 1 > cluster->size) {
215*2d9fd380Sjfb8856606 		cluster->size = RTE_MAX(1, cluster->size * 2);
216*2d9fd380Sjfb8856606 		sz = sizeof(struct graph *) * cluster->size;
217*2d9fd380Sjfb8856606 		cluster->graphs = realloc(cluster->graphs, sz);
218*2d9fd380Sjfb8856606 		if (cluster->graphs == NULL)
219*2d9fd380Sjfb8856606 			SET_ERR_JMP(ENOMEM, free, "Failed to realloc");
220*2d9fd380Sjfb8856606 	}
221*2d9fd380Sjfb8856606 
222*2d9fd380Sjfb8856606 	/* Add graph to cluster */
223*2d9fd380Sjfb8856606 	cluster->graphs[cluster->nb_graphs++] = graph;
224*2d9fd380Sjfb8856606 	return 0;
225*2d9fd380Sjfb8856606 
226*2d9fd380Sjfb8856606 free:
227*2d9fd380Sjfb8856606 	return -rte_errno;
228*2d9fd380Sjfb8856606 }
229*2d9fd380Sjfb8856606 
230*2d9fd380Sjfb8856606 static void
cluster_fini(struct cluster * cluster)231*2d9fd380Sjfb8856606 cluster_fini(struct cluster *cluster)
232*2d9fd380Sjfb8856606 {
233*2d9fd380Sjfb8856606 	if (cluster->graphs)
234*2d9fd380Sjfb8856606 		free(cluster->graphs);
235*2d9fd380Sjfb8856606 }
236*2d9fd380Sjfb8856606 
237*2d9fd380Sjfb8856606 static int
expand_pattern_to_cluster(struct cluster * cluster,const char * pattern)238*2d9fd380Sjfb8856606 expand_pattern_to_cluster(struct cluster *cluster, const char *pattern)
239*2d9fd380Sjfb8856606 {
240*2d9fd380Sjfb8856606 	struct graph_head *graph_head = graph_list_head_get();
241*2d9fd380Sjfb8856606 	struct graph *graph;
242*2d9fd380Sjfb8856606 	bool found = false;
243*2d9fd380Sjfb8856606 
244*2d9fd380Sjfb8856606 	/* Check for pattern match */
245*2d9fd380Sjfb8856606 	STAILQ_FOREACH(graph, graph_head, next) {
246*2d9fd380Sjfb8856606 		if (fnmatch(pattern, graph->name, 0) == 0) {
247*2d9fd380Sjfb8856606 			if (cluster_add(cluster, graph))
248*2d9fd380Sjfb8856606 				goto fail;
249*2d9fd380Sjfb8856606 			found = true;
250*2d9fd380Sjfb8856606 		}
251*2d9fd380Sjfb8856606 	}
252*2d9fd380Sjfb8856606 	if (found == false)
253*2d9fd380Sjfb8856606 		SET_ERR_JMP(EFAULT, fail, "Pattern %s graph not found",
254*2d9fd380Sjfb8856606 			    pattern);
255*2d9fd380Sjfb8856606 
256*2d9fd380Sjfb8856606 	return 0;
257*2d9fd380Sjfb8856606 fail:
258*2d9fd380Sjfb8856606 	return -rte_errno;
259*2d9fd380Sjfb8856606 }
260*2d9fd380Sjfb8856606 
261*2d9fd380Sjfb8856606 struct rte_graph_cluster_stats *
rte_graph_cluster_stats_create(const struct rte_graph_cluster_stats_param * prm)262*2d9fd380Sjfb8856606 rte_graph_cluster_stats_create(const struct rte_graph_cluster_stats_param *prm)
263*2d9fd380Sjfb8856606 {
264*2d9fd380Sjfb8856606 	struct rte_graph_cluster_stats *stats, *rc = NULL;
265*2d9fd380Sjfb8856606 	struct graph_node *graph_node;
266*2d9fd380Sjfb8856606 	struct cluster cluster;
267*2d9fd380Sjfb8856606 	struct graph *graph;
268*2d9fd380Sjfb8856606 	const char *pattern;
269*2d9fd380Sjfb8856606 	rte_graph_t i;
270*2d9fd380Sjfb8856606 
271*2d9fd380Sjfb8856606 	/* Sanity checks */
272*2d9fd380Sjfb8856606 	if (!rte_graph_has_stats_feature())
273*2d9fd380Sjfb8856606 		SET_ERR_JMP(EINVAL, fail, "Stats feature is not enabled");
274*2d9fd380Sjfb8856606 
275*2d9fd380Sjfb8856606 	if (prm == NULL)
276*2d9fd380Sjfb8856606 		SET_ERR_JMP(EINVAL, fail, "Invalid param");
277*2d9fd380Sjfb8856606 
278*2d9fd380Sjfb8856606 	if (prm->graph_patterns == NULL || prm->nb_graph_patterns == 0)
279*2d9fd380Sjfb8856606 		SET_ERR_JMP(EINVAL, fail, "Invalid graph param");
280*2d9fd380Sjfb8856606 
281*2d9fd380Sjfb8856606 	cluster_init(&cluster);
282*2d9fd380Sjfb8856606 
283*2d9fd380Sjfb8856606 	graph_spinlock_lock();
284*2d9fd380Sjfb8856606 	/* Expand graph pattern and add the graph to the cluster */
285*2d9fd380Sjfb8856606 	for (i = 0; i < prm->nb_graph_patterns; i++) {
286*2d9fd380Sjfb8856606 		pattern = prm->graph_patterns[i];
287*2d9fd380Sjfb8856606 		if (expand_pattern_to_cluster(&cluster, pattern))
288*2d9fd380Sjfb8856606 			goto bad_pattern;
289*2d9fd380Sjfb8856606 	}
290*2d9fd380Sjfb8856606 
291*2d9fd380Sjfb8856606 	/* Alloc the stats memory */
292*2d9fd380Sjfb8856606 	stats = stats_mem_init(&cluster, prm);
293*2d9fd380Sjfb8856606 	if (stats == NULL)
294*2d9fd380Sjfb8856606 		SET_ERR_JMP(ENOMEM, bad_pattern, "Failed alloc stats memory");
295*2d9fd380Sjfb8856606 
296*2d9fd380Sjfb8856606 	/* Iterate over M(Graph) x N (Nodes in graph) */
297*2d9fd380Sjfb8856606 	for (i = 0; i < cluster.nb_graphs; i++) {
298*2d9fd380Sjfb8856606 		graph = cluster.graphs[i];
299*2d9fd380Sjfb8856606 		STAILQ_FOREACH(graph_node, &graph->node_list, next) {
300*2d9fd380Sjfb8856606 			struct rte_graph *graph_fp = graph->graph;
301*2d9fd380Sjfb8856606 			if (stats_mem_populate(&stats, graph_fp, graph_node))
302*2d9fd380Sjfb8856606 				goto realloc_fail;
303*2d9fd380Sjfb8856606 		}
304*2d9fd380Sjfb8856606 	}
305*2d9fd380Sjfb8856606 
306*2d9fd380Sjfb8856606 	/* Finally copy to hugepage memory to avoid pressure on rte_realloc */
307*2d9fd380Sjfb8856606 	rc = rte_malloc_socket(NULL, stats->sz, 0, stats->socket_id);
308*2d9fd380Sjfb8856606 	if (rc)
309*2d9fd380Sjfb8856606 		rte_memcpy(rc, stats, stats->sz);
310*2d9fd380Sjfb8856606 	else
311*2d9fd380Sjfb8856606 		SET_ERR_JMP(ENOMEM, realloc_fail, "rte_malloc failed");
312*2d9fd380Sjfb8856606 
313*2d9fd380Sjfb8856606 realloc_fail:
314*2d9fd380Sjfb8856606 	stats_mem_fini(stats);
315*2d9fd380Sjfb8856606 bad_pattern:
316*2d9fd380Sjfb8856606 	graph_spinlock_unlock();
317*2d9fd380Sjfb8856606 	cluster_fini(&cluster);
318*2d9fd380Sjfb8856606 fail:
319*2d9fd380Sjfb8856606 	return rc;
320*2d9fd380Sjfb8856606 }
321*2d9fd380Sjfb8856606 
322*2d9fd380Sjfb8856606 void
rte_graph_cluster_stats_destroy(struct rte_graph_cluster_stats * stat)323*2d9fd380Sjfb8856606 rte_graph_cluster_stats_destroy(struct rte_graph_cluster_stats *stat)
324*2d9fd380Sjfb8856606 {
325*2d9fd380Sjfb8856606 	return rte_free(stat);
326*2d9fd380Sjfb8856606 }
327*2d9fd380Sjfb8856606 
328*2d9fd380Sjfb8856606 static inline void
cluster_node_arregate_stats(struct cluster_node * cluster)329*2d9fd380Sjfb8856606 cluster_node_arregate_stats(struct cluster_node *cluster)
330*2d9fd380Sjfb8856606 {
331*2d9fd380Sjfb8856606 	uint64_t calls = 0, cycles = 0, objs = 0, realloc_count = 0;
332*2d9fd380Sjfb8856606 	struct rte_graph_cluster_node_stats *stat = &cluster->stat;
333*2d9fd380Sjfb8856606 	struct rte_node *node;
334*2d9fd380Sjfb8856606 	rte_node_t count;
335*2d9fd380Sjfb8856606 
336*2d9fd380Sjfb8856606 	for (count = 0; count < cluster->nb_nodes; count++) {
337*2d9fd380Sjfb8856606 		node = cluster->nodes[count];
338*2d9fd380Sjfb8856606 
339*2d9fd380Sjfb8856606 		calls += node->total_calls;
340*2d9fd380Sjfb8856606 		objs += node->total_objs;
341*2d9fd380Sjfb8856606 		cycles += node->total_cycles;
342*2d9fd380Sjfb8856606 		realloc_count += node->realloc_count;
343*2d9fd380Sjfb8856606 	}
344*2d9fd380Sjfb8856606 
345*2d9fd380Sjfb8856606 	stat->calls = calls;
346*2d9fd380Sjfb8856606 	stat->objs = objs;
347*2d9fd380Sjfb8856606 	stat->cycles = cycles;
348*2d9fd380Sjfb8856606 	stat->ts = rte_get_timer_cycles();
349*2d9fd380Sjfb8856606 	stat->realloc_count = realloc_count;
350*2d9fd380Sjfb8856606 }
351*2d9fd380Sjfb8856606 
352*2d9fd380Sjfb8856606 static inline void
cluster_node_store_prev_stats(struct cluster_node * cluster)353*2d9fd380Sjfb8856606 cluster_node_store_prev_stats(struct cluster_node *cluster)
354*2d9fd380Sjfb8856606 {
355*2d9fd380Sjfb8856606 	struct rte_graph_cluster_node_stats *stat = &cluster->stat;
356*2d9fd380Sjfb8856606 
357*2d9fd380Sjfb8856606 	stat->prev_ts = stat->ts;
358*2d9fd380Sjfb8856606 	stat->prev_calls = stat->calls;
359*2d9fd380Sjfb8856606 	stat->prev_objs = stat->objs;
360*2d9fd380Sjfb8856606 	stat->prev_cycles = stat->cycles;
361*2d9fd380Sjfb8856606 }
362*2d9fd380Sjfb8856606 
363*2d9fd380Sjfb8856606 void
rte_graph_cluster_stats_get(struct rte_graph_cluster_stats * stat,bool skip_cb)364*2d9fd380Sjfb8856606 rte_graph_cluster_stats_get(struct rte_graph_cluster_stats *stat, bool skip_cb)
365*2d9fd380Sjfb8856606 {
366*2d9fd380Sjfb8856606 	struct cluster_node *cluster;
367*2d9fd380Sjfb8856606 	rte_node_t count;
368*2d9fd380Sjfb8856606 	int rc = 0;
369*2d9fd380Sjfb8856606 
370*2d9fd380Sjfb8856606 	cluster = stat->clusters;
371*2d9fd380Sjfb8856606 
372*2d9fd380Sjfb8856606 	for (count = 0; count < stat->max_nodes; count++) {
373*2d9fd380Sjfb8856606 		cluster_node_arregate_stats(cluster);
374*2d9fd380Sjfb8856606 		if (!skip_cb)
375*2d9fd380Sjfb8856606 			rc = stat->fn(!count, (count == stat->max_nodes - 1),
376*2d9fd380Sjfb8856606 				      stat->cookie, &cluster->stat);
377*2d9fd380Sjfb8856606 		cluster_node_store_prev_stats(cluster);
378*2d9fd380Sjfb8856606 		if (rc)
379*2d9fd380Sjfb8856606 			break;
380*2d9fd380Sjfb8856606 		cluster = RTE_PTR_ADD(cluster, stat->cluster_node_size);
381*2d9fd380Sjfb8856606 	}
382*2d9fd380Sjfb8856606 }
383*2d9fd380Sjfb8856606 
384*2d9fd380Sjfb8856606 void
rte_graph_cluster_stats_reset(struct rte_graph_cluster_stats * stat)385*2d9fd380Sjfb8856606 rte_graph_cluster_stats_reset(struct rte_graph_cluster_stats *stat)
386*2d9fd380Sjfb8856606 {
387*2d9fd380Sjfb8856606 	struct cluster_node *cluster;
388*2d9fd380Sjfb8856606 	rte_node_t count;
389*2d9fd380Sjfb8856606 
390*2d9fd380Sjfb8856606 	cluster = stat->clusters;
391*2d9fd380Sjfb8856606 
392*2d9fd380Sjfb8856606 	for (count = 0; count < stat->max_nodes; count++) {
393*2d9fd380Sjfb8856606 		struct rte_graph_cluster_node_stats *node = &cluster->stat;
394*2d9fd380Sjfb8856606 
395*2d9fd380Sjfb8856606 		node->ts = 0;
396*2d9fd380Sjfb8856606 		node->calls = 0;
397*2d9fd380Sjfb8856606 		node->objs = 0;
398*2d9fd380Sjfb8856606 		node->cycles = 0;
399*2d9fd380Sjfb8856606 		node->prev_ts = 0;
400*2d9fd380Sjfb8856606 		node->prev_calls = 0;
401*2d9fd380Sjfb8856606 		node->prev_objs = 0;
402*2d9fd380Sjfb8856606 		node->prev_cycles = 0;
403*2d9fd380Sjfb8856606 		node->realloc_count = 0;
404*2d9fd380Sjfb8856606 		cluster = RTE_PTR_ADD(cluster, stat->cluster_node_size);
405*2d9fd380Sjfb8856606 	}
406*2d9fd380Sjfb8856606 }
407