Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2014 Intel Corporation
3 : : */
4 : :
5 : : #include <eal_export.h>
6 : : #include <rte_eal_memconfig.h>
7 : : #include <rte_string_fns.h>
8 : : #include <rte_acl.h>
9 : : #include <rte_tailq.h>
10 : :
11 : : #include "acl.h"
12 : : #include "acl_log.h"
13 : :
14 [ - + ]: 301 : RTE_LOG_REGISTER_DEFAULT(acl_logtype, INFO);
15 : :
16 : : TAILQ_HEAD(rte_acl_list, rte_tailq_entry);
17 : :
18 : : static struct rte_tailq_elem rte_acl_tailq = {
19 : : .name = "RTE_ACL",
20 : : };
21 [ - + ]: 301 : EAL_REGISTER_TAILQ(rte_acl_tailq)
22 : :
23 : : #ifndef CC_AVX512_SUPPORT
24 : : /*
25 : : * If the compiler doesn't support AVX512 instructions,
26 : : * then the dummy one would be used instead for AVX512 classify method.
27 : : */
28 : : int
29 : : rte_acl_classify_avx512x16(__rte_unused const struct rte_acl_ctx *ctx,
30 : : __rte_unused const uint8_t **data,
31 : : __rte_unused uint32_t *results,
32 : : __rte_unused uint32_t num,
33 : : __rte_unused uint32_t categories)
34 : : {
35 : : return -ENOTSUP;
36 : : }
37 : :
38 : : int
39 : : rte_acl_classify_avx512x32(__rte_unused const struct rte_acl_ctx *ctx,
40 : : __rte_unused const uint8_t **data,
41 : : __rte_unused uint32_t *results,
42 : : __rte_unused uint32_t num,
43 : : __rte_unused uint32_t categories)
44 : : {
45 : : return -ENOTSUP;
46 : : }
47 : : #endif
48 : :
49 : : #ifndef RTE_ARCH_X86
50 : : /*
51 : : * If ISA doesn't have AVX2 or SSE, provide dummy fallbacks
52 : : */
53 : : int
54 : : rte_acl_classify_avx2(__rte_unused const struct rte_acl_ctx *ctx,
55 : : __rte_unused const uint8_t **data,
56 : : __rte_unused uint32_t *results,
57 : : __rte_unused uint32_t num,
58 : : __rte_unused uint32_t categories)
59 : : {
60 : : return -ENOTSUP;
61 : : }
62 : : int
63 : : rte_acl_classify_sse(__rte_unused const struct rte_acl_ctx *ctx,
64 : : __rte_unused const uint8_t **data,
65 : : __rte_unused uint32_t *results,
66 : : __rte_unused uint32_t num,
67 : : __rte_unused uint32_t categories)
68 : : {
69 : : return -ENOTSUP;
70 : : }
71 : : #endif
72 : :
73 : : #ifndef RTE_ARCH_ARM
74 : : int
75 : 0 : rte_acl_classify_neon(__rte_unused const struct rte_acl_ctx *ctx,
76 : : __rte_unused const uint8_t **data,
77 : : __rte_unused uint32_t *results,
78 : : __rte_unused uint32_t num,
79 : : __rte_unused uint32_t categories)
80 : : {
81 : 0 : return -ENOTSUP;
82 : : }
83 : : #endif
84 : :
85 : : #ifndef RTE_ARCH_PPC_64
86 : : int
87 : 0 : rte_acl_classify_altivec(__rte_unused const struct rte_acl_ctx *ctx,
88 : : __rte_unused const uint8_t **data,
89 : : __rte_unused uint32_t *results,
90 : : __rte_unused uint32_t num,
91 : : __rte_unused uint32_t categories)
92 : : {
93 : 0 : return -ENOTSUP;
94 : : }
95 : : #endif
96 : :
97 : : #ifndef RTE_RISCV_FEATURE_V
98 : : int
99 : 0 : rte_acl_classify_rvv(__rte_unused const struct rte_acl_ctx *ctx,
100 : : __rte_unused const uint8_t **data,
101 : : __rte_unused uint32_t *results,
102 : : __rte_unused uint32_t num,
103 : : __rte_unused uint32_t categories)
104 : : {
105 : 0 : return -ENOTSUP;
106 : : }
107 : : #endif
108 : :
109 : : static const rte_acl_classify_t classify_fns[] = {
110 : : [RTE_ACL_CLASSIFY_DEFAULT] = rte_acl_classify_scalar,
111 : : [RTE_ACL_CLASSIFY_SCALAR] = rte_acl_classify_scalar,
112 : : [RTE_ACL_CLASSIFY_SSE] = rte_acl_classify_sse,
113 : : [RTE_ACL_CLASSIFY_AVX2] = rte_acl_classify_avx2,
114 : : [RTE_ACL_CLASSIFY_NEON] = rte_acl_classify_neon,
115 : : [RTE_ACL_CLASSIFY_ALTIVEC] = rte_acl_classify_altivec,
116 : : [RTE_ACL_CLASSIFY_AVX512X16] = rte_acl_classify_avx512x16,
117 : : [RTE_ACL_CLASSIFY_AVX512X32] = rte_acl_classify_avx512x32,
118 : : [RTE_ACL_CLASSIFY_RVV] = rte_acl_classify_rvv,
119 : : };
120 : :
121 : : /*
122 : : * Helper function for acl_check_alg.
123 : : * Check support for ARM specific classify methods.
124 : : */
125 : : static int
126 : : acl_check_alg_arm(enum rte_acl_classify_alg alg)
127 : : {
128 : : if (alg == RTE_ACL_CLASSIFY_NEON) {
129 : : #if defined(RTE_ARCH_ARM64)
130 : : if (rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128)
131 : : return 0;
132 : : #elif defined(RTE_ARCH_ARM)
133 : : if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_NEON) &&
134 : : rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128)
135 : : return 0;
136 : : #endif
137 : : return -ENOTSUP;
138 : : }
139 : :
140 : : return -EINVAL;
141 : : }
142 : :
143 : : /*
144 : : * Helper function for acl_check_alg.
145 : : * Check support for PPC specific classify methods.
146 : : */
147 : : static int
148 : : acl_check_alg_ppc(enum rte_acl_classify_alg alg)
149 : : {
150 : : if (alg == RTE_ACL_CLASSIFY_ALTIVEC) {
151 : : #if defined(RTE_ARCH_PPC_64)
152 : : if (rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128)
153 : : return 0;
154 : : #endif
155 : : return -ENOTSUP;
156 : : }
157 : :
158 : : return -EINVAL;
159 : : }
160 : :
161 : : #ifdef CC_AVX512_SUPPORT
162 : : static int
163 : 58252 : acl_check_avx512_cpu_flags(void)
164 : : {
165 [ + - ]: 116504 : return (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512F) &&
166 [ + - ]: 116504 : rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512VL) &&
167 [ + - - + ]: 174756 : rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512CD) &&
168 : 58252 : rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512BW));
169 : : }
170 : : #endif
171 : :
172 : : /*
173 : : * Helper function for acl_check_alg.
174 : : * Check support for x86 specific classify methods.
175 : : */
176 : : static int
177 : 66562 : acl_check_alg_x86(enum rte_acl_classify_alg alg)
178 : : {
179 [ + + ]: 66562 : if (alg == RTE_ACL_CLASSIFY_AVX512X32) {
180 : : #ifdef CC_AVX512_SUPPORT
181 [ + - + - ]: 41632 : if (acl_check_avx512_cpu_flags() != 0 &&
182 : 20816 : rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_512)
183 : : return 0;
184 : : #endif
185 : 20816 : return -ENOTSUP;
186 : : }
187 : :
188 [ + + ]: 45746 : if (alg == RTE_ACL_CLASSIFY_AVX512X16) {
189 : : #ifdef CC_AVX512_SUPPORT
190 [ + - - + ]: 74872 : if (acl_check_avx512_cpu_flags() != 0 &&
191 : 37436 : rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_256)
192 : : return 0;
193 : : #endif
194 : 0 : return -ENOTSUP;
195 : : }
196 : :
197 [ + + ]: 8310 : if (alg == RTE_ACL_CLASSIFY_AVX2) {
198 : : #ifdef RTE_ARCH_X86
199 [ + - - + ]: 8310 : if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2) &&
200 : 4155 : rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_256)
201 : : return 0;
202 : : #endif
203 : 0 : return -ENOTSUP;
204 : : }
205 : :
206 [ + - ]: 4155 : if (alg == RTE_ACL_CLASSIFY_SSE) {
207 : : #ifdef RTE_ARCH_X86
208 [ + - - + ]: 8310 : if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_SSE4_1) &&
209 : 4155 : rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128)
210 : : return 0;
211 : : #endif
212 : 0 : return -ENOTSUP;
213 : : }
214 : :
215 : : return -EINVAL;
216 : : }
217 : : /*
218 : : * Helper function for acl_check_alg.
219 : : * Check support for x86 specific classify methods.
220 : : */
221 : : static int
222 : : acl_check_alg_rvv(enum rte_acl_classify_alg alg)
223 : : {
224 : : if (alg == RTE_ACL_CLASSIFY_RVV) {
225 : : #ifdef RTE_RISCV_FEATURE_V
226 : : if (rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128)
227 : : return 0;
228 : : #endif
229 : : return -ENOTSUP;
230 : : }
231 : :
232 : : return -EINVAL;
233 : : }
234 : :
235 : : /*
236 : : * Check if input alg is supported by given platform/binary.
237 : : * Note that both conditions should be met:
238 : : * - at build time compiler supports ISA used by given methods
239 : : * - at run time target cpu supports necessary ISA.
240 : : */
241 : : static int
242 : 83182 : acl_check_alg(enum rte_acl_classify_alg alg)
243 : : {
244 [ + + + + : 83182 : switch (alg) {
- + ]
245 : : case RTE_ACL_CLASSIFY_NEON:
246 : : return acl_check_alg_arm(alg);
247 : : case RTE_ACL_CLASSIFY_ALTIVEC:
248 : : return acl_check_alg_ppc(alg);
249 : 66562 : case RTE_ACL_CLASSIFY_AVX512X32:
250 : : case RTE_ACL_CLASSIFY_AVX512X16:
251 : : case RTE_ACL_CLASSIFY_AVX2:
252 : : case RTE_ACL_CLASSIFY_SSE:
253 : 66562 : return acl_check_alg_x86(alg);
254 : : case RTE_ACL_CLASSIFY_RVV:
255 : : return acl_check_alg_rvv(alg);
256 : : /* scalar method is supported on all platforms */
257 : : case RTE_ACL_CLASSIFY_SCALAR:
258 : : return 0;
259 : 0 : default:
260 : 0 : return -EINVAL;
261 : : }
262 : : }
263 : :
264 : : /*
265 : : * Get preferred alg for given platform.
266 : : */
267 : : static enum rte_acl_classify_alg
268 : 16661 : acl_get_best_alg(void)
269 : : {
270 : : /*
271 : : * array of supported methods for each platform.
272 : : * Note that order is important - from most to less preferable.
273 : : */
274 : : static const enum rte_acl_classify_alg alg[] = {
275 : : #if defined(RTE_ARCH_ARM)
276 : : RTE_ACL_CLASSIFY_NEON,
277 : : #elif defined(RTE_ARCH_PPC_64)
278 : : RTE_ACL_CLASSIFY_ALTIVEC,
279 : : #elif defined(RTE_ARCH_X86)
280 : : RTE_ACL_CLASSIFY_AVX512X32,
281 : : RTE_ACL_CLASSIFY_AVX512X16,
282 : : RTE_ACL_CLASSIFY_AVX2,
283 : : RTE_ACL_CLASSIFY_SSE,
284 : : #elif defined(RTE_RISCV_FEATURE_V)
285 : : RTE_ACL_CLASSIFY_RVV,
286 : : #endif
287 : : RTE_ACL_CLASSIFY_SCALAR,
288 : : };
289 : :
290 : : uint32_t i;
291 : :
292 : : /* find best possible alg */
293 [ + - + + ]: 33322 : for (i = 0; i != RTE_DIM(alg) && acl_check_alg(alg[i]) != 0; i++)
294 : : ;
295 : :
296 : : /* we always have to find something suitable */
297 [ - + ]: 16661 : RTE_VERIFY(i != RTE_DIM(alg));
298 : 16661 : return alg[i];
299 : : }
300 : :
301 : : static void *
302 : 42 : acl_mem_default_zalloc(char *name, size_t size, size_t align, int32_t socket_id, void *udata)
303 : : {
304 : : RTE_SET_USED(udata);
305 : 42 : return rte_zmalloc_socket(name, size, align, socket_id);
306 : : }
307 : :
308 : : static void
309 : 87 : acl_mem_default_free(void *ptr, void *udata)
310 : : {
311 : : RTE_SET_USED(udata);
312 : 87 : rte_free(ptr);
313 : 87 : }
314 : :
315 : : RTE_EXPORT_SYMBOL(rte_acl_set_ctx_classify)
316 : : extern int
317 : 49860 : rte_acl_set_ctx_classify(struct rte_acl_ctx *ctx, enum rte_acl_classify_alg alg)
318 : : {
319 : : int32_t rc;
320 : :
321 : : /* formal parameters check */
322 [ + - ]: 49860 : if (ctx == NULL || (uint32_t)alg >= RTE_DIM(classify_fns))
323 : : return -EINVAL;
324 : :
325 : : /* user asked us to select the *best* one */
326 [ + + ]: 49860 : if (alg == RTE_ACL_CLASSIFY_DEFAULT)
327 : 16620 : alg = acl_get_best_alg();
328 : :
329 : : /* check that given alg is supported */
330 : 49860 : rc = acl_check_alg(alg);
331 [ + + ]: 49860 : if (rc != 0)
332 : : return rc;
333 : :
334 : 33240 : ctx->alg = alg;
335 : 33240 : return 0;
336 : : }
337 : :
338 : : RTE_EXPORT_SYMBOL(rte_acl_classify_alg)
339 : : int
340 : 1080269 : rte_acl_classify_alg(const struct rte_acl_ctx *ctx, const uint8_t **data,
341 : : uint32_t *results, uint32_t num, uint32_t categories,
342 : : enum rte_acl_classify_alg alg)
343 : : {
344 [ + + ]: 1080269 : if (categories != 1 &&
345 [ + + ]: 1080260 : ((RTE_ACL_RESULTS_MULTIPLIER - 1) & categories) != 0)
346 : : return -EINVAL;
347 : :
348 : 1080267 : return classify_fns[alg](ctx, data, results, num, categories);
349 : : }
350 : :
351 : : RTE_EXPORT_SYMBOL(rte_acl_classify)
352 : : int
353 : 1080266 : rte_acl_classify(const struct rte_acl_ctx *ctx, const uint8_t **data,
354 : : uint32_t *results, uint32_t num, uint32_t categories)
355 : : {
356 : 2160532 : return rte_acl_classify_alg(ctx, data, results, num, categories,
357 : 1080266 : ctx->alg);
358 : : }
359 : :
360 : : RTE_EXPORT_SYMBOL(rte_acl_find_existing)
361 : : struct rte_acl_ctx *
362 : 4 : rte_acl_find_existing(const char *name)
363 : : {
364 : : struct rte_acl_ctx *ctx = NULL;
365 : : struct rte_acl_list *acl_list;
366 : : struct rte_tailq_entry *te;
367 : :
368 : 4 : acl_list = RTE_TAILQ_CAST(rte_acl_tailq.head, rte_acl_list);
369 : :
370 : 4 : rte_mcfg_tailq_read_lock();
371 [ + + ]: 7 : TAILQ_FOREACH(te, acl_list, next) {
372 : 5 : ctx = (struct rte_acl_ctx *) te->data;
373 [ + + ]: 5 : if (strncmp(name, ctx->name, sizeof(ctx->name)) == 0)
374 : : break;
375 : : }
376 : 4 : rte_mcfg_tailq_read_unlock();
377 : :
378 [ + + ]: 4 : if (te == NULL) {
379 : 2 : rte_errno = ENOENT;
380 : 2 : return NULL;
381 : : }
382 : : return ctx;
383 : : }
384 : :
385 : : RTE_EXPORT_SYMBOL(rte_acl_free)
386 : : void
387 : 46 : rte_acl_free(struct rte_acl_ctx *ctx)
388 : : {
389 : : struct rte_acl_list *acl_list;
390 : : struct rte_tailq_entry *te;
391 : :
392 [ + + ]: 46 : if (ctx == NULL)
393 : : return;
394 : :
395 : 41 : acl_list = RTE_TAILQ_CAST(rte_acl_tailq.head, rte_acl_list);
396 : :
397 : 41 : rte_mcfg_tailq_write_lock();
398 : :
399 : : /* find our tailq entry */
400 [ + - ]: 53 : TAILQ_FOREACH(te, acl_list, next) {
401 [ + + ]: 53 : if (te->data == (void *) ctx)
402 : : break;
403 : : }
404 [ - + ]: 41 : if (te == NULL) {
405 : 0 : rte_mcfg_tailq_write_unlock();
406 : 0 : return;
407 : : }
408 : :
409 [ + + ]: 41 : TAILQ_REMOVE(acl_list, te, next);
410 : :
411 : 41 : rte_mcfg_tailq_write_unlock();
412 : :
413 : 41 : ctx->mem_hook.free(ctx->mem, ctx->mem_hook.udata);
414 : 41 : rte_free(ctx);
415 : 41 : rte_free(te);
416 : : }
417 : :
418 : : RTE_EXPORT_SYMBOL(rte_acl_create)
419 : : struct rte_acl_ctx *
420 : 45 : rte_acl_create(const struct rte_acl_param *param)
421 : : {
422 : : size_t sz;
423 : : struct rte_acl_ctx *ctx;
424 : : struct rte_acl_list *acl_list;
425 : : struct rte_tailq_entry *te;
426 : : char name[sizeof(ctx->name)];
427 : :
428 : 45 : acl_list = RTE_TAILQ_CAST(rte_acl_tailq.head, rte_acl_list);
429 : :
430 : : /* check that input parameters are valid. */
431 [ + + + + ]: 45 : if (param == NULL || param->name == NULL) {
432 : 2 : rte_errno = EINVAL;
433 : 2 : return NULL;
434 : : }
435 : :
436 : : snprintf(name, sizeof(name), "ACL_%s", param->name);
437 : :
438 : : /* calculate amount of memory required for pattern set. */
439 : 43 : sz = sizeof(*ctx) + param->max_rule_num * param->rule_size;
440 : :
441 : : /* get EAL TAILQ lock. */
442 : 43 : rte_mcfg_tailq_write_lock();
443 : :
444 : : /* if we already have one with that name */
445 [ + + ]: 75 : TAILQ_FOREACH(te, acl_list, next) {
446 : 34 : ctx = (struct rte_acl_ctx *) te->data;
447 [ + + ]: 34 : if (strncmp(param->name, ctx->name, sizeof(ctx->name)) == 0)
448 : : break;
449 : : }
450 : :
451 : : /* if ACL with such name doesn't exist, then create a new one. */
452 [ + + ]: 43 : if (te == NULL) {
453 : : ctx = NULL;
454 : 41 : te = rte_zmalloc("ACL_TAILQ_ENTRY", sizeof(*te), 0);
455 : :
456 [ - + ]: 41 : if (te == NULL) {
457 : 0 : ACL_LOG(ERR, "Cannot allocate tailq entry!");
458 : 0 : goto exit;
459 : : }
460 : :
461 : 41 : ctx = rte_zmalloc_socket(name, sz, RTE_CACHE_LINE_SIZE, param->socket_id);
462 : :
463 [ - + ]: 41 : if (ctx == NULL) {
464 : 0 : ACL_LOG(ERR,
465 : : "allocation of %zu bytes on socket %d for %s failed",
466 : : sz, param->socket_id, name);
467 : 0 : rte_free(te);
468 : 0 : goto exit;
469 : : }
470 : : /* init new allocated context. */
471 : 41 : ctx->rules = ctx + 1;
472 : 41 : ctx->max_rules = param->max_rule_num;
473 : 41 : ctx->rule_sz = param->rule_size;
474 : 41 : ctx->socket_id = param->socket_id;
475 : 41 : ctx->alg = acl_get_best_alg();
476 : 41 : ctx->mem_hook.zalloc = acl_mem_default_zalloc;
477 : 41 : ctx->mem_hook.free = acl_mem_default_free;
478 : 41 : ctx->mem_hook.udata = NULL;
479 : 41 : strlcpy(ctx->name, param->name, sizeof(ctx->name));
480 : :
481 : 41 : te->data = (void *) ctx;
482 : :
483 : 41 : TAILQ_INSERT_TAIL(acl_list, te, next);
484 : : }
485 : :
486 : 2 : exit:
487 : 43 : rte_mcfg_tailq_write_unlock();
488 : 43 : return ctx;
489 : : }
490 : :
491 : : static int
492 : 6459 : acl_add_rules(struct rte_acl_ctx *ctx, const void *rules, uint32_t num)
493 : : {
494 : : uint8_t *pos;
495 : :
496 [ + + ]: 6459 : if (num + ctx->num_rules > ctx->max_rules)
497 : : return -ENOMEM;
498 : :
499 : 6458 : pos = ctx->rules;
500 : 6458 : pos += ctx->rule_sz * ctx->num_rules;
501 : 6458 : memcpy(pos, rules, num * ctx->rule_sz);
502 : 6458 : ctx->num_rules += num;
503 : :
504 : 6458 : return 0;
505 : : }
506 : :
507 : : static int
508 : : acl_check_rule(const struct rte_acl_rule_data *rd)
509 : : {
510 : 6459 : if ((RTE_LEN2MASK(RTE_ACL_MAX_CATEGORIES, typeof(rd->category_mask)) &
511 : 12918 : rd->category_mask) == 0 ||
512 [ + - + - ]: 6459 : rd->priority > RTE_ACL_MAX_PRIORITY ||
513 : : rd->priority < RTE_ACL_MIN_PRIORITY)
514 : : return -EINVAL;
515 : : return 0;
516 : : }
517 : :
518 : : RTE_EXPORT_SYMBOL(rte_acl_add_rules)
519 : : int
520 : 6459 : rte_acl_add_rules(struct rte_acl_ctx *ctx, const struct rte_acl_rule *rules,
521 : : uint32_t num)
522 : : {
523 : : const struct rte_acl_rule *rv;
524 : : uint32_t i;
525 : : int32_t rc;
526 : :
527 [ + - + - ]: 6459 : if (ctx == NULL || rules == NULL || 0 == ctx->rule_sz)
528 : : return -EINVAL;
529 : :
530 [ + + ]: 12918 : for (i = 0; i != num; i++) {
531 : 6459 : rv = (const struct rte_acl_rule *)
532 [ + - ]: 6459 : ((uintptr_t)rules + i * ctx->rule_sz);
533 : : rc = acl_check_rule(&rv->data);
534 : : if (rc != 0) {
535 : 0 : ACL_LOG(ERR, "%s(%s): rule #%u is invalid",
536 : : __func__, ctx->name, i + 1);
537 : 0 : return rc;
538 : : }
539 : : }
540 : :
541 : 6459 : return acl_add_rules(ctx, rules, num);
542 : : }
543 : :
544 : : /*
545 : : * Reset all rules.
546 : : * Note that RT structures are not affected.
547 : : */
548 : : RTE_EXPORT_SYMBOL(rte_acl_reset_rules)
549 : : void
550 : 21 : rte_acl_reset_rules(struct rte_acl_ctx *ctx)
551 : : {
552 [ + - ]: 21 : if (ctx != NULL)
553 : 21 : ctx->num_rules = 0;
554 : 21 : }
555 : :
556 : : /*
557 : : * Reset all rules and destroys RT structures.
558 : : */
559 : : RTE_EXPORT_SYMBOL(rte_acl_reset)
560 : : void
561 : 9 : rte_acl_reset(struct rte_acl_ctx *ctx)
562 : : {
563 [ + - ]: 9 : if (ctx != NULL) {
564 : 9 : rte_acl_reset_rules(ctx);
565 : 9 : rte_acl_build(ctx, &ctx->config);
566 : : }
567 : 9 : }
568 : :
569 : : /*
570 : : * Dump ACL context to the stdout.
571 : : */
572 : : RTE_EXPORT_SYMBOL(rte_acl_dump)
573 : : void
574 : 3 : rte_acl_dump(const struct rte_acl_ctx *ctx)
575 : : {
576 [ + + ]: 3 : if (!ctx)
577 : : return;
578 : 2 : printf("acl context <%s>@%p\n", ctx->name, ctx);
579 : 2 : printf(" socket_id=%"PRId32"\n", ctx->socket_id);
580 : 2 : printf(" alg=%"PRId32"\n", ctx->alg);
581 : 2 : printf(" first_load_sz=%"PRIu32"\n", ctx->first_load_sz);
582 : 2 : printf(" max_rules=%"PRIu32"\n", ctx->max_rules);
583 : 2 : printf(" rule_size=%"PRIu32"\n", ctx->rule_sz);
584 : 2 : printf(" num_rules=%"PRIu32"\n", ctx->num_rules);
585 : 2 : printf(" num_categories=%"PRIu32"\n", ctx->num_categories);
586 : 2 : printf(" num_tries=%"PRIu32"\n", ctx->num_tries);
587 : : }
588 : :
589 : : /*
590 : : * Dump all ACL contexts to the stdout.
591 : : */
592 : : RTE_EXPORT_SYMBOL(rte_acl_list_dump)
593 : : void
594 : 1 : rte_acl_list_dump(void)
595 : : {
596 : : struct rte_acl_ctx *ctx;
597 : : struct rte_acl_list *acl_list;
598 : : struct rte_tailq_entry *te;
599 : :
600 : 1 : acl_list = RTE_TAILQ_CAST(rte_acl_tailq.head, rte_acl_list);
601 : :
602 : 1 : rte_mcfg_tailq_read_lock();
603 [ + + ]: 2 : TAILQ_FOREACH(te, acl_list, next) {
604 : 1 : ctx = (struct rte_acl_ctx *) te->data;
605 : 1 : rte_acl_dump(ctx);
606 : : }
607 : 1 : rte_mcfg_tailq_read_unlock();
608 : 1 : }
609 : :
610 : : /*
611 : : * Set memory allocation hooks for a given ACL context.
612 : : */
613 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_acl_set_mem_hook, 26.03)
614 : : int
615 : 1 : rte_acl_set_mem_hook(struct rte_acl_ctx *acl, const struct rte_acl_mem_hook *mhook)
616 : : {
617 [ + - + - : 1 : if (acl == NULL || mhook == NULL || mhook->zalloc == NULL || mhook->free == NULL)
+ - ]
618 : : return -EINVAL;
619 : 1 : memcpy(&acl->mem_hook, mhook, sizeof(struct rte_acl_mem_hook));
620 : 1 : return 0;
621 : : }
622 : :
623 : : /*
624 : : * Retrieve the memory allocation hooks assigned to the ACL context.
625 : : */
626 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_acl_get_mem_hook, 26.03)
627 : : int
628 : 1 : rte_acl_get_mem_hook(const struct rte_acl_ctx *acl, struct rte_acl_mem_hook *mhook)
629 : : {
630 [ + - ]: 1 : if (acl == NULL || mhook == NULL)
631 : : return -EINVAL;
632 : 1 : memcpy(mhook, &acl->mem_hook, sizeof(struct rte_acl_mem_hook));
633 : 1 : return 0;
634 : : }
|