X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Fl2fwd-event%2Fmain.c;h=dcc72f3f1eed7b0b2fcde6e8a22e300994b08609;hb=92d55afe0ffa8e98cee454fa2c6f60c6bec81f04;hp=142c00e8f5e214bb088521d08e8bbd0027197fda;hpb=3dd1f9fb32ea81aed8df3f75390f50f3c8715590;p=dpdk.git diff --git a/examples/l2fwd-event/main.c b/examples/l2fwd-event/main.c index 142c00e8f5..dcc72f3f1e 100644 --- a/examples/l2fwd-event/main.c +++ b/examples/l2fwd-event/main.c @@ -2,6 +2,8 @@ * Copyright(C) 2019 Marvell International Ltd. */ +#include + #include "l2fwd_event.h" #include "l2fwd_poll.h" @@ -22,7 +24,12 @@ l2fwd_event_usage(const char *prgname) " Default mode = eventdev\n" " --eventq-sched: Event queue schedule type, ordered, atomic or parallel.\n" " Default: atomic\n" - " Valid only if --mode=eventdev\n\n", + " Valid only if --mode=eventdev\n" + " --event-vector: Enable event vectorization.\n" + " --event-vector-size: Max vector size if event vectorization is enabled.\n" + " --event-vector-tmo: Max timeout to form vector in nanoseconds if event vectorization is enabled\n" + " --config: Configure forwarding port pair mapping\n" + " Default: alternate port pairs\n\n", prgname); } @@ -35,10 +42,7 @@ l2fwd_event_parse_portmask(const char *portmask) /* parse hexadecimal string */ pm = strtoul(portmask, &end, 16); if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0')) - return -1; - - if (pm == 0) - return -1; + return 0; return pm; } @@ -99,6 +103,70 @@ l2fwd_event_parse_eventq_sched(const char *optarg, rsrc->sched_type = RTE_SCHED_TYPE_PARALLEL; } +static int +l2fwd_parse_port_pair_config(const char *q_arg, struct l2fwd_resources *rsrc) +{ + enum fieldnames { + FLD_PORT1 = 0, + FLD_PORT2, + _NUM_FLD + }; + const char *p, *p0 = q_arg; + uint16_t int_fld[_NUM_FLD]; + char *str_fld[_NUM_FLD]; + uint16_t port_pair = 0; + unsigned int size; + char s[256]; + char *end; + int i; + + while ((p = strchr(p0, '(')) != NULL) { + ++p; + p0 = strchr(p, ')'); + if (p0 == NULL) + return -1; + + size = p0 - p; + if (size >= sizeof(s)) + return -1; + + memcpy(s, p, size); + if (rte_strsplit(s, sizeof(s), str_fld, + _NUM_FLD, ',') != _NUM_FLD) + return -1; + + for (i = 0; i < _NUM_FLD; i++) { + errno = 0; + int_fld[i] = strtoul(str_fld[i], &end, 0); + if (errno != 0 || end == str_fld[i] || + int_fld[i] >= RTE_MAX_ETHPORTS) + return -1; + } + + if (port_pair >= RTE_MAX_ETHPORTS / 2) { + printf("exceeded max number of port pair params: Current %d Max = %d\n", + port_pair, RTE_MAX_ETHPORTS / 2); + return -1; + } + + if ((rsrc->dst_ports[int_fld[FLD_PORT1]] != UINT32_MAX) || + (rsrc->dst_ports[int_fld[FLD_PORT2]] != UINT32_MAX)) { + printf("Duplicate port pair (%d,%d) config\n", + int_fld[FLD_PORT1], int_fld[FLD_PORT2]); + return -1; + } + + rsrc->dst_ports[int_fld[FLD_PORT1]] = int_fld[FLD_PORT2]; + rsrc->dst_ports[int_fld[FLD_PORT2]] = int_fld[FLD_PORT1]; + + port_pair++; + } + + rsrc->port_pairs = true; + + return 0; +} + static const char short_options[] = "p:" /* portmask */ "q:" /* number of queues */ @@ -109,6 +177,10 @@ static const char short_options[] = #define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating" #define CMD_LINE_OPT_MODE "mode" #define CMD_LINE_OPT_EVENTQ_SCHED "eventq-sched" +#define CMD_LINE_OPT_PORT_PAIR_CONF "config" +#define CMD_LINE_OPT_ENABLE_VECTOR "event-vector" +#define CMD_LINE_OPT_VECTOR_SIZE "event-vector-size" +#define CMD_LINE_OPT_VECTOR_TMO_NS "event-vector-tmo" enum { /* long options mapped to a short option */ @@ -119,12 +191,15 @@ enum { CMD_LINE_OPT_MIN_NUM = 256, CMD_LINE_OPT_MODE_NUM, CMD_LINE_OPT_EVENTQ_SCHED_NUM, + CMD_LINE_OPT_PORT_PAIR_CONF_NUM, + CMD_LINE_OPT_ENABLE_VECTOR_NUM, + CMD_LINE_OPT_VECTOR_SIZE_NUM, + CMD_LINE_OPT_VECTOR_TMO_NS_NUM }; /* Parse the argument given in the command line of the application */ static int -l2fwd_event_parse_args(int argc, char **argv, - struct l2fwd_resources *rsrc) +l2fwd_event_parse_args(int argc, char **argv, struct l2fwd_resources *rsrc) { int mac_updating = 1; struct option lgopts[] = { @@ -134,12 +209,25 @@ l2fwd_event_parse_args(int argc, char **argv, CMD_LINE_OPT_MODE_NUM}, { CMD_LINE_OPT_EVENTQ_SCHED, required_argument, NULL, CMD_LINE_OPT_EVENTQ_SCHED_NUM}, + { CMD_LINE_OPT_PORT_PAIR_CONF, required_argument, NULL, + CMD_LINE_OPT_PORT_PAIR_CONF_NUM}, + {CMD_LINE_OPT_ENABLE_VECTOR, no_argument, NULL, + CMD_LINE_OPT_ENABLE_VECTOR_NUM}, + {CMD_LINE_OPT_VECTOR_SIZE, required_argument, NULL, + CMD_LINE_OPT_VECTOR_SIZE_NUM}, + {CMD_LINE_OPT_VECTOR_TMO_NS, required_argument, NULL, + CMD_LINE_OPT_VECTOR_TMO_NS_NUM}, {NULL, 0, 0, 0} }; int opt, ret, timer_secs; char *prgname = argv[0]; - char **argvopt; + uint16_t port_id; int option_index; + char **argvopt; + + /* Reset l2fwd_dst_ports. 8< */ + for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) + rsrc->dst_ports[port_id] = UINT32_MAX; argvopt = argv; while ((opt = getopt_long(argc, argvopt, short_options, @@ -189,6 +277,25 @@ l2fwd_event_parse_args(int argc, char **argv, l2fwd_event_parse_eventq_sched(optarg, rsrc); break; + case CMD_LINE_OPT_PORT_PAIR_CONF_NUM: + ret = l2fwd_parse_port_pair_config(optarg, rsrc); + if (ret) { + printf("Invalid port pair config\n"); + l2fwd_event_usage(prgname); + return -1; + } + break; + case CMD_LINE_OPT_ENABLE_VECTOR_NUM: + printf("event vectorization is enabled\n"); + rsrc->evt_vec.enabled = 1; + break; + case CMD_LINE_OPT_VECTOR_SIZE_NUM: + rsrc->evt_vec.size = strtol(optarg, NULL, 10); + break; + case CMD_LINE_OPT_VECTOR_TMO_NS_NUM: + rsrc->evt_vec.timeout_ns = strtoull(optarg, NULL, 10); + break; + /* long options */ case 0: break; @@ -201,12 +308,71 @@ l2fwd_event_parse_args(int argc, char **argv, rsrc->mac_updating = mac_updating; + if (rsrc->evt_vec.enabled && !rsrc->evt_vec.size) { + rsrc->evt_vec.size = VECTOR_SIZE_DEFAULT; + printf("vector size set to default (%" PRIu16 ")\n", + rsrc->evt_vec.size); + } + + if (rsrc->evt_vec.enabled && !rsrc->evt_vec.timeout_ns) { + rsrc->evt_vec.timeout_ns = VECTOR_TMO_NS_DEFAULT; + printf("vector timeout set to default (%" PRIu64 " ns)\n", + rsrc->evt_vec.timeout_ns); + } + if (optind >= 0) argv[optind-1] = prgname; ret = optind-1; optind = 1; /* reset getopt lib */ return ret; + /* >8 End of reset l2fwd_dst_ports. */ +} + +/* + * Check port pair config with enabled port mask, + * and for valid port pair combinations. + */ +static int +check_port_pair_config(struct l2fwd_resources *rsrc) +{ + uint32_t port_pair_mask = 0; + uint32_t portid; + uint16_t index; + + for (index = 0; index < rte_eth_dev_count_avail(); index++) { + if ((rsrc->enabled_port_mask & (1 << index)) == 0 || + (port_pair_mask & (1 << index))) + continue; + + portid = rsrc->dst_ports[index]; + if (portid == UINT32_MAX) { + printf("port %u is enabled in but no valid port pair\n", + index); + return -1; + } + + if (!rte_eth_dev_is_valid_port(index)) { + printf("port %u is not valid\n", index); + return -1; + } + + if (!rte_eth_dev_is_valid_port(portid)) { + printf("port %u is not valid\n", portid); + return -1; + } + + if (port_pair_mask & (1 << portid) && + rsrc->dst_ports[portid] != index) { + printf("port %u is used in other port pairs\n", portid); + return -1; + } + + port_pair_mask |= (1 << portid); + port_pair_mask |= (1 << index); + } + + return 0; } static int @@ -234,6 +400,8 @@ check_all_ports_link_status(struct l2fwd_resources *rsrc, uint16_t port_id; uint8_t count, all_ports_up, print_flag = 0; struct rte_eth_link link; + int ret; + char link_status_text[RTE_ETH_LINK_MAX_STR_LEN]; printf("\nChecking link status..."); fflush(stdout); @@ -247,21 +415,24 @@ check_all_ports_link_status(struct l2fwd_resources *rsrc, if ((port_mask & (1 << port_id)) == 0) continue; memset(&link, 0, sizeof(link)); - rte_eth_link_get_nowait(port_id, &link); + ret = rte_eth_link_get_nowait(port_id, &link); + if (ret < 0) { + all_ports_up = 0; + if (print_flag == 1) + printf("Port %u link get failed: %s\n", + port_id, rte_strerror(-ret)); + continue; + } /* print link status if flag set */ if (print_flag == 1) { - if (link.link_status) - printf( - "Port%d Link Up. Speed %u Mbps - %s\n", - port_id, link.link_speed, - (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? - ("full-duplex") : ("half-duplex\n")); - else - printf("Port %d Link Down\n", port_id); + rte_eth_link_to_str(link_status_text, + sizeof(link_status_text), &link); + printf("Port %d %s\n", port_id, + link_status_text); continue; } /* clear all_ports_up flag if any link down */ - if (link.link_status == ETH_LINK_DOWN) { + if (link.link_status == RTE_ETH_LINK_DOWN) { all_ports_up = 0; break; } @@ -377,6 +548,8 @@ print_stats(struct l2fwd_resources *rsrc) total_packets_rx, total_packets_dropped); printf("\n====================================================\n"); + + fflush(stdout); } static void @@ -428,7 +601,7 @@ main(int argc, char **argv) uint16_t nb_ports; int i, ret; - /* init EAL */ + /* Init EAL. 8< */ ret = rte_eal_init(argc, argv); if (ret < 0) rte_panic("Invalid EAL arguments\n"); @@ -444,6 +617,7 @@ main(int argc, char **argv) ret = l2fwd_event_parse_args(argc, argv, rsrc); if (ret < 0) rte_panic("Invalid L2FWD arguments\n"); + /* >8 End of init EAL. */ printf("MAC updating %s\n", rsrc->mac_updating ? "enabled" : "disabled"); @@ -457,31 +631,33 @@ main(int argc, char **argv) rte_panic("Invalid portmask; possible (0x%x)\n", (1 << nb_ports) - 1); - /* reset l2fwd_dst_ports */ - for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) - rsrc->dst_ports[port_id] = 0; - last_port = 0; + if (!rsrc->port_pairs) { + last_port = 0; + /* + * Each logical core is assigned a dedicated TX queue on each + * port. + */ + RTE_ETH_FOREACH_DEV(port_id) { + /* skip ports that are not enabled */ + if ((rsrc->enabled_port_mask & (1 << port_id)) == 0) + continue; - /* - * Each logical core is assigned a dedicated TX queue on each port. - */ - RTE_ETH_FOREACH_DEV(port_id) { - /* skip ports that are not enabled */ - if ((rsrc->enabled_port_mask & (1 << port_id)) == 0) - continue; + if (nb_ports_in_mask % 2) { + rsrc->dst_ports[port_id] = last_port; + rsrc->dst_ports[last_port] = port_id; + } else { + last_port = port_id; + } + nb_ports_in_mask++; + } if (nb_ports_in_mask % 2) { - rsrc->dst_ports[port_id] = last_port; - rsrc->dst_ports[last_port] = port_id; - } else { - last_port = port_id; + printf("Notice: odd number of ports in portmask.\n"); + rsrc->dst_ports[last_port] = last_port; } - - nb_ports_in_mask++; - } - if (nb_ports_in_mask % 2) { - printf("Notice: odd number of ports in portmask.\n"); - rsrc->dst_ports[last_port] = last_port; + } else { + if (check_port_pair_config(rsrc) < 0) + rte_panic("Invalid port pair config\n"); } nb_mbufs = RTE_MAX(nb_ports * (RTE_TEST_RX_DESC_DEFAULT + @@ -489,12 +665,24 @@ main(int argc, char **argv) MAX_PKT_BURST + rte_lcore_count() * MEMPOOL_CACHE_SIZE), 8192U); - /* create the mbuf pool */ + /* Create the mbuf pool. 8< */ rsrc->pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", nb_mbufs, MEMPOOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); if (rsrc->pktmbuf_pool == NULL) rte_panic("Cannot init mbuf pool\n"); + /* >8 End of creation of mbuf pool. */ + + if (rsrc->evt_vec.enabled) { + unsigned int nb_vec, vec_size; + + vec_size = rsrc->evt_vec.size; + nb_vec = (nb_mbufs + vec_size - 1) / vec_size; + rsrc->evt_vec_pool = rte_event_vector_pool_create( + "vector_pool", nb_vec, 0, vec_size, rte_socket_id()); + if (rsrc->evt_vec_pool == NULL) + rte_panic("Cannot init event vector pool\n"); + } nb_ports_available = l2fwd_event_init_ports(rsrc); if (!nb_ports_available) @@ -530,7 +718,7 @@ main(int argc, char **argv) /* launch per-lcore init on every lcore */ rte_eal_mp_remote_launch(l2fwd_launch_one_lcore, rsrc, - SKIP_MASTER); + SKIP_MAIN); l2fwd_event_print_stats(rsrc); if (rsrc->event_mode) { struct l2fwd_event_resources *evt_rsrc = @@ -546,7 +734,10 @@ main(int argc, char **argv) if ((rsrc->enabled_port_mask & (1 << port_id)) == 0) continue; - rte_eth_dev_stop(port_id); + ret = rte_eth_dev_stop(port_id); + if (ret < 0) + printf("rte_eth_dev_stop:err=%d, port=%u\n", + ret, port_id); } rte_eal_mp_wait_lcore(); @@ -568,11 +759,17 @@ main(int argc, char **argv) (1 << port_id)) == 0) continue; printf("Closing port %d...", port_id); - rte_eth_dev_stop(port_id); + ret = rte_eth_dev_stop(port_id); + if (ret < 0) + printf("rte_eth_dev_stop:err=%d, port=%u\n", + ret, port_id); rte_eth_dev_close(port_id); printf(" Done\n"); } } + + /* clean up the EAL */ + rte_eal_cleanup(); printf("Bye...\n"); return 0;