Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2025 Marvell International Ltd.
3 : : */
4 : :
5 : : #include <rte_graph.h>
6 : : #include <rte_graph_worker.h>
7 : : #include <rte_graph_feature_arc_worker.h>
8 : :
9 : : #include "rte_node_ip4_api.h"
10 : :
11 : : #define IP4_OUTPUT_HOOK_FEATURE1_NAME "app_ip4_out_feat1"
12 : : #define IP4_OUTPUT_HOOK_FEATURE2_NAME "app_ip4_out_feat2"
13 : :
14 : : struct output_hook_node_ctx {
15 : : rte_graph_feature_arc_t out_arc;
16 : : uint16_t last_index;
17 : : };
18 : :
19 : : enum {
20 : : OUTPUT_HOOK_PKT_DROP = 0,
21 : : OUTPUT_HOOK_PKT_CLS,
22 : : OUTPUT_HOOK_MAX_NB_EDGES,
23 : : };
24 : :
25 : : #define OUTPUT_HOOK_FEATURE_ARC(ctx) \
26 : : (((struct output_hook_node_ctx *)ctx)->out_arc)
27 : :
28 : : #define OUTPUT_HOOK_LAST_NEXT_INDEX(ctx) \
29 : : (((struct output_hook_node_ctx *)ctx)->last_index)
30 : :
31 : : static int
32 : : __app_graph_ip4_output_hook_node_init(const struct rte_graph *graph, struct rte_node *node)
33 : : {
34 : : rte_graph_feature_arc_t feature;
35 : :
36 : : RTE_SET_USED(graph);
37 : :
38 : 0 : rte_graph_feature_arc_lookup_by_name(RTE_IP4_OUTPUT_FEATURE_ARC_NAME, &feature);
39 : :
40 : 0 : OUTPUT_HOOK_FEATURE_ARC(node->ctx) = feature;
41 : : /* pkt_drop */
42 : 0 : OUTPUT_HOOK_LAST_NEXT_INDEX(node->ctx) = 0;
43 : :
44 : : return 0;
45 : : }
46 : :
47 : : static __rte_always_inline uint16_t
48 : : __app_graph_ip4_output_hook_node_process(struct rte_graph *graph, struct rte_node *node,
49 : : void **objs, uint16_t nb_objs)
50 : : {
51 : : struct rte_graph_feature_arc *arc =
52 : 0 : rte_graph_feature_arc_get(OUTPUT_HOOK_FEATURE_ARC(node->ctx));
53 : : struct rte_graph_feature_arc_mbuf_dynfields *mbfields = NULL;
54 : : uint16_t next = OUTPUT_HOOK_PKT_DROP;
55 : : void **to_next, **from;
56 : : uint16_t last_spec = 0;
57 : : rte_edge_t next_index;
58 : : struct rte_mbuf *mbuf;
59 : : uint16_t held = 0;
60 : : int i;
61 : :
62 : : /* Speculative next */
63 : 0 : next_index = OUTPUT_HOOK_LAST_NEXT_INDEX(node->ctx);
64 : :
65 : : from = objs;
66 : 0 : to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
67 : 0 : for (i = 0; i < nb_objs; i++) {
68 : :
69 : 0 : mbuf = (struct rte_mbuf *)objs[i];
70 : :
71 : : /* Send mbuf to next enabled feature */
72 : 0 : mbfields = rte_graph_feature_arc_mbuf_dynfields_get(mbuf, arc->mbuf_dyn_offset);
73 : : rte_graph_feature_data_next_feature_get(arc, &mbfields->feature_data, &next);
74 : :
75 : 0 : if (unlikely(next_index != next)) {
76 : : /* Copy things successfully speculated till now */
77 : 0 : rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
78 : 0 : from += last_spec;
79 : 0 : to_next += last_spec;
80 : 0 : held += last_spec;
81 : : last_spec = 0;
82 : :
83 : 0 : rte_node_enqueue_x1(graph, node, next, from[0]);
84 : 0 : from += 1;
85 : : } else {
86 : 0 : last_spec += 1;
87 : : }
88 : : }
89 : : /* !!! Home run !!! */
90 : 0 : if (likely(last_spec == nb_objs)) {
91 : 0 : rte_node_next_stream_move(graph, node, next_index);
92 : 0 : return nb_objs;
93 : : }
94 : 0 : held += last_spec;
95 : 0 : rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
96 : 0 : rte_node_next_stream_put(graph, node, next_index, held);
97 : 0 : OUTPUT_HOOK_LAST_NEXT_INDEX(node->ctx) = next;
98 : :
99 : 0 : return nb_objs;
100 : : }
101 : :
102 : : static int
103 : 0 : app_graph_ip4_output_hook_node1_init(const struct rte_graph *graph, struct rte_node *node)
104 : : {
105 : 0 : return __app_graph_ip4_output_hook_node_init(graph, node);
106 : : }
107 : :
108 : : static __rte_always_inline uint16_t
109 : 0 : app_graph_ip4_output_hook_node1_process(struct rte_graph *graph, struct rte_node *node,
110 : : void **objs, uint16_t nb_objs)
111 : : {
112 : 0 : return __app_graph_ip4_output_hook_node_process(graph, node, objs, nb_objs);
113 : : }
114 : :
115 : : static struct rte_node_register app_graph_ip4_output_hook_node1 = {
116 : : .process = app_graph_ip4_output_hook_node1_process,
117 : : .init = app_graph_ip4_output_hook_node1_init,
118 : : .name = "app_ip4_output_node1",
119 : : .nb_edges = OUTPUT_HOOK_MAX_NB_EDGES,
120 : : .next_nodes = {
121 : : [OUTPUT_HOOK_PKT_DROP] = "pkt_drop",
122 : : [OUTPUT_HOOK_PKT_CLS] = "pkt_cls",
123 : : },
124 : : };
125 : :
126 : 0 : RTE_NODE_REGISTER(app_graph_ip4_output_hook_node1);
127 : :
128 : : static int
129 : 0 : app_graph_ip4_output_hook_node2_init(const struct rte_graph *graph, struct rte_node *node)
130 : : {
131 : 0 : return __app_graph_ip4_output_hook_node_init(graph, node);
132 : : }
133 : :
134 : : static __rte_always_inline uint16_t
135 : 0 : app_graph_ip4_output_hook_node2_process(struct rte_graph *graph, struct rte_node *node,
136 : : void **objs, uint16_t nb_objs)
137 : : {
138 : 0 : return __app_graph_ip4_output_hook_node_process(graph, node, objs, nb_objs);
139 : : }
140 : :
141 : : static struct rte_node_register app_graph_ip4_output_hook_node2 = {
142 : : .process = app_graph_ip4_output_hook_node2_process,
143 : : .init = app_graph_ip4_output_hook_node2_init,
144 : : .name = "app_ip4_output_node2",
145 : : .nb_edges = 1,
146 : : .next_nodes = {
147 : : [OUTPUT_HOOK_PKT_DROP] = "pkt_drop",
148 : : },
149 : : };
150 : :
151 : : /* Override max_index for arc create */
152 : 0 : static uint16_t override_arc_index(void)
153 : : {
154 : 0 : return 64;
155 : : }
156 : :
157 : 0 : RTE_NODE_REGISTER(app_graph_ip4_output_hook_node2);
158 : :
159 : : /* if feature1 */
160 : : struct rte_graph_feature_register app_graph_ip4_output_hook_feature1 = {
161 : : .feature_name = IP4_OUTPUT_HOOK_FEATURE1_NAME,
162 : : .arc_name = RTE_IP4_OUTPUT_FEATURE_ARC_NAME,
163 : : /* Same as regular function */
164 : : .feature_process_fn = app_graph_ip4_output_hook_node1_process,
165 : : .feature_node = &app_graph_ip4_output_hook_node1,
166 : : .runs_before = IP4_OUTPUT_HOOK_FEATURE2_NAME,
167 : : .override_index_cb = override_arc_index,
168 : : };
169 : :
170 : : /* if feature2 (same as f1) */
171 : : struct rte_graph_feature_register app_graph_ip4_output_hook_feature2 = {
172 : : .feature_name = IP4_OUTPUT_HOOK_FEATURE2_NAME,
173 : : .arc_name = RTE_IP4_OUTPUT_FEATURE_ARC_NAME,
174 : : /* Same as regular function */
175 : : .feature_node = &app_graph_ip4_output_hook_node2,
176 : : .feature_process_fn = app_graph_ip4_output_hook_node2_process,
177 : : };
178 : :
179 : 0 : RTE_GRAPH_FEATURE_REGISTER(app_graph_ip4_output_hook_feature1);
180 : 0 : RTE_GRAPH_FEATURE_REGISTER(app_graph_ip4_output_hook_feature2);
|