From ee653bd8004469fa7a15bf8f0c2780ff87b57aac Mon Sep 17 00:00:00 2001 From: Wei Dai Date: Tue, 9 Jan 2018 16:56:07 +0800 Subject: [PATCH] net/i40e: determine number of queues per VF at run time Without this patch, the number of queues per i40e VF is set to 4 by CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base. It is a fixed value determined at compile time and can't be changed at run time. With this patch, the number of queues per i40e VF can be determined at run time. For example, if the PCI address of an i40e PF is aaaa:bb.cc, with the EAL parameter -w aaaa:bb.cc,queue-num-per-vf=8, the number of queues per VF created from this PF is set to 8. If there is no "queue-num-per-vf" setting in EAL parameters, it uses the default value of 4. And if the value after the "queue-num-per-vf" is invalid, it will also use the default value. The valid values can be 1, 2, 4, 8, or 16. Signed-off-by: Wei Dai Acked-by: Konstantin Ananyev --- config/common_base | 1 - doc/guides/nics/i40e.rst | 16 ++++-- doc/guides/rel_notes/release_18_02.rst | 8 +++ drivers/net/i40e/i40e_ethdev.c | 69 +++++++++++++++++++++++++- 4 files changed, 87 insertions(+), 7 deletions(-) diff --git a/config/common_base b/config/common_base index 5ee18420ca..465ebf3fb7 100644 --- a/config/common_base +++ b/config/common_base @@ -203,7 +203,6 @@ CONFIG_RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC=y CONFIG_RTE_LIBRTE_I40E_INC_VECTOR=y CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF=64 -CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM=4 # interval up to 8160 us, aligned to 2 (or default value) CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL=-1 diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst index 2507d5f27b..c4c10d3b80 100644 --- a/doc/guides/nics/i40e.rst +++ b/doc/guides/nics/i40e.rst @@ -115,10 +115,6 @@ Please note that enabling debugging options may affect system performance. Number of queues reserved for PF. -- ``CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF`` (default ``4``) - - Number of queues reserved for each SR-IOV VF. - - ``CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM`` (default ``4``) Number of queues reserved for each VMDQ Pool. @@ -128,6 +124,18 @@ Please note that enabling debugging options may affect system performance. Interrupt Throttling interval. +Runtime Config Options +~~~~~~~~~~~~~~~~~~~~~~ + +- ``Number of Queues per VF`` (default ``4``) + + The number of queue per VF is determined by its host PF. If the PCI address + of an i40e PF is aaaa:bb.cc, the number of queues per VF can be configured + with EAL parameter like -w aaaa:bb.cc,queue-num-per-vf=n. The value n can be + 1, 2, 4, 8 or 16. If no such parameter is configured, the number of queues + per VF is 4 by default. + + Driver compilation and testing ------------------------------ diff --git a/doc/guides/rel_notes/release_18_02.rst b/doc/guides/rel_notes/release_18_02.rst index 8fe5b9499d..51b43f9d1d 100644 --- a/doc/guides/rel_notes/release_18_02.rst +++ b/doc/guides/rel_notes/release_18_02.rst @@ -53,6 +53,14 @@ New Features users. According to the device configuration, it will setup TX->RX loopback link or not. +* **Add the support of run time determination of number of queues per i40e VF** + + The number of queue per VF is determined by its host PF. If the PCI address + of an i40e PF is aaaa:bb.cc, the number of queues per VF can be configured + with EAL parameter like -w aaaa:bb.cc,queue-num-per-vf=n. The value n can be + 1, 2, 4, 8 or 16. If no such parameter is configured, the number of queues + per VF is 4 by default. + * **Added NVGRE and UDP tunnels support in Solarflare network PMD.** Added support for NVGRE, VXLAN and GENEVE tunnels. diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 04fc3a19ec..3dc026fbf5 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -3952,6 +3952,69 @@ i40e_get_cap(struct i40e_hw *hw) return ret; } +#define RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF 4 +#define QUEUE_NUM_PER_VF_ARG "queue-num-per-vf" +RTE_PMD_REGISTER_PARAM_STRING(net_i40e, QUEUE_NUM_PER_VF_ARG "=1|2|4|8|16"); + +static int i40e_pf_parse_vf_queue_number_handler(const char *key, + const char *value, + void *opaque) +{ + struct i40e_pf *pf; + unsigned long num; + char *end; + + pf = (struct i40e_pf *)opaque; + RTE_SET_USED(key); + + errno = 0; + num = strtoul(value, &end, 0); + if (errno != 0 || end == value || *end != 0) { + PMD_DRV_LOG(WARNING, "Wrong VF queue number = %s, Now it is " + "kept the value = %hu", value, pf->vf_nb_qp_max); + return -(EINVAL); + } + + if (num <= I40E_MAX_QP_NUM_PER_VF && rte_is_power_of_2(num)) + pf->vf_nb_qp_max = (uint16_t)num; + else + /* here return 0 to make next valid same argument work */ + PMD_DRV_LOG(WARNING, "Wrong VF queue number = %lu, it must be " + "power of 2 and equal or less than 16 !, Now it is " + "kept the value = %hu", num, pf->vf_nb_qp_max); + + return 0; +} + +static int i40e_pf_config_vf_rxq_number(struct rte_eth_dev *dev) +{ + static const char * const valid_keys[] = {QUEUE_NUM_PER_VF_ARG, NULL}; + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); + struct rte_kvargs *kvlist; + + /* set default queue number per VF as 4 */ + pf->vf_nb_qp_max = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF; + + if (dev->device->devargs == NULL) + return 0; + + kvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys); + if (kvlist == NULL) + return -(EINVAL); + + if (rte_kvargs_count(kvlist, QUEUE_NUM_PER_VF_ARG) > 1) + PMD_DRV_LOG(WARNING, "More than one argument \"%s\" and only " + "the first invalid or last valid one is used !", + QUEUE_NUM_PER_VF_ARG); + + rte_kvargs_process(kvlist, QUEUE_NUM_PER_VF_ARG, + i40e_pf_parse_vf_queue_number_handler, pf); + + rte_kvargs_free(kvlist); + + return 0; +} + static int i40e_pf_parameter_init(struct rte_eth_dev *dev) { @@ -3964,6 +4027,9 @@ i40e_pf_parameter_init(struct rte_eth_dev *dev) PMD_INIT_LOG(ERR, "HW configuration doesn't support SRIOV"); return -EINVAL; } + + i40e_pf_config_vf_rxq_number(dev); + /* Add the parameter init for LFC */ pf->fc_conf.pause_time = I40E_DEFAULT_PAUSE_TIME; pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS] = I40E_DEFAULT_HIGH_WATER; @@ -3973,7 +4039,6 @@ i40e_pf_parameter_init(struct rte_eth_dev *dev) pf->max_num_vsi = hw->func_caps.num_vsis; pf->lan_nb_qp_max = RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF; pf->vmdq_nb_qp_max = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM; - pf->vf_nb_qp_max = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF; /* FDir queue/VSI allocation */ pf->fdir_qp_offset = 0; @@ -4003,7 +4068,7 @@ i40e_pf_parameter_init(struct rte_eth_dev *dev) pf->vf_qp_offset = pf->lan_qp_offset + pf->lan_nb_qps; if (hw->func_caps.sr_iov_1_1 && pci_dev->max_vfs) { pf->flags |= I40E_FLAG_SRIOV; - pf->vf_nb_qps = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF; + pf->vf_nb_qps = pf->vf_nb_qp_max; pf->vf_num = pci_dev->max_vfs; PMD_DRV_LOG(DEBUG, "%u VF VSIs, %u queues per VF VSI, in total %u queues", -- 2.20.1