Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2020 Marvell.
3 : : */
4 : :
5 : : #include <stdalign.h>
6 : :
7 : : #include <rte_graph.h>
8 : : #include <rte_graph_worker.h>
9 : :
10 : : #include "pkt_cls_priv.h"
11 : : #include "node_private.h"
12 : : #include "rte_node_pkt_cls_api.h"
13 : :
14 : : /* Next node for each ptype, default is '0' is "pkt_drop" */
15 : : static const alignas(RTE_CACHE_LINE_SIZE) uint8_t p_nxt[256] = {
16 : : [RTE_PTYPE_L3_IPV4] = RTE_NODE_PKT_CLS_NEXT_IP4_LOOKUP,
17 : :
18 : : [RTE_PTYPE_L3_IPV4_EXT] = RTE_NODE_PKT_CLS_NEXT_IP4_LOOKUP,
19 : :
20 : : [RTE_PTYPE_L3_IPV4_EXT_UNKNOWN] = RTE_NODE_PKT_CLS_NEXT_IP4_LOOKUP,
21 : :
22 : : [RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L2_ETHER] =
23 : : RTE_NODE_PKT_CLS_NEXT_IP4_LOOKUP,
24 : :
25 : : [RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_L2_ETHER] =
26 : : RTE_NODE_PKT_CLS_NEXT_IP4_LOOKUP,
27 : :
28 : : [RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L2_ETHER] =
29 : : RTE_NODE_PKT_CLS_NEXT_IP4_LOOKUP,
30 : :
31 : : [RTE_PTYPE_L3_IPV6] = RTE_NODE_PKT_CLS_NEXT_IP6_LOOKUP,
32 : :
33 : : [RTE_PTYPE_L3_IPV6_EXT] = RTE_NODE_PKT_CLS_NEXT_IP6_LOOKUP,
34 : :
35 : : [RTE_PTYPE_L3_IPV6_EXT_UNKNOWN] = RTE_NODE_PKT_CLS_NEXT_IP6_LOOKUP,
36 : :
37 : : [RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L2_ETHER] = RTE_NODE_PKT_CLS_NEXT_IP6_LOOKUP,
38 : :
39 : : [RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L2_ETHER] = RTE_NODE_PKT_CLS_NEXT_IP6_LOOKUP,
40 : :
41 : : [RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L2_ETHER] =
42 : : RTE_NODE_PKT_CLS_NEXT_IP6_LOOKUP,
43 : : };
44 : :
45 : : static uint16_t
46 : 0 : pkt_cls_node_process(struct rte_graph *graph, struct rte_node *node,
47 : : void **objs, uint16_t nb_objs)
48 : : {
49 : : struct rte_mbuf *mbuf0, *mbuf1, *mbuf2, *mbuf3, **pkts;
50 : : uint8_t l0, l1, l2, l3, last_type;
51 : : uint16_t next_index, n_left_from;
52 : : uint16_t held = 0, last_spec = 0;
53 : : struct pkt_cls_node_ctx *ctx;
54 : : void **to_next, **from;
55 : : uint32_t i;
56 : :
57 : : pkts = (struct rte_mbuf **)objs;
58 : : from = objs;
59 : : n_left_from = nb_objs;
60 : :
61 [ # # ]: 0 : for (i = OBJS_PER_CLINE; i < RTE_GRAPH_BURST_SIZE; i += OBJS_PER_CLINE)
62 : 0 : rte_prefetch0(&objs[i]);
63 : :
64 : : #if RTE_GRAPH_BURST_SIZE > 64
65 [ # # # # ]: 0 : for (i = 0; i < 4 && i < n_left_from; i++)
66 : 0 : rte_prefetch0(pkts[i]);
67 : : #endif
68 : :
69 : : ctx = (struct pkt_cls_node_ctx *)node->ctx;
70 : 0 : last_type = ctx->l2l3_type;
71 : 0 : next_index = p_nxt[last_type];
72 : :
73 : : /* Get stream for the speculated next node */
74 : 0 : to_next = rte_node_next_stream_get(graph, node,
75 : : next_index, nb_objs);
76 [ # # ]: 0 : while (n_left_from >= 4) {
77 : : #if RTE_GRAPH_BURST_SIZE > 64
78 [ # # ]: 0 : if (likely(n_left_from > 7)) {
79 : 0 : rte_prefetch0(pkts[4]);
80 : 0 : rte_prefetch0(pkts[5]);
81 : 0 : rte_prefetch0(pkts[6]);
82 : 0 : rte_prefetch0(pkts[7]);
83 : : }
84 : : #endif
85 : :
86 : 0 : mbuf0 = pkts[0];
87 : 0 : mbuf1 = pkts[1];
88 : 0 : mbuf2 = pkts[2];
89 : 0 : mbuf3 = pkts[3];
90 : 0 : pkts += 4;
91 : 0 : n_left_from -= 4;
92 : :
93 : 0 : l0 = mbuf0->packet_type &
94 : : (RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK);
95 : 0 : l1 = mbuf1->packet_type &
96 : : (RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK);
97 : 0 : l2 = mbuf2->packet_type &
98 : : (RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK);
99 : 0 : l3 = mbuf3->packet_type &
100 : : (RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK);
101 : :
102 : : /* Check if they are destined to same
103 : : * next node based on l2l3 packet type.
104 : : */
105 : 0 : uint8_t fix_spec = (last_type ^ l0) | (last_type ^ l1) |
106 : : (last_type ^ l2) | (last_type ^ l3);
107 : :
108 [ # # ]: 0 : if (unlikely(fix_spec)) {
109 : : /* Copy things successfully speculated till now */
110 [ # # ]: 0 : rte_memcpy(to_next, from,
111 : : last_spec * sizeof(from[0]));
112 : 0 : from += last_spec;
113 : 0 : to_next += last_spec;
114 : 0 : held += last_spec;
115 : : last_spec = 0;
116 : :
117 : : /* l0 */
118 [ # # ]: 0 : if (p_nxt[l0] == next_index) {
119 : 0 : to_next[0] = from[0];
120 : 0 : to_next++;
121 : 0 : held++;
122 : : } else {
123 : 0 : rte_node_enqueue_x1(graph, node,
124 : : p_nxt[l0], from[0]);
125 : : }
126 : :
127 : : /* l1 */
128 [ # # ]: 0 : if (p_nxt[l1] == next_index) {
129 : 0 : to_next[0] = from[1];
130 : 0 : to_next++;
131 : 0 : held++;
132 : : } else {
133 : 0 : rte_node_enqueue_x1(graph, node,
134 : : p_nxt[l1], from[1]);
135 : : }
136 : :
137 : : /* l2 */
138 [ # # ]: 0 : if (p_nxt[l2] == next_index) {
139 : 0 : to_next[0] = from[2];
140 : 0 : to_next++;
141 : 0 : held++;
142 : : } else {
143 : 0 : rte_node_enqueue_x1(graph, node,
144 : : p_nxt[l2], from[2]);
145 : : }
146 : :
147 : : /* l3 */
148 [ # # ]: 0 : if (p_nxt[l3] == next_index) {
149 : 0 : to_next[0] = from[3];
150 : 0 : to_next++;
151 : 0 : held++;
152 : : } else {
153 : 0 : rte_node_enqueue_x1(graph, node,
154 : : p_nxt[l3], from[3]);
155 : : }
156 : :
157 : : /* Update speculated ptype */
158 [ # # # # ]: 0 : if ((last_type != l3) && (l2 == l3) &&
159 : : (next_index != p_nxt[l3])) {
160 : : /* Put the current stream for
161 : : * speculated ltype.
162 : : */
163 [ # # ]: 0 : rte_node_next_stream_put(graph, node,
164 : : next_index, held);
165 : :
166 : : held = 0;
167 : :
168 : : /* Get next stream for new ltype */
169 : : next_index = p_nxt[l3];
170 : : last_type = l3;
171 : 0 : to_next = rte_node_next_stream_get(graph, node,
172 : : next_index,
173 : : nb_objs);
174 [ # # ]: 0 : } else if (next_index == p_nxt[l3]) {
175 : : last_type = l3;
176 : : }
177 : :
178 : 0 : from += 4;
179 : : } else {
180 : 0 : last_spec += 4;
181 : : }
182 : : }
183 : :
184 [ # # ]: 0 : while (n_left_from > 0) {
185 : 0 : mbuf0 = pkts[0];
186 : :
187 : 0 : pkts += 1;
188 : 0 : n_left_from -= 1;
189 : :
190 : 0 : l0 = mbuf0->packet_type &
191 : : (RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK);
192 [ # # # # ]: 0 : if (unlikely((l0 != last_type) &&
193 : : (p_nxt[l0] != next_index))) {
194 : : /* Copy things successfully speculated till now */
195 [ # # ]: 0 : rte_memcpy(to_next, from,
196 : : last_spec * sizeof(from[0]));
197 : 0 : from += last_spec;
198 : 0 : to_next += last_spec;
199 : 0 : held += last_spec;
200 : : last_spec = 0;
201 : :
202 : 0 : rte_node_enqueue_x1(graph, node,
203 : : p_nxt[l0], from[0]);
204 : 0 : from += 1;
205 : : } else {
206 : 0 : last_spec += 1;
207 : : }
208 : : }
209 : :
210 : : /* !!! Home run !!! */
211 [ # # ]: 0 : if (likely(last_spec == nb_objs)) {
212 : 0 : rte_node_next_stream_move(graph, node, next_index);
213 : 0 : return nb_objs;
214 : : }
215 : :
216 : 0 : held += last_spec;
217 : : /* Copy things successfully speculated till now */
218 [ # # ]: 0 : rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
219 [ # # ]: 0 : rte_node_next_stream_put(graph, node, next_index, held);
220 : :
221 : 0 : ctx->l2l3_type = last_type;
222 : 0 : return nb_objs;
223 : : }
224 : :
225 : : /* Packet Classification Node */
226 : : struct rte_node_register pkt_cls_node = {
227 : : .process = pkt_cls_node_process,
228 : : .name = "pkt_cls",
229 : :
230 : : .nb_edges = RTE_NODE_PKT_CLS_NEXT_MAX,
231 : : .next_nodes = {
232 : : /* Pkt drop node starts at '0' */
233 : : [RTE_NODE_PKT_CLS_NEXT_PKT_DROP] = "pkt_drop",
234 : : [RTE_NODE_PKT_CLS_NEXT_IP4_LOOKUP] = "ip4_lookup",
235 : : [RTE_NODE_PKT_CLS_NEXT_IP6_LOOKUP] = "ip6_lookup",
236 : : [RTE_NODE_PKT_CLS_NEXT_IP4_LOOKUP_FIB] = "ip4_lookup_fib",
237 : : [RTE_NODE_PKT_CLS_NEXT_IP6_LOOKUP_FIB] = "ip6_lookup_fib",
238 : : },
239 : : };
240 : 254 : RTE_NODE_REGISTER(pkt_cls_node);
|