From patchwork Fri Jan 27 10:49:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Iremonger, Bernard" X-Patchwork-Id: 20016 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 348BF2B83; Fri, 27 Jan 2017 11:50:44 +0100 (CET) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id 807DDDE3 for ; Fri, 27 Jan 2017 11:50:07 +0100 (CET) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga101.jf.intel.com with ESMTP; 27 Jan 2017 02:50:06 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,294,1477983600"; d="scan'208";a="218283250" Received: from sivswdev01.ir.intel.com (HELO localhost.localdomain) ([10.237.217.45]) by fmsmga004.fm.intel.com with ESMTP; 27 Jan 2017 02:50:05 -0800 From: Bernard Iremonger To: dev@dpdk.org, jingjing.wu@intel.com Cc: Bernard Iremonger Date: Fri, 27 Jan 2017 10:49:59 +0000 Message-Id: <1485514200-25230-2-git-send-email-bernard.iremonger@intel.com> X-Mailer: git-send-email 1.7.0.7 In-Reply-To: <1485354963-17326-1-git-send-email-bernard.iremonger@intel.com> References: <1485354963-17326-1-git-send-email-bernard.iremonger@intel.com> Subject: [dpdk-dev] [PATCH v6 1/2] app/testpmd: add command to configure VMDq 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" Add the following command to configure VMDq: port config vmdq Add the following command to set number of pools: set nbpool Add new commands to testpmd user guide. Signed-off-by: Bernard Iremonger --- app/test-pmd/cmdline.c | 72 ++++++++- app/test-pmd/config.c | 14 +- app/test-pmd/parameters.c | 15 +- app/test-pmd/testpmd.c | 220 +++++++++++++++++++++++++++- app/test-pmd/testpmd.h | 7 +- doc/guides/testpmd_app_ug/testpmd_funcs.rst | 18 ++- 6 files changed, 334 insertions(+), 12 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 2fd862f..f017833 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2017 Intel Corporation. All rights reserved. * Copyright(c) 2014 6WIND S.A. * All rights reserved. * @@ -238,6 +238,9 @@ static void cmd_help_long_parsed(void *parsed_result, "set nbcore (num)\n" " Set number of cores.\n\n" + "set nbpool (num)\n" + " Set number of VMDq pools.\n\n" + "set coremask (mask)\n" " Set the forwarding cores hexadecimal mask.\n\n" @@ -629,6 +632,9 @@ static void cmd_help_long_parsed(void *parsed_result, " pfc (on|off)\n" " Set the DCB mode.\n\n" + "port config (port_id) vmdq\n" + " Configure VMDq for a port.\n\n" + "port config all burst (value)\n" " Set the number of packets per burst.\n\n" @@ -2322,6 +2328,61 @@ cmdline_parse_inst_t cmd_config_dcb = { }, }; +/* *** Configure VMDq *** */ +struct cmd_config_vmdq { + cmdline_fixed_string_t port; + cmdline_fixed_string_t config; + uint8_t port_id; + cmdline_fixed_string_t vmdq; +}; + +static void +cmd_config_vmdq_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_vmdq *res = parsed_result; + portid_t port_id = res->port_id; + struct rte_port *port; + int ret; + + port = &ports[port_id]; + /** Check if the port is not started **/ + if (port->port_status != RTE_PORT_STOPPED) { + printf("Please stop port %d first\n", port_id); + return; + } + + ret = init_port_vmdq_config(port_id); + if (ret != 0) { + printf("Cannot configure VMDQ for port %d.\n", port_id); + return; + } + cmd_reconfig_device_queue(port_id, 0, 0); +} + +cmdline_parse_token_string_t cmd_config_vmdq_port = + TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, port, "port"); +cmdline_parse_token_string_t cmd_config_vmdq_config = + TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, config, "config"); +cmdline_parse_token_num_t cmd_config_vmdq_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_config_vmdq, port_id, UINT8); +cmdline_parse_token_string_t cmd_config_vmdq_vmdq = + TOKEN_STRING_INITIALIZER(struct cmd_config_vmdq, vmdq, "vmdq"); + +cmdline_parse_inst_t cmd_config_vmdq = { + .f = cmd_config_vmdq_parsed, + .data = NULL, + .help_str = "port config vmdq", + .tokens = { + (void *)&cmd_config_vmdq_port, + (void *)&cmd_config_vmdq_config, + (void *)&cmd_config_vmdq_port_id, + (void *)&cmd_config_vmdq_vmdq, + NULL, + }, +}; + /* *** configure number of packets per burst *** */ struct cmd_config_burst { cmdline_fixed_string_t port; @@ -2722,7 +2783,7 @@ cmdline_parse_inst_t cmd_set_fwd_mask = { }; /* - * SET NBPORT, NBCORE, PACKET BURST, and VERBOSE LEVEL CONFIGURATION + * SET NBPORT, NBCORE, NBPOOL, PACKET BURST, and VERBOSE LEVEL CONFIGURATION */ struct cmd_set_result { cmdline_fixed_string_t set; @@ -2741,6 +2802,8 @@ static void cmd_set_parsed(void *parsed_result, } else if (!strcmp(res->what, "nbcore")) { set_fwd_lcores_number(res->value); fwd_config_setup(); + } else if (!strcmp(res->what, "nbpool")) { + set_vmdq_pool_number(res->value); } else if (!strcmp(res->what, "burst")) set_nb_pkt_per_burst(res->value); else if (!strcmp(res->what, "verbose")) @@ -2751,14 +2814,14 @@ cmdline_parse_token_string_t cmd_set_set = TOKEN_STRING_INITIALIZER(struct cmd_set_result, set, "set"); cmdline_parse_token_string_t cmd_set_what = TOKEN_STRING_INITIALIZER(struct cmd_set_result, what, - "nbport#nbcore#burst#verbose"); + "nbport#nbcore#nbpool#burst#verbose"); cmdline_parse_token_num_t cmd_set_value = TOKEN_NUM_INITIALIZER(struct cmd_set_result, value, UINT16); cmdline_parse_inst_t cmd_set_numbers = { .f = cmd_set_parsed, .data = NULL, - .help_str = "set nbport|nbcore|burst|verbose ", + .help_str = "set nbport|nbcore|nbpool|burst|verbose ", .tokens = { (void *)&cmd_set_set, (void *)&cmd_set_what, @@ -12462,6 +12525,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_link_flow_control_set_autoneg, (cmdline_parse_inst_t *)&cmd_priority_flow_control_set, (cmdline_parse_inst_t *)&cmd_config_dcb, + (cmdline_parse_inst_t *)&cmd_config_vmdq, (cmdline_parse_inst_t *)&cmd_read_reg, (cmdline_parse_inst_t *)&cmd_read_reg_bit_field, (cmdline_parse_inst_t *)&cmd_read_reg_bit, diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 5834498..2df501f 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2017 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -2063,6 +2063,18 @@ set_fwd_lcores_number(uint16_t nb_lc) } void +set_vmdq_pool_number(uint32_t nbpool) +{ + if (nbpool <= ETH_64_POOLS) { + nb_pools = nbpool; + printf("Number of VMDq pools set to %u\n", nb_pools); + } else { + printf("invalid nbpool %u ignored\n", nbpool); + return; + } +} + +void set_fwd_ports_list(unsigned int *portlist, unsigned int nb_pt) { unsigned int i; diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c index 28db8cd..5674f94 100644 --- a/app/test-pmd/parameters.c +++ b/app/test-pmd/parameters.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2017 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -90,7 +90,7 @@ usage(char* progname) "[--help|-h] | [--auto-start|-a] | [" "--coremask=COREMASK --portmask=PORTMASK --numa " "--mbuf-size= | --total-num-mbufs= | " - "--nb-cores= | --nb-ports= | " + "--nb-cores= | --nb-ports= | --nb-pools |" #ifdef RTE_LIBRTE_CMDLINE "--eth-peers-configfile= | " "--eth-peer=X,M:M:M:M:M:M | " @@ -196,6 +196,7 @@ usage(char* progname) " or total packet length.\n"); printf(" --disable-link-check: disable check on link status when " "starting/stopping ports.\n"); + printf(" --nb-pools=N: set the number of VMDq pools (N < 64).\n"); } #ifdef RTE_LIBRTE_CMDLINE @@ -561,6 +562,7 @@ launch_args_parse(int argc, char** argv) { "no-flush-rx", 0, 0, 0 }, { "txpkts", 1, 0, 0 }, { "disable-link-check", 0, 0, 0 }, + { "nb-pools", 1, 0, 0 }, { 0, 0, 0, 0 }, }; @@ -978,7 +980,14 @@ launch_args_parse(int argc, char** argv) no_flush_rx = 1; if (!strcmp(lgopts[opt_idx].name, "disable-link-check")) no_link_check = 1; - + if (!strcmp(lgopts[opt_idx].name, "nb-pools")) { + n = atoi(optarg); + if (n <= ETH_64_POOLS) + nb_pools = (uint32_t)n; + else + rte_exit(EXIT_FAILURE, + "Invalid number of pools %d\n", n); + } break; case 'h': usage(argv[0]); diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index bfb2f8e..3d25436 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2017 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -1888,13 +1888,229 @@ uint8_t port_is_bonding_slave(portid_t slave_pid) return port->slave_flag; } +static const struct rte_eth_conf vmdq_conf_default = { + .rxmode = { + .mq_mode = ETH_MQ_RX_VMDQ_ONLY, + .split_hdr_size = 0, + .header_split = 0, /**< Header Split disabled */ + .hw_ip_checksum = 0, /**< IP checksum offload disabled */ + .hw_vlan_filter = 0, /**< VLAN filtering disabled */ + .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ + }, + + .txmode = { + .mq_mode = ETH_MQ_TX_NONE, + }, + .rx_adv_conf = { + /* + * should be overridden separately in code with + * appropriate values + */ + .vmdq_rx_conf = { + .nb_queue_pools = ETH_8_POOLS, + .enable_default_pool = 0, + .default_pool = 0, + .nb_pool_maps = 0, + .pool_map = {{0, 0},}, + }, + }, +}; + const uint16_t vlan_tags[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31 + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, +}; + +const uint16_t num_vlans = RTE_DIM(vlan_tags); +static uint16_t num_pf_queues, num_vmdq_queues; +static uint16_t vmdq_pool_base, vmdq_queue_base; +static uint32_t num_queues; +/* number of pools (if user does not specify any, 8 by default */ +uint32_t nb_pools = ETH_8_POOLS; +/* ethernet addresses of ports */ +static struct ether_addr vmdq_ports_eth_addr[RTE_MAX_ETHPORTS]; +/* pool mac addr template, pool mac addr is like: 52 54 00 12 port# pool# */ +static struct ether_addr pool_addr_template = { + .addr_bytes = {0x52, 0x54, 0x00, 0x12, 0x00, 0x00} }; +/** + * Builds up the correct configuration for vmdq based on the vlan tags array + * given above, and determine the queue number and pool map number according to + * valid pool number + */ +static int +get_eth_vmdq_conf(struct rte_eth_conf *eth_conf, uint32_t nb_pools) +{ + struct rte_eth_vmdq_rx_conf conf; + uint8_t i; + + conf.nb_queue_pools = (enum rte_eth_nb_pools)nb_pools; + conf.nb_pool_maps = nb_pools; + conf.enable_default_pool = 0; + conf.default_pool = 0; /* set explicit value, even if not used */ + + for (i = 0; i < conf.nb_pool_maps; i++) { + conf.pool_map[i].vlan_id = vlan_tags[i]; + conf.pool_map[i].pools = (1UL << (i % nb_pools)); + } + + (void)(rte_memcpy(eth_conf, &vmdq_conf_default, sizeof(*eth_conf))); + (void)(rte_memcpy(ð_conf->rx_adv_conf.vmdq_rx_conf, &conf, + sizeof(eth_conf->rx_adv_conf.vmdq_rx_conf))); + return 0; +} + +/** + * Configures VMDq for a given port using global settings. + */ +int +init_port_vmdq_config(uint8_t port) +{ + struct rte_eth_dev_info dev_info; + struct rte_eth_rxconf *rxconf; + struct rte_eth_conf port_conf; + struct rte_mempool *mbp; + uint16_t rx_queues, tx_queues; + const uint16_t rx_queue_size = RTE_TEST_RX_DESC_DEFAULT; + const uint16_t tx_queue_size = RTE_TEST_TX_DESC_DEFAULT; + int retval; + uint16_t q; + uint16_t queues_per_pool; + uint32_t max_nb_pools; + + if (port >= rte_eth_dev_count()) + return -1; + /** + * The max pool number from dev_info will be used to validate the pool + * number. + */ + rte_eth_dev_info_get(port, &dev_info); + max_nb_pools = (uint32_t)dev_info.max_vmdq_pools; + /** + * We allow to process part of VMDQ pools specified by nb_pools in + * command line. + */ + if (nb_pools > max_nb_pools) { + printf("nb_pools %d > max_nb_pools %d\n", + nb_pools, max_nb_pools); + return -1; + } + + retval = get_eth_vmdq_conf(&port_conf, max_nb_pools); + if (retval < 0) + return retval; + + /* + * NIC queues are divided into pf queues and vmdq queues. + */ + /* There is assumption here all ports have the same configuration! */ + num_pf_queues = dev_info.max_rx_queues - dev_info.vmdq_queue_num; + queues_per_pool = dev_info.vmdq_queue_num / dev_info.max_vmdq_pools; + num_vmdq_queues = nb_pools * queues_per_pool; + num_queues = num_pf_queues + num_vmdq_queues; + vmdq_queue_base = dev_info.vmdq_queue_base; + vmdq_pool_base = dev_info.vmdq_pool_base; + + printf("num_pf_queues: %u nb_pools: %u\n", num_pf_queues, nb_pools); + printf("each vmdq pool has %u queues\n", queues_per_pool); + printf("vmdq_queue_base: %d vmdq_pool_base: %d\n", vmdq_queue_base, vmdq_pool_base); + + /* + * All queues including pf queues are setup. + * This is because VMDQ queues doesn't always start from zero, and the + * PMD layer doesn't support selectively initialising part of rx/tx + * queues. + */ + rx_queues = (uint16_t)dev_info.max_rx_queues; + tx_queues = (uint16_t)dev_info.max_tx_queues; + retval = rte_eth_dev_configure(port, rx_queues, tx_queues, &port_conf); + if (retval < 0) { + printf("rte_eth_dev_configure %d failed\n", retval); + return retval; + } + + mbp = mbuf_pool_find(0); + if (mbp == NULL) { + printf("mbuf_pool_find failed\n"); + return -1; + } + + rte_eth_dev_info_get(port, &dev_info); + rxconf = &dev_info.default_rxconf; + rxconf->rx_drop_en = 1; + for (q = 0; q < rx_queues; q++) { + retval = rte_eth_rx_queue_setup(port, q, rx_queue_size, + rte_eth_dev_socket_id(port), + rxconf, + mbp); + if (retval < 0) { + printf("initialise rx queue %d failed\n", q); + return retval; + } + } + + for (q = 0; q < tx_queues; q++) { + retval = rte_eth_tx_queue_setup(port, q, tx_queue_size, + rte_eth_dev_socket_id(port), + NULL); + if (retval < 0) { + printf("initialise tx queue %d failed\n", q); + return retval; + } + } + + retval = rte_eth_dev_start(port); + if (retval < 0) { + printf("rte_eth_dev_start %d failed\n", retval); + return retval; + } + printf("port %d started\n", port); + + rte_eth_macaddr_get(port, &vmdq_ports_eth_addr[port]); + + printf("Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8 + " %02"PRIx8" %02"PRIx8" %02"PRIx8"\n", port, + vmdq_ports_eth_addr[port].addr_bytes[0], + vmdq_ports_eth_addr[port].addr_bytes[1], + vmdq_ports_eth_addr[port].addr_bytes[2], + vmdq_ports_eth_addr[port].addr_bytes[3], + vmdq_ports_eth_addr[port].addr_bytes[4], + vmdq_ports_eth_addr[port].addr_bytes[5]); + + /* + * Set mac for each pool. + * There is no default mac for the pools in i40. + * Removes this after i40e fixes this issue. + */ + for (q = 0; q < nb_pools; q++) { + struct ether_addr mac; + + mac = pool_addr_template; + mac.addr_bytes[4] = port; + mac.addr_bytes[5] = q; + printf("Port %u vmdq pool %u set mac %02x:%02x:%02x:%02x:%02x:%02x\n", + port, q, + mac.addr_bytes[0], mac.addr_bytes[1], + mac.addr_bytes[2], mac.addr_bytes[3], + mac.addr_bytes[4], mac.addr_bytes[5]); + retval = rte_eth_dev_mac_addr_add(port, &mac, + q + vmdq_pool_base); + if (retval) { + printf("mac addr add failed at pool %d\n", q); + return retval; + } + } + + return 0; +} + static int get_eth_dcb_conf(struct rte_eth_conf *eth_conf, enum dcb_mode_enable dcb_mode, diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index ee59460..eadb1c2 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2017 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -368,6 +368,8 @@ extern queueid_t nb_txq; extern uint16_t nb_rxd; extern uint16_t nb_txd; +extern uint32_t nb_pools; + extern int16_t rx_free_thresh; extern int8_t rx_drop_en; extern int16_t tx_free_thresh; @@ -546,6 +548,8 @@ void set_fwd_ports_mask(uint64_t portmask); void set_fwd_ports_number(uint16_t nb_pt); int port_is_forwarding(portid_t port_id); +void set_vmdq_pool_number(uint32_t nbpool); + void rx_vlan_strip_set(portid_t port_id, int on); void rx_vlan_strip_set_on_queue(portid_t port_id, uint16_t queue_id, int on); @@ -582,6 +586,7 @@ uint8_t port_is_bonding_slave(portid_t slave_pid); int init_port_dcb_config(portid_t pid, enum dcb_mode_enable dcb_mode, enum rte_eth_nb_tcs num_tcs, uint8_t pfc_en); +int init_port_vmdq_config(uint8_t port); int start_port(portid_t pid); void stop_port(portid_t pid); void close_port(portid_t pid); diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index 16ac097..37bf7b1 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -1,5 +1,5 @@ .. BSD LICENSE - Copyright(c) 2010-2016 Intel Corporation. All rights reserved. + Copyright(c) 2010-2017 Intel Corporation. All rights reserved. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -360,6 +360,15 @@ set nbport (num) This is equivalent to the ``--nb-ports`` command-line option. +set nbpool +~~~~~~~~~~ + +Set the number of pools used by the application:: + + testpmd> set nbpool (num) + +This is equivalent to the ``--nb-pools`` command-line option. + set nbcore ~~~~~~~~~~ @@ -1438,6 +1447,13 @@ Set the DCB mode for an individual port:: The traffic class should be 4 or 8. +port config - VMDq +~~~~~~~~~~~~~~~~~~ + +Configure VMDq for an individual port:: + + testpmd> port config (port_id) vmdq + port config - Burst ~~~~~~~~~~~~~~~~~~~