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