Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2024 Marvell International Ltd.
3 : : */
4 : :
5 : : #include "test.h"
6 : :
7 : : #include <assert.h>
8 : : #include <inttypes.h>
9 : : #include <signal.h>
10 : : #include <stdalign.h>
11 : : #include <stdio.h>
12 : : #include <string.h>
13 : : #include <unistd.h>
14 : :
15 : : #include <rte_errno.h>
16 : :
17 : : #ifndef RTE_EXEC_ENV_WINDOWS
18 : : #include <rte_graph.h>
19 : : #include <rte_graph_worker.h>
20 : : #include <rte_mbuf.h>
21 : : #include <rte_mbuf_dyn.h>
22 : : #include <rte_random.h>
23 : : #include <rte_graph_feature_arc.h>
24 : : #include <rte_graph_feature_arc_worker.h>
25 : :
26 : : #define MBUF_NUM 256
27 : : #define TEST_ARC1_NAME "arc1"
28 : : #define TEST_ARC2_NAME "arc2"
29 : : #define TEST_FAILED_ARC "failed_arc"
30 : : #define MAX_INDEXES 10
31 : : #define OVERRIDE_MAX_INDEX MBUF_NUM
32 : : #define MAX_FEATURES 5
33 : :
34 : : #define dbg(...)
35 : :
36 : : #define SOURCE1 "arc_source1_node"
37 : : #define INPUT_STATIC "arc_input_static_node"
38 : : #define OUTPUT_STATIC "arc_output_static_node"
39 : : #define PKT_FREE_STATIC "arc_pkt_free_static_node"
40 : : #define ARC1_FEATURE1 "arc1_feature1_node"
41 : : #define ARC1_FEATURE2 "arc1_feature2_node"
42 : : #define ARC2_FEATURE1 "arc2_feature1_node"
43 : : #define ARC2_FEATURE2 "arc2_feature2_node"
44 : : #define ARC2_FEATURE3 "arc2_feature3_node"
45 : : #define DUMMY1_STATIC "arc_dummy1_static_node"
46 : : #define DUMMY2_STATIC "arc_dummy2_static_node"
47 : :
48 : : #define feature_cast(x) ((rte_graph_feature_t)(x))
49 : :
50 : : /* (Node index, Node Name, feature app_cookie base */
51 : : #define FOREACH_TEST_NODE_ARC { \
52 : : R(0, SOURCE1, 64) \
53 : : R(1, INPUT_STATIC, 128) \
54 : : R(2, OUTPUT_STATIC, 256) \
55 : : R(3, PKT_FREE_STATIC, 512) \
56 : : R(4, ARC1_FEATURE1, 1024) \
57 : : R(5, ARC1_FEATURE2, 2048) \
58 : : R(6, ARC2_FEATURE1, 4096) \
59 : : R(7, ARC2_FEATURE2, 8192) \
60 : : R(8, ARC2_FEATURE3, 16384) \
61 : : R(9, DUMMY1_STATIC, 32768) \
62 : : R(10, DUMMY2_STATIC, 65536) \
63 : : }
64 : :
65 : : /**
66 : : * ARC1: Feature arc on ingress interface
67 : : * ARC2: Feature arc on egress interface
68 : : * XX_static: Static nodes
69 : : * XX_featureX: Feature X on arc
70 : : *
71 : : * -----> ARC1_FEATURE1
72 : : * | | |
73 : : * | | v
74 : : * | | ARC1_FEATURE2
75 : : * | | |
76 : : * | v v
77 : : * SOURCE1 ->-----> INPUT_STATIC --> OUTPUT_STATIC -----> PKT_FREE_STATIC
78 : : * | | | ^ ^ ^
79 : : * | | | | | |
80 : : * | | --> ARC2_FEATURE1 | |
81 : : * | | ^ ^ | |
82 : : * | | | | | |
83 : : * | ----------c-> ARC2_FEATURE2 |
84 : : * | | ^ |
85 : : * | | | |
86 : : * ----------> ARC2_FEATURE3 -------
87 : : */
88 : : const char *node_names_feature_arc[] = {
89 : : SOURCE1, INPUT_STATIC, OUTPUT_STATIC, PKT_FREE_STATIC,
90 : : ARC1_FEATURE1, ARC1_FEATURE2, ARC2_FEATURE1, ARC2_FEATURE2, ARC2_FEATURE3,
91 : : DUMMY1_STATIC, DUMMY2_STATIC
92 : : };
93 : :
94 : : const char *arc_names[] = {
95 : : TEST_ARC1_NAME, TEST_ARC2_NAME,
96 : : };
97 : :
98 : : const char *arc1_feature_seq[] = {
99 : : ARC1_FEATURE1, ARC1_FEATURE2, INPUT_STATIC,
100 : : };
101 : :
102 : : const char *arc2_feature_seq[] = {
103 : : ARC2_FEATURE1, ARC2_FEATURE2, ARC2_FEATURE3, PKT_FREE_STATIC,
104 : : };
105 : :
106 : : #define MAX_NODES RTE_DIM(node_names_feature_arc)
107 : :
108 : : typedef enum {
109 : : START_NODE,
110 : : INTERMEDIATE_FEATURE,
111 : : END_FEATURE,
112 : : } fp_node_type_t;
113 : :
114 : : static int fp_test_case_result_failed;
115 : : static const char *fp_error_node;
116 : : static uint64_t fp_end_feature_counters;
117 : : static uint64_t sp_enable_counters, sp_enable_cb_counters;
118 : : static uint64_t sp_disable_counters, sp_disable_cb_counters;
119 : :
120 : : /* Function declarations */
121 : : static uint16_t
122 : : source1_fn(struct rte_graph *graph, struct rte_node *node,
123 : : void **objs, uint16_t nb_objs);
124 : : static uint16_t
125 : : input_fa_fn(struct rte_graph *graph, struct rte_node *node,
126 : : void **objs, uint16_t nb_objs);
127 : : static uint16_t
128 : : output_fa_fn(struct rte_graph *graph, struct rte_node *node,
129 : : void **objs, uint16_t nb_objs);
130 : : static uint16_t
131 : : pkt_free_fn(struct rte_graph *graph, struct rte_node *node,
132 : : void **objs, uint16_t nb_objs);
133 : : static uint16_t
134 : : pkt_free_fa_fn(struct rte_graph *graph, struct rte_node *node,
135 : : void **objs, uint16_t nb_objs);
136 : : static uint16_t
137 : : dummy1_fn(struct rte_graph *graph, struct rte_node *node,
138 : : void **objs, uint16_t nb_objs);
139 : : static uint16_t
140 : : dummy2_fn(struct rte_graph *graph, struct rte_node *node,
141 : : void **objs, uint16_t nb_objs);
142 : : static uint16_t
143 : : arc1_feature1_fn(struct rte_graph *graph, struct rte_node *node,
144 : : void **objs, uint16_t nb_objs);
145 : : static uint16_t
146 : : arc1_feature1_fa_fn(struct rte_graph *graph, struct rte_node *node,
147 : : void **objs, uint16_t nb_objs);
148 : : static uint16_t
149 : : arc1_feature2_fa_fn(struct rte_graph *graph, struct rte_node *node,
150 : : void **objs, uint16_t nb_objs);
151 : : static uint16_t
152 : : arc2_feature1_fa_fn(struct rte_graph *graph, struct rte_node *node,
153 : : void **objs, uint16_t nb_objs);
154 : : static uint16_t
155 : : arc2_feature2_fa_fn(struct rte_graph *graph, struct rte_node *node,
156 : : void **objs, uint16_t nb_objs);
157 : : static uint16_t
158 : : arc2_feature3_fa_fn(struct rte_graph *graph, struct rte_node *node,
159 : : void **objs, uint16_t nb_objs);
160 : : static int
161 : : common_arc1_init(const struct rte_graph *graph, struct rte_node *node);
162 : : static int
163 : : common_arc2_init(const struct rte_graph *graph, struct rte_node *node);
164 : : static uint16_t
165 : : common_process_fn(struct rte_graph *graph, struct rte_node *node,
166 : : void **objs, uint16_t nb_objs, uint16_t max_indexes,
167 : : uint16_t mbuf_arr_offset, fp_node_type_t type);
168 : :
169 : : typedef struct test_node_priv {
170 : : int stop_enqueue;
171 : :
172 : : /* rte_graph node id */
173 : : uint32_t node_id;
174 : :
175 : : rte_graph_feature_arc_t arc;
176 : : } test_node_priv_t;
177 : :
178 : : typedef struct {
179 : : rte_graph_feature_t feature;
180 : : uint16_t egress_interface;
181 : : uint16_t ingress_interface;
182 : : } graph_dynfield_t;
183 : :
184 : : #define MAX_FEATURE_ARCS 4
185 : : static rte_graph_feature_arc_t arcs[MAX_FEATURE_ARCS];
186 : : static struct rte_mbuf mbufs[MAX_NODES + 1][MBUF_NUM];
187 : : static void *mbuf_p[MAX_NODES + 1][MBUF_NUM];
188 : : static rte_graph_t graph_id = RTE_GRAPH_ID_INVALID;
189 : :
190 : : static uint16_t
191 : 833 : compute_unique_user_data(const char *parent, const char *child, uint32_t interface_index)
192 : : {
193 : 833 : uint16_t user_data = interface_index;
194 : :
195 : : RTE_SET_USED(parent);
196 : : #define R(idx, node, node_cookie) { \
197 : : if (!strcmp(child, node)) { \
198 : : user_data += node_cookie + idx; \
199 : : } \
200 : : }
201 : :
202 [ - + + + : 833 : FOREACH_TEST_NODE_ARC
- + + + +
+ + + + +
+ + + + -
+ - + ]
203 : : #undef R
204 : :
205 : 833 : return user_data;
206 : : }
207 : :
208 : 816 : static void update_sp_counters(const char *arc_name, const char *feature_name,
209 : : rte_node_t feature_node_id, uint32_t index,
210 : : bool enable_disable, uint16_t app_cookie)
211 : :
212 : : {
213 : : RTE_SET_USED(feature_node_id);
214 : :
215 [ + + ]: 816 : if (app_cookie != UINT16_MAX) {
216 [ - + ]: 544 : if (app_cookie != compute_unique_user_data(arc_name, feature_name, index)) {
217 : 0 : printf("cb():%s/%s/%u: app_cookie mismatch %u != %u\n",
218 : : arc_name, feature_name, index, app_cookie,
219 : : compute_unique_user_data(arc_name, feature_name, index));
220 : 0 : sp_enable_counters = UINT16_MAX;
221 : 0 : sp_disable_counters = UINT16_MAX;
222 : : }
223 : : }
224 [ + + ]: 816 : if (enable_disable)
225 : 272 : sp_enable_cb_counters++;
226 : : else
227 : 544 : sp_disable_cb_counters++;
228 : 816 : }
229 : :
230 : : static int
231 : 17 : get_edge(struct rte_node_register *parent_node,
232 : : struct rte_node_register *child_node, rte_edge_t *_edge)
233 : : {
234 : : char **next_edges = NULL;
235 : : uint32_t count, i;
236 : :
237 : 17 : count = rte_node_edge_get(parent_node->id, NULL);
238 : :
239 [ + - ]: 17 : if (!count)
240 : : return -1;
241 : :
242 : 17 : next_edges = malloc(count);
243 : :
244 [ + - ]: 17 : if (!next_edges)
245 : : return -1;
246 : :
247 : 17 : count = rte_node_edge_get(parent_node->id, next_edges);
248 [ + - ]: 55 : for (i = 0; i < count; i++) {
249 [ + + ]: 55 : if (strstr(child_node->name, next_edges[i])) {
250 [ + + ]: 17 : if (_edge)
251 : 16 : *_edge = (rte_edge_t)i;
252 : :
253 : 17 : free(next_edges);
254 : 17 : return 0;
255 : : }
256 : : }
257 : 0 : free(next_edges);
258 : :
259 : 0 : return -1;
260 : : }
261 : :
262 : : int
263 : 12 : common_arc1_init(const struct rte_graph *graph, struct rte_node *node)
264 : : {
265 : : test_node_priv_t *priv = (test_node_priv_t *)node->ctx;
266 : :
267 : : RTE_SET_USED(graph);
268 : :
269 : 12 : priv->node_id = node->id;
270 : 12 : priv->stop_enqueue = 0;
271 [ - + ]: 12 : if (rte_graph_feature_arc_lookup_by_name(TEST_ARC1_NAME, &priv->arc) < 0)
272 : 0 : return -1;
273 : :
274 : : return 0;
275 : : }
276 : :
277 : : int
278 : 21 : common_arc2_init(const struct rte_graph *graph, struct rte_node *node)
279 : : {
280 : : test_node_priv_t *priv = (test_node_priv_t *)node->ctx;
281 : :
282 : : RTE_SET_USED(graph);
283 : :
284 : 21 : priv->node_id = node->id;
285 [ - + ]: 21 : if (rte_graph_feature_arc_lookup_by_name(TEST_ARC2_NAME, &priv->arc) < 0)
286 : 0 : return -1;
287 : :
288 : : return 0;
289 : : }
290 : :
291 : : uint16_t
292 : 31 : common_process_fn(struct rte_graph *graph, struct rte_node *node,
293 : : void **objs, uint16_t nb_objs, uint16_t max_indexes,
294 : : uint16_t mbuf_arr_offset,
295 : : fp_node_type_t ndtype)
296 : : {
297 : : test_node_priv_t *priv = (test_node_priv_t *)node->ctx;
298 : : struct rte_graph_feature_arc *arc =
299 [ + - ]: 31 : rte_graph_feature_arc_get(priv->arc);
300 : : struct rte_graph_feature_arc_mbuf_dynfields *mbfields = NULL;
301 : : struct rte_mbuf *bufs[MBUF_NUM];
302 : : rte_edge_t edges[MBUF_NUM];
303 : : uint32_t i, idx;
304 : :
305 : : RTE_SET_USED(objs);
306 [ + + ]: 31 : if (priv->stop_enqueue)
307 : : return 0;
308 : :
309 [ + + ]: 13 : if (ndtype == START_NODE)
310 : : nb_objs = MBUF_NUM;
311 : :
312 [ + + ]: 2432 : for (i = 0; i < nb_objs; i++) {
313 [ + + + ]: 2419 : switch (ndtype) {
314 : 1024 : case START_NODE:
315 : 1024 : edges[i] = UINT16_MAX;
316 : 1024 : bufs[i] = mbuf_p[mbuf_arr_offset][i];
317 : 1024 : break;
318 : 371 : case INTERMEDIATE_FEATURE:
319 : 371 : edges[i] = UINT16_MAX;
320 : 371 : bufs[i] = (struct rte_mbuf *)objs[i];
321 : 371 : break;
322 : 1024 : default:
323 : 1024 : edges[i] = 0;
324 : 1024 : bufs[i] = (struct rte_mbuf *)objs[i];
325 : 1024 : break;
326 : : }
327 [ + + ]: 2419 : mbfields = rte_graph_feature_arc_mbuf_dynfields_get(bufs[i], arc->mbuf_dyn_offset);
328 [ + + ]: 2419 : if (ndtype == START_NODE) {
329 [ - + ]: 1024 : idx = i % max_indexes;
330 : : if (!rte_graph_feature_data_first_feature_get(arc, idx,
331 : : &mbfields->feature_data,
332 : : &edges[i])) {
333 : 0 : fp_test_case_result_failed = 1;
334 : 0 : fp_error_node = node->name;
335 : 0 : priv->stop_enqueue = 1;
336 : 0 : return i;
337 : : }
338 [ + + ]: 1395 : } else if (ndtype == INTERMEDIATE_FEATURE) {
339 [ - + ]: 371 : if (!rte_graph_feature_data_next_feature_get(arc,
340 : : &mbfields->feature_data,
341 : : &edges[i])) {
342 : 0 : fp_test_case_result_failed = 1;
343 : 0 : fp_error_node = node->name;
344 : 0 : return i;
345 : : }
346 : : } else {
347 : : /* Send pkts from arc1_end to arc2_start*/
348 [ + + ]: 1024 : if (mbuf_arr_offset == 0)
349 : 512 : edges[i] = 0;
350 : 1024 : fp_end_feature_counters++;
351 : : }
352 [ - + ]: 2419 : if (edges[i] == UINT16_MAX)
353 : 0 : RTE_VERIFY(0);
354 : : }
355 [ + + ]: 13 : if (ndtype == START_NODE)
356 : 4 : priv->stop_enqueue = 1;
357 : :
358 [ + - + + ]: 13 : if (!fp_test_case_result_failed && (!mbuf_arr_offset || (ndtype != END_FEATURE)))
359 : 11 : rte_node_enqueue_next(graph, node, edges, (void **)bufs, nb_objs);
360 : :
361 : : return nb_objs;
362 : : }
363 : :
364 : : uint16_t
365 : 20 : source1_fn(struct rte_graph *graph, struct rte_node *node,
366 : : void **objs, uint16_t nb_objs)
367 : : {
368 : 20 : return common_process_fn(graph, node, objs, nb_objs, MAX_INDEXES, 0, START_NODE);
369 : : }
370 : :
371 : : static struct rte_node_register node_source1 = {
372 : : .name = SOURCE1,
373 : : .process = source1_fn,
374 : : .flags = RTE_NODE_SOURCE_F,
375 : : .nb_edges = 3,
376 : : .init = common_arc1_init,
377 : : .next_nodes = {INPUT_STATIC, DUMMY1_STATIC, DUMMY2_STATIC},
378 : : };
379 : 253 : RTE_NODE_REGISTER(node_source1);
380 : :
381 : : uint16_t
382 : 2 : input_fa_fn(struct rte_graph *graph, struct rte_node *node,
383 : : void **objs, uint16_t nb_objs)
384 : : {
385 : 2 : return common_process_fn(graph, node, objs, nb_objs, MAX_INDEXES, 0, END_FEATURE);
386 : : }
387 : :
388 : : static struct rte_node_register node_input = {
389 : : .name = INPUT_STATIC,
390 : : .process = input_fa_fn,
391 : : .nb_edges = 2,
392 : : .init = common_arc1_init,
393 : : .next_nodes = {OUTPUT_STATIC, DUMMY1_STATIC},
394 : : };
395 : 253 : RTE_NODE_REGISTER(node_input);
396 : :
397 : : struct rte_graph_feature_register arc1_end_feature = {
398 : : .feature_name = INPUT_STATIC,
399 : : .arc_name = TEST_ARC1_NAME,
400 : : .feature_process_fn = input_fa_fn,
401 : : .feature_node = &node_input,
402 : : .notifier_cb = update_sp_counters,
403 : : };
404 : :
405 : : static struct rte_graph_feature_arc_register arc1_input = {
406 : : .arc_name = TEST_ARC1_NAME,
407 : : .max_indexes = MAX_INDEXES,
408 : : .max_features = MAX_FEATURES,
409 : : .start_node = &node_source1,
410 : : .start_node_feature_process_fn = source1_fn,
411 : : .end_feature = &arc1_end_feature,
412 : : };
413 : :
414 : : uint16_t
415 : 2 : output_fa_fn(struct rte_graph *graph, struct rte_node *node,
416 : : void **objs, uint16_t nb_objs)
417 : : {
418 : 2 : return common_process_fn(graph, node, objs, nb_objs,
419 : : OVERRIDE_MAX_INDEX, 1, START_NODE);
420 : : }
421 : :
422 : : static struct rte_node_register node_output = {
423 : : .name = OUTPUT_STATIC,
424 : : .process = output_fa_fn,
425 : : .nb_edges = 3,
426 : : .init = common_arc2_init,
427 : : .next_nodes = {DUMMY1_STATIC, PKT_FREE_STATIC, DUMMY2_STATIC},
428 : : };
429 : 253 : RTE_NODE_REGISTER(node_output);
430 : :
431 : : uint16_t
432 : 0 : pkt_free_fn(struct rte_graph *graph, struct rte_node *node,
433 : : void **objs, uint16_t nb_objs)
434 : : {
435 : : RTE_SET_USED(graph);
436 : : RTE_SET_USED(node);
437 : : RTE_SET_USED(objs);
438 : : RTE_SET_USED(nb_objs);
439 : :
440 : 0 : fp_test_case_result_failed = 1;
441 : 0 : fp_error_node = node->name;
442 : 0 : return 0;
443 : : }
444 : :
445 : : uint16_t
446 : 2 : pkt_free_fa_fn(struct rte_graph *graph, struct rte_node *node,
447 : : void **objs, uint16_t nb_objs)
448 : : {
449 : 2 : return common_process_fn(graph, node, objs, nb_objs,
450 : : OVERRIDE_MAX_INDEX, 1, END_FEATURE);
451 : : }
452 : :
453 : : static struct rte_node_register node_pkt_free = {
454 : : .name = PKT_FREE_STATIC,
455 : : .process = pkt_free_fn,
456 : : .nb_edges = 1,
457 : : .init = common_arc2_init,
458 : : .next_nodes = {DUMMY1_STATIC},
459 : : };
460 : 253 : RTE_NODE_REGISTER(node_pkt_free);
461 : :
462 : 8 : static uint16_t override_arc2_index(void)
463 : : {
464 : 8 : return OVERRIDE_MAX_INDEX;
465 : : }
466 : :
467 : : struct rte_graph_feature_register arc2_end_feature = {
468 : : .feature_name = PKT_FREE_STATIC,
469 : : .arc_name = TEST_ARC2_NAME,
470 : : .feature_process_fn = pkt_free_fa_fn,
471 : : .feature_node = &node_pkt_free,
472 : : .notifier_cb = update_sp_counters,
473 : : };
474 : :
475 : : static struct rte_graph_feature_arc_register arc2_output = {
476 : : .arc_name = TEST_ARC2_NAME,
477 : : .max_indexes = 1, /* Let feature override with bigger value */
478 : : /* max_features not provided. End feature is a feature hence should work*/
479 : : .start_node = &node_output,
480 : : .start_node_feature_process_fn = output_fa_fn,
481 : : .end_feature = &arc2_end_feature,
482 : : };
483 : 253 : RTE_GRAPH_FEATURE_ARC_REGISTER(arc2_output);
484 : :
485 : : /** Dummy nodes */
486 : : uint16_t
487 : 0 : dummy1_fn(struct rte_graph *graph, struct rte_node *node,
488 : : void **objs, uint16_t nb_objs)
489 : : {
490 : : RTE_SET_USED(graph);
491 : : RTE_SET_USED(node);
492 : : RTE_SET_USED(objs);
493 : : RTE_SET_USED(nb_objs);
494 : 0 : return 0;
495 : : }
496 : :
497 : : static struct rte_node_register dummy1 = {
498 : : .name = DUMMY1_STATIC,
499 : : .process = dummy1_fn,
500 : : .nb_edges = 0,
501 : : .init = common_arc2_init,
502 : : };
503 : 253 : RTE_NODE_REGISTER(dummy1);
504 : :
505 : : uint16_t
506 : 0 : dummy2_fn(struct rte_graph *graph, struct rte_node *node,
507 : : void **objs, uint16_t nb_objs)
508 : : {
509 : : RTE_SET_USED(graph);
510 : : RTE_SET_USED(node);
511 : : RTE_SET_USED(objs);
512 : : RTE_SET_USED(nb_objs);
513 : 0 : return 0;
514 : : }
515 : :
516 : : static struct rte_node_register dummy2 = {
517 : : .name = DUMMY2_STATIC,
518 : : .process = dummy2_fn,
519 : : .nb_edges = 5,
520 : : .init = common_arc2_init,
521 : : .next_nodes = { ARC1_FEATURE1, ARC1_FEATURE2, ARC2_FEATURE1,
522 : : ARC2_FEATURE2, ARC2_FEATURE3},
523 : : };
524 : 253 : RTE_NODE_REGISTER(dummy2);
525 : :
526 : : /** Failed registrations */
527 : :
528 : : struct rte_graph_feature_register sink_valid_feature = {
529 : : .feature_name = "sink_valid_feature",
530 : : .arc_name = TEST_FAILED_ARC,
531 : : .feature_process_fn = dummy2_fn,
532 : : .feature_node = &dummy2,
533 : : };
534 : :
535 : : struct rte_graph_feature_register sink_mismatch_arc_name = {
536 : : .feature_name = "sink_mismatch_arc_name",
537 : : .arc_name = "mismatch_arc_name",
538 : : .feature_process_fn = dummy2_fn,
539 : : .feature_node = &dummy2,
540 : : };
541 : :
542 : : struct rte_graph_feature_register sink_no_feature_node = {
543 : : .feature_name = "sink_no_feature_node",
544 : : .arc_name = TEST_FAILED_ARC,
545 : : .feature_process_fn = dummy2_fn,
546 : : };
547 : :
548 : : struct rte_graph_feature_register sink_no_feature_fn = {
549 : : .feature_name = "sink_no_feature_fn",
550 : : .arc_name = TEST_FAILED_ARC,
551 : : .feature_node = &dummy2,
552 : : };
553 : :
554 : : /* failed_arc1
555 : : * - max_features not provided
556 : : * - end_feature not provided
557 : : */
558 : : static struct rte_graph_feature_arc_register failed_arc1 = {
559 : : .arc_name = TEST_FAILED_ARC,
560 : : .max_indexes = 1, /* Let features override it*/
561 : : /* max_features field is missing */
562 : : /* end_feature missing */
563 : : .start_node = &dummy1,
564 : : .start_node_feature_process_fn = dummy1_fn,
565 : : };
566 : 253 : RTE_GRAPH_FEATURE_ARC_REGISTER(failed_arc1);
567 : :
568 : : /* failed_arc2
569 : : * - max_indexes not provided
570 : : */
571 : : static struct rte_graph_feature_arc_register failed_arc2 = {
572 : : .arc_name = TEST_FAILED_ARC,
573 : : .end_feature = &sink_valid_feature,
574 : : /* max_index not provided and neither override_index_cb() in any feature */
575 : : .start_node = &dummy1,
576 : : .start_node_feature_process_fn = dummy1_fn,
577 : : };
578 : 253 : RTE_GRAPH_FEATURE_ARC_REGISTER(failed_arc2);
579 : :
580 : : /* failed_arc3
581 : : * - start_node not provided
582 : : */
583 : : static struct rte_graph_feature_arc_register failed_arc3 = {
584 : : .arc_name = TEST_FAILED_ARC,
585 : : .end_feature = &sink_valid_feature,
586 : : .max_indexes = 1,
587 : : /* start_node not provided */
588 : : .start_node_feature_process_fn = dummy1_fn,
589 : : };
590 : 253 : RTE_GRAPH_FEATURE_ARC_REGISTER(failed_arc3)
591 : :
592 : : /* failed_arc4
593 : : * - start_node not provided
594 : : */
595 : : static struct rte_graph_feature_arc_register failed_arc4 = {
596 : : .arc_name = TEST_FAILED_ARC,
597 : : .end_feature = &sink_valid_feature,
598 : : .max_indexes = 5,
599 : : .start_node = &dummy1,
600 : : /* start_node fn not provided */
601 : : };
602 : 253 : RTE_GRAPH_FEATURE_ARC_REGISTER(failed_arc4);
603 : :
604 : : /* failed_arc5
605 : : * - end_feature has mismatch arc_name
606 : : */
607 : : static struct rte_graph_feature_arc_register failed_arc5 = {
608 : : .arc_name = TEST_FAILED_ARC,
609 : : .end_feature = &sink_mismatch_arc_name,
610 : : .max_indexes = 5,
611 : : .start_node = &dummy1,
612 : : .start_node_feature_process_fn = dummy1_fn,
613 : : };
614 : 253 : RTE_GRAPH_FEATURE_ARC_REGISTER(failed_arc5);
615 : :
616 : : /* failed_arc6
617 : : * - end_feature does not have feature_node
618 : : */
619 : : static struct rte_graph_feature_arc_register failed_arc6 = {
620 : : .arc_name = TEST_FAILED_ARC,
621 : : .end_feature = &sink_no_feature_node,
622 : : .max_indexes = 5,
623 : : .start_node = &dummy1,
624 : : .start_node_feature_process_fn = dummy1_fn,
625 : : };
626 : 253 : RTE_GRAPH_FEATURE_ARC_REGISTER(failed_arc6);
627 : :
628 : : /* failed_arc7
629 : : * - end_feature does not have feature_fn
630 : : */
631 : : static struct rte_graph_feature_arc_register failed_arc7 = {
632 : : .arc_name = TEST_FAILED_ARC,
633 : : .end_feature = &sink_no_feature_fn,
634 : : .max_indexes = 5,
635 : : .start_node = &dummy1,
636 : : .start_node_feature_process_fn = dummy1_fn,
637 : : };
638 : 253 : RTE_GRAPH_FEATURE_ARC_REGISTER(failed_arc7);
639 : :
640 : : uint16_t
641 : 0 : arc1_feature1_fn(struct rte_graph *graph, struct rte_node *node,
642 : : void **objs, uint16_t nb_objs)
643 : : {
644 : : RTE_SET_USED(graph);
645 : : RTE_SET_USED(node);
646 : : RTE_SET_USED(objs);
647 : : RTE_SET_USED(nb_objs);
648 : :
649 : : /* Feature on an arc cannot be called if feature arc is disabled */
650 : 0 : fp_test_case_result_failed = 1;
651 : 0 : fp_error_node = node->name;
652 : 0 : return 0;
653 : : }
654 : :
655 : : uint16_t
656 : 1 : arc1_feature1_fa_fn(struct rte_graph *graph, struct rte_node *node,
657 : : void **objs, uint16_t nb_objs)
658 : : {
659 : 1 : return common_process_fn(graph, node, objs, nb_objs,
660 : : MAX_INDEXES, 0, INTERMEDIATE_FEATURE);
661 : : }
662 : :
663 : : static struct rte_node_register arc1_feature1 = {
664 : : .name = ARC1_FEATURE1,
665 : : .process = arc1_feature1_fn,
666 : : .nb_edges = 0,
667 : : .init = common_arc1_init,
668 : : };
669 : 253 : RTE_NODE_REGISTER(arc1_feature1);
670 : :
671 : : static struct rte_graph_feature_register feat_arc1_feature1 = {
672 : : .feature_name = ARC1_FEATURE1,
673 : : .arc_name = TEST_ARC1_NAME,
674 : : .feature_process_fn = arc1_feature1_fa_fn,
675 : : .feature_node = &arc1_feature1,
676 : : .override_index_cb = override_arc2_index,
677 : : .notifier_cb = update_sp_counters,
678 : : };
679 : 253 : RTE_GRAPH_FEATURE_REGISTER(feat_arc1_feature1);
680 : :
681 : : uint16_t
682 : 1 : arc1_feature2_fa_fn(struct rte_graph *graph, struct rte_node *node,
683 : : void **objs, uint16_t nb_objs)
684 : : {
685 : 1 : return common_process_fn(graph, node, objs, nb_objs,
686 : : MAX_INDEXES, 0, INTERMEDIATE_FEATURE);
687 : : }
688 : :
689 : : static struct rte_node_register arc1_feature2 = {
690 : : .name = ARC1_FEATURE2,
691 : : .process = arc1_feature2_fa_fn,
692 : : .nb_edges = 0,
693 : : .init = common_arc1_init,
694 : : };
695 : 253 : RTE_NODE_REGISTER(arc1_feature2);
696 : :
697 : : /* add arc1_feature2 later using rte_graph_feature_add()*/
698 : : static struct rte_graph_feature_register feat_arc1_feature2 = {
699 : : .feature_name = ARC1_FEATURE2,
700 : : .arc_name = TEST_ARC1_NAME,
701 : : .feature_process_fn = arc1_feature2_fa_fn,
702 : : .feature_node = &arc1_feature2,
703 : : .runs_after = ARC1_FEATURE1,
704 : : .notifier_cb = update_sp_counters,
705 : : };
706 : :
707 : : uint16_t
708 : 1 : arc2_feature1_fa_fn(struct rte_graph *graph, struct rte_node *node,
709 : : void **objs, uint16_t nb_objs)
710 : : {
711 : 1 : return common_process_fn(graph, node, objs, nb_objs,
712 : : OVERRIDE_MAX_INDEX, 1, INTERMEDIATE_FEATURE);
713 : : }
714 : :
715 : : static struct rte_node_register arc2_feature1 = {
716 : : .name = ARC2_FEATURE1,
717 : : .process = arc2_feature1_fa_fn,
718 : : .nb_edges = 0,
719 : : .init = common_arc2_init,
720 : : };
721 : 253 : RTE_NODE_REGISTER(arc2_feature1);
722 : :
723 : : static struct rte_graph_feature_register feat_arc2_feature1 = {
724 : : .feature_name = ARC2_FEATURE1,
725 : : .arc_name = TEST_ARC2_NAME,
726 : : .feature_process_fn = arc2_feature1_fa_fn,
727 : : .feature_node = &arc2_feature1,
728 : : .notifier_cb = update_sp_counters,
729 : : };
730 : 253 : RTE_GRAPH_FEATURE_REGISTER(feat_arc2_feature1);
731 : :
732 : : uint16_t
733 : 1 : arc2_feature2_fa_fn(struct rte_graph *graph, struct rte_node *node,
734 : : void **objs, uint16_t nb_objs)
735 : : {
736 : 1 : return common_process_fn(graph, node, objs, nb_objs,
737 : : OVERRIDE_MAX_INDEX, 1, INTERMEDIATE_FEATURE);
738 : : }
739 : :
740 : : static struct rte_node_register arc2_feature2 = {
741 : : .name = ARC2_FEATURE2,
742 : : .process = arc2_feature2_fa_fn,
743 : : .nb_edges = 0,
744 : : .init = common_arc2_init,
745 : : };
746 : 253 : RTE_NODE_REGISTER(arc2_feature2);
747 : :
748 : : static struct rte_graph_feature_register feat_arc2_feature2 = {
749 : : .feature_name = ARC2_FEATURE2,
750 : : .arc_name = TEST_ARC2_NAME,
751 : : .feature_process_fn = arc2_feature2_fa_fn,
752 : : .feature_node = &arc2_feature2,
753 : : .runs_after = ARC2_FEATURE1,
754 : : .runs_before = ARC2_FEATURE3,
755 : : .override_index_cb = override_arc2_index,
756 : : .notifier_cb = update_sp_counters,
757 : : };
758 : 253 : RTE_GRAPH_FEATURE_REGISTER(feat_arc2_feature2);
759 : :
760 : : uint16_t
761 : 1 : arc2_feature3_fa_fn(struct rte_graph *graph, struct rte_node *node,
762 : : void **objs, uint16_t nb_objs)
763 : : {
764 : 1 : return common_process_fn(graph, node, objs, nb_objs,
765 : : OVERRIDE_MAX_INDEX, 1, INTERMEDIATE_FEATURE);
766 : : }
767 : :
768 : : static struct rte_node_register arc2_feature3 = {
769 : : .name = ARC2_FEATURE3,
770 : : .process = arc2_feature3_fa_fn,
771 : : .nb_edges = 0,
772 : : .init = common_arc2_init,
773 : : };
774 : 253 : RTE_NODE_REGISTER(arc2_feature3);
775 : :
776 : : static struct rte_graph_feature_register feat_arc2_feature3 = {
777 : : .feature_name = ARC2_FEATURE3,
778 : : .arc_name = TEST_ARC2_NAME,
779 : : .feature_process_fn = arc2_feature3_fa_fn,
780 : : .feature_node = &arc2_feature3,
781 : : .runs_after = ARC2_FEATURE1,
782 : : .notifier_cb = update_sp_counters,
783 : : };
784 : 253 : RTE_GRAPH_FEATURE_REGISTER(feat_arc2_feature3);
785 : :
786 : : static int
787 : 3 : create_graph(void)
788 : : {
789 : 3 : struct rte_graph_param gconf = {
790 : : .socket_id = SOCKET_ID_ANY,
791 : : .nb_node_patterns = RTE_DIM(node_names_feature_arc),
792 : : .node_patterns = node_names_feature_arc,
793 : : };
794 : :
795 : 3 : graph_id = rte_graph_create("worker0", &gconf);
796 [ - + ]: 3 : if (graph_id == RTE_GRAPH_ID_INVALID) {
797 : 0 : printf("Graph creation failed with error = %d\n", rte_errno);
798 : 0 : return TEST_FAILED;
799 : : }
800 : :
801 : : return TEST_SUCCESS;
802 : : }
803 : :
804 : : static int
805 : : destroy_graph(void)
806 : : {
807 [ + - + - ]: 3 : if (graph_id != RTE_GRAPH_ID_INVALID) {
808 : 3 : rte_graph_destroy(graph_id);
809 : 3 : graph_id = RTE_GRAPH_ID_INVALID;
810 : : }
811 : :
812 : : return TEST_SUCCESS;
813 : : }
814 : :
815 : 2 : static int test_perf(uint64_t end_feature_counters)
816 : : {
817 : : struct rte_graph *graph = NULL;
818 : : int i;
819 : :
820 : 2 : fp_test_case_result_failed = 0;
821 : 2 : fp_error_node = NULL;
822 : 2 : fp_end_feature_counters = 0;
823 : :
824 [ - + ]: 2 : if (create_graph() < 0) {
825 : : printf("Graph creation failed while walk\n");
826 : 0 : return TEST_FAILED;
827 : : }
828 : 2 : graph = rte_graph_lookup("worker0");
829 [ + - ]: 2 : if (graph) {
830 [ + + ]: 22 : for (i = 0; i < 10; i++)
831 : 20 : rte_graph_walk(graph);
832 : : }
833 : : if (destroy_graph() < 0) {
834 : : printf("Graph destroy failed while walk\n");
835 : : return TEST_FAILED;
836 : : }
837 [ - + ]: 2 : if (fp_test_case_result_failed) {
838 : 0 : printf("Feature arc test failed for node %s\n", fp_error_node);
839 : 0 : return TEST_FAILED;
840 : : }
841 : :
842 [ + + ]: 2 : if (sp_enable_counters &&
843 [ - + ]: 1 : (sp_enable_cb_counters != sp_enable_counters)) {
844 : : printf("sp_enable_cb_counters mismatch %"PRIu64" != %"PRIu64"\n",
845 : : sp_enable_cb_counters, sp_enable_counters);
846 : 0 : return TEST_FAILED;
847 : : }
848 [ + + ]: 2 : if (sp_disable_counters &&
849 [ - + ]: 1 : (sp_disable_cb_counters != sp_disable_counters)) {
850 : : printf("sp_disable_cb_counters mismatch %"PRIu64" != %"PRIu64"\n",
851 : : sp_disable_cb_counters, sp_disable_counters);
852 : 0 : return TEST_FAILED;
853 : : }
854 [ - + ]: 2 : if (fp_end_feature_counters != end_feature_counters) {
855 : : printf("end_bufs_counters mismatch %"PRIu64" != %"PRIu64"\n",
856 : : fp_end_feature_counters, end_feature_counters);
857 : 0 : return TEST_FAILED;
858 : : }
859 : 2 : sp_enable_counters = 0;
860 : 2 : sp_enable_cb_counters = 0;
861 : 2 : sp_disable_counters = 0;
862 : 2 : sp_disable_cb_counters = 0;
863 : 2 : return TEST_SUCCESS;
864 : : }
865 : :
866 : : static int
867 : 1 : __test_create_feature_arc(rte_graph_feature_arc_t *arcs, uint16_t max_arcs)
868 : : {
869 : : struct rte_graph_feature_arc_register reg;
870 : : struct rte_graph_feature_register feat;
871 : : rte_graph_feature_arc_t arc;
872 : : const char *sample_arc_name = "sample_arc";
873 : : char arc_name[256];
874 : : int n_arcs;
875 : :
876 [ - + ]: 1 : if (rte_graph_feature_arc_init(max_arcs) < 0) {
877 : : printf("Feature arc creation failed for arc: %u\n", max_arcs);
878 : 0 : return TEST_FAILED;
879 : : }
880 : :
881 : 1 : feat.feature_name = DUMMY2_STATIC;
882 : 1 : feat.feature_process_fn = dummy2_fn;
883 : 1 : feat.feature_node = &dummy2;
884 : 1 : feat.feature_node_id = dummy2.id;
885 : 1 : feat.runs_after = NULL;
886 : 1 : feat.runs_before = NULL;
887 : :
888 : 1 : reg.max_indexes = MAX_INDEXES;
889 : 1 : reg.max_features = 3;
890 : 1 : reg.start_node = &dummy1;
891 : 1 : reg.start_node_feature_process_fn = dummy1_fn;
892 : 1 : reg.end_feature = &feat;
893 [ + + ]: 5 : for (n_arcs = 0; n_arcs < max_arcs; n_arcs++) {
894 : : snprintf(arc_name, sizeof(arc_name), "%s-%u", sample_arc_name, n_arcs);
895 : 4 : feat.arc_name = arc_name;
896 : 4 : reg.arc_name = arc_name;
897 [ - + ]: 4 : if (rte_graph_feature_arc_create(®, &arcs[n_arcs]) < 0) {
898 : : printf("%s: Test failed for creating arc at index %u\n", arc_name, n_arcs);
899 : 0 : return TEST_FAILED;
900 : : }
901 : : }
902 : :
903 [ - + ]: 1 : if (rte_graph_feature_arc_create(&arc2_output, NULL) == 0) {
904 : 0 : printf("Failure: Feature arc %s should have already been created\n",
905 : : arc2_output.arc_name);
906 : 0 : return TEST_FAILED;
907 : : }
908 : : /* Verify feature arc created more than max_arcs must fail */
909 [ + + ]: 5 : for (n_arcs = 0; n_arcs < max_arcs; n_arcs++) {
910 : : snprintf(arc_name, sizeof(arc_name), "%s-%u", sample_arc_name, n_arcs);
911 : 4 : arc = RTE_GRAPH_FEATURE_ARC_INITIALIZER;
912 [ + - ]: 4 : if (rte_graph_feature_arc_lookup_by_name(arc_name, &arc) == 0) {
913 [ - + ]: 4 : if (arc != arcs[n_arcs]) {
914 : 0 : printf("%s: Feature arc lookup mismatch for arc [%u, exp: %u]\n",
915 : : arc_name, arc, arcs[n_arcs]);
916 : 0 : return TEST_FAILED;
917 : : }
918 : : dbg("Feature arc lookup %s succeeded\n", arc_name);
919 : : } else {
920 : : printf("Feature arc lookup %s failed after creation\n", arc_name);
921 : 0 : return TEST_FAILED;
922 : : }
923 : : }
924 : : return TEST_SUCCESS;
925 : : }
926 : :
927 : : static int
928 : 1 : test_graph_feature_arc_create(void)
929 : : {
930 : : int ret = 0;
931 : :
932 : 1 : ret = __test_create_feature_arc(arcs, MAX_FEATURE_ARCS);
933 [ - + ]: 1 : if (ret) {
934 : : printf("Feature arc creation test failed for %u number of arc create\n",
935 : : MAX_FEATURE_ARCS);
936 : 0 : goto test_failed;
937 : : }
938 [ - + ]: 1 : if (rte_graph_feature_arc_lookup_by_name(TEST_FAILED_ARC, NULL) == 0) {
939 : : printf("Feature arc %s should not have been created\n", TEST_FAILED_ARC);
940 : 0 : goto test_failed;
941 : : }
942 : :
943 : : /* Cleanup to verify recreation */
944 : 1 : rte_graph_feature_arc_cleanup();
945 : :
946 : : dbg("Feature arc cleanup done\n");
947 : :
948 : 1 : return TEST_SUCCESS;
949 : :
950 : : test_failed:
951 : : return TEST_FAILED;
952 : : }
953 : :
954 : : static int
955 : 1 : graph_feature_arc_setup(void)
956 : : {
957 : : unsigned long i, j;
958 : :
959 [ + + ]: 13 : for (i = 0; i <= MAX_NODES; i++) {
960 [ + + ]: 3084 : for (j = 0; j < MBUF_NUM; j++)
961 : 3072 : mbuf_p[i][j] = &mbufs[i][j];
962 : : }
963 : :
964 : 1 : return TEST_SUCCESS;
965 : :
966 : : }
967 : : static int
968 : 1 : test_graph_feature_arc_features_add(void)
969 : : {
970 : : struct rte_graph_feature_arc *arc = NULL;
971 : : rte_graph_feature_t temp;
972 : :
973 [ - + ]: 1 : if (rte_graph_feature_arc_init(1) < 0) {
974 : : printf("Feature arc creation failed just for adding features\n");
975 : 0 : return TEST_FAILED;
976 : : }
977 : :
978 : : /* see if duplicates fails */
979 [ - + ]: 1 : if (rte_graph_feature_add(&feat_arc2_feature1) == 0) {
980 : 0 : printf("%s: Feature add failed for adding feature %s\n",
981 : : feat_arc2_feature1.arc_name, feat_arc2_feature1.feature_name);
982 : 0 : goto test_failed;
983 : : }
984 : :
985 : : /* Create new arc1 */
986 : 1 : arc1_input.end_feature->feature_node_id = arc1_input.end_feature->feature_node->id;
987 [ - + ]: 1 : if (rte_graph_feature_arc_create(&arc1_input, &arcs[0]) < 0) {
988 : : printf("%s: Feature arc creation failed\n", TEST_ARC2_NAME);
989 : 0 : goto test_failed;
990 : : }
991 : :
992 : : /* Add features to arc1 */
993 : 1 : feat_arc1_feature1.feature_node_id = feat_arc1_feature1.feature_node->id;
994 [ - + ]: 1 : if (rte_graph_feature_add(&feat_arc1_feature1) < 0) {
995 : 0 : printf("%s: Feature add failed for adding feature %s\n",
996 : : feat_arc1_feature1.arc_name, feat_arc1_feature1.feature_name);
997 : 0 : goto test_failed;
998 : : }
999 : :
1000 : 1 : feat_arc1_feature2.feature_node_id = feat_arc1_feature2.feature_node->id;
1001 [ - + ]: 1 : if (rte_graph_feature_add(&feat_arc1_feature2) < 0) {
1002 : 0 : printf("%s: Feature add failed for adding feature %s\n",
1003 : : feat_arc1_feature2.arc_name, feat_arc1_feature2.feature_name);
1004 : : }
1005 : :
1006 [ - + ]: 1 : if (rte_graph_feature_arc_lookup_by_name(TEST_ARC2_NAME, &arcs[1]) < 0) {
1007 : : printf("%s: Feature arc lookup failed while adding features\n",
1008 : : TEST_ARC2_NAME);
1009 : 0 : goto test_failed;
1010 : : }
1011 : :
1012 [ + - ]: 1 : arc = rte_graph_feature_arc_get(arcs[1]);
1013 [ - + ]: 1 : if (!arc) {
1014 : : printf("%s: Feature arc ptr cannot be NULL\n",
1015 : : TEST_ARC2_NAME);
1016 : 0 : goto test_failed;
1017 : : }
1018 : :
1019 : : /* Make sure number of indexes are overridden by feature*/
1020 [ - + ]: 1 : if (arc->max_indexes < OVERRIDE_MAX_INDEX) {
1021 : 0 : printf("%s: Feature arc max_indexes mismatch %u < %u\n",
1022 : : TEST_ARC2_NAME, arc->max_indexes, OVERRIDE_MAX_INDEX);
1023 : 0 : goto test_failed;
1024 : : }
1025 : :
1026 : : /* arc1_feature1 must be first feature to arcs[0] */
1027 [ - + ]: 1 : if (!strstr(ARC1_FEATURE1,
1028 : 1 : rte_graph_feature_arc_feature_to_name(arcs[0],
1029 : : feature_cast(0)))) {
1030 : 0 : printf("%s: %s is not the first feature instead %s\n",
1031 : : TEST_ARC1_NAME, ARC1_FEATURE1,
1032 : 0 : rte_graph_feature_arc_feature_to_name(arcs[0], feature_cast(0)));
1033 : 0 : goto test_failed;
1034 : : }
1035 : :
1036 : : /* arc1_feature2 must be second feature to arcs[0] */
1037 [ - + ]: 1 : if (!strstr(ARC1_FEATURE2,
1038 : 1 : rte_graph_feature_arc_feature_to_name(arcs[0],
1039 : : feature_cast(1)))) {
1040 : 0 : printf("%s: %s is not the second feature instead %s\n",
1041 : : TEST_ARC1_NAME, ARC1_FEATURE2,
1042 : 0 : rte_graph_feature_arc_feature_to_name(arcs[0], feature_cast(1)));
1043 : 0 : goto test_failed;
1044 : : }
1045 : :
1046 : : /* Make sure INPUT_STATIC is the last feature in arcs[0] */
1047 : 1 : temp = rte_graph_feature_arc_num_features(arcs[0]);
1048 [ - + ]: 1 : if (!strstr(INPUT_STATIC,
1049 : 1 : rte_graph_feature_arc_feature_to_name(arcs[0],
1050 : 1 : temp - feature_cast(1)))) {
1051 : 0 : printf("%s: %s is not the last feature instead %s\n",
1052 : : TEST_ARC1_NAME, INPUT_STATIC,
1053 : 0 : rte_graph_feature_arc_feature_to_name(arcs[0],
1054 : : temp - feature_cast(1)));
1055 : 0 : goto test_failed;
1056 : : }
1057 : :
1058 : : /* arc2_feature1 must be first feature to arcs[1] */
1059 [ - + ]: 1 : if (!strstr(ARC2_FEATURE1,
1060 : 1 : rte_graph_feature_arc_feature_to_name(arcs[1],
1061 : : feature_cast(0)))) {
1062 : 0 : printf("%s: %s is not the first feature instead %s\n",
1063 : : TEST_ARC2_NAME, ARC2_FEATURE1,
1064 : 0 : rte_graph_feature_arc_feature_to_name(arcs[1], feature_cast(0)));
1065 : 0 : goto test_failed;
1066 : : }
1067 : :
1068 : : /* arc2_feature2 must be second feature to arcs[1] */
1069 [ - + ]: 1 : if (!strstr(ARC2_FEATURE2,
1070 : 1 : rte_graph_feature_arc_feature_to_name(arcs[1],
1071 : : feature_cast(1)))) {
1072 : 0 : printf("%s: %s is not the second feature instead %s\n",
1073 : : TEST_ARC2_NAME, ARC2_FEATURE2,
1074 : 0 : rte_graph_feature_arc_feature_to_name(arcs[1], feature_cast(1)));
1075 : 0 : goto test_failed;
1076 : : }
1077 : :
1078 : : /* arc2_feature3 must be third feature to arcs[1] */
1079 [ - + ]: 1 : if (!strstr(ARC2_FEATURE3,
1080 : 1 : rte_graph_feature_arc_feature_to_name(arcs[1],
1081 : : feature_cast(2)))) {
1082 : 0 : printf("%s: %s is not the third feature instead %s\n",
1083 : : TEST_ARC2_NAME, ARC2_FEATURE3,
1084 : 0 : rte_graph_feature_arc_feature_to_name(arcs[1], feature_cast(2)));
1085 : 0 : goto test_failed;
1086 : : }
1087 : :
1088 : : /* Make sure PKT_FREE is the last feature in arcs[1] */
1089 : 1 : temp = rte_graph_feature_arc_num_features(arcs[1]);
1090 [ - + ]: 1 : if (!strstr(PKT_FREE_STATIC,
1091 : 1 : rte_graph_feature_arc_feature_to_name(arcs[1],
1092 : 1 : temp - feature_cast(1)))) {
1093 : 0 : printf("%s: %s is not the last feature instead %s\n",
1094 : : TEST_ARC2_NAME, PKT_FREE_STATIC,
1095 : 0 : rte_graph_feature_arc_feature_to_name(arcs[1],
1096 : : temp - feature_cast(1)));
1097 : 0 : goto test_failed;
1098 : : }
1099 : :
1100 : : /* Make sure feature is connected to end feature */
1101 [ - + ]: 1 : if (get_edge(&arc2_feature1, &node_pkt_free, NULL)) {
1102 : : printf("%s: Edge not found between %s and %s\n",
1103 : : TEST_ARC2_NAME, ARC2_FEATURE1, PKT_FREE_STATIC);
1104 : 0 : goto test_failed;
1105 : : }
1106 : :
1107 [ - + ]: 1 : if (create_graph() < 0) {
1108 : : printf("Graph creation failed while adding features\n");
1109 : 0 : goto test_failed;
1110 : : }
1111 : : if (destroy_graph() < 0) {
1112 : : printf("Graph destroy failed while adding features\n");
1113 : : goto test_failed;
1114 : : }
1115 : : return TEST_SUCCESS;
1116 : 0 : test_failed:
1117 : 0 : rte_graph_feature_arc_cleanup();
1118 : 0 : return TEST_FAILED;
1119 : : }
1120 : :
1121 : : static int
1122 : 1 : test_graph_feature_arc_feature_enable(void)
1123 : : {
1124 : : uint32_t n_indexes, n_features, count = 0;
1125 : : struct rte_node_register *parent, *child;
1126 : : struct rte_graph_feature_arc *arc;
1127 : : rte_graph_feature_data_t fdata;
1128 : : char *feature_name = NULL;
1129 : : rte_edge_t edge1, edge2;
1130 : : uint16_t user_data;
1131 : :
1132 [ - + ]: 1 : if (rte_graph_feature_arc_lookup_by_name(TEST_ARC1_NAME, &arcs[0]) < 0) {
1133 : : printf("%s: Feature arc lookup failed while adding features\n",
1134 : : TEST_ARC1_NAME);
1135 : 0 : return TEST_FAILED;
1136 : : }
1137 : :
1138 [ + - ]: 1 : arc = rte_graph_feature_arc_get(arcs[0]);
1139 : :
1140 [ - + ]: 1 : if (rte_graph_feature_arc_is_any_feature_enabled(arc)) {
1141 : : printf("%s: Feature arc should not have any feature enabled by now\n",
1142 : : TEST_ARC1_NAME);
1143 : 0 : return TEST_FAILED;
1144 : : }
1145 : :
1146 [ - + ]: 1 : if (rte_graph_feature_arc_num_enabled_features(arcs[0])) {
1147 : : printf("%s: Feature arc should not have any_feature() enabled by now\n",
1148 : : TEST_ARC1_NAME);
1149 : 0 : return TEST_FAILED;
1150 : : }
1151 : : /*
1152 : : * On interface 0, enable feature 0,
1153 : : * On interface 1, enable feature 1 and so on so forth
1154 : : *
1155 : : * later verify first feature on every interface index is unique
1156 : : * and check [rte_edge, user_data] retrieved via fast path APIs
1157 : : */
1158 [ + + ]: 17 : for (n_indexes = 0; n_indexes < arc->max_indexes; n_indexes++) {
1159 : 16 : n_features = n_indexes % RTE_DIM(arc1_feature_seq);
1160 : 16 : feature_name = rte_graph_feature_arc_feature_to_name(arcs[0], n_features);
1161 [ - + ]: 16 : if (strncmp(feature_name, arc1_feature_seq[n_features],
1162 : : RTE_GRAPH_NAMESIZE)) {
1163 : : printf("%s: Feature(%u) seq mismatch [found: %s, exp: %s]\n",
1164 : : TEST_ARC1_NAME, n_features, feature_name,
1165 : : arc1_feature_seq[n_features]);
1166 : 0 : return TEST_FAILED;
1167 : : }
1168 : 16 : user_data = compute_unique_user_data(arc->start_node->name, feature_name,
1169 : : n_indexes);
1170 : : /* negative test case. enable feature on invalid index */
1171 [ + + - + ]: 16 : if (!n_indexes && (rte_graph_feature_enable(arcs[0], 65535, feature_name,
1172 : : user_data, NULL) == 0)) {
1173 : : printf("%s: Feature %s should not be enabled on invalid index\n",
1174 : : TEST_ARC1_NAME, feature_name);
1175 : 0 : return TEST_FAILED;
1176 : : }
1177 [ - + ]: 16 : if (rte_graph_feature_enable(arcs[0], n_indexes, feature_name,
1178 : : user_data, NULL) < 0) {
1179 : : printf("%s: Feature enable failed for %s on index %u\n",
1180 : : TEST_ARC1_NAME, feature_name, n_indexes);
1181 : 0 : return TEST_FAILED;
1182 : : }
1183 [ + - ]: 16 : sp_enable_counters++;
1184 : : /* has any feature should be valid */
1185 [ - + ]: 16 : if (!rte_graph_feature_arc_is_any_feature_enabled(arc)) {
1186 : : printf("%s: Feature arc should have any_feature enabled by now\n",
1187 : : TEST_ARC1_NAME);
1188 : 0 : return TEST_FAILED;
1189 : : }
1190 [ - + ]: 16 : if ((count + 1) != rte_graph_feature_arc_num_enabled_features(arcs[0])) {
1191 : 0 : printf("%s: Number of enabled mismatches [found: %u, exp: %u]\n",
1192 : : TEST_ARC1_NAME,
1193 : 0 : rte_graph_feature_arc_num_enabled_features(arcs[0]),
1194 : : count + 1);
1195 : 0 : return TEST_FAILED;
1196 : : }
1197 : : count++;
1198 : : }
1199 : : /* Negative test case */
1200 : 1 : user_data = compute_unique_user_data(arc->start_node->name, ARC2_FEATURE1, 1);
1201 [ - + ]: 1 : if (!rte_graph_feature_enable(arcs[0], 1 /* index */, ARC2_FEATURE1, user_data, NULL)) {
1202 : : printf("%s: Invalid feature %s is enabled on index 1\n",
1203 : : TEST_ARC1_NAME, ARC2_FEATURE1);
1204 : 0 : return TEST_FAILED;
1205 : : }
1206 : : /* Duplicate enable */
1207 [ - + ]: 1 : if (!rte_graph_feature_enable(arcs[0], 1 /* index */, ARC1_FEATURE2, user_data, NULL)) {
1208 : : printf("%s: Duplicate feature %s shouldn't be enabled again on index 1\n",
1209 : : TEST_ARC1_NAME, ARC1_FEATURE2);
1210 : 0 : return TEST_FAILED;
1211 : : }
1212 [ + + ]: 17 : for (n_indexes = 0; n_indexes < arc->max_indexes; n_indexes++) {
1213 [ - + ]: 16 : if (!rte_graph_feature_data_first_feature_get(arc, n_indexes, &fdata, &edge2)) {
1214 : : printf("%s: FP first feature data get failed for index %u\n",
1215 : : TEST_ARC1_NAME, n_indexes);
1216 : 0 : return TEST_FAILED;
1217 : : }
1218 : 16 : parent = arc->start_node;
1219 [ + + ]: 16 : if (0 == (n_indexes % RTE_DIM(arc1_feature_seq)))
1220 : : child = &arc1_feature1;
1221 [ + + ]: 10 : else if (1 == (n_indexes % RTE_DIM(arc1_feature_seq)))
1222 : : child = &arc1_feature2;
1223 : : else
1224 : : child = &node_input;
1225 : :
1226 [ - + ]: 16 : if (get_edge(parent, child, &edge1)) {
1227 : : printf("%s: Edge not found between %s and %s\n",
1228 : 0 : TEST_ARC1_NAME, parent->name, child->name);
1229 : 0 : return TEST_FAILED;
1230 : : }
1231 [ - + ]: 16 : if (edge1 != edge2) {
1232 : 0 : printf("%s: Edge mismatch for first feature on index %u [%u, exp: %u]\n",
1233 : : TEST_ARC1_NAME, n_indexes, edge2, edge1);
1234 : 0 : return TEST_FAILED;
1235 : : }
1236 [ - + ]: 16 : if (compute_unique_user_data(parent->name, child->name, n_indexes) !=
1237 : : rte_graph_feature_data_app_cookie_get(arc, fdata)) {
1238 : 0 : printf("%s/idx: %u: Cookie mismatch for first feature [%u, exp: %u]\n",
1239 : : TEST_ARC1_NAME, n_indexes,
1240 : : rte_graph_feature_data_app_cookie_get(arc, fdata),
1241 : 0 : compute_unique_user_data(parent->name, child->name, n_indexes));
1242 : 0 : return TEST_FAILED;
1243 : : }
1244 : : }
1245 [ + - ]: 1 : arc = rte_graph_feature_arc_get(arcs[1]);
1246 [ + + ]: 257 : for (n_indexes = 0; n_indexes < arc->max_indexes; n_indexes++) {
1247 : 256 : n_features = n_indexes % RTE_DIM(arc2_feature_seq);
1248 : 256 : feature_name = rte_graph_feature_arc_feature_to_name(arcs[1], n_features);
1249 [ - + ]: 256 : if (strncmp(feature_name, arc2_feature_seq[n_features],
1250 : : RTE_GRAPH_NAMESIZE)) {
1251 : : printf("%s: Feature(%u) seq mismatch [found: %s, exp: %s]\n",
1252 : 0 : arc->feature_arc_name, n_features, feature_name,
1253 : : arc2_feature_seq[n_features]);
1254 : 0 : return TEST_FAILED;
1255 : : }
1256 : 256 : user_data = compute_unique_user_data(arc->start_node->name, feature_name,
1257 : : n_indexes);
1258 [ - + ]: 256 : if (rte_graph_feature_enable(arcs[1], n_indexes, feature_name,
1259 : : user_data, NULL) < 0) {
1260 : : printf("%s: Feature enable failed for %s on index %u\n",
1261 : : TEST_ARC2_NAME, feature_name, n_indexes);
1262 : 0 : return TEST_FAILED;
1263 : : }
1264 : 256 : sp_enable_counters++;
1265 : : }
1266 : :
1267 : 1 : return test_perf((2 * MBUF_NUM));
1268 : : }
1269 : :
1270 : : static int
1271 : 1 : test_graph_feature_arc_feature_disable(void)
1272 : : {
1273 : : struct rte_graph_feature_arc *arc;
1274 : : uint32_t n_indexes, n_features;
1275 : : char *feature_name = NULL;
1276 : :
1277 [ + - ]: 1 : arc = rte_graph_feature_arc_get(arcs[0]);
1278 [ + + ]: 17 : for (n_indexes = 0; n_indexes < arc->max_indexes; n_indexes++) {
1279 : 16 : n_features = n_indexes % RTE_DIM(arc1_feature_seq);
1280 : 16 : feature_name = rte_graph_feature_arc_feature_to_name(arcs[0], n_features);
1281 [ - + ]: 16 : if (rte_graph_feature_disable(arcs[0], n_indexes, feature_name, NULL)) {
1282 : : printf("%s: feature disable failed for %s on index %u\n",
1283 : 0 : arc->feature_arc_name, feature_name, n_indexes);
1284 : 0 : return TEST_FAILED;
1285 : : }
1286 : 16 : sp_disable_counters++;
1287 : : }
1288 : :
1289 [ + - ]: 1 : arc = rte_graph_feature_arc_get(arcs[1]);
1290 [ + + ]: 257 : for (n_indexes = 0; n_indexes < arc->max_indexes; n_indexes++) {
1291 : 256 : n_features = n_indexes % RTE_DIM(arc2_feature_seq);
1292 : 256 : feature_name = rte_graph_feature_arc_feature_to_name(arcs[1], n_features);
1293 [ - + ]: 256 : if (rte_graph_feature_disable(arcs[1], n_indexes, feature_name, NULL)) {
1294 : : printf("%s: feature disable failed for %s on index %u\n",
1295 : 0 : arc->feature_arc_name, feature_name, n_indexes);
1296 : 0 : return TEST_FAILED;
1297 : : }
1298 : 256 : sp_disable_counters++;
1299 : : }
1300 : : /* All packets should exit */
1301 : 1 : return test_perf((2 * MBUF_NUM));
1302 : : }
1303 : :
1304 : : static int
1305 : 1 : test_graph_feature_arc_destroy(void)
1306 : : {
1307 : : rte_graph_feature_arc_t arc;
1308 : :
1309 [ - + ]: 1 : if (rte_graph_feature_arc_lookup_by_name(TEST_ARC1_NAME, &arc)) {
1310 : : printf("Feature arc lookup failed for %s\n", TEST_ARC1_NAME);
1311 : 0 : return TEST_FAILED;
1312 : : }
1313 : :
1314 [ - + ]: 1 : if (arc != arcs[0]) {
1315 : 0 : printf("Feature arc lookup mismatch for %s [%u, exp: %u]\n",
1316 : : TEST_ARC1_NAME, arc, arcs[0]);
1317 : 0 : return TEST_FAILED;
1318 : : }
1319 : :
1320 [ - + ]: 1 : if (rte_graph_feature_arc_destroy(arc)) {
1321 : : printf("Feature arc destroy failed for %s\n", TEST_ARC1_NAME);
1322 : 0 : return TEST_FAILED;
1323 : : }
1324 : :
1325 [ - + ]: 1 : if (rte_graph_feature_arc_lookup_by_name(TEST_ARC2_NAME, &arc)) {
1326 : : printf("Feature arc lookup success after destroy for %s\n", TEST_ARC2_NAME);
1327 : 0 : return TEST_FAILED;
1328 : : }
1329 : :
1330 [ - + ]: 1 : if (arc != arcs[1]) {
1331 : 0 : printf("Feature arc lookup mismatch for %s [%u, exp: %u]\n",
1332 : : TEST_ARC2_NAME, arc, arcs[1]);
1333 : 0 : return TEST_FAILED;
1334 : : }
1335 [ - + ]: 1 : if (rte_graph_feature_arc_destroy(arc)) {
1336 : : printf("Feature arc destroy failed for %s\n", TEST_ARC2_NAME);
1337 : 0 : return TEST_FAILED;
1338 : : }
1339 : : return TEST_SUCCESS;
1340 : : }
1341 : :
1342 : : static void
1343 : 1 : graph_feature_arc_teardown(void)
1344 : : {
1345 [ - + ]: 1 : if (graph_id != RTE_GRAPH_ID_INVALID)
1346 : 0 : rte_graph_destroy(graph_id);
1347 : :
1348 : 1 : rte_graph_feature_arc_cleanup();
1349 : 1 : }
1350 : :
1351 : : static struct unit_test_suite graph_feature_arc_testsuite = {
1352 : : .suite_name = "Graph Feature arc library test suite",
1353 : : .setup = graph_feature_arc_setup,
1354 : : .teardown = graph_feature_arc_teardown,
1355 : : .unit_test_cases = {
1356 : : TEST_CASE(test_graph_feature_arc_create),
1357 : : TEST_CASE(test_graph_feature_arc_features_add),
1358 : : TEST_CASE(test_graph_feature_arc_feature_enable),
1359 : : TEST_CASE(test_graph_feature_arc_feature_disable),
1360 : : TEST_CASE(test_graph_feature_arc_destroy),
1361 : : TEST_CASES_END(), /**< NULL terminate unit test array */
1362 : : },
1363 : : };
1364 : :
1365 : : static int
1366 : 1 : graph_feature_arc_autotest_fn(void)
1367 : : {
1368 : 1 : return unit_test_suite_runner(&graph_feature_arc_testsuite);
1369 : : }
1370 : :
1371 : 253 : REGISTER_FAST_TEST(graph_feature_arc_autotest, true, true, graph_feature_arc_autotest_fn);
1372 : :
1373 : : #endif /* !RTE_EXEC_ENV_WINDOWS */
|