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 [ - + ]: 252 : 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 [ - + ]: 252 : 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 : 58138 : acl_check_avx512_cpu_flags(void)
151 : : {
152 [ + - ]: 116276 : return (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512F) &&
153 [ + - ]: 116276 : rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512VL) &&
154 [ + - - + ]: 174414 : rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX512CD) &&
155 : 58138 : 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 : 66432 : acl_check_alg_x86(enum rte_acl_classify_alg alg)
165 : : {
166 [ + + ]: 66432 : if (alg == RTE_ACL_CLASSIFY_AVX512X32) {
167 : : #ifdef CC_AVX512_SUPPORT
168 [ + - + - ]: 41550 : if (acl_check_avx512_cpu_flags() != 0 &&
169 : 20775 : rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_512)
170 : : return 0;
171 : : #endif
172 : 20775 : return -ENOTSUP;
173 : : }
174 : :
175 [ + + ]: 45657 : if (alg == RTE_ACL_CLASSIFY_AVX512X16) {
176 : : #ifdef CC_AVX512_SUPPORT
177 [ + - - + ]: 74726 : if (acl_check_avx512_cpu_flags() != 0 &&
178 : 37363 : rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_256)
179 : : return 0;
180 : : #endif
181 : 0 : return -ENOTSUP;
182 : : }
183 : :
184 [ + + ]: 8294 : if (alg == RTE_ACL_CLASSIFY_AVX2) {
185 : : #ifdef RTE_ARCH_X86
186 [ + - - + ]: 8294 : if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2) &&
187 : 4147 : rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_256)
188 : : return 0;
189 : : #endif
190 : 0 : return -ENOTSUP;
191 : : }
192 : :
193 [ + - ]: 4147 : if (alg == RTE_ACL_CLASSIFY_SSE) {
194 : : #ifdef RTE_ARCH_X86
195 [ + - - + ]: 8294 : if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_SSE4_1) &&
196 : 4147 : 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 : 78873 : acl_check_alg(enum rte_acl_classify_alg alg)
213 : : {
214 [ + + + - : 78873 : 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 : 66432 : case RTE_ACL_CLASSIFY_AVX512X32:
220 : : case RTE_ACL_CLASSIFY_AVX512X16:
221 : : case RTE_ACL_CLASSIFY_AVX2:
222 : : case RTE_ACL_CLASSIFY_SSE:
223 : 66432 : 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 : 16628 : 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 [ + - + + ]: 33256 : 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 [ - + ]: 16628 : RTE_VERIFY(i != RTE_DIM(alg));
264 : 16628 : return alg[i];
265 : : }
266 : :
267 : : RTE_EXPORT_SYMBOL(rte_acl_set_ctx_classify)
268 : : extern int
269 : 45617 : rte_acl_set_ctx_classify(struct rte_acl_ctx *ctx, enum rte_acl_classify_alg alg)
270 : : {
271 : : int32_t rc;
272 : :
273 : : /* formal parameters check */
274 [ + - ]: 45617 : if (ctx == NULL || (uint32_t)alg >= RTE_DIM(classify_fns))
275 : : return -EINVAL;
276 : :
277 : : /* user asked us to select the *best* one */
278 [ + + ]: 45617 : if (alg == RTE_ACL_CLASSIFY_DEFAULT)
279 : 16588 : alg = acl_get_best_alg();
280 : :
281 : : /* check that given alg is supported */
282 : 45617 : rc = acl_check_alg(alg);
283 [ + + ]: 45617 : if (rc != 0)
284 : : return rc;
285 : :
286 : 33176 : ctx->alg = alg;
287 : 33176 : return 0;
288 : : }
289 : :
290 : : RTE_EXPORT_SYMBOL(rte_acl_classify_alg)
291 : : int
292 : 1078125 : rte_acl_classify_alg(const struct rte_acl_ctx *ctx, const uint8_t **data,
293 : : uint32_t *results, uint32_t num, uint32_t categories,
294 : : enum rte_acl_classify_alg alg)
295 : : {
296 [ + + ]: 1078125 : if (categories != 1 &&
297 [ + + ]: 1078116 : ((RTE_ACL_RESULTS_MULTIPLIER - 1) & categories) != 0)
298 : : return -EINVAL;
299 : :
300 : 1078123 : return classify_fns[alg](ctx, data, results, num, categories);
301 : : }
302 : :
303 : : RTE_EXPORT_SYMBOL(rte_acl_classify)
304 : : int
305 : 1078122 : rte_acl_classify(const struct rte_acl_ctx *ctx, const uint8_t **data,
306 : : uint32_t *results, uint32_t num, uint32_t categories)
307 : : {
308 : 2156244 : return rte_acl_classify_alg(ctx, data, results, num, categories,
309 : 1078122 : ctx->alg);
310 : : }
311 : :
312 : : RTE_EXPORT_SYMBOL(rte_acl_find_existing)
313 : : struct rte_acl_ctx *
314 : 4 : rte_acl_find_existing(const char *name)
315 : : {
316 : : struct rte_acl_ctx *ctx = NULL;
317 : : struct rte_acl_list *acl_list;
318 : : struct rte_tailq_entry *te;
319 : :
320 : 4 : acl_list = RTE_TAILQ_CAST(rte_acl_tailq.head, rte_acl_list);
321 : :
322 : 4 : rte_mcfg_tailq_read_lock();
323 [ + + ]: 7 : TAILQ_FOREACH(te, acl_list, next) {
324 : 5 : ctx = (struct rte_acl_ctx *) te->data;
325 [ + + ]: 5 : if (strncmp(name, ctx->name, sizeof(ctx->name)) == 0)
326 : : break;
327 : : }
328 : 4 : rte_mcfg_tailq_read_unlock();
329 : :
330 [ + + ]: 4 : if (te == NULL) {
331 : 2 : rte_errno = ENOENT;
332 : 2 : return NULL;
333 : : }
334 : : return ctx;
335 : : }
336 : :
337 : : RTE_EXPORT_SYMBOL(rte_acl_free)
338 : : void
339 : 45 : rte_acl_free(struct rte_acl_ctx *ctx)
340 : : {
341 : : struct rte_acl_list *acl_list;
342 : : struct rte_tailq_entry *te;
343 : :
344 [ + + ]: 45 : if (ctx == NULL)
345 : : return;
346 : :
347 : 40 : acl_list = RTE_TAILQ_CAST(rte_acl_tailq.head, rte_acl_list);
348 : :
349 : 40 : rte_mcfg_tailq_write_lock();
350 : :
351 : : /* find our tailq entry */
352 [ + - ]: 52 : TAILQ_FOREACH(te, acl_list, next) {
353 [ + + ]: 52 : if (te->data == (void *) ctx)
354 : : break;
355 : : }
356 [ - + ]: 40 : if (te == NULL) {
357 : 0 : rte_mcfg_tailq_write_unlock();
358 : 0 : return;
359 : : }
360 : :
361 [ + + ]: 40 : TAILQ_REMOVE(acl_list, te, next);
362 : :
363 : 40 : rte_mcfg_tailq_write_unlock();
364 : :
365 : 40 : rte_free(ctx->mem);
366 : 40 : rte_free(ctx);
367 : 40 : rte_free(te);
368 : : }
369 : :
370 : : RTE_EXPORT_SYMBOL(rte_acl_create)
371 : : struct rte_acl_ctx *
372 : 44 : rte_acl_create(const struct rte_acl_param *param)
373 : : {
374 : : size_t sz;
375 : : struct rte_acl_ctx *ctx;
376 : : struct rte_acl_list *acl_list;
377 : : struct rte_tailq_entry *te;
378 : : char name[sizeof(ctx->name)];
379 : :
380 : 44 : acl_list = RTE_TAILQ_CAST(rte_acl_tailq.head, rte_acl_list);
381 : :
382 : : /* check that input parameters are valid. */
383 [ + + + + ]: 44 : if (param == NULL || param->name == NULL) {
384 : 2 : rte_errno = EINVAL;
385 : 2 : return NULL;
386 : : }
387 : :
388 : : snprintf(name, sizeof(name), "ACL_%s", param->name);
389 : :
390 : : /* calculate amount of memory required for pattern set. */
391 : 42 : sz = sizeof(*ctx) + param->max_rule_num * param->rule_size;
392 : :
393 : : /* get EAL TAILQ lock. */
394 : 42 : rte_mcfg_tailq_write_lock();
395 : :
396 : : /* if we already have one with that name */
397 [ + + ]: 74 : TAILQ_FOREACH(te, acl_list, next) {
398 : 34 : ctx = (struct rte_acl_ctx *) te->data;
399 [ + + ]: 34 : if (strncmp(param->name, ctx->name, sizeof(ctx->name)) == 0)
400 : : break;
401 : : }
402 : :
403 : : /* if ACL with such name doesn't exist, then create a new one. */
404 [ + + ]: 42 : if (te == NULL) {
405 : : ctx = NULL;
406 : 40 : te = rte_zmalloc("ACL_TAILQ_ENTRY", sizeof(*te), 0);
407 : :
408 [ - + ]: 40 : if (te == NULL) {
409 : 0 : ACL_LOG(ERR, "Cannot allocate tailq entry!");
410 : 0 : goto exit;
411 : : }
412 : :
413 : 40 : ctx = rte_zmalloc_socket(name, sz, RTE_CACHE_LINE_SIZE, param->socket_id);
414 : :
415 [ - + ]: 40 : if (ctx == NULL) {
416 : 0 : ACL_LOG(ERR,
417 : : "allocation of %zu bytes on socket %d for %s failed",
418 : : sz, param->socket_id, name);
419 : 0 : rte_free(te);
420 : 0 : goto exit;
421 : : }
422 : : /* init new allocated context. */
423 : 40 : ctx->rules = ctx + 1;
424 : 40 : ctx->max_rules = param->max_rule_num;
425 : 40 : ctx->rule_sz = param->rule_size;
426 : 40 : ctx->socket_id = param->socket_id;
427 : 40 : ctx->alg = acl_get_best_alg();
428 : 40 : strlcpy(ctx->name, param->name, sizeof(ctx->name));
429 : :
430 : 40 : te->data = (void *) ctx;
431 : :
432 : 40 : TAILQ_INSERT_TAIL(acl_list, te, next);
433 : : }
434 : :
435 : 2 : exit:
436 : 42 : rte_mcfg_tailq_write_unlock();
437 : 42 : return ctx;
438 : : }
439 : :
440 : : static int
441 : 6351 : acl_add_rules(struct rte_acl_ctx *ctx, const void *rules, uint32_t num)
442 : : {
443 : : uint8_t *pos;
444 : :
445 [ + + ]: 6351 : if (num + ctx->num_rules > ctx->max_rules)
446 : : return -ENOMEM;
447 : :
448 : 6350 : pos = ctx->rules;
449 : 6350 : pos += ctx->rule_sz * ctx->num_rules;
450 : 6350 : memcpy(pos, rules, num * ctx->rule_sz);
451 : 6350 : ctx->num_rules += num;
452 : :
453 : 6350 : return 0;
454 : : }
455 : :
456 : : static int
457 : : acl_check_rule(const struct rte_acl_rule_data *rd)
458 : : {
459 : 6351 : if ((RTE_LEN2MASK(RTE_ACL_MAX_CATEGORIES, typeof(rd->category_mask)) &
460 : 12702 : rd->category_mask) == 0 ||
461 [ + - + - ]: 6351 : rd->priority > RTE_ACL_MAX_PRIORITY ||
462 : : rd->priority < RTE_ACL_MIN_PRIORITY)
463 : : return -EINVAL;
464 : : return 0;
465 : : }
466 : :
467 : : RTE_EXPORT_SYMBOL(rte_acl_add_rules)
468 : : int
469 : 6351 : rte_acl_add_rules(struct rte_acl_ctx *ctx, const struct rte_acl_rule *rules,
470 : : uint32_t num)
471 : : {
472 : : const struct rte_acl_rule *rv;
473 : : uint32_t i;
474 : : int32_t rc;
475 : :
476 [ + - + - ]: 6351 : if (ctx == NULL || rules == NULL || 0 == ctx->rule_sz)
477 : : return -EINVAL;
478 : :
479 [ + + ]: 12702 : for (i = 0; i != num; i++) {
480 : 6351 : rv = (const struct rte_acl_rule *)
481 [ + - ]: 6351 : ((uintptr_t)rules + i * ctx->rule_sz);
482 : : rc = acl_check_rule(&rv->data);
483 : : if (rc != 0) {
484 : 0 : ACL_LOG(ERR, "%s(%s): rule #%u is invalid",
485 : : __func__, ctx->name, i + 1);
486 : 0 : return rc;
487 : : }
488 : : }
489 : :
490 : 6351 : return acl_add_rules(ctx, rules, num);
491 : : }
492 : :
493 : : /*
494 : : * Reset all rules.
495 : : * Note that RT structures are not affected.
496 : : */
497 : : RTE_EXPORT_SYMBOL(rte_acl_reset_rules)
498 : : void
499 : 13 : rte_acl_reset_rules(struct rte_acl_ctx *ctx)
500 : : {
501 [ + - ]: 13 : if (ctx != NULL)
502 : 13 : ctx->num_rules = 0;
503 : 13 : }
504 : :
505 : : /*
506 : : * Reset all rules and destroys RT structures.
507 : : */
508 : : RTE_EXPORT_SYMBOL(rte_acl_reset)
509 : : void
510 : 7 : rte_acl_reset(struct rte_acl_ctx *ctx)
511 : : {
512 [ + - ]: 7 : if (ctx != NULL) {
513 : 7 : rte_acl_reset_rules(ctx);
514 : 7 : rte_acl_build(ctx, &ctx->config);
515 : : }
516 : 7 : }
517 : :
518 : : /*
519 : : * Dump ACL context to the stdout.
520 : : */
521 : : RTE_EXPORT_SYMBOL(rte_acl_dump)
522 : : void
523 : 3 : rte_acl_dump(const struct rte_acl_ctx *ctx)
524 : : {
525 [ + + ]: 3 : if (!ctx)
526 : : return;
527 : 2 : printf("acl context <%s>@%p\n", ctx->name, ctx);
528 : 2 : printf(" socket_id=%"PRId32"\n", ctx->socket_id);
529 : 2 : printf(" alg=%"PRId32"\n", ctx->alg);
530 : 2 : printf(" first_load_sz=%"PRIu32"\n", ctx->first_load_sz);
531 : 2 : printf(" max_rules=%"PRIu32"\n", ctx->max_rules);
532 : 2 : printf(" rule_size=%"PRIu32"\n", ctx->rule_sz);
533 : 2 : printf(" num_rules=%"PRIu32"\n", ctx->num_rules);
534 : 2 : printf(" num_categories=%"PRIu32"\n", ctx->num_categories);
535 : 2 : printf(" num_tries=%"PRIu32"\n", ctx->num_tries);
536 : : }
537 : :
538 : : /*
539 : : * Dump all ACL contexts to the stdout.
540 : : */
541 : : RTE_EXPORT_SYMBOL(rte_acl_list_dump)
542 : : void
543 : 1 : rte_acl_list_dump(void)
544 : : {
545 : : struct rte_acl_ctx *ctx;
546 : : struct rte_acl_list *acl_list;
547 : : struct rte_tailq_entry *te;
548 : :
549 : 1 : acl_list = RTE_TAILQ_CAST(rte_acl_tailq.head, rte_acl_list);
550 : :
551 : 1 : rte_mcfg_tailq_read_lock();
552 [ + + ]: 2 : TAILQ_FOREACH(te, acl_list, next) {
553 : 1 : ctx = (struct rte_acl_ctx *) te->data;
554 : 1 : rte_acl_dump(ctx);
555 : : }
556 : 1 : rte_mcfg_tailq_read_unlock();
557 : 1 : }
|