[dpdk-dev] [PATCH v4 2/2] app/testpmd: add command to configure VMDq

Wu, Jingjing jingjing.wu at intel.com
Fri Jan 20 14:33:46 CET 2017



> -----Original Message-----
> From: Iremonger, Bernard
> Sent: Wednesday, January 18, 2017 12:39 AM
> To: dev at dpdk.org; Lu, Wenzhuo <wenzhuo.lu at intel.com>; Wu, Jingjing
> <jingjing.wu at intel.com>; Zhang, Helin <helin.zhang at intel.com>
> Cc: Iremonger, Bernard <bernard.iremonger at intel.com>
> Subject: [PATCH v4 2/2] app/testpmd: add command to configure VMDq
> 
> Add the following command to configure VMDq:
> port config <port> vmdq
> 
> Add new command to testpmd user guide.
> 
> Signed-off-by: Bernard Iremonger <bernard.iremonger at intel.com>
> ---
>  app/test-pmd/cmdline.c                      |  60 +++++++++++++
>  app/test-pmd/testpmd.c                      | 126 +++++++++++++++++++++++++++-
>  app/test-pmd/testpmd.h                      |   1 +
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |   7 ++
>  4 files changed, 193 insertions(+), 1 deletion(-)
> 
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index
> 21d10e4..30969b4 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -629,6 +629,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.\n\n"
> +
>  			"port config all burst (value)\n"
>  			"    Set the number of packets per burst.\n\n"
> 
> @@ -2322,6 +2325,62 @@ 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 initialize network ports.\n");
> +		return;
> +	}
> +
> +	cmd_reconfig_device_queue(port_id, 0, 1); }
I think the device also need to be reconfigured, it should be
cmd_reconfig_device_queue(port_id, 1, 1);

> +
> +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 <port-id> 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;
> @@ -12438,6 +12497,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/testpmd.c b/app/test-pmd/testpmd.c index bfb2f8e..11d263d 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
> @@ -196,6 +196,34 @@ uint8_t dcb_test = 0;  queueid_t nb_rxq = 1; /**<
> Number of RX queues per port. */  queueid_t nb_txq = 1; /**< Number of TX
> queues per port. */
> 
> +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},},
> +		},
> +	},
> +};
> +
>  /*
>   * Configurable number of RX/TX ring descriptors.
>   */
> @@ -1895,6 +1923,102 @@ const uint16_t vlan_tags[] = {
>  		24, 25, 26, 27, 28, 29, 30, 31
>  };
> 
> +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;
> +/* number of pools (if user does not specify any, 8 by default */
> +static uint32_t num_queues = 8; static uint32_t num_pools = 8;
> +
> +/**
> + * 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 num_pools) {
> +	struct rte_eth_vmdq_rx_conf conf;
> +	uint8_t i;
> +
> +	conf.nb_queue_pools = (enum rte_eth_nb_pools)num_pools;
> +	conf.nb_pool_maps = num_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 % num_pools));
> +	}
> +
> +	(void)(rte_memcpy(eth_conf, &vmdq_conf_default, sizeof(*eth_conf)));
> +	(void)(rte_memcpy(&eth_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_conf port_conf;
> +	uint16_t rx_queues, tx_queues;
> +	int retval;
> +	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 num_pools in
> +	 * command line.
> +	 */
Only found "static uint32_t num_pools = 8;", haven't found any code related
with the num_pools as command arguments.

> +	if (num_pools > max_nb_pools) {
> +		printf("num_pools %d >max_nb_pools %d\n",
> +			num_pools, max_nb_pools);
> +		return -1;
> +	}
> +
> +	retval = get_eth_vmdq_conf(&port_conf, num_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 = num_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;

The variable is set only for printing?
> +
> +	printf("num_pf_queues: %u num_pools: %u\n", num_pf_queues,
> num_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);
> +	return retval;
> +}
> +
>  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..67bb641 100644
> --- a/app/test-pmd/testpmd.h
> +++ b/app/test-pmd/testpmd.h
> @@ -582,6 +582,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 60f30bb..ddc4016 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -1438,6 +1438,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
>  ~~~~~~~~~~~~~~~~~~~
> 
> --
> 2.10.1



More information about the dev mailing list