X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-acl%2Fmain.c;h=2cb2fe2579adebd8d442385fac7034d6b764100b;hb=00dac9a99c783e0d442e73842ebb006f2f39c59d;hp=d65440977b25b58ce946c8034e52a7e7fa304186;hpb=26c057ab6c45a6a875099bc2363a873006b073bb;p=dpdk.git diff --git a/app/test-acl/main.c b/app/test-acl/main.c index d65440977b..2cb2fe2579 100644 --- a/app/test-acl/main.c +++ b/app/test-acl/main.c @@ -1,68 +1,22 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation */ +#include #include #include #include -#ifndef RTE_LIBRTE_ACL_STANDALONE - #include #include #include #include -#define PRINT_USAGE_START "%s [EAL options]\n" - -#else - -#define IPv4(a, b, c, d) ((uint32_t)(((a) & 0xff) << 24) | \ - (((b) & 0xff) << 16) | \ - (((c) & 0xff) << 8) | \ - ((d) & 0xff)) - -#define RTE_LCORE_FOREACH_SLAVE(x) while (((x) = 0)) - -#define rte_eal_remote_launch(a, b, c) DUMMY_MACRO -#define rte_eal_mp_wait_lcore() DUMMY_MACRO - -#define rte_eal_init(c, v) (0) - -#define PRINT_USAGE_START "%s\n" +#define PRINT_USAGE_START "%s [EAL options] --\n" -#endif /*RTE_LIBRTE_ACL_STANDALONE */ +#define RTE_LOGTYPE_TESTACL RTE_LOGTYPE_USER1 -#include "main.h" +#define APP_NAME "TESTACL" #define GET_CB_FIELD(in, fd, base, lim, dlm) do { \ unsigned long val; \ @@ -80,9 +34,10 @@ #define OPT_RULE_NUM "rulenum" #define OPT_TRACE_NUM "tracenum" #define OPT_TRACE_STEP "tracestep" -#define OPT_SEARCH_SCALAR "scalar" +#define OPT_SEARCH_ALG "alg" #define OPT_BLD_CATEGORIES "bldcat" #define OPT_RUN_CATEGORIES "runcat" +#define OPT_MAX_SIZE "maxsize" #define OPT_ITER_NUM "iter" #define OPT_VERBOSE "verbose" #define OPT_IPV6 "ipv6" @@ -100,10 +55,47 @@ enum { DUMP_MAX }; +struct acl_alg { + const char *name; + enum rte_acl_classify_alg alg; +}; + +static const struct acl_alg acl_alg[] = { + { + .name = "scalar", + .alg = RTE_ACL_CLASSIFY_SCALAR, + }, + { + .name = "sse", + .alg = RTE_ACL_CLASSIFY_SSE, + }, + { + .name = "avx2", + .alg = RTE_ACL_CLASSIFY_AVX2, + }, + { + .name = "neon", + .alg = RTE_ACL_CLASSIFY_NEON, + }, + { + .name = "altivec", + .alg = RTE_ACL_CLASSIFY_ALTIVEC, + }, + { + .name = "avx512x16", + .alg = RTE_ACL_CLASSIFY_AVX512X16, + }, + { + .name = "avx512x32", + .alg = RTE_ACL_CLASSIFY_AVX512X32, + }, +}; + static struct { const char *prgname; const char *rule_file; const char *trace_file; + size_t max_size; uint32_t bld_categories; uint32_t run_categories; uint32_t nb_rules; @@ -112,11 +104,11 @@ static struct { uint32_t trace_sz; uint32_t iter_num; uint32_t verbose; - uint32_t scalar; + uint32_t ipv6; + struct acl_alg alg; uint32_t used_traces; void *traces; struct rte_acl_ctx *acx; - uint32_t ipv6; } config = { .bld_categories = 3, .run_categories = 1, @@ -125,6 +117,10 @@ static struct { .trace_step = TRACE_STEP_DEF, .iter_num = 1, .verbose = DUMP_MAX, + .alg = { + .name = "default", + .alg = RTE_ACL_CLASSIFY_DEFAULT, + }, .ipv6 = 0 }; @@ -154,6 +150,23 @@ enum { NUM_FIELDS_IPV4 }; +/* + * That effectively defines order of IPV4VLAN classifications: + * - PROTO + * - VLAN (TAG and DOMAIN) + * - SRC IP ADDRESS + * - DST IP ADDRESS + * - PORTS (SRC and DST) + */ +enum { + RTE_ACL_IPV4VLAN_PROTO, + RTE_ACL_IPV4VLAN_VLAN, + RTE_ACL_IPV4VLAN_SRC, + RTE_ACL_IPV4VLAN_DST, + RTE_ACL_IPV4VLAN_PORTS, + RTE_ACL_IPV4VLAN_NUM +}; + struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = { { .type = RTE_ACL_FIELD_TYPE_BITMASK, @@ -470,7 +483,7 @@ tracef_init(void) struct ipv6_5tuple *w; sz = config.nb_traces * (config.ipv6 ? sizeof(*w) : sizeof(*v)); - config.traces = rte_zmalloc_socket(name, sz, CACHE_LINE_SIZE, + config.traces = rte_zmalloc_socket(name, sz, RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY); if (config.traces == NULL) rte_exit(EXIT_FAILURE, "Cannot allocate %zu bytes for " @@ -620,7 +633,7 @@ parse_ipv4_net(const char *in, uint32_t *addr, uint32_t *mask_len) GET_CB_FIELD(in, d, 0, UINT8_MAX, '/'); GET_CB_FIELD(in, m, 0, sizeof(uint32_t) * CHAR_BIT, 0); - addr[0] = IPv4(a, b, c, d); + addr[0] = RTE_IPV4(a, b, c, d); mask_len[0] = m; return 0; @@ -731,7 +744,8 @@ add_cb_rules(FILE *f, struct rte_acl_ctx *ctx) return rc; } - v.data.category_mask = LEN2MASK(RTE_ACL_MAX_CATEGORIES); + v.data.category_mask = RTE_LEN2MASK(RTE_ACL_MAX_CATEGORIES, + typeof(v.data.category_mask)); v.data.priority = RTE_ACL_MAX_PRIORITY - n; v.data.userdata = n; @@ -754,6 +768,8 @@ acx_init(void) FILE *f; struct rte_acl_config cfg; + memset(&cfg, 0, sizeof(cfg)); + /* setup ACL build config. */ if (config.ipv6) { cfg.num_fields = RTE_DIM(ipv6_defs); @@ -763,6 +779,7 @@ acx_init(void) memcpy(&cfg.defs, ipv4_defs, sizeof(ipv4_defs)); } cfg.num_categories = config.bld_categories; + cfg.max_size = config.max_size; /* setup ACL creation parameters. */ prm.rule_size = RTE_ACL_RULE_SZ(cfg.num_fields); @@ -772,6 +789,14 @@ acx_init(void) if (config.acx == NULL) rte_exit(rte_errno, "failed to create ACL context\n"); + /* set default classify method for this context. */ + if (config.alg.alg != RTE_ACL_CLASSIFY_DEFAULT) { + ret = rte_acl_set_ctx_classify(config.acx, config.alg.alg); + if (ret != 0) + rte_exit(ret, "failed to setup %s method " + "for ACL context\n", config.alg.name); + } + /* add ACL rules. */ f = fopen(config.rule_file, "r"); if (f == NULL) @@ -780,7 +805,7 @@ acx_init(void) ret = add_cb_rules(f, config.acx); if (ret != 0) - rte_exit(rte_errno, "failed to add rules into ACL context\n"); + rte_exit(ret, "failed to add rules into ACL context\n"); fclose(f); @@ -798,7 +823,7 @@ acx_init(void) } static uint32_t -search_ip5tuples_once(uint32_t categories, uint32_t step, int scalar) +search_ip5tuples_once(uint32_t categories, uint32_t step, const char *alg) { int ret; uint32_t i, j, k, n, r; @@ -815,13 +840,8 @@ search_ip5tuples_once(uint32_t categories, uint32_t step, int scalar) v += config.trace_sz; } - if (scalar != 0) - ret = rte_acl_classify_scalar(config.acx, data, - results, n, categories); - - else - ret = rte_acl_classify(config.acx, data, - results, n, categories); + ret = rte_acl_classify(config.acx, data, results, + n, categories); if (ret != 0) rte_exit(ret, "classify for ipv%c_5tuples returns %d\n", @@ -841,37 +861,42 @@ search_ip5tuples_once(uint32_t categories, uint32_t step, int scalar) dump_verbose(DUMP_SEARCH, stdout, "%s(%u, %u, %s) returns %u\n", __func__, - categories, step, scalar != 0 ? "scalar" : "sse", i); + categories, step, alg, i); return i; } static int -search_ip5tuples(__attribute__((unused)) void *arg) +search_ip5tuples(__rte_unused void *arg) { uint64_t pkt, start, tm; uint32_t i, lcore; + long double st; lcore = rte_lcore_id(); - start = rte_rdtsc(); + start = rte_rdtsc_precise(); pkt = 0; for (i = 0; i != config.iter_num; i++) { pkt += search_ip5tuples_once(config.run_categories, - config.trace_step, config.scalar); + config.trace_step, config.alg.name); } - tm = rte_rdtsc() - start; + tm = rte_rdtsc_precise() - start; + + st = (long double)tm / rte_get_timer_hz(); dump_verbose(DUMP_NONE, stdout, "%s @lcore %u: %" PRIu32 " iterations, %" PRIu64 " pkts, %" - PRIu32 " categories, %" PRIu64 " cycles, %#Lf cycles/pkt\n", - __func__, lcore, i, pkt, config.run_categories, - tm, (long double)tm / pkt); + PRIu32 " categories, %" PRIu64 " cycles (%.2Lf sec), " + "%.2Lf cycles/pkt, %.2Lf pkt/sec\n", + __func__, lcore, i, pkt, + config.run_categories, tm, st, + (pkt == 0) ? 0 : (long double)tm / pkt, pkt / st); return 0; } -static uint32_t -get_uint32_opt(const char *opt, const char *name, uint32_t min, uint32_t max) +static unsigned long +get_ulong_opt(const char *opt, const char *name, size_t min, size_t max) { unsigned long val; char *end; @@ -884,9 +909,41 @@ get_uint32_opt(const char *opt, const char *name, uint32_t min, uint32_t max) return val; } +static void +get_alg_opt(const char *opt, const char *name) +{ + uint32_t i; + + for (i = 0; i != RTE_DIM(acl_alg); i++) { + if (strcmp(opt, acl_alg[i].name) == 0) { + config.alg = acl_alg[i]; + return; + } + } + + rte_exit(-EINVAL, "invalid value: \"%s\" for option: %s\n", + opt, name); +} + static void print_usage(const char *prgname) { + uint32_t i, n, rc; + char buf[PATH_MAX]; + + n = 0; + buf[0] = 0; + + for (i = 0; i < RTE_DIM(acl_alg) - 1; i++) { + rc = snprintf(buf + n, sizeof(buf) - n, "%s|", + acl_alg[i].name); + if (rc > sizeof(buf) - n) + break; + n += rc; + } + + strlcpy(buf + n, acl_alg[i].name, sizeof(buf) - n); + fprintf(stdout, PRINT_USAGE_START "--" OPT_RULE_FILE "=\n" @@ -903,12 +960,16 @@ print_usage(const char *prgname) "= " "should be either 1 or multiple of %zu, " "but not greater then %u]\n" + "[--" OPT_MAX_SIZE + "= " + "leave 0 for default behaviour]\n" "[--" OPT_ITER_NUM "=]\n" "[--" OPT_VERBOSE "=]\n" - "[--" OPT_SEARCH_SCALAR "=]\n" + "[--" OPT_SEARCH_ALG "=%s]\n" "[--" OPT_IPV6 "=]\n", prgname, RTE_ACL_RESULTS_MULTIPLIER, - (uint32_t)RTE_ACL_MAX_CATEGORIES); + (uint32_t)RTE_ACL_MAX_CATEGORIES, + buf); } static void @@ -922,9 +983,11 @@ dump_config(FILE *f) fprintf(f, "%s:%u\n", OPT_TRACE_STEP, config.trace_step); fprintf(f, "%s:%u\n", OPT_BLD_CATEGORIES, config.bld_categories); fprintf(f, "%s:%u\n", OPT_RUN_CATEGORIES, config.run_categories); + fprintf(f, "%s:%zu\n", OPT_MAX_SIZE, config.max_size); fprintf(f, "%s:%u\n", OPT_ITER_NUM, config.iter_num); fprintf(f, "%s:%u\n", OPT_VERBOSE, config.verbose); - fprintf(f, "%s:%u\n", OPT_SEARCH_SCALAR, config.scalar); + fprintf(f, "%s:%u(%s)\n", OPT_SEARCH_ALG, config.alg.alg, + config.alg.name); fprintf(f, "%s:%u\n", OPT_IPV6, config.ipv6); } @@ -947,12 +1010,13 @@ get_input_opts(int argc, char **argv) {OPT_TRACE_FILE, 1, 0, 0}, {OPT_TRACE_NUM, 1, 0, 0}, {OPT_RULE_NUM, 1, 0, 0}, + {OPT_MAX_SIZE, 1, 0, 0}, {OPT_TRACE_STEP, 1, 0, 0}, {OPT_BLD_CATEGORIES, 1, 0, 0}, {OPT_RUN_CATEGORIES, 1, 0, 0}, {OPT_ITER_NUM, 1, 0, 0}, {OPT_VERBOSE, 1, 0, 0}, - {OPT_SEARCH_SCALAR, 0, 0, 0}, + {OPT_SEARCH_ALG, 1, 0, 0}, {OPT_IPV6, 0, 0, 0}, {NULL, 0, 0, 0} }; @@ -971,33 +1035,36 @@ get_input_opts(int argc, char **argv) } else if (strcmp(lgopts[opt_idx].name, OPT_TRACE_FILE) == 0) { config.trace_file = optarg; } else if (strcmp(lgopts[opt_idx].name, OPT_RULE_NUM) == 0) { - config.nb_rules = get_uint32_opt(optarg, + config.nb_rules = get_ulong_opt(optarg, lgopts[opt_idx].name, 1, RTE_ACL_MAX_INDEX + 1); + } else if (strcmp(lgopts[opt_idx].name, OPT_MAX_SIZE) == 0) { + config.max_size = get_ulong_opt(optarg, + lgopts[opt_idx].name, 0, SIZE_MAX); } else if (strcmp(lgopts[opt_idx].name, OPT_TRACE_NUM) == 0) { - config.nb_traces = get_uint32_opt(optarg, + config.nb_traces = get_ulong_opt(optarg, lgopts[opt_idx].name, 1, UINT32_MAX); } else if (strcmp(lgopts[opt_idx].name, OPT_TRACE_STEP) == 0) { - config.trace_step = get_uint32_opt(optarg, + config.trace_step = get_ulong_opt(optarg, lgopts[opt_idx].name, 1, TRACE_STEP_MAX); } else if (strcmp(lgopts[opt_idx].name, OPT_BLD_CATEGORIES) == 0) { - config.bld_categories = get_uint32_opt(optarg, + config.bld_categories = get_ulong_opt(optarg, lgopts[opt_idx].name, 1, RTE_ACL_MAX_CATEGORIES); } else if (strcmp(lgopts[opt_idx].name, OPT_RUN_CATEGORIES) == 0) { - config.run_categories = get_uint32_opt(optarg, + config.run_categories = get_ulong_opt(optarg, lgopts[opt_idx].name, 1, RTE_ACL_MAX_CATEGORIES); } else if (strcmp(lgopts[opt_idx].name, OPT_ITER_NUM) == 0) { - config.iter_num = get_uint32_opt(optarg, - lgopts[opt_idx].name, 1, UINT16_MAX); + config.iter_num = get_ulong_opt(optarg, + lgopts[opt_idx].name, 1, INT32_MAX); } else if (strcmp(lgopts[opt_idx].name, OPT_VERBOSE) == 0) { - config.verbose = get_uint32_opt(optarg, + config.verbose = get_ulong_opt(optarg, lgopts[opt_idx].name, DUMP_NONE, DUMP_MAX); } else if (strcmp(lgopts[opt_idx].name, - OPT_SEARCH_SCALAR) == 0) { - config.scalar = 1; + OPT_SEARCH_ALG) == 0) { + get_alg_opt(optarg, lgopts[opt_idx].name); } else if (strcmp(lgopts[opt_idx].name, OPT_IPV6) == 0) { config.ipv6 = 1; } @@ -1008,7 +1075,7 @@ get_input_opts(int argc, char **argv) } int -MAIN(int argc, char **argv) +main(int argc, char **argv) { int ret; uint32_t lcore; @@ -1031,7 +1098,7 @@ MAIN(int argc, char **argv) if (config.trace_file != NULL) tracef_init(); - RTE_LCORE_FOREACH_SLAVE(lcore) + RTE_LCORE_FOREACH_WORKER(lcore) rte_eal_remote_launch(search_ip5tuples, NULL, lcore); search_ip5tuples(NULL);