From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id D698A7286 for ; Tue, 20 Mar 2018 04:27:22 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Mar 2018 20:27:21 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,333,1517904000"; d="scan'208";a="39472427" Received: from dpdk6.bj.intel.com ([172.16.182.119]) by fmsmga001.fm.intel.com with ESMTP; 19 Mar 2018 20:27:20 -0700 From: Wei Dai To: wenzhuo.lu@intel.com, jingjing.wu@intel.com Cc: dev@dpdk.org, Wei Dai Date: Tue, 20 Mar 2018 11:09:06 +0800 Message-Id: <1521515347-45383-2-git-send-email-wei.dai@intel.com> X-Mailer: git-send-email 2.7.5 In-Reply-To: <1521515347-45383-1-git-send-email-wei.dai@intel.com> References: <1521463235-16451-1-git-send-email-wei.dai@intel.com> <1521515347-45383-1-git-send-email-wei.dai@intel.com> Subject: [dpdk-dev] [PATCH v5 1/2] app/testpmd: add commands to test new Rx offload API 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: , X-List-Received-Date: Tue, 20 Mar 2018 03:27:24 -0000 Add following testpmd run-time commands to support test of new Rx offload API: rx_offload get capability rx_offload get configuration rx_offload enable|disable per_port rx_offload enable|disable per_queue Above last 2 commands should be run when the port is stopped. And can be one of "vlan_strip", "ipv4_cksum", ... Signed-off-by: Wei Dai --- app/test-pmd/cmdline.c | 373 +++++++++++++++++++++++++++++++++++++++++++++++++ app/test-pmd/testpmd.c | 19 ++- app/test-pmd/testpmd.h | 1 + 3 files changed, 391 insertions(+), 2 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 40b31ad..017416b 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -15996,6 +15996,375 @@ cmdline_parse_inst_t cmd_ptype_mapping_update = { }, }; +/* Get Rx offloads capability */ +struct cmd_rx_offload_get_capa_result { + cmdline_fixed_string_t rx_offload; + cmdline_fixed_string_t get; + cmdline_fixed_string_t capability; + portid_t port_id; +}; + +cmdline_parse_token_string_t cmd_rx_offload_get_capa_rx_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_rx_offload_get_capa_result, + rx_offload, "rx_offload"); +cmdline_parse_token_string_t cmd_rx_offload_get_capa_get = + TOKEN_STRING_INITIALIZER + (struct cmd_rx_offload_get_capa_result, + get, "get"); +cmdline_parse_token_string_t cmd_rx_offload_get_capa_capability = + TOKEN_STRING_INITIALIZER + (struct cmd_rx_offload_get_capa_result, + capability, "capability"); +cmdline_parse_token_num_t cmd_rx_offload_get_capa_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_rx_offload_get_capa_result, + port_id, UINT16); + +static void +print_rx_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_rx_offload_name(single_offload)); + single_offload <<= 1; + } +} + +static void +cmd_rx_offload_get_capa_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_rx_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.rx_queue_offload_capa; + port_offloads = dev_info.rx_offload_capa ^ queue_offloads; + + printf("Rx Offloading Capabilities of port %d :\n", port_id); + printf(" Per Queue :"); + print_rx_offloads(queue_offloads); + + printf("\n"); + printf(" Per Port :"); + print_rx_offloads(port_offloads); + printf("\n\n"); +} + +cmdline_parse_inst_t cmd_rx_offload_get_capa = { + .f = cmd_rx_offload_get_capa_parsed, + .data = NULL, + .help_str = "rx_offload get capability ", + .tokens = { + (void *)&cmd_rx_offload_get_capa_rx_offload, + (void *)&cmd_rx_offload_get_capa_get, + (void *)&cmd_rx_offload_get_capa_capability, + (void *)&cmd_rx_offload_get_capa_port_id, + NULL, + } +}; + +/* Get Rx offloads configuration */ +struct cmd_rx_offload_get_configuration_result { + cmdline_fixed_string_t rx_offload; + cmdline_fixed_string_t get; + cmdline_fixed_string_t configuration; + portid_t port_id; +}; + +cmdline_parse_token_string_t cmd_rx_offload_get_configuration_rx_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_rx_offload_get_configuration_result, + rx_offload, "rx_offload"); +cmdline_parse_token_string_t cmd_rx_offload_get_configuration_get = + TOKEN_STRING_INITIALIZER + (struct cmd_rx_offload_get_configuration_result, + get, "get"); +cmdline_parse_token_string_t cmd_rx_offload_get_configuration_configuration = + TOKEN_STRING_INITIALIZER + (struct cmd_rx_offload_get_configuration_result, + configuration, "configuration"); +cmdline_parse_token_num_t cmd_rx_offload_get_configuration_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_rx_offload_get_configuration_result, + port_id, UINT16); + +static void +cmd_rx_offload_get_configuration_parsed( + void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_rx_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_rx_queues; + int q; + + printf("Rx Offloading Configuration of port %d :\n", port_id); + + port_offloads = port->dev_conf.rxmode.offloads; + printf(" Port :"); + print_rx_offloads(port_offloads); + printf("\n"); + + rte_eth_dev_info_get(port_id, &dev_info); + nb_rx_queues = dev_info.nb_rx_queues; + for (q = 0; q < nb_rx_queues; q++) { + queue_offloads = port->rx_offloads[q]; + printf(" Queue[%2d] :", q); + print_rx_offloads(queue_offloads); + printf("\n"); + } + printf("\n"); +} + +cmdline_parse_inst_t cmd_rx_offload_get_configuration = { + .f = cmd_rx_offload_get_configuration_parsed, + .data = NULL, + .help_str = "rx_offload get configuration ", + .tokens = { + (void *)&cmd_rx_offload_get_configuration_rx_offload, + (void *)&cmd_rx_offload_get_configuration_get, + (void *)&cmd_rx_offload_get_configuration_configuration, + (void *)&cmd_rx_offload_get_configuration_port_id, + NULL, + } +}; + +/* Enable/Disable a per port offloading */ +struct cmd_config_per_port_rx_offload_result { + cmdline_fixed_string_t rx_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_rx_offload_result_rx_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_port_rx_offload_result, + rx_offload, "rx_offload"); +cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_en_dis = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_port_rx_offload_result, + en_dis, "enable#disable"); +cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_per_port = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_port_rx_offload_result, + per_port, "per_port"); +cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_port_rx_offload_result, + offload, "vlan_strip#ipv4_cksum#udp_cksum#tcp_cksum#tcp_lro#" + "qinq_strip#outer_ipv4_cksum#macsec_strip#" + "header_split#vlan_filter#vlan_extend#jumbo_frame#" + "crc_strip#scatter#timestamp#security"); +cmdline_parse_token_num_t cmd_config_per_port_rx_offload_result_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_config_per_port_rx_offload_result, + port_id, UINT16); + +static uint64_t +search_rx_offload(const char *name) +{ + uint64_t single_offload; + const char *single_name; + int found = 0; + unsigned int bit; + + single_offload = 1; + for (bit = 0; bit < sizeof(single_offload) * CHAR_BIT; bit++) { + single_name = rte_eth_dev_rx_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) + return single_offload; + + return 0; +} + +static void +cmd_config_per_port_rx_offload_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_per_port_rx_offload_result *res = parsed_result; + portid_t port_id = res->port_id; + struct rte_eth_dev_info dev_info; + struct rte_port *port = &ports[port_id]; + uint64_t single_offload; + uint16_t nb_rx_queues; + int q; + + if (port->port_status != RTE_PORT_STOPPED) { + printf("Error: Can't config offload when Port %d " + "is not stopped\n", port_id); + return; + } + + single_offload = search_rx_offload(res->offload); + if (single_offload == 0) { + printf("Unknown offload name: %s", res->offload); + return; + } + + rte_eth_dev_info_get(port_id, &dev_info); + nb_rx_queues = dev_info.nb_rx_queues; + if (!strcmp(res->en_dis, "enable")) { + port->dev_conf.rxmode.offloads |= single_offload; + for (q = 0; q < nb_rx_queues; q++) + port->rx_offloads[q] |= single_offload; + } else { + port->dev_conf.rxmode.offloads &= ~single_offload; + for (q = 0; q < nb_rx_queues; q++) + port->rx_offloads[q] &= ~single_offload; + } +} + +cmdline_parse_inst_t cmd_config_per_port_rx_offload = { + .f = cmd_config_per_port_rx_offload_parsed, + .data = NULL, + .help_str = "rx_offload enable|disable per_port vlan_strip|ipv4_cksum|" + "udp_cksum|tcp_cksum|tcp_lro|qinq_strip|outer_ipv4_cksum|" + "macsec_strip|header_split|vlan_filter|vlan_extend|" + "jumbo_frame|crc_strip|scatter|timestamp|security " + "", + .tokens = { + (void *)&cmd_config_per_port_rx_offload_result_rx_offload, + (void *)&cmd_config_per_port_rx_offload_result_en_dis, + (void *)&cmd_config_per_port_rx_offload_result_per_port, + (void *)&cmd_config_per_port_rx_offload_result_offload, + (void *)&cmd_config_per_port_rx_offload_result_port_id, + NULL, + } +}; + +/* Enable/Disable a per queue offloading */ +struct cmd_config_per_queue_rx_offload_result { + cmdline_fixed_string_t rx_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_rx_offload_result_rx_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_queue_rx_offload_result, + rx_offload, "rx_offload"); +cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_en_dis = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_queue_rx_offload_result, + en_dis, "enable#disable"); +cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_per_queue = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_queue_rx_offload_result, + per_queue, "per_queue"); +cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_offload = + TOKEN_STRING_INITIALIZER + (struct cmd_config_per_queue_rx_offload_result, + offload, "vlan_strip#ipv4_cksum#udp_cksum#tcp_cksum#tcp_lro#" + "qinq_strip#outer_ipv4_cksum#macsec_strip#" + "header_split#vlan_filter#vlan_extend#jumbo_frame#" + "crc_strip#scatter#timestamp#security"); +cmdline_parse_token_num_t cmd_config_per_queue_rx_offload_result_port_id = + TOKEN_NUM_INITIALIZER + (struct cmd_config_per_queue_rx_offload_result, + port_id, UINT16); +cmdline_parse_token_num_t cmd_config_per_queue_rx_offload_result_queue_id = + TOKEN_NUM_INITIALIZER + (struct cmd_config_per_queue_rx_offload_result, + queue_id, UINT16); + + +static void +cmd_config_per_queue_rx_offload_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_per_queue_rx_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]; + uint64_t single_offload; + + if (port->port_status != RTE_PORT_STOPPED) { + printf("Error: Can't config offload when Port %d " + "is not stopped\n", port_id); + return; + } + + rte_eth_dev_info_get(port_id, &dev_info); + if (queue_id >= dev_info.nb_rx_queues) { + printf("Error: input queue_id should be 0 ... " + "%d", dev_info.nb_rx_queues - 1); + return; + } + + single_offload = search_rx_offload(res->offload); + if (single_offload == 0) { + printf("Unknown offload name: %s", res->offload); + return; + } + + if (!strcmp(res->en_dis, "enable")) + port->rx_offloads[queue_id] |= single_offload; + else + port->rx_offloads[queue_id] &= ~single_offload; +} + +cmdline_parse_inst_t cmd_config_per_queue_rx_offload = { + .f = cmd_config_per_queue_rx_offload_parsed, + .data = NULL, + .help_str = "rx_offload enable|disable per_queue vlan_strip|ipv4_cksum|" + "udp_cksum|tcp_cksum|tcp_lro|qinq_strip|outer_ipv4_cksum|" + "macsec_strip|header_split|vlan_filter|vlan_extend|" + "jumbo_frame|crc_strip|scatter|timestamp|security " + " ", + .tokens = { + (void *)&cmd_config_per_queue_rx_offload_result_rx_offload, + (void *)&cmd_config_per_queue_rx_offload_result_en_dis, + (void *)&cmd_config_per_queue_rx_offload_result_per_queue, + (void *)&cmd_config_per_queue_rx_offload_result_offload, + (void *)&cmd_config_per_queue_rx_offload_result_port_id, + (void *)&cmd_config_per_queue_rx_offload_result_queue_id, + NULL, + } +}; + /* Common result structure for file commands */ struct cmd_cmdfile_result { cmdline_fixed_string_t load; @@ -16272,6 +16641,10 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_del_port_tm_node, (cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent, (cmdline_parse_inst_t *)&cmd_port_tm_hierarchy_commit, + (cmdline_parse_inst_t *)&cmd_rx_offload_get_capa, + (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, NULL, }; diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 4c0e258..e5de40a 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -656,6 +656,7 @@ init_config(void) uint8_t port_per_socket[RTE_MAX_NUMA_NODES]; struct rte_gro_param gro_param; uint32_t gso_types; + int k; memset(port_per_socket,0,RTE_MAX_NUMA_NODES); @@ -707,6 +708,17 @@ init_config(void) } } + port->rx_offloads = rte_zmalloc("testpmd: port->rx_offloads", + sizeof(port->rx_offloads[0]) * + port->dev_info.max_rx_queues, + sizeof(port->rx_offloads[0])); + if (port->rx_offloads == NULL) + rte_exit(EXIT_FAILURE, + "rte_zmalloc(%d port->rx_offload[0]) " + "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; + /* set flag to initialize port/queue */ port->need_reconfig = 1; port->need_reconfig_queues = 1; @@ -1615,10 +1627,9 @@ start_port(portid_t pid) port->need_reconfig_queues = 1; return -1; } - /* Apply Rx offloads configuration */ - port->rx_conf.offloads = port->dev_conf.rxmode.offloads; /* setup rx queues */ for (qi = 0; qi < nb_rxq; qi++) { + port->rx_conf.offloads = port->rx_offloads[qi]; if ((numa_support) && (rxring_numa[pi] != NUMA_NO_CONFIG)) { struct rte_mempool * mp = @@ -1915,6 +1926,7 @@ detach_port(portid_t port_id) void pmd_test_exit(void) { + struct rte_port *port; portid_t pt_id; if (test_done == 0) @@ -1927,6 +1939,9 @@ pmd_test_exit(void) fflush(stdout); stop_port(pt_id); close_port(pt_id); + port = &ports[pt_id]; + rte_free(port->rx_offloads); + port->rx_offloads = NULL; } } printf("\nBye...\n"); diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 153abea..dcad260 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -183,6 +183,7 @@ struct rte_port { uint8_t dcb_flag; /**< enable dcb */ 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 */ 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