From mboxrd@z Thu Jan 1 00:00:00 1970 From: Wei Dai Subject: [PATCH v3 3/3] app/testpmd: add commands to test new Tx offload API Date: Sat, 17 Mar 2018 21:31:50 +0800 Message-ID: <1521293510-31421-4-git-send-email-wei.dai@intel.com> References: <1520923325-40400-1-git-send-email-wei.dai@intel.com> <1521293510-31421-1-git-send-email-wei.dai@intel.com> Cc: dev@dpdk.org, Wei Dai To: wenzhuo.lu@intel.com, jingjing.wu@intel.com Return-path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id 7FD2D5F5D for ; Sat, 17 Mar 2018 14:49:48 +0100 (CET) In-Reply-To: <1521293510-31421-1-git-send-email-wei.dai@intel.com> List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add following testpmd run-time commands to support test of new Tx offload API: tx_offload get capability tx_offload get configuration tx_offload enable|disable per_port tx_offload enable|disable per_queue Above last 2 commands should be run when the port is stopped. And can be one of "vlan_insert", "udp_cksum", ... Signed-off-by: Wei Dai --- app/test-pmd/cmdline.c | 372 +++++++++++++++++++++++++++++++++++++++++++++++++ app/test-pmd/testpmd.c | 15 +- app/test-pmd/testpmd.h | 1 + 3 files changed, 386 insertions(+), 2 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 0475064..a142517 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -16359,6 +16359,374 @@ cmdline_parse_inst_t cmd_config_per_queue_rx_offload = { } }; +/* Get Tx offloads capability */ +struct cmd_tx_offload_get_capa_result { + cmdline_fixed_string_t tx_offload; + cmdline_fixed_string_t get; + cmdline_fixed_string_t capability; + portid_t port_id; +}; + +cmdline_parse_token_string_t cmd_tx_offload_get_capa_tx_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_tx_offload_get_capa_result, + tx_offload, "tx_offload"); +cmdline_parse_token_string_t cmd_tx_offload_get_capa_get = + TOKEN_STRING_INITIALIZER + (struct cmd_tx_offload_get_capa_result, + get, "get"); +cmdline_parse_token_string_t cmd_tx_offload_get_capa_capability = + TOKEN_STRING_INITIALIZER + (struct cmd_tx_offload_get_capa_result, + capability, "capability"); +cmdline_parse_token_num_t cmd_tx_offload_get_capa_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_tx_offload_get_capa_result, + port_id, UINT16); + +static void +print_tx_offloads(uint64_t offloads) +{ + uint64_t single_offload; + int begin; + int end; + int bit; + + if (offloads == 0) + return; + + begin = __builtin_ctzll(offloads); + end = sizeof(offloads) * CHAR_BIT - __builtin_clzll(offloads); + + single_offload = 1 << begin; + for (bit = begin; bit < end; bit++) { + if (offloads & single_offload) + printf(" %s", + rte_eth_dev_tx_offload_name(single_offload)); + single_offload <<= 1; + } +} + +static void +cmd_tx_offload_get_capa_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_tx_offload_get_capa_result *res = parsed_result; + struct rte_eth_dev_info dev_info; + portid_t port_id = res->port_id; + uint64_t queue_offloads; + uint64_t port_offloads; + + rte_eth_dev_info_get(port_id, &dev_info); + queue_offloads = dev_info.tx_queue_offload_capa; + port_offloads = dev_info.tx_offload_capa ^ queue_offloads; + + printf("Tx Offloading Capabilities of port %d :\n", port_id); + printf(" Per Queue :"); + print_tx_offloads(queue_offloads); + printf("\n"); + printf(" Per Port :"); + print_tx_offloads(port_offloads); + printf("\n\n"); +} + +cmdline_parse_inst_t cmd_tx_offload_get_capa = { + .f = cmd_tx_offload_get_capa_parsed, + .data = NULL, + .help_str = "tx_offload get capability ", + .tokens = { + (void *)&cmd_tx_offload_get_capa_tx_offload, + (void *)&cmd_tx_offload_get_capa_get, + (void *)&cmd_tx_offload_get_capa_capability, + (void *)&cmd_tx_offload_get_capa_port_id, + NULL, + } +}; + +/* Get Tx offloads configuration */ +struct cmd_tx_offload_get_configuration_result { + cmdline_fixed_string_t tx_offload; + cmdline_fixed_string_t get; + cmdline_fixed_string_t configuration; + portid_t port_id; +}; + +cmdline_parse_token_string_t cmd_tx_offload_get_configuration_tx_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_tx_offload_get_configuration_result, + tx_offload, "tx_offload"); +cmdline_parse_token_string_t cmd_tx_offload_get_configuration_get = + TOKEN_STRING_INITIALIZER + (struct cmd_tx_offload_get_configuration_result, + get, "get"); +cmdline_parse_token_string_t cmd_tx_offload_get_configuration_configuration = + TOKEN_STRING_INITIALIZER + (struct cmd_tx_offload_get_configuration_result, + configuration, "configuration"); +cmdline_parse_token_num_t cmd_tx_offload_get_configuration_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_tx_offload_get_configuration_result, + port_id, UINT16); + +static void +cmd_tx_offload_get_configuration_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_tx_offload_get_configuration_result *res = parsed_result; + struct rte_eth_dev_info dev_info; + portid_t port_id = res->port_id; + struct rte_port *port = &ports[port_id]; + uint64_t port_offloads; + uint64_t queue_offloads; + uint16_t nb_tx_queues; + int q; + + printf("Tx Offloading Configuration of port %d :\n", port_id); + + port_offloads = port->dev_conf.txmode.offloads; + printf(" Port :"); + print_tx_offloads(port_offloads); + printf("\n"); + + rte_eth_dev_info_get(port_id, &dev_info); + nb_tx_queues = dev_info.nb_tx_queues; + for (q = 0; q < nb_tx_queues; q++) { + queue_offloads = port->tx_offloads[q]; + printf(" Queue[%2d] :", q); + print_tx_offloads(queue_offloads); + printf("\n"); + } + printf("\n"); +} + +cmdline_parse_inst_t cmd_tx_offload_get_configuration = { + .f = cmd_tx_offload_get_configuration_parsed, + .data = NULL, + .help_str = "tx_offload get configuration ", + .tokens = { + (void *)&cmd_tx_offload_get_configuration_tx_offload, + (void *)&cmd_tx_offload_get_configuration_get, + (void *)&cmd_tx_offload_get_configuration_configuration, + (void *)&cmd_tx_offload_get_configuration_port_id, + NULL, + } +}; + +/* Enable/Disable a per port offloading */ +struct cmd_config_per_port_tx_offload_result { + cmdline_fixed_string_t tx_offload; + cmdline_fixed_string_t en_dis; + cmdline_fixed_string_t per_port; + cmdline_fixed_string_t offload; + portid_t port_id; +}; + +cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_tx_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_port_tx_offload_result, + tx_offload, "tx_offload"); +cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_en_dis = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_port_tx_offload_result, + en_dis, "enable#disable"); +cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_per_port = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_port_tx_offload_result, + per_port, "per_port"); +cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_port_tx_offload_result, + offload, "vlan_insert#ipv4_cksum#udp_cksum#udp_cksum#" + "sctp_cksum#tcp_tso#udp_tso#outer_ipv4_cksum#" + "qinq_insert#vxlan_tnl_tso#gre_tnl_tso#" + "ipip_tnl_tso#geneve_tnl_tso#macsec_insert#" + "mt_lockfree#multi_segs#fast_free#security"); +cmdline_parse_token_num_t cmd_config_per_port_tx_offload_result_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_config_per_port_tx_offload_result, + port_id, UINT16); + +static int +config_tx_offload(const char *name, uint64_t *offload, int on) +{ + uint64_t single_offload; + const char *single_name; + int found = 0; + enum rte_eth_tx_offload_type type; + + single_offload = 1; + for (type = ETH_TX_OFFLOAD_FIRST_FEATURE; + type < ETH_TX_OFFLOAD_TOTAL_NUM; type++) { + single_name = rte_eth_dev_tx_offload_name(single_offload); + if (!strcasecmp(single_name, name)) { + found = 1; + break; + } else if (!strcasecmp(single_name, "UNKNOWN")) + break; + else if (single_name == NULL) + break; + single_offload <<= 1; + } + + if (found) { + if (on) + *offload |= single_offload; + else + *offload &= ~single_offload; + return 0; + } + + return -1; +} + +static void +cmd_config_per_port_tx_offload_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_per_port_tx_offload_result *res = parsed_result; + portid_t port_id = res->port_id; + struct rte_port *port = &ports[port_id]; + int on; + + if (port->port_status != RTE_PORT_STOPPED) { + printf("Error: Can't config offload when Port %d " + "is not stopped\n", port_id); + return; + } + + if (!strcmp(res->en_dis, "enable")) + on = 1; + else + on = 0; + + if (config_tx_offload(res->offload, + &port->dev_conf.txmode.offloads, on)) { + printf("Unknown offload name: %s", res->offload); + } +} + +cmdline_parse_inst_t cmd_config_per_port_tx_offload = { + .f = cmd_config_per_port_tx_offload_parsed, + .data = NULL, + .help_str = "tx_offload enable|disable per_port " + "vlan_insert|ipv4_cksum|udp_cksum|udp_cksum|" + "sctp_cksum|tcp_tso|udp_tso|outer_ipv4_cksum|" + "qinq_insert|vxlan_tnl_tso|gre_tnl_tso|" + "ipip_tnl_tso|geneve_tnl_tso|macsec_insert|" + "mt_lockfree|multi_segs|fast_free|security " + "", + .tokens = { + (void *)&cmd_config_per_port_tx_offload_result_tx_offload, + (void *)&cmd_config_per_port_tx_offload_result_en_dis, + (void *)&cmd_config_per_port_tx_offload_result_per_port, + (void *)&cmd_config_per_port_tx_offload_result_offload, + (void *)&cmd_config_per_port_tx_offload_result_port_id, + NULL, + } +}; + +/* Enable/Disable a per queue offloading */ +struct cmd_config_per_queue_tx_offload_result { + cmdline_fixed_string_t tx_offload; + cmdline_fixed_string_t en_dis; + cmdline_fixed_string_t per_queue; + cmdline_fixed_string_t offload; + portid_t port_id; + uint16_t queue_id; +}; + +cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_tx_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_queue_tx_offload_result, + tx_offload, "tx_offload"); +cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_en_dis = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_queue_tx_offload_result, + en_dis, "enable#disable"); +cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_per_queue = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_queue_tx_offload_result, + per_queue, "per_queue"); +cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_queue_tx_offload_result, + offload, "vlan_insert#ipv4_cksum#udp_cksum#udp_cksum#" + "sctp_cksum#tcp_tso#udp_tso#outer_ipv4_cksum#" + "qinq_insert#vxlan_tnl_tso#gre_tnl_tso#" + "ipip_tnl_tso#geneve_tnl_tso#macsec_insert#" + "mt_lockfree#multi_segs#fast_free#security "); +cmdline_parse_token_num_t cmd_config_per_queue_tx_offload_result_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_config_per_queue_tx_offload_result, + port_id, UINT16); +cmdline_parse_token_num_t cmd_config_per_queue_tx_offload_result_queue_id = + TOKEN_NUM_INITIALIZER + (struct cmd_config_per_queue_tx_offload_result, + queue_id, UINT16); + + +static void +cmd_config_per_queue_tx_offload_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_per_queue_tx_offload_result *res = parsed_result; + struct rte_eth_dev_info dev_info; + portid_t port_id = res->port_id; + uint16_t queue_id = res->queue_id; + struct rte_port *port = &ports[port_id]; + int on; + + if (port->port_status != RTE_PORT_STOPPED) { + printf("Error: Can't config offload when Port %d " + "is not stopped\n", port_id); + return; + } + + if (!strcmp(res->en_dis, "enable")) + on = 1; + else + on = 0; + + rte_eth_dev_info_get(port_id, &dev_info); + if (queue_id >= dev_info.nb_tx_queues) { + printf("Error: input queue_id should be 0 ... " + "%d", dev_info.nb_tx_queues - 1); + return; + } + + if (config_tx_offload(res->offload, + &port->tx_offloads[queue_id], on)) { + printf("Unknown offload name: %s", res->offload); + } +} + +cmdline_parse_inst_t cmd_config_per_queue_tx_offload = { + .f = cmd_config_per_queue_tx_offload_parsed, + .data = NULL, + .help_str = "tx_offload enable|disable per_queue " + "vlan_insert|ipv4_cksum|udp_cksum|udp_cksum|" + "sctp_cksum|tcp_tso|udp_tso|outer_ipv4_cksum|" + "qinq_insert|vxlan_tnl_tso|gre_tnl_tso|" + "ipip_tnl_tso|geneve_tnl_tso|macsec_insert|" + "mt_lockfree|multi_segs|fast_free|security " + " ", + .tokens = { + (void *)&cmd_config_per_queue_tx_offload_result_tx_offload, + (void *)&cmd_config_per_queue_tx_offload_result_en_dis, + (void *)&cmd_config_per_queue_tx_offload_result_per_queue, + (void *)&cmd_config_per_queue_tx_offload_result_offload, + (void *)&cmd_config_per_queue_tx_offload_result_port_id, + (void *)&cmd_config_per_queue_tx_offload_result_queue_id, + NULL, + } +}; + /* Common result structure for file commands */ struct cmd_cmdfile_result { cmdline_fixed_string_t load; @@ -16639,6 +17007,10 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_rx_offload_get_configuration, (cmdline_parse_inst_t *)&cmd_config_per_port_rx_offload, (cmdline_parse_inst_t *)&cmd_config_per_queue_rx_offload, + (cmdline_parse_inst_t *)&cmd_tx_offload_get_capa, + (cmdline_parse_inst_t *)&cmd_tx_offload_get_configuration, + (cmdline_parse_inst_t *)&cmd_config_per_port_tx_offload, + (cmdline_parse_inst_t *)&cmd_config_per_queue_tx_offload, NULL, }; diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index e5de40a..d7d5d4c 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -718,6 +718,16 @@ init_config(void) "failed\n", port->dev_info.max_rx_queues); for (k = 0; k < port->dev_info.max_rx_queues; k++) port->rx_offloads[k] = port->dev_conf.rxmode.offloads; + port->tx_offloads = rte_zmalloc("testpmd: port->tx_offloads", + sizeof(port->tx_offloads[0]) * + port->dev_info.max_tx_queues, + sizeof(port->tx_offloads[0])); + if (port->tx_offloads == NULL) + rte_exit(EXIT_FAILURE, + "rte_zmalloc(%d port->tx_offload[0]) " + "failed\n", port->dev_info.max_tx_queues); + for (k = 0; k < port->dev_info.max_tx_queues; k++) + port->tx_offloads[k] = port->dev_conf.txmode.offloads; /* set flag to initialize port/queue */ port->need_reconfig = 1; @@ -1599,10 +1609,9 @@ start_port(portid_t pid) if (port->need_reconfig_queues > 0) { port->need_reconfig_queues = 0; port->tx_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE; - /* Apply Tx offloads configuration */ - port->tx_conf.offloads = port->dev_conf.txmode.offloads; /* setup tx queues */ for (qi = 0; qi < nb_txq; qi++) { + port->tx_conf.offloads = port->tx_offloads[qi]; if ((numa_support) && (txring_numa[pi] != NUMA_NO_CONFIG)) diag = rte_eth_tx_queue_setup(pi, qi, @@ -1942,6 +1951,8 @@ pmd_test_exit(void) port = &ports[pt_id]; rte_free(port->rx_offloads); port->rx_offloads = NULL; + rte_free(port->tx_offloads); + port->tx_offloads = NULL; } } printf("\nBye...\n"); diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index dcad260..b0bd14e 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -184,6 +184,7 @@ struct rte_port { struct rte_eth_rxconf rx_conf; /**< rx configuration */ struct rte_eth_txconf tx_conf; /**< tx configuration */ uint64_t *rx_offloads; /**< offloads of each Rx queue */ + uint64_t *tx_offloads; /**< offloads of each Tx queue */ struct ether_addr *mc_addr_pool; /**< pool of multicast addrs */ uint32_t mc_addr_nb; /**< nb. of addr. in mc_addr_pool */ uint8_t slave_flag; /**< bonding slave port */ -- 2.7.5