X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-acl%2Fmain.c;h=06e3847ab93879e8cbd615feb24478dc57508ba3;hb=23f7ec1d9b7ccfcfb9b9f67d33cf6cbf7f5034d3;hp=9d4dce61b068f80297be2b892560864b7627ebad;hpb=503f9e8b42562b923e73e908be6ba69964f1f1e7;p=dpdk.git diff --git a/app/test-acl/main.c b/app/test-acl/main.c index 9d4dce61b0..06e3847ab9 100644 --- a/app/test-acl/main.c +++ b/app/test-acl/main.c @@ -1,66 +1,18 @@ -/*- - * 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" - -#endif /*RTE_LIBRTE_ACL_STANDALONE */ +#define PRINT_USAGE_START "%s [EAL options] --\n" #define RTE_LOGTYPE_TESTACL RTE_LOGTYPE_USER1 @@ -82,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" @@ -95,6 +48,8 @@ #define RULE_NUM 0x10000 +#define COMMENT_LEAD_CHAR '#' + enum { DUMP_NONE, DUMP_SEARCH, @@ -102,10 +57,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; @@ -114,11 +106,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, @@ -127,6 +119,10 @@ static struct { .trace_step = TRACE_STEP_DEF, .iter_num = 1, .verbose = DUMP_MAX, + .alg = { + .name = "default", + .alg = RTE_ACL_CLASSIFY_DEFAULT, + }, .ipv6 = 0 }; @@ -156,6 +152,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, @@ -373,8 +386,8 @@ parse_cb_ipv4_trace(char *str, struct ipv4_5tuple *v) } /* - * Parses IPV6 address, exepcts the following format: - * XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX (where X - is a hexedecimal digit). + * Parse IPv6 address, expects the following format: + * XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX (where X is a hexadecimal digit). */ static int parse_ipv6_addr(const char *in, const char **end, uint32_t v[IPV6_ADDR_U32], @@ -461,18 +474,33 @@ parse_cb_ipv6_trace(char *str, struct ipv6_5tuple *v) return 0; } +/* Bypass comment and empty lines */ +static int +skip_line(const char *buf) +{ + uint32_t i; + + for (i = 0; isspace(buf[i]) != 0; i++) + ; + + if (buf[i] == 0 || buf[i] == COMMENT_LEAD_CHAR) + return 1; + + return 0; +} + static void tracef_init(void) { static const char name[] = APP_NAME; FILE *f; size_t sz; - uint32_t n; + uint32_t i, k, n; struct ipv4_5tuple *v; 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 " @@ -486,27 +514,36 @@ tracef_init(void) v = config.traces; w = config.traces; - for (n = 0; n != config.nb_traces; n++) { + k = 0; + n = 0; + for (i = 0; n != config.nb_traces; i++) { if (fgets(line, sizeof(line), f) == NULL) break; + if (skip_line(line) != 0) { + k++; + continue; + } + + n = i - k; + if (config.ipv6) { if (parse_cb_ipv6_trace(line, w + n) != 0) rte_exit(EXIT_FAILURE, "%s: failed to parse ipv6 trace " "record at line %u\n", - config.trace_file, n + 1); + config.trace_file, i + 1); } else { if (parse_cb_ipv4_trace(line, v + n) != 0) rte_exit(EXIT_FAILURE, "%s: failed to parse ipv4 trace " "record at line %u\n", - config.trace_file, n + 1); + config.trace_file, i + 1); } } - config.used_traces = n; + config.used_traces = i - k; fclose(f); } @@ -622,7 +659,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; @@ -716,24 +753,32 @@ static int add_cb_rules(FILE *f, struct rte_acl_ctx *ctx) { int rc; - uint32_t n; + uint32_t i, k, n; struct acl_rule v; parse_5tuple parser; memset(&v, 0, sizeof(v)); parser = (config.ipv6 != 0) ? parse_cb_ipv6_rule : parse_cb_ipv4_rule; - for (n = 1; fgets(line, sizeof(line), f) != NULL; n++) { + k = 0; + for (i = 1; fgets(line, sizeof(line), f) != NULL; i++) { + if (skip_line(line) != 0) { + k++; + continue; + } + + n = i - k; rc = parser(line, &v); if (rc != 0) { RTE_LOG(ERR, TESTACL, "line %u: parse_cb_ipv4vlan_rule" " failed, error code: %d (%s)\n", - n, rc, strerror(-rc)); + i, rc, strerror(-rc)); 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; @@ -741,7 +786,7 @@ add_cb_rules(FILE *f, struct rte_acl_ctx *ctx) if (rc != 0) { RTE_LOG(ERR, TESTACL, "line %u: failed to add rules " "into ACL context, error code: %d (%s)\n", - n, rc, strerror(-rc)); + i, rc, strerror(-rc)); return rc; } } @@ -756,6 +801,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); @@ -765,6 +812,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); @@ -774,13 +822,12 @@ acx_init(void) if (config.acx == NULL) rte_exit(rte_errno, "failed to create ACL context\n"); - /* set default classify method to scalar for this context. */ - if (config.scalar) { - ret = rte_acl_set_ctx_classify(config.acx, - RTE_ACL_CLASSIFY_SCALAR); + /* 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 classify method " - "for ACL context\n"); + rte_exit(ret, "failed to setup %s method " + "for ACL context\n", config.alg.name); } /* add ACL rules. */ @@ -809,7 +856,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; @@ -847,37 +894,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; @@ -890,9 +942,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" @@ -909,12 +993,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 @@ -928,9 +1016,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); } @@ -953,12 +1043,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} }; @@ -977,33 +1068,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; } @@ -1037,7 +1131,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);