Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2014 Intel Corporation
3 : : */
4 : :
5 : : #ifndef _ACL_RUN_H_
6 : : #define _ACL_RUN_H_
7 : :
8 : : #include <rte_acl.h>
9 : : #include "acl.h"
10 : :
11 : : #define MAX_SEARCHES_AVX16 16
12 : : #define MAX_SEARCHES_SSE8 8
13 : : #define MAX_SEARCHES_ALTIVEC8 8
14 : : #define MAX_SEARCHES_RVV8 8
15 : : #define MAX_SEARCHES_SSE4 4
16 : : #define MAX_SEARCHES_ALTIVEC4 4
17 : : #define MAX_SEARCHES_RVV4 4
18 : : #define MAX_SEARCHES_SCALAR 2
19 : :
20 : : #define GET_NEXT_4BYTES(prm, idx) \
21 : : (*((const int32_t *)((prm)[(idx)].data + *(prm)[idx].data_index++)))
22 : :
23 : :
24 : : #define RTE_ACL_NODE_INDEX ((uint32_t)~RTE_ACL_NODE_TYPE)
25 : :
26 : : #define SCALAR_QRANGE_MULT 0x01010101
27 : : #define SCALAR_QRANGE_MASK 0x7f7f7f7f
28 : : #define SCALAR_QRANGE_MIN 0x80808080
29 : :
30 : : /*
31 : : * Structure to manage N parallel trie traversals.
32 : : * The runtime trie traversal routines can process 8, 4, or 2 tries
33 : : * in parallel. Each packet may require multiple trie traversals (up to 4).
34 : : * This structure is used to fill the slots (0 to n-1) for parallel processing
35 : : * with the trie traversals needed for each packet.
36 : : */
37 : : struct acl_flow_data {
38 : : uint32_t num_packets;
39 : : /* number of packets processed */
40 : : uint32_t started;
41 : : /* number of trie traversals in progress */
42 : : uint32_t trie;
43 : : /* current trie index (0 to N-1) */
44 : : uint32_t cmplt_size;
45 : : /* maximum number of packets to process */
46 : : uint32_t total_packets;
47 : : /* number of result categories per packet. */
48 : : uint32_t categories;
49 : : const uint64_t *trans;
50 : : const uint8_t **data;
51 : : uint32_t *results;
52 : : struct completion *last_cmplt;
53 : : struct completion *cmplt_array;
54 : : };
55 : :
56 : : /*
57 : : * Structure to maintain running results for
58 : : * a single packet (up to 4 tries).
59 : : */
60 : : struct __rte_aligned(XMM_SIZE) completion {
61 : : uint32_t *results; /* running results. */
62 : : int32_t priority[RTE_ACL_MAX_CATEGORIES]; /* running priorities. */
63 : : uint32_t count; /* num of remaining tries */
64 : : /* true for allocated struct */
65 : : };
66 : :
67 : : /*
68 : : * One parms structure for each slot in the search engine.
69 : : */
70 : : struct parms {
71 : : const uint8_t *data;
72 : : /* input data for this packet */
73 : : const uint32_t *data_index;
74 : : /* data indirection for this trie */
75 : : struct completion *cmplt;
76 : : /* completion data for this packet */
77 : : };
78 : :
79 : : /*
80 : : * Define an global idle node for unused engine slots
81 : : */
82 : : static const uint32_t idle[UINT8_MAX + 1];
83 : :
84 : : /*
85 : : * Allocate a completion structure to manage the tries for a packet.
86 : : */
87 : : static inline struct completion *
88 : : alloc_completion(struct completion *p, uint32_t size, uint32_t tries,
89 : : uint32_t *results)
90 : : {
91 : : uint32_t n;
92 : :
93 [ + - ]: 119025333 : for (n = 0; n < size; n++) {
94 : :
95 [ + + ]: 119025333 : if (p[n].count == 0) {
96 : :
97 : : /* mark as allocated and set number of tries. */
98 : 26429696 : p[n].count = tries;
99 : 26429696 : p[n].results = results;
100 : 26429696 : return &(p[n]);
101 : : }
102 : : }
103 : :
104 : : /* should never get here */
105 : : return NULL;
106 : : }
107 : :
108 : : /*
109 : : * Resolve priority for a single result trie.
110 : : */
111 : : static inline void
112 : : resolve_single_priority(uint64_t transition, int n,
113 : : const struct rte_acl_ctx *ctx, struct parms *parms,
114 : : const struct rte_acl_match_results *p)
115 : : {
116 [ - + ]: 34 : if (parms[n].cmplt->count == ctx->num_tries ||
117 : 0 : parms[n].cmplt->priority[0] <=
118 [ # # ]: 0 : p[transition].priority[0]) {
119 : :
120 : 34 : parms[n].cmplt->priority[0] = p[transition].priority[0];
121 : 34 : parms[n].cmplt->results[0] = p[transition].results[0];
122 : : }
123 : : }
124 : :
125 : : /*
126 : : * Routine to fill a slot in the parallel trie traversal array (parms) from
127 : : * the list of packets (flows).
128 : : */
129 : : static inline uint64_t
130 : 33135209 : acl_start_next_trie(struct acl_flow_data *flows, struct parms *parms, int n,
131 : : const struct rte_acl_ctx *ctx)
132 : : {
133 : : uint64_t transition;
134 : :
135 : : /* if there are any more packets to process */
136 [ + + ]: 33135209 : if (flows->num_packets < flows->total_packets) {
137 : 26612027 : parms[n].data = flows->data[flows->num_packets];
138 : 26612027 : parms[n].data_index = ctx->trie[flows->trie].data_index;
139 : :
140 : : /* if this is the first trie for this packet */
141 [ + + ]: 26612027 : if (flows->trie == 0) {
142 : 26429696 : flows->last_cmplt = alloc_completion(flows->cmplt_array,
143 : 26429696 : flows->cmplt_size, ctx->num_tries,
144 : 26429696 : flows->results +
145 : 26429696 : flows->num_packets * flows->categories);
146 : : }
147 : :
148 : : /* set completion parameters and starting index for this slot */
149 : 26612027 : parms[n].cmplt = flows->last_cmplt;
150 : 26612027 : transition =
151 : 26612027 : flows->trans[parms[n].data[*parms[n].data_index++] +
152 : 26612027 : ctx->trie[flows->trie].root_index];
153 : :
154 : : /*
155 : : * if this is the last trie for this packet,
156 : : * then setup next packet.
157 : : */
158 : 26612027 : flows->trie++;
159 [ + + ]: 26612027 : if (flows->trie >= ctx->num_tries) {
160 : 26429696 : flows->trie = 0;
161 : 26429696 : flows->num_packets++;
162 : : }
163 : :
164 : : /* keep track of number of active trie traversals */
165 : 26612027 : flows->started++;
166 : :
167 : : /* no more tries to process, set slot to an idle position */
168 : : } else {
169 : 6523182 : transition = ctx->idle;
170 : 6523182 : parms[n].data = (const uint8_t *)idle;
171 : 6523182 : parms[n].data_index = idle;
172 : : }
173 : 33135209 : return transition;
174 : : }
175 : :
176 : : static inline void
177 : : acl_set_flow(struct acl_flow_data *flows, struct completion *cmplt,
178 : : uint32_t cmplt_size, const uint8_t **data, uint32_t *results,
179 : : uint32_t data_num, uint32_t categories, const uint64_t *trans)
180 : : {
181 : : unsigned int i;
182 : :
183 : 876669 : flows->num_packets = 0;
184 : 876669 : flows->started = 0;
185 : 876669 : flows->trie = 0;
186 : 876669 : flows->last_cmplt = NULL;
187 : 876669 : flows->cmplt_array = cmplt;
188 : 876669 : flows->total_packets = data_num;
189 : 876669 : flows->categories = categories;
190 : 876669 : flows->cmplt_size = cmplt_size;
191 : 876669 : flows->data = data;
192 : 876669 : flows->results = results;
193 : 876669 : flows->trans = trans;
194 : :
195 [ + + + + : 7399851 : for (i = 0; i < cmplt_size; i++)
+ + ]
196 : 6523182 : cmplt[i].count = 0;
197 : : }
198 : :
199 : : typedef void (*resolve_priority_t)
200 : : (uint64_t transition, int n, const struct rte_acl_ctx *ctx,
201 : : struct parms *parms, const struct rte_acl_match_results *p,
202 : : uint32_t categories);
203 : :
204 : : /*
205 : : * Detect matches. If a match node transition is found, then this trie
206 : : * traversal is complete and fill the slot with the next trie
207 : : * to be processed.
208 : : */
209 : : static inline uint64_t
210 : 28483516 : acl_match_check(uint64_t transition, int slot,
211 : : const struct rte_acl_ctx *ctx, struct parms *parms,
212 : : struct acl_flow_data *flows, resolve_priority_t resolve_priority)
213 : : {
214 : : const struct rte_acl_match_results *p;
215 : :
216 : 28483516 : p = (const struct rte_acl_match_results *)
217 : 28483516 : (flows->trans + ctx->match_index);
218 : :
219 [ + + ]: 28483516 : if (transition & RTE_ACL_NODE_MATCH) {
220 : :
221 : : /* Remove flags from index and decrement active traversals */
222 : 26612027 : transition &= RTE_ACL_NODE_INDEX;
223 : 26612027 : flows->started--;
224 : :
225 : : /* Resolve priorities for this trie and running results */
226 [ + + ]: 26612027 : if (flows->categories == 1)
227 : : resolve_single_priority(transition, slot, ctx,
228 : : parms, p);
229 : : else
230 : 26611993 : resolve_priority(transition, slot, ctx, parms,
231 : : p, flows->categories);
232 : :
233 : : /* Count down completed tries for this search request */
234 : 26612027 : parms[slot].cmplt->count--;
235 : :
236 : : /* Fill the slot with the next trie or idle trie */
237 : 26612027 : transition = acl_start_next_trie(flows, parms, slot, ctx);
238 : : }
239 : :
240 : 28483516 : return transition;
241 : : }
242 : :
243 : : #endif /* _ACL_RUN_H_ */
|