From patchwork Tue Mar 31 12:53:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavan Nikhilesh Bhagavatula X-Patchwork-Id: 67482 X-Patchwork-Delegate: jerinj@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 421C3A0562; Tue, 31 Mar 2020 14:53:28 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 207121C02A; Tue, 31 Mar 2020 14:53:28 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by dpdk.org (Postfix) with ESMTP id E89551BFD9 for ; Tue, 31 Mar 2020 14:53:25 +0200 (CEST) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 02VCoTSl028044; Tue, 31 Mar 2020 05:53:25 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0818; bh=psrb0dUJYwdtCJ4i2oeDzJyv3ZydmAB1mTcEYUekVT0=; b=mmZ2kngQox8LMPTBrLheEQ9jhU3ZB7BhBVov2BES/i8MNyZJB84L8T+tpEkU/awb+GHq HCkXq0+4yQpQYXz1zYtgX9/Bqx1g5aPwEhEWyIq5s1f1Z9YP9VYuYGI5nTkRoNbYW1O5 24G6p855YqAWBQOHHxNXHUMb4T/fnQcgInfrxMgyZZBBid/8B06FhQD89AXmZTSY5lrg 12HTQZoaGSED8tHjre0WMJRnETuRmHHz9Wcv9+nQRdU1wqmTWgDg3vlHk5FxysYM7Pyu ubHURQwAmJiwNUxBq5tTx1l3g1rjdjtYsIAQHXBzlQ8gAYoh2vctiaTeaGhIiBDraJEF ew== Received: from sc-exch01.marvell.com ([199.233.58.181]) by mx0b-0016f401.pphosted.com with ESMTP id 30263kjnpa-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Tue, 31 Mar 2020 05:53:25 -0700 Received: from SC-EXCH01.marvell.com (10.93.176.81) by SC-EXCH01.marvell.com (10.93.176.81) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 31 Mar 2020 05:53:22 -0700 Received: from maili.marvell.com (10.93.176.43) by SC-EXCH01.marvell.com (10.93.176.81) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 31 Mar 2020 05:53:22 -0700 Received: from BG-LT7430.marvell.com (BG-LT7430.marvell.com [10.28.163.117]) by maili.marvell.com (Postfix) with ESMTP id DD8543F7044; Tue, 31 Mar 2020 05:53:17 -0700 (PDT) From: To: , , Marko Kovacevic , Ori Kam , Bruce Richardson , Radu Nicolau , "Akhil Goyal" , Tomasz Kantecki , Sunil Kumar Kori , Pavan Nikhilesh , John McNamara CC: Date: Tue, 31 Mar 2020 18:23:15 +0530 Message-ID: <20200331125315.2521-1-pbhagavatula@marvell.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200326064216.5676-1-pbhagavatula@marvell.com> References: <20200326064216.5676-1-pbhagavatula@marvell.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.676 definitions=2020-03-31_04:2020-03-31, 2020-03-31 signatures=0 Subject: [dpdk-dev] [PATCH v3] examples/l2fwd-event: add option to configure port pairs X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Pavan Nikhilesh Current l2fwd-event application statically configures adjacent ports as destination ports for forwarding the traffic. Add a config option to pass the forwarding port pair mapping which allows the user to configure forwarding port mapping. If no config argument is specified, destination port map is not changed and traffic gets forwarded with existing mapping. To align port/queue configuration of each lcore with destination port map, port/queue configuration of each lcore gets modified when config option is specificed. Ex: ./l2fwd-event -c 0xff -- -p 0x3f -q 2 --config="(0,3)(1,4)(2,5)" With above config option, traffic received from portid = 0 gets forwarded to port = 3 and vice versa, similarly traffic gets forwarded on other port pairs (1,4) and (2,5). Signed-off-by: Pavan Nikhilesh Reviewed-by: Andrzej Ostruszka --- v3 Changes: - Use simple memcpy instead of snprintf. (Andrzej) - Skip redudant loop iterations. (Andrzej) - Use RTE_MAX_ETHPORTS instead of hardcoding to 255. (Andrzej) v2 Changes: - Fix minor formatting error. - Change uint8_t to bool. doc/guides/sample_app_ug/l2_forward_event.rst | 2 + examples/l2fwd-event/l2fwd_common.h | 1 + examples/l2fwd-event/main.c | 183 +++++++++++++++--- 3 files changed, 161 insertions(+), 25 deletions(-) -- 2.17.1 diff --git a/doc/guides/sample_app_ug/l2_forward_event.rst b/doc/guides/sample_app_ug/l2_forward_event.rst index 8c519c304..8bdf352c4 100644 --- a/doc/guides/sample_app_ug/l2_forward_event.rst +++ b/doc/guides/sample_app_ug/l2_forward_event.rst @@ -66,6 +66,8 @@ where, * --eventq-sched=SCHED_MODE: Event queue schedule mode, Ordered, Atomic or Parallel. Atomic by default. +* --config: Configure forwarding port pair mapping. Alternate port pairs by default. + Sample usage commands are given below to run the application into different mode: Poll mode with 4 lcores, 16 ports and 8 RX queues per lcore and MAC address updating enabled, diff --git a/examples/l2fwd-event/l2fwd_common.h b/examples/l2fwd-event/l2fwd_common.h index 7e33ee749..939221d45 100644 --- a/examples/l2fwd-event/l2fwd_common.h +++ b/examples/l2fwd-event/l2fwd_common.h @@ -69,6 +69,7 @@ struct l2fwd_resources { uint8_t sched_type; uint8_t mac_updating; uint8_t rx_queue_per_lcore; + bool port_pairs; uint16_t nb_rxd; uint16_t nb_txd; uint32_t enabled_port_mask; diff --git a/examples/l2fwd-event/main.c b/examples/l2fwd-event/main.c index 89a6bb9a4..9cc29d732 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,9 @@ 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" + " --config: Configure forwarding port pair mapping\n" + " Default: alternate port pairs\n\n", prgname); } @@ -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,7 @@ 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" enum { /* long options mapped to a short option */ @@ -119,12 +188,12 @@ 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, }; /* 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 +203,19 @@ 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}, {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 */ + 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 +265,15 @@ 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; + /* long options */ case 0: break; @@ -209,6 +294,52 @@ l2fwd_event_parse_args(int argc, char **argv, return ret; } +/* + * 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 l2fwd_launch_one_lcore(void *args) { @@ -465,31 +596,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 +