DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v2] net/i40e: determine number of queues per VF during run time
@ 2017-11-19  7:43 Wei Dai
  2017-11-19 14:08 ` [dpdk-dev] [PATCH v3] " Wei Dai
  0 siblings, 1 reply; 18+ messages in thread
From: Wei Dai @ 2017-11-19  7:43 UTC (permalink / raw)
  To: jingjing.wu, beilei.xing; +Cc: dev, Wei Dai

Without this patch, the number of queues per i40e  VF is defined as 4
by CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base.
It is fixed value determined in building time and can't be changed
during run time.
With this patch, the number of queues per i40e VF can be determinated
during run time. For example, if the PCI address of an i40e VF is
aaaa:bb.cc, with the EAL parameter -w aaaa:bb.cc,i40e-queue-num-per-vf=8
, the number of queues per VF is 8.
If there is no "i40e-queue-num-per-vf" setting in EAL parameters,
it is 4 by default as before. And if the value after the
"i40e-queue-num-per-vf" is invalid, it is set as 4 forcibly.
The valid values include 1, 2, 4, 8, 16 .

Signed-off-by: Wei Dai <wei.dai@intel.com>

---
v2: fix WARNING of coding style issues from checkpatch@dpdk.org
---
 config/common_base             |  1 -
 drivers/net/i40e/i40e_ethdev.c | 68 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 66 insertions(+), 3 deletions(-)

diff --git a/config/common_base b/config/common_base
index e74febe..4e20389 100644
--- a/config/common_base
+++ b/config/common_base
@@ -208,7 +208,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/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 811cc9f..5b8c309 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3971,6 +3971,68 @@ i40e_get_cap(struct i40e_hw *hw)
 	return ret;
 }
 
+static int i40e_pf_config_vf_rxq_number(struct rte_eth_dev *dev)
+{
+#define RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF	4
+#define I40E_QUEUE_NUM_PER_VF_ARG		"i40e-queue-num-per-vf"
+#define IS_POWER_OF_2(n)			((n) && !((n) & ((n) - 1)))
+
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	char *s;
+	char *ps0, *ps1, *pv;
+	char *end;
+	unsigned long value;
+
+	if (!is_i40e_supported(dev))
+		return -ENOTSUP;
+
+	/* 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;
+
+	s = rte_zmalloc(__func__, strlen(dev->device->devargs->args) + 1, 0);
+	if (s == NULL)
+		return -(ENOMEM);
+	strcpy(s, dev->device->devargs->args);
+
+	ps0 = s;
+	do {
+		while (isblank(*ps0))
+			ps0++;
+		pv = strchr(ps0, '=');
+		if (pv == NULL)
+			break;
+		ps1 = pv - 1;
+		*pv++ = 0;
+
+		while (isblank(*ps1))
+			*ps1-- = 0;
+
+		if (!strcmp(ps0, I40E_QUEUE_NUM_PER_VF_ARG)) {
+			errno = 0;
+			value = strtoul(pv, &end, 0);
+			if (errno != 0 || end == pv)
+				break;
+			if (value <= 16 && IS_POWER_OF_2(value))
+				pf->vf_nb_qp_max = (uint16_t)value;
+			else
+				PMD_DRV_LOG(ERR, "Wrong VF queue number = %lu,"
+					" it must be power of 2 and equal or"
+					" less than 16 !", value);
+			break;
+		}
+		ps0 = strchr(pv, ',');
+		if (ps0 == NULL)
+			break;
+		ps0++;
+	} while (1);
+
+	rte_free(s);
+	return 0;
+}
+
 static int
 i40e_pf_parameter_init(struct rte_eth_dev *dev)
 {
@@ -3983,6 +4045,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;
@@ -3992,7 +4057,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;
@@ -4022,7 +4086,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.7.5

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [dpdk-dev] [PATCH v3] net/i40e: determine number of queues per VF during run time
  2017-11-19  7:43 [dpdk-dev] [PATCH v2] net/i40e: determine number of queues per VF during run time Wei Dai
@ 2017-11-19 14:08 ` Wei Dai
  2017-11-20 11:32   ` Ananyev, Konstantin
  2017-11-22 14:10   ` [dpdk-dev] [PATCH v4] " Wei Dai
  0 siblings, 2 replies; 18+ messages in thread
From: Wei Dai @ 2017-11-19 14:08 UTC (permalink / raw)
  To: jingjing.wu, beilei.xing; +Cc: dev, Wei Dai

Without this patch, the number of queues per i40e  VF is defined as 4
by CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base.
It is fixed value determined in building time and can't be changed
during run time.
With this patch, the number of queues per i40e VF can be determinated
during run time. For example, if the PCI address of an i40e VF is
aaaa:bb.cc, with the EAL parameter -w aaaa:bb.cc,i40e-queue-num-per-vf=8
, the number of queues per VF is 8.
If there is no "i40e-queue-num-per-vf" setting in EAL parameters,
it is 4 by default as before. And if the value after the
"i40e-queue-num-per-vf" is invalid, it is set as 4 forcibly.
The valid values include 1, 2, 4, 8, 16 .

Signed-off-by: Wei Dai <wei.dai@intel.com>

---
v3: fix WARNING of coding style issues from checkpatch@dpdk.org
v2: fix WARNING of coding style issues from checkpatch@dpdk.org
---
 config/common_base             |  1 -
 drivers/net/i40e/i40e_ethdev.c | 67 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/config/common_base b/config/common_base
index e74febe..4e20389 100644
--- a/config/common_base
+++ b/config/common_base
@@ -208,7 +208,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/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 811cc9f..b23a39e 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3971,6 +3971,67 @@ i40e_get_cap(struct i40e_hw *hw)
 	return ret;
 }
 
+static int i40e_pf_config_vf_rxq_number(struct rte_eth_dev *dev)
+{
+#define RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF	4
+#define I40E_QUEUE_NUM_PER_VF_ARG		"i40e-queue-num-per-vf"
+
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	char *s;
+	char *ps0, *ps1, *pv;
+	char *end;
+	unsigned long value;
+
+	if (!is_i40e_supported(dev))
+		return -ENOTSUP;
+
+	/* 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;
+
+	s = rte_zmalloc(__func__, strlen(dev->device->devargs->args) + 1, 0);
+	if (s == NULL)
+		return -(ENOMEM);
+	strcpy(s, dev->device->devargs->args);
+
+	ps0 = s;
+	do {
+		while (isblank(*ps0))
+			ps0++;
+		pv = strchr(ps0, '=');
+		if (pv == NULL)
+			break;
+		ps1 = pv - 1;
+		*pv++ = 0;
+
+		while (isblank(*ps1))
+			*ps1-- = 0;
+
+		if (!strcmp(ps0, I40E_QUEUE_NUM_PER_VF_ARG)) {
+			errno = 0;
+			value = strtoul(pv, &end, 0);
+			if (errno != 0 || end == pv)
+				break;
+			if (value <= 16 && rte_is_power_of_2(value))
+				pf->vf_nb_qp_max = (uint16_t)value;
+			else
+				PMD_DRV_LOG(ERR, "Wrong VF queue number = %lu,"
+					" it must be power of 2 and equal or"
+					" less than 16 !", value);
+			break;
+		}
+		ps0 = strchr(pv, ',');
+		if (ps0 == NULL)
+			break;
+		ps0++;
+	} while (1);
+
+	rte_free(s);
+	return 0;
+}
+
 static int
 i40e_pf_parameter_init(struct rte_eth_dev *dev)
 {
@@ -3983,6 +4044,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;
@@ -3992,7 +4056,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;
@@ -4022,7 +4085,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.7.5

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [dpdk-dev] [PATCH v3] net/i40e: determine number of queues per VF during run time
  2017-11-19 14:08 ` [dpdk-dev] [PATCH v3] " Wei Dai
@ 2017-11-20 11:32   ` Ananyev, Konstantin
  2017-11-22  2:46     ` Dai, Wei
  2017-11-22 14:10   ` [dpdk-dev] [PATCH v4] " Wei Dai
  1 sibling, 1 reply; 18+ messages in thread
From: Ananyev, Konstantin @ 2017-11-20 11:32 UTC (permalink / raw)
  To: Dai, Wei, Wu, Jingjing, Xing, Beilei; +Cc: dev, Dai, Wei



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Wei Dai
> Sent: Sunday, November 19, 2017 2:08 PM
> To: Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Dai, Wei <wei.dai@intel.com>
> Subject: [dpdk-dev] [PATCH v3] net/i40e: determine number of queues per VF during run time
> 
> Without this patch, the number of queues per i40e  VF is defined as 4
> by CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base.
> It is fixed value determined in building time and can't be changed
> during run time.
> With this patch, the number of queues per i40e VF can be determinated
> during run time. For example, if the PCI address of an i40e VF is
> aaaa:bb.cc, with the EAL parameter -w aaaa:bb.cc,i40e-queue-num-per-vf=8
> , the number of queues per VF is 8.
> If there is no "i40e-queue-num-per-vf" setting in EAL parameters,
> it is 4 by default as before. And if the value after the
> "i40e-queue-num-per-vf" is invalid, it is set as 4 forcibly.
> The valid values include 1, 2, 4, 8, 16 .
> 
> Signed-off-by: Wei Dai <wei.dai@intel.com>
> 
> ---
> v3: fix WARNING of coding style issues from checkpatch@dpdk.org
> v2: fix WARNING of coding style issues from checkpatch@dpdk.org
> ---
>  config/common_base             |  1 -
>  drivers/net/i40e/i40e_ethdev.c | 67 ++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 65 insertions(+), 3 deletions(-)
> 
> diff --git a/config/common_base b/config/common_base
> index e74febe..4e20389 100644
> --- a/config/common_base
> +++ b/config/common_base
> @@ -208,7 +208,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/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 811cc9f..b23a39e 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -3971,6 +3971,67 @@ i40e_get_cap(struct i40e_hw *hw)
>  	return ret;
>  }
> 
> +static int i40e_pf_config_vf_rxq_number(struct rte_eth_dev *dev)
> +{
> +#define RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF	4
> +#define I40E_QUEUE_NUM_PER_VF_ARG		"i40e-queue-num-per-vf"

Does it need to have i40e prefix?
Provably other HW type would support similar devarg?

> +
> +	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
> +	char *s;
> +	char *ps0, *ps1, *pv;
> +	char *end;
> +	unsigned long value;
> +
> +	if (!is_i40e_supported(dev))
> +		return -ENOTSUP;

Not a big deal - but that function is static, so I suppose the check is redundant.

> +
> +	/* 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;
> +
> +	s = rte_zmalloc(__func__, strlen(dev->device->devargs->args) + 1, 0);

No need to allocate temp memory from hugepages here.
Normal malloc, or even alloca() would do, I think.


> +	if (s == NULL)
> +		return -(ENOMEM);
> +	strcpy(s, dev->device->devargs->args);
> +

What is the point to write your own parsing function from scratch?
Why just not use rte_kvargs API as most other PMDs do?
BTW, i40e does the same in few other places.

> +	ps0 = s;
> +	do {
> +		while (isblank(*ps0))
> +			ps0++;
> +		pv = strchr(ps0, '=');
> +		if (pv == NULL)
> +			break;
> +		ps1 = pv - 1;
> +		*pv++ = 0;
> +
> +		while (isblank(*ps1))
> +			*ps1-- = 0;
> +
> +		if (!strcmp(ps0, I40E_QUEUE_NUM_PER_VF_ARG)) {
> +			errno = 0;
> +			value = strtoul(pv, &end, 0);
> +			if (errno != 0 || end == pv)

That wouldn't catch something like ...=1blah,
Should be *end != '0' (or whatever your stop-character is).
Anyway would be much better to use kvargs.
Even better to have a common function, something like:
int devargs_get_uint(const struct rte_devargs *devargs, const char *name,uint64_t *value);
and use it in all appropriate places.

Konstantin

> +				break;
> +			if (value <= 16 && rte_is_power_of_2(value))
> +				pf->vf_nb_qp_max = (uint16_t)value;
> +			else
> +				PMD_DRV_LOG(ERR, "Wrong VF queue number = %lu,"
> +					" it must be power of 2 and equal or"
> +					" less than 16 !", value);
> +			break;
> +		}
> +		ps0 = strchr(pv, ',');
> +		if (ps0 == NULL)
> +			break;
> +		ps0++;
> +	} while (1);
> +
> +	rte_free(s);
> +	return 0;
> +}
> +
>  static int
>  i40e_pf_parameter_init(struct rte_eth_dev *dev)
>  {
> @@ -3983,6 +4044,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;
> @@ -3992,7 +4056,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;
> @@ -4022,7 +4085,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.7.5

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [dpdk-dev] [PATCH v3] net/i40e: determine number of queues per VF during run time
  2017-11-20 11:32   ` Ananyev, Konstantin
@ 2017-11-22  2:46     ` Dai, Wei
  0 siblings, 0 replies; 18+ messages in thread
From: Dai, Wei @ 2017-11-22  2:46 UTC (permalink / raw)
  To: Ananyev, Konstantin, Wu, Jingjing, Xing, Beilei; +Cc: dev

Thank you, Konstantin for your quick feedback.
Please see my inline comments below.

> -----Original Message-----
> From: Ananyev, Konstantin
> Sent: Monday, November 20, 2017 7:32 PM
> To: Dai, Wei <wei.dai@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>;
> Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org; Dai, Wei <wei.dai@intel.com>
> Subject: RE: [dpdk-dev] [PATCH v3] net/i40e: determine number of queues
> per VF during run time
> 
> 
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Wei Dai
> > Sent: Sunday, November 19, 2017 2:08 PM
> > To: Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei
> > <beilei.xing@intel.com>
> > Cc: dev@dpdk.org; Dai, Wei <wei.dai@intel.com>
> > Subject: [dpdk-dev] [PATCH v3] net/i40e: determine number of queues
> > per VF during run time
> >
> > Without this patch, the number of queues per i40e  VF is defined as 4
> > by CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in
> config/common_base.
> > It is fixed value determined in building time and can't be changed
> > during run time.
> > With this patch, the number of queues per i40e VF can be determinated
> > during run time. For example, if the PCI address of an i40e VF is
> > aaaa:bb.cc, with the EAL parameter -w
> > aaaa:bb.cc,i40e-queue-num-per-vf=8
> > , the number of queues per VF is 8.
> > If there is no "i40e-queue-num-per-vf" setting in EAL parameters, it
> > is 4 by default as before. And if the value after the
> > "i40e-queue-num-per-vf" is invalid, it is set as 4 forcibly.
> > The valid values include 1, 2, 4, 8, 16 .
> >
> > Signed-off-by: Wei Dai <wei.dai@intel.com>
> >
> > ---
> > v3: fix WARNING of coding style issues from checkpatch@dpdk.org
> > v2: fix WARNING of coding style issues from checkpatch@dpdk.org
> > ---
> >  config/common_base             |  1 -
> >  drivers/net/i40e/i40e_ethdev.c | 67
> > ++++++++++++++++++++++++++++++++++++++++--
> >  2 files changed, 65 insertions(+), 3 deletions(-)
> >
> > diff --git a/config/common_base b/config/common_base index
> > e74febe..4e20389 100644
> > --- a/config/common_base
> > +++ b/config/common_base
> > @@ -208,7 +208,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/drivers/net/i40e/i40e_ethdev.c
> > b/drivers/net/i40e/i40e_ethdev.c index 811cc9f..b23a39e 100644
> > --- a/drivers/net/i40e/i40e_ethdev.c
> > +++ b/drivers/net/i40e/i40e_ethdev.c
> > @@ -3971,6 +3971,67 @@ i40e_get_cap(struct i40e_hw *hw)
> >  	return ret;
> >  }
> >
> > +static int i40e_pf_config_vf_rxq_number(struct rte_eth_dev *dev) {
> > +#define RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF	4
> > +#define I40E_QUEUE_NUM_PER_VF_ARG
> 	"i40e-queue-num-per-vf"
> 
> Does it need to have i40e prefix?
> Provably other HW type would support similar devarg?
Yes, I can't be sure if other HW type support this.
Will remove i40e prefix in next version of patch.

> 
> > +
> > +	struct i40e_pf *pf =
> I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
> > +	char *s;
> > +	char *ps0, *ps1, *pv;
> > +	char *end;
> > +	unsigned long value;
> > +
> > +	if (!is_i40e_supported(dev))
> > +		return -ENOTSUP;
> 
> Not a big deal - but that function is static, so I suppose the check is
> redundant.
Yes, this is a static function, so it can't be called by other type of NIC.
I add this in order to prevent it being called by other NIC.
Now I see it is unnecessary. I will remove it in next version of patch.

> 
> > +
> > +	/* 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;
> > +
> > +	s = rte_zmalloc(__func__, strlen(dev->device->devargs->args) + 1,
> > +0);
> 
> No need to allocate temp memory from hugepages here.
> Normal malloc, or even alloca() would do, I think.
Yes, no need to allocate memory from hugepage.
I will use normal malloc/freee instead of rte_zmalloc/rte_free.

> 
> 
> > +	if (s == NULL)
> > +		return -(ENOMEM);
> > +	strcpy(s, dev->device->devargs->args);
> > +
> 
> What is the point to write your own parsing function from scratch?
> Why just not use rte_kvargs API as most other PMDs do?
> BTW, i40e does the same in few other places.

Thanks for your guidance. I will use rte_kvargs in next version of patch.
I write my own parsing function only for performance.
As it is only in control path and for SW maintenance, it is better to use rte_kvargs.

> 
> > +	ps0 = s;
> > +	do {
> > +		while (isblank(*ps0))
> > +			ps0++;
> > +		pv = strchr(ps0, '=');
> > +		if (pv == NULL)
> > +			break;
> > +		ps1 = pv - 1;
> > +		*pv++ = 0;
> > +
> > +		while (isblank(*ps1))
> > +			*ps1-- = 0;
> > +
> > +		if (!strcmp(ps0, I40E_QUEUE_NUM_PER_VF_ARG)) {
> > +			errno = 0;
> > +			value = strtoul(pv, &end, 0);
> > +			if (errno != 0 || end == pv)
> 
> That wouldn't catch something like ...=1blah, Should be *end != '0' (or
> whatever your stop-character is).
> Anyway would be much better to use kvargs.
> Even better to have a common function, something like:
> int devargs_get_uint(const struct rte_devargs *devargs, const char
> *name,uint64_t *value); and use it in all appropriate places.
Will follow your guidance in next version of patch.
> 
> Konstantin
> 
> > +				break;
> > +			if (value <= 16 && rte_is_power_of_2(value))
> > +				pf->vf_nb_qp_max = (uint16_t)value;
> > +			else
> > +				PMD_DRV_LOG(ERR, "Wrong VF queue number = %lu,"
> > +					" it must be power of 2 and equal or"
> > +					" less than 16 !", value);
> > +			break;
> > +		}
> > +		ps0 = strchr(pv, ',');
> > +		if (ps0 == NULL)
> > +			break;
> > +		ps0++;
> > +	} while (1);
> > +
> > +	rte_free(s);
> > +	return 0;
> > +}
> > +
> >  static int
> >  i40e_pf_parameter_init(struct rte_eth_dev *dev)  { @@ -3983,6
> +4044,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; @@ -3992,7 +4056,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;
> > @@ -4022,7 +4085,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.7.5

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [dpdk-dev] [PATCH v4] net/i40e: determine number of queues per VF during run time
  2017-11-19 14:08 ` [dpdk-dev] [PATCH v3] " Wei Dai
  2017-11-20 11:32   ` Ananyev, Konstantin
@ 2017-11-22 14:10   ` Wei Dai
  2017-11-24  6:12     ` [dpdk-dev] [PATCH v5] " Wei Dai
  1 sibling, 1 reply; 18+ messages in thread
From: Wei Dai @ 2017-11-22 14:10 UTC (permalink / raw)
  To: jingjing.wu, beilei.xing; +Cc: dev, Wei Dai

Without this patch, the number of queues per i40e  VF is defined as 4
by CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base.
It is fixed value determined in building time and can't be changed
during run time.
With this patch, the number of queues per i40e VF can be determinated
during run time. For example, if the PCI address of an i40e VF is
aaaa:bb.cc, with the EAL parameter -w aaaa:bb.cc,queue-num-per-vf=8
, the number of queues per VF is 8.
If there is no "i40e-queue-num-per-vf" setting in EAL parameters,
it is 4 by default as before. And if the value after the
"i40e-queue-num-per-vf" is invalid, it is set as 4 forcibly.
The valid values include 1, 2, 4, 8, 16 .

Signed-off-by: Wei Dai <wei.dai@intel.com>

---
v4:
    use rte_kvargs instead of pervious parsing function;
    use malloc/free instead of rte_zmalloc/rte_free.
v3:
    fix WARNING of coding style issues from checkpatch@dpdk.org
v2:
    fix WARNING of coding style issues from checkpatch@dpdk.org
---
 config/common_base             |  1 -
 drivers/net/i40e/i40e_ethdev.c | 67 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/config/common_base b/config/common_base
index e74febe..4e20389 100644
--- a/config/common_base
+++ b/config/common_base
@@ -208,7 +208,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/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 811cc9f..b01ff3f 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3971,6 +3971,67 @@ 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"
+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(ERR, "Wrong VF queue number = %s, Now it is kept "
+				 "the value = %hu", value, pf->vf_nb_qp_max);
+		return -(EINVAL);
+	}
+
+	if (num <= 16 && 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(ERR, "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)
+{
+	const char *valid_keys[] = {QUEUE_NUM_PER_VF_ARG, ""};
+	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)
 {
@@ -3983,6 +4044,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;
@@ -3992,7 +4056,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;
@@ -4022,7 +4085,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.7.5

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [dpdk-dev] [PATCH v5] net/i40e: determine number of queues per VF during run time
  2017-11-22 14:10   ` [dpdk-dev] [PATCH v4] " Wei Dai
@ 2017-11-24  6:12     ` Wei Dai
  2017-11-27  8:08       ` [dpdk-dev] [PATCH v6] " Wei Dai
  0 siblings, 1 reply; 18+ messages in thread
From: Wei Dai @ 2017-11-24  6:12 UTC (permalink / raw)
  To: jingjing.wu, beilei.xing, konstantin.ananyev; +Cc: dev, Wei Dai

Without this patch, the number of queues per i40e  VF is defined as 4
by CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base.
It is fixed value determined in building time and can't be changed
during run time.
With this patch, the number of queues per i40e VF can be determinated
during run time. For example, if the PCI address of an i40e VF is
aaaa:bb.cc, with the EAL parameter -w aaaa:bb.cc,queue-num-per-vf=8,
the number of queues per VF is 8.
If there is no "queue-num-per-vf" setting in EAL parameters, it is 4
by default as before. And if the value after the "queue-num-per-vf"
is invalid, it is set as 4 forcibly. The valid values include 1, 2, 4,
8, 16 .

Signed-off-by: Wei Dai <wei.dai@intel.com>

---
v5:
    fix git log message and WARNING of coding stype
v4:
    use rte_kvargs instead of pervious parsing function;
    use malloc/free instead of rte_zmalloc/rte_free.
v3:
    fix WARNING of coding style issues from checkpatch@dpdk.org
v2:
    fix WARNING of coding style issues from checkpatch@dpdk.org
---
 config/common_base             |  1 -
 drivers/net/i40e/i40e_ethdev.c | 67 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/config/common_base b/config/common_base
index e74febe..4e20389 100644
--- a/config/common_base
+++ b/config/common_base
@@ -208,7 +208,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/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 811cc9f..a366163 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3971,6 +3971,67 @@ 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"
+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 <= 16 && 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, ""};
+	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)
 {
@@ -3983,6 +4044,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;
@@ -3992,7 +4056,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;
@@ -4022,7 +4085,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.7.5

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [dpdk-dev] [PATCH v6] net/i40e: determine number of queues per VF during run time
  2017-11-24  6:12     ` [dpdk-dev] [PATCH v5] " Wei Dai
@ 2017-11-27  8:08       ` Wei Dai
  2017-12-03 11:19         ` Ananyev, Konstantin
  2017-12-08  1:53         ` [dpdk-dev] [PATCH v7] " Wei Dai
  0 siblings, 2 replies; 18+ messages in thread
From: Wei Dai @ 2017-11-27  8:08 UTC (permalink / raw)
  To: jingjing.wu, beilei.xing, konstantin.ananyev; +Cc: dev, Wei Dai

Without this patch, the number of queues per i40e  VF is defined as 4
by CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base.
It is fixed value determined in building time and can't be changed
during run time.
With this patch, the number of queues per i40e VF can be determinated
during run time. For example, if the PCI address of an i40e VF is
aaaa:bb.cc, with the EAL parameter -w aaaa:bb.cc,queue-num-per-vf=8,
the number of queues per VF is 8.
If there is no "queue-num-per-vf" setting in EAL parameters, it is 4
by default as before. And if the value after the "queue-num-per-vf"
is invalid, it is set as 4 forcibly. The valid values include 1, 2, 4,
8, 16 .

Signed-off-by: Wei Dai <wei.dai@intel.com>

---
v6:
    fix a small bug when detecting end character of strtoul
v5:
    fix git log message and WARNING of coding stype
v4:
    use rte_kvargs instead of pervious parsing function;
    use malloc/free instead of rte_zmalloc/rte_free.
v3:
    fix WARNING of coding style issues from checkpatch@dpdk.org
v2:
    fix WARNING of coding style issues from checkpatch@dpdk.org
---
 config/common_base             |  1 -
 drivers/net/i40e/i40e_ethdev.c | 67 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/config/common_base b/config/common_base
index e74febe..4e20389 100644
--- a/config/common_base
+++ b/config/common_base
@@ -208,7 +208,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/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 811cc9f..6eceea1 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3971,6 +3971,67 @@ 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"
+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 <= 16 && 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, ""};
+	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)
 {
@@ -3983,6 +4044,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;
@@ -3992,7 +4056,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;
@@ -4022,7 +4085,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.7.5

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [dpdk-dev] [PATCH v6] net/i40e: determine number of queues per VF during run time
  2017-11-27  8:08       ` [dpdk-dev] [PATCH v6] " Wei Dai
@ 2017-12-03 11:19         ` Ananyev, Konstantin
  2017-12-08  1:53         ` [dpdk-dev] [PATCH v7] " Wei Dai
  1 sibling, 0 replies; 18+ messages in thread
From: Ananyev, Konstantin @ 2017-12-03 11:19 UTC (permalink / raw)
  To: Dai, Wei, Wu, Jingjing, Xing, Beilei; +Cc: dev

Hi Wei,

> -----Original Message-----
> From: Dai, Wei
> Sent: Monday, November 27, 2017 8:09 AM
> To: Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Cc: dev@dpdk.org; Dai, Wei <wei.dai@intel.com>
> Subject: [PATCH v6] net/i40e: determine number of queues per VF during run time
> 
> Without this patch, the number of queues per i40e  VF is defined as 4
> by CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base.
> It is fixed value determined in building time and can't be changed
> during run time.
> With this patch, the number of queues per i40e VF can be determinated
> during run time. For example, if the PCI address of an i40e VF is
> aaaa:bb.cc, with the EAL parameter -w aaaa:bb.cc,queue-num-per-vf=8,
> the number of queues per VF is 8.
> If there is no "queue-num-per-vf" setting in EAL parameters, it is 4
> by default as before. And if the value after the "queue-num-per-vf"
> is invalid, it is set as 4 forcibly. The valid values include 1, 2, 4,
> 8, 16 .
> 
> Signed-off-by: Wei Dai <wei.dai@intel.com>
> 
> ---
> v6:
>     fix a small bug when detecting end character of strtoul
> v5:
>     fix git log message and WARNING of coding stype
> v4:
>     use rte_kvargs instead of pervious parsing function;
>     use malloc/free instead of rte_zmalloc/rte_free.
> v3:
>     fix WARNING of coding style issues from checkpatch@dpdk.org
> v2:
>     fix WARNING of coding style issues from checkpatch@dpdk.org
> ---
>  config/common_base             |  1 -
>  drivers/net/i40e/i40e_ethdev.c | 67 ++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 65 insertions(+), 3 deletions(-)
> 
> diff --git a/config/common_base b/config/common_base
> index e74febe..4e20389 100644
> --- a/config/common_base
> +++ b/config/common_base
> @@ -208,7 +208,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/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 811cc9f..6eceea1 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -3971,6 +3971,67 @@ 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"
> +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 <= 16 && rte_is_power_of_2(num))

As a nit - better to use some macro instead of '16' here.
Apart from that - looks good to me.
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

> +		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, ""};
> +	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)
>  {
> @@ -3983,6 +4044,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;
> @@ -3992,7 +4056,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;
> @@ -4022,7 +4085,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.7.5

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [dpdk-dev] [PATCH v7] net/i40e: determine number of queues per VF during run time
  2017-11-27  8:08       ` [dpdk-dev] [PATCH v6] " Wei Dai
  2017-12-03 11:19         ` Ananyev, Konstantin
@ 2017-12-08  1:53         ` Wei Dai
  2017-12-11  2:33           ` Peng, Yuan
                             ` (2 more replies)
  1 sibling, 3 replies; 18+ messages in thread
From: Wei Dai @ 2017-12-08  1:53 UTC (permalink / raw)
  To: konstantin.ananyev, jingjing.wu, beilei.xing, yuan.peng; +Cc: dev, Wei Dai

Without this patch, the number of queues per i40e  VF is defined as 4
by CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base.
It is fixed value determined in building time and can't be changed
during run time.
With this patch, the number of queues per i40e VF can be determinated
during 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 8.
If there is no "queue-num-per-vf" setting in EAL parameters, it is 4
by default as before. And if the value after the "queue-num-per-vf"
is invalid, it is set as 4 forcibly. The valid values include 1, 2, 4,
8, 16 .

Signed-off-by: Wei Dai <wei.dai@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

---
v7:
    use the macro instead of natural number
    correct git log message as the EAL parameter is only valid for PF
v6:
    fix a small bug when detecting end character of strtoul
v5:
    fix git log message and WARNING of coding stype
v4:
    use rte_kvargs instead of pervious parsing function;
    use malloc/free instead of rte_zmalloc/rte_free.
v3:
    fix WARNING of coding style issues from checkpatch@dpdk.org
v2:
    fix WARNING of coding style issues from checkpatch@dpdk.org
---
 config/common_base             |  1 -
 drivers/net/i40e/i40e_ethdev.c | 67 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/config/common_base b/config/common_base
index e74febe..4e20389 100644
--- a/config/common_base
+++ b/config/common_base
@@ -208,7 +208,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/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 811cc9f..9295e1b 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3971,6 +3971,67 @@ 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"
+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, ""};
+	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)
 {
@@ -3983,6 +4044,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;
@@ -3992,7 +4056,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;
@@ -4022,7 +4085,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.7.5

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [dpdk-dev] [PATCH v7] net/i40e: determine number of queues per VF during run time
  2017-12-08  1:53         ` [dpdk-dev] [PATCH v7] " Wei Dai
@ 2017-12-11  2:33           ` Peng, Yuan
  2017-12-20  5:59           ` Zhang, Helin
  2017-12-25 11:45           ` [dpdk-dev] [PATCH v8] " Wei Dai
  2 siblings, 0 replies; 18+ messages in thread
From: Peng, Yuan @ 2017-12-11  2:33 UTC (permalink / raw)
  To: Dai, Wei, Ananyev, Konstantin, Wu, Jingjing, Xing, Beilei; +Cc: dev

Tested-by: Peng,Yuan<yuan.peng@intel.com>

- Tested Branch: dpdk master
- Tested Commit: 224374cc0e3ca44af5141fb7035a97f338d00c18
- OS: 4.5.5-300.fc24.x86_64
- GCC: gcc (GCC) 5.3.1 20151207 (Red Hat 5.3.1-2)
- CPU: Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz
- NIC: X710 for 10GbE SFP+ [8086:1572]
- Default x86_64-native-linuxapp-gcc configuration
- Prerequisites:
- Total 7 cases, 7 passed, 0 failed

- Prerequisites command / instruction:
 1.bind the pf port to dpdk driver::
    ./usertools/dpdk-devbind.py -b igb_uio 05:00.0
 2. set up two vfs from the pf with DPDK driver::
    echo 2 > /sys/bus/pci/devices/0000\:05\:00.0/max_vfs
   bind the two vfs to DPDK driver::
    ./usertools/dpdk-devbind.py -b vfio-pci 05:02.0 05:02.1

- Case: 
Test case 1: set valid VF max queue number
==========================================
1. try the valid values 1::
    ./x86_64-native-linuxapp-gcc/app/testpmd -c f -n 4 \
    -w 05:00.0,queue-num-per-vf=1 --file-prefix=test1 \
    --socket-mem 1024,1024 -- -i
   testpmd can be started normally without any wrong or error.
2. start VF testpmd with "--rxq=1 --txq=1", the number of rxq and txq is
   consistent with the configured VF max queue number::
    ./x86_64-native-linuxapp-gcc/app/testpmd -c 0xf0 -n 4 -w 05:02.0 \
    --file-prefix=test2 --socket-mem 1024,1024 -- -i --rxq=1 --txq=1
   check the Max possible RX queues and TX queues is 1::
   start forwarding, you can see the actual queue number is 1::
3. repeat step1-2 with "queue-num-per-vf=2/4/8/16", and start VF testpmd
   with consistent rxq and txq number. check the max queue num and actual
   queue number is 2/4/8/16.

Test case 2: set invalid VF max queue number
============================================
1. try the invalid value 0::
    ./x86_64-native-linuxapp-gcc/app/testpmd -c f -n 4 \
    -w 05:00.0,queue-num-per-vf=0 --file-prefix=test1 \
    --socket-mem 1024,1024 -- -i
   testpmd started with "i40e_pf_parse_vf_queue_number_handler(): Wrong
   VF queue number = 0, it must be power of 2 and equal or less than 16 !,
   Now it is kept the value = 4"
2. start VF testpmd with "--rxq=4 --txq=4", the number of rxq and txq is
   consistent with the default VF max queue number::
   check the Max possible RX queues and TX queues is 4::
   start forwarding, you can see the actual queue number is 4::
3. repeat step1-2 with "queue-num-per-vf=6/17/32", and start VF testpmd
   with default max rxq and txq number. check the max queue num and actual
   queue number is 4.

Test case 3: set VF queue number in testpmd command-line options
================================================================
1. set VF max queue number by PF::
    ./x86_64-native-linuxapp-gcc/app/testpmd -c f -n 4 \
    -w 05:00.0,queue-num-per-vf=8 --file-prefix=test1 \
    --socket-mem 1024,1024 -- -i
2. start VF testpmd with "--rxq=3 --txq=3"::
   check the Max possible RX queues and TX queues is 8::
   start forwarding, you can see the actual queue number is 3::
3. quit the VF testpmd, then restart VF testpmd with "--rxq=9 --txq=9"::
   VF testpmd failed to start with the print::
    Fail: nb_rxq(9) is greater than max_rx_queues(8)

Test case 4: set VF queue number with testpmd function command
==============================================================
1. set VF max queue number by PF::
    ./x86_64-native-linuxapp-gcc/app/testpmd -c f -n 4 \
    -w 05:00.0,queue-num-per-vf=8 --file-prefix=test1 \
    --socket-mem 1024,1024 -- -i
2. start VF testpmd without setting "rxq" and "txq"::
   check the Max possible RX queues and TX queues is 8::
   start forwarding, you can see the actual queue number is 1::
3. set rx queue number and tx queue number with testpmd function command::
    testpmd> port config all rxq 8
    testpmd> port config all txq 8
   start forwarding, you can see the actual queue number is 8::
4. reset rx queue number and tx queue number to 9::
    testpmd> port config all txq 9
    Fail: nb_txq(9) is greater than max_tx_queues(8)
    testpmd> port config all rxq 9
    Fail: nb_rxq(9) is greater than max_rx_queues(8)
  Failed to set it.

Test case 5: VF max queue number when VF bound to kernel driver
===============================================================
1. set VF max queue number to 2 by PF::
2. check the VF0 and VF1 rxq and txq number is 2::
    # ethtool -S enp5s2
3. repeat step1-2 with "queue-num-per-vf=1/4/8/16", check the rxq and txq
   number is 1/4/8/16.

Test case 6: set VF max queue number with 32 VFs on one PF port
===============================================================
1. set up 32 VFs from one PF with DPDK driver::
    echo 32 > /sys/bus/pci/devices/0000\:05\:00.0/max_vfs
   bind the two of the VFs to DPDK driver::
    ./usertools/dpdk-devbind.py -b vfio-pci 05:02.0 05:05.7
2. set VF max queue number to 16 by PF::
    ./x86_64-native-linuxapp-gcc/app/testpmd -c f -n 4 \
    -w 05:00.0,queue-num-per-vf=16 --file-prefix=test1 \
    --socket-mem 1024,1024 -- -i
   PF port failed to started with "i40e_pf_parameter_init():
   Failed to allocate 577 queues, which exceeds the hardware maximum 384"
3. set VF max queue number to 8 by PF::
   testpmd can be started normally without any wrong or error.
4. start the two VFs testpmd with "--rxq=8 --txq=8" and "--rxq=6 --txq=6"::
    ./x86_64-native-linuxapp-gcc/app/testpmd -c 0xf0 -n 4 -w 05:02.0 \
    --file-prefix=test2 --socket-mem 1024,1024 -- -i --rxq=8 --txq=8
    ./x86_64-native-linuxapp-gcc/app/testpmd -c 0xf00 -n 4 -w 05:05.7 \
    --file-prefix=test3 --socket-mem 1024,1024 -- -i --rxq=6 --txq=6
   check the Max possible RX queues and TX queues of the two VFs are both 8::
   start forwarding, you can see the actual queue number
   VF0 is 8, VF1 is 6.

Test case 7: pass through VF to VM
==================================
1. bind the pf to dpdk driver, then create 1 vf from pf,
   Detach VF from the host, bind VF to pci-stub driver,
   Lauch the VM with the VF PCI passthrough::
    taskset -c 5-20 qemu-system-x86_64 \
    -enable-kvm -m 8192 -smp cores=16,sockets=1 -cpu host -name dpdk1-vm1 \
    -drive file=/home/VM/ubuntu-14.04.img \
    -device pci-assign,host=0000:05:02.0 \
    -netdev tap,id=ipvm1,ifname=tap3,script=/etc/qemu-ifup -device rtl8139,netdev=ipvm1,id=net0,mac=00:00:00:00:00:01 \
    -localtime -vnc :2 -daemonize
2. set VF Max possible RX queues and TX queues to 8 by PF::
    ./x86_64-native-linuxapp-gcc/app/testpmd -c f -n 4 \
    -w 05:00.0,queue-num-per-vf=8 --file-prefix=test1 \
    --socket-mem 1024,1024 -- -i
   testpmd can be started normally without any wrong or error.
3. start VF testpmd with "--rxq=6 --txq=6", the number of rxq and txq is
   consistent with the configured VF max queue number,
   check the Max possible RX queues and TX queues is 8,
   start forwarding, you can see the actual queue number is 6.
   modify the queue number of VF::
    testpmd> port config all rxq 8
    testpmd> port config all txq 8
   start forwarding, you can see the VF1 actual queue number is 8.
4. repeat step2-3 with "queue-num-per-vf=1/2/4/16", and start VF testpmd
   with consistent rxq and txq number. check the max queue num and actual
   queue number is 1/2/4/16.
5. bind VF to kernel driver i40evf, check the rxq and txq number.
   if set VF Max possible RX queues and TX queues to 2 by PF,
   the VF rxq and txq number is 2::
    #ethtool -S eth0
   try to set VF Max possible RX queues and TX queues to 1/4/8/16 by PF,
   the VF rxq and txq number is 1/4/8/16::

                                                                         
- Case: 
  Description: l2fwd_crypto with SHA224_HMAC authentication test
  Command / instruction:
    Start l2fwd_crypto with QAT technology enable.
    Authentication method is SHA224_HMAC, auth key is also inputted in.
    Authentication key length for SHA224_HMAC should be 64 bytes.
      ./examples/l2fwd-crypto/build/app/l2fwd-crypto -c0xf -n4 -- -p0x1 \
        --chain HASH_ONLY --cdev_type ANY --auth_algo SHA224_HMAC \
        --auth_op GENERATE --auth_key $auth_key

    Send 65 packets with random 64 bytes payload and capture forwarded packets.
    Check all forwarded packets contained of 28 bytes hashed value.
    Check hash values are same as automatic calculated value.

-----Original Message-----
From: Dai, Wei 
Sent: Friday, December 8, 2017 9:54 AM
To: Ananyev, Konstantin <konstantin.ananyev@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Peng, Yuan <yuan.peng@intel.com>
Cc: dev@dpdk.org; Dai, Wei <wei.dai@intel.com>
Subject: [PATCH v7] net/i40e: determine number of queues per VF during run time

Without this patch, the number of queues per i40e  VF is defined as 4 by CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base.
It is fixed value determined in building time and can't be changed during run time.
With this patch, the number of queues per i40e VF can be determinated during 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 8.
If there is no "queue-num-per-vf" setting in EAL parameters, it is 4 by default as before. And if the value after the "queue-num-per-vf"
is invalid, it is set as 4 forcibly. The valid values include 1, 2, 4, 8, 16 .

Signed-off-by: Wei Dai <wei.dai@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

---
v7:
    use the macro instead of natural number
    correct git log message as the EAL parameter is only valid for PF
v6:
    fix a small bug when detecting end character of strtoul
v5:
    fix git log message and WARNING of coding stype
v4:
    use rte_kvargs instead of pervious parsing function;
    use malloc/free instead of rte_zmalloc/rte_free.
v3:
    fix WARNING of coding style issues from checkpatch@dpdk.org
v2:
    fix WARNING of coding style issues from checkpatch@dpdk.org
---
 config/common_base             |  1 -
 drivers/net/i40e/i40e_ethdev.c | 67 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/config/common_base b/config/common_base index e74febe..4e20389 100644
--- a/config/common_base
+++ b/config/common_base
@@ -208,7 +208,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/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 811cc9f..9295e1b 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3971,6 +3971,67 @@ 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"
+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, ""};
+	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)  { @@ -3983,6 +4044,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; @@ -3992,7 +4056,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;
@@ -4022,7 +4085,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.7.5

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [dpdk-dev] [PATCH v7] net/i40e: determine number of queues per VF during run time
  2017-12-08  1:53         ` [dpdk-dev] [PATCH v7] " Wei Dai
  2017-12-11  2:33           ` Peng, Yuan
@ 2017-12-20  5:59           ` Zhang, Helin
  2017-12-25 11:45           ` [dpdk-dev] [PATCH v8] " Wei Dai
  2 siblings, 0 replies; 18+ messages in thread
From: Zhang, Helin @ 2017-12-20  5:59 UTC (permalink / raw)
  To: Dai, Wei, Ananyev, Konstantin, Wu, Jingjing, Xing, Beilei, Peng, Yuan
  Cc: dev, Dai, Wei



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Wei Dai
> Sent: Friday, December 8, 2017 9:54 AM
> To: Ananyev, Konstantin; Wu, Jingjing; Xing, Beilei; Peng, Yuan
> Cc: dev@dpdk.org; Dai, Wei
> Subject: [dpdk-dev] [PATCH v7] net/i40e: determine number of queues per
> VF during run time
> 
> Without this patch, the number of queues per i40e  VF is defined as 4 by
> CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base.
> It is fixed value determined in building time and can't be changed during run
> time.
> With this patch, the number of queues per i40e VF can be determinated
> during 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 8.
> If there is no "queue-num-per-vf" setting in EAL parameters, it is 4 by default
> as before. And if the value after the "queue-num-per-vf"
> is invalid, it is set as 4 forcibly. The valid values include 1, 2, 4, 8, 16 .
> 
> Signed-off-by: Wei Dai <wei.dai@intel.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

Applied to next-net-intel. Thanks! /Helin

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [dpdk-dev] [PATCH v8] net/i40e: determine number of queues per VF during run time
  2017-12-08  1:53         ` [dpdk-dev] [PATCH v7] " Wei Dai
  2017-12-11  2:33           ` Peng, Yuan
  2017-12-20  5:59           ` Zhang, Helin
@ 2017-12-25 11:45           ` Wei Dai
  2017-12-26 15:24             ` [dpdk-dev] [PATCH v9] " Wei Dai
  2 siblings, 1 reply; 18+ messages in thread
From: Wei Dai @ 2017-12-25 11:45 UTC (permalink / raw)
  To: jingjing.wu, beilei.xing; +Cc: dev, Wei Dai

Without this patch, the number of queues per i40e  VF is defined as 4
by CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base.
It is fixed value determined in building time and can't be changed
during run time.
With this patch, the number of queues per i40e VF can be determinated
during 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 8.
If there is no "queue-num-per-vf" setting in EAL parameters, it is 4
by default as before. And if the value after the "queue-num-per-vf"
is invalid, it is set as 4 forcibly. The valid values include 1, 2, 4,
8, 16 .

Signed-off-by: Wei Dai <wei.dai@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
v8:
    As v7 patch has been accepted into dpdk-next-net-intel, this patch
    is based on v7 patch.
    add description in i40e document
    fix the last member of valid_keys[] for rte_kvargs_parse( )
    add RTE_PMD_REGISTER_PARAM_STRING for this feature
v7:
    use the macro instead of natural number
    correct git log message as the EAL parameter is only valid for PF
v6:
    fix a small bug when detecting end character of strtoul
v5:
    fix git log message and WARNING of coding stype
v4:
    use rte_kvargs instead of pervious parsing function;
    use malloc/free instead of rte_zmalloc/rte_free.
v3:
    fix WARNING of coding style issues from checkpatch@dpdk.org
v2:
    fix WARNING of coding style issues from checkpatch@dpdk.org
---
 doc/guides/nics/i40e.rst       | 12 ++++++++----
 drivers/net/i40e/i40e_ethdev.c |  4 +++-
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index 2507d5f..68ae8eb 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -117,10 +117,6 @@ Please note that enabling debugging options may affect system performance.
 
 - ``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.
 
 - ``CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL`` (default ``-1``)
@@ -374,6 +370,14 @@ configuration passed on the EAL command line.
 The floating VEB functionality requires a NIC firmware version of 5.0
 or greater.
 
+Number of Queues per 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 paramter like -w aaaa:bb.cc,queue-num-per-vf=n. The value n can be 1, 2, 4,
+8 or 16. If no such paramter is configured, the number of queues per VF is 4
+by default.
 
 Limitations or Known issues
 ---------------------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 9916f49..24dae37 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3973,6 +3973,8 @@ i40e_get_cap(struct i40e_hw *hw)
 
 #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)
@@ -4005,7 +4007,7 @@ static int i40e_pf_parse_vf_queue_number_handler(const char *key,
 
 static int i40e_pf_config_vf_rxq_number(struct rte_eth_dev *dev)
 {
-	static const char * const valid_keys[] = {QUEUE_NUM_PER_VF_ARG, ""};
+	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;
 
-- 
2.7.5

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [dpdk-dev] [PATCH v9] net/i40e: determine number of queues per VF during run time
  2017-12-25 11:45           ` [dpdk-dev] [PATCH v8] " Wei Dai
@ 2017-12-26 15:24             ` Wei Dai
  2018-01-08  6:00               ` Zhang, Helin
                                 ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Wei Dai @ 2017-12-26 15:24 UTC (permalink / raw)
  To: jingjing.wu, beilei.xing, helin.zhang; +Cc: dev, Wei Dai

Without this patch, the number of queues per i40e  VF is defined as 4
by CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base.
It is fixed value determined in building time and can't be changed
during run time.
With this patch, the number of queues per i40e VF can be determinated
during 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 8.
If there is no "queue-num-per-vf" setting in EAL parameters, it is 4
by default as before. And if the value after the "queue-num-per-vf"
is invalid, it is set as 4 forcibly. The valid values include 1, 2, 4,
8, 16 .

Signed-off-by: Wei Dai <wei.dai@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
v9:
    v9 = v8+v7, is a complete version for maintainer's convenience.
v8:
    As v7 patch has been accepted into dpdk-next-net-intel, this patch
    is based on v7 patch.
    add description in i40e document
    fix the last member of valid_keys[] for rte_kvargs_parse( )
    add RTE_PMD_REGISTER_PARAM_STRING for this feature
v7:
    use the macro instead of natural number
    correct git log message as the EAL parameter is only valid for PF
v6:
    fix a small bug when detecting end character of strtoul
v5:
    fix git log message and WARNING of coding stype
v4:
    use rte_kvargs instead of pervious parsing function;
    use malloc/free instead of rte_zmalloc/rte_free.
v3:
    fix WARNING of coding style issues from checkpatch@dpdk.org
v2:
    fix WARNING of coding style issues from checkpatch@dpdk.org
---
 config/common_base             |  1 -
 doc/guides/nics/i40e.rst       | 12 ++++---
 drivers/net/i40e/i40e_ethdev.c | 75 +++++++++++++++++++++++++++++++++++++++---
 3 files changed, 78 insertions(+), 10 deletions(-)

diff --git a/config/common_base b/config/common_base
index e74febe..4e20389 100644
--- a/config/common_base
+++ b/config/common_base
@@ -208,7 +208,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 cd46874..abb20da 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.
@@ -374,6 +370,14 @@ configuration passed on the EAL command line.
 The floating VEB functionality requires a NIC firmware version of 5.0
 or greater.
 
+Number of Queues per 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.
 
 Limitations or Known issues
 ---------------------------
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 811cc9f..24dae37 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3971,6 +3971,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)
 {
@@ -3983,6 +4046,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;
@@ -3992,7 +4058,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;
@@ -4022,7 +4087,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",
@@ -5315,15 +5380,15 @@ i40e_dev_init_vlan(struct rte_eth_dev *dev)
 	int mask = 0;
 
 	/* Apply vlan offload setting */
-	mask = ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK;
+	mask = ETH_VLAN_STRIP_MASK |
+	       ETH_VLAN_FILTER_MASK |
+	       ETH_VLAN_EXTEND_MASK;
 	ret = i40e_vlan_offload_set(dev, mask);
 	if (ret) {
 		PMD_DRV_LOG(INFO, "Failed to update vlan offload");
 		return ret;
 	}
 
-	/* Apply double-vlan setting, not implemented yet */
-
 	/* Apply pvid setting */
 	ret = i40e_vlan_pvid_set(dev, data->dev_conf.txmode.pvid,
 				data->dev_conf.txmode.hw_vlan_insert_pvid);
-- 
2.7.5

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [dpdk-dev] [PATCH v9] net/i40e: determine number of queues per VF during run time
  2017-12-26 15:24             ` [dpdk-dev] [PATCH v9] " Wei Dai
@ 2018-01-08  6:00               ` Zhang, Helin
  2018-01-09  9:09                 ` Dai, Wei
  2018-01-08 13:23               ` Ferruh Yigit
  2018-01-09  8:56               ` [dpdk-dev] [PATCH v10] " Wei Dai
  2 siblings, 1 reply; 18+ messages in thread
From: Zhang, Helin @ 2018-01-08  6:00 UTC (permalink / raw)
  To: Dai, Wei, Wu, Jingjing, Xing, Beilei; +Cc: dev



> -----Original Message-----
> From: Dai, Wei
> Sent: Tuesday, December 26, 2017 11:25 PM
> To: Wu, Jingjing; Xing, Beilei; Zhang, Helin
> Cc: dev@dpdk.org; Dai, Wei
> Subject: [PATCH v9] net/i40e: determine number of queues per VF during run
> time
> 
> Without this patch, the number of queues per i40e  VF is defined as 4 by
> CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base.
> It is fixed value determined in building time and can't be changed during run
> time.
> With this patch, the number of queues per i40e VF can be determinated during
> 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 8.
> If there is no "queue-num-per-vf" setting in EAL parameters, it is 4 by default as
> before. And if the value after the "queue-num-per-vf"
> is invalid, it is set as 4 forcibly. The valid values include 1, 2, 4, 8, 16 .
> 
> Signed-off-by: Wei Dai <wei.dai@intel.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> ---
> v9:
>     v9 = v8+v7, is a complete version for maintainer's convenience.
> v8:
>     As v7 patch has been accepted into dpdk-next-net-intel, this patch
>     is based on v7 patch.
>     add description in i40e document
>     fix the last member of valid_keys[] for rte_kvargs_parse( )
>     add RTE_PMD_REGISTER_PARAM_STRING for this feature
> v7:
>     use the macro instead of natural number
>     correct git log message as the EAL parameter is only valid for PF
> v6:
>     fix a small bug when detecting end character of strtoul
> v5:
>     fix git log message and WARNING of coding stype
> v4:
>     use rte_kvargs instead of pervious parsing function;
>     use malloc/free instead of rte_zmalloc/rte_free.
> v3:
>     fix WARNING of coding style issues from checkpatch@dpdk.org
> v2:
>     fix WARNING of coding style issues from checkpatch@dpdk.org
> ---
>  config/common_base             |  1 -
>  doc/guides/nics/i40e.rst       | 12 ++++---
>  drivers/net/i40e/i40e_ethdev.c | 75
> +++++++++++++++++++++++++++++++++++++++---
>  3 files changed, 78 insertions(+), 10 deletions(-)

BTW, I think release notes should be updated for your modifications.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [dpdk-dev] [PATCH v9] net/i40e: determine number of queues per VF during run time
  2017-12-26 15:24             ` [dpdk-dev] [PATCH v9] " Wei Dai
  2018-01-08  6:00               ` Zhang, Helin
@ 2018-01-08 13:23               ` Ferruh Yigit
  2018-01-09  8:56               ` [dpdk-dev] [PATCH v10] " Wei Dai
  2 siblings, 0 replies; 18+ messages in thread
From: Ferruh Yigit @ 2018-01-08 13:23 UTC (permalink / raw)
  To: Wei Dai, jingjing.wu, beilei.xing, helin.zhang; +Cc: dev

On 12/26/2017 3:24 PM, Wei Dai wrote:
> Without this patch, the number of queues per i40e  VF is defined as 4
> by CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base.
> It is fixed value determined in building time and can't be changed
> during run time.
> With this patch, the number of queues per i40e VF can be determinated
> during 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 8.
> If there is no "queue-num-per-vf" setting in EAL parameters, it is 4
> by default as before. And if the value after the "queue-num-per-vf"
> is invalid, it is set as 4 forcibly. The valid values include 1, 2, 4,
> 8, 16 .
> 
> Signed-off-by: Wei Dai <wei.dai@intel.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> ---
> v9:
>     v9 = v8+v7, is a complete version for maintainer's convenience.
> v8:
>     As v7 patch has been accepted into dpdk-next-net-intel, this patch
>     is based on v7 patch.
>     add description in i40e document
>     fix the last member of valid_keys[] for rte_kvargs_parse( )
>     add RTE_PMD_REGISTER_PARAM_STRING for this feature
> v7:
>     use the macro instead of natural number
>     correct git log message as the EAL parameter is only valid for PF
> v6:
>     fix a small bug when detecting end character of strtoul
> v5:
>     fix git log message and WARNING of coding stype
> v4:
>     use rte_kvargs instead of pervious parsing function;
>     use malloc/free instead of rte_zmalloc/rte_free.
> v3:
>     fix WARNING of coding style issues from checkpatch@dpdk.org
> v2:
>     fix WARNING of coding style issues from checkpatch@dpdk.org
> ---
>  config/common_base             |  1 -
>  doc/guides/nics/i40e.rst       | 12 ++++---
>  drivers/net/i40e/i40e_ethdev.c | 75 +++++++++++++++++++++++++++++++++++++++---
>  3 files changed, 78 insertions(+), 10 deletions(-)
> 
> diff --git a/config/common_base b/config/common_base
> index e74febe..4e20389 100644
> --- a/config/common_base
> +++ b/config/common_base
> @@ -208,7 +208,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 cd46874..abb20da 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``)
>  

Hi Wei,

What do you think creating a section for "Runtime config options" in same level
for "Config File Options" and explain new "queue-num-per-vf" option there?

Thanks,
ferruh

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [dpdk-dev] [PATCH v10] net/i40e: determine number of queues per VF during run time
  2017-12-26 15:24             ` [dpdk-dev] [PATCH v9] " Wei Dai
  2018-01-08  6:00               ` Zhang, Helin
  2018-01-08 13:23               ` Ferruh Yigit
@ 2018-01-09  8:56               ` Wei Dai
  2018-01-09 14:36                 ` Zhang, Helin
  2 siblings, 1 reply; 18+ messages in thread
From: Wei Dai @ 2018-01-09  8:56 UTC (permalink / raw)
  To: helin.zhang, ferruh.yigit, jingjing.wu, beilei.xing; +Cc: dev, Wei Dai

Without this patch, the number of queues per i40e  VF is defined as 4
by CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base.
It is fixed value determined in building time and can't be changed
during run time.
With this patch, the number of queues per i40e VF can be determinated
during 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 8.
If there is no "queue-num-per-vf" setting in EAL parameters, it is 4
by default as before. And if the value after the "queue-num-per-vf"
is invalid, it is set as 4 forcibly. The valid values include 1, 2, 4,
8, 16 .

Signed-off-by: Wei Dai <wei.dai@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
v10:
    update doc according to feedback from Ferruh and Helin.

v9:
    v9 = v8+v7, is a complete version for maintainer's convenience.
v8:
    As v7 patch has been accepted into dpdk-next-net-intel, this patch
    is based on v7 patch.
    add description in i40e document
    fix the last member of valid_keys[] for rte_kvargs_parse( )
    add RTE_PMD_REGISTER_PARAM_STRING for this feature
v7:
    use the macro instead of natural number
    correct git log message as the EAL parameter is only valid for PF
v6:
    fix a small bug when detecting end character of strtoul
v5:
    fix git log message and WARNING of coding stype
v4:
    use rte_kvargs instead of pervious parsing function;
    use malloc/free instead of rte_zmalloc/rte_free.
v3:
    fix WARNING of coding style issues from checkpatch@dpdk.org
v2:
    fix WARNING of coding style issues from checkpatch@dpdk.org
---
 config/common_base                     |  1 -
 doc/guides/nics/i40e.rst               | 16 ++++++--
 doc/guides/rel_notes/release_18_02.rst |  9 +++++
 drivers/net/i40e/i40e_ethdev.c         | 69 +++++++++++++++++++++++++++++++++-
 4 files changed, 88 insertions(+), 7 deletions(-)

diff --git a/config/common_base b/config/common_base
index b8ee8f9..0338074 100644
--- a/config/common_base
+++ b/config/common_base
@@ -208,7 +208,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 2507d5f..c4c10d3 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 f6e8090..2e0e796 100644
--- a/doc/guides/rel_notes/release_18_02.rst
+++ b/doc/guides/rel_notes/release_18_02.rst
@@ -69,6 +69,15 @@ New Features
   rte_flow. This patch is to support igb and ixgbe NIC with existing RSS
   configuration using rte_flow API.
 
+* **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.
+
+
 API Changes
 -----------
 
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 2324525..ec250e9 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.7.5

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [dpdk-dev] [PATCH v9] net/i40e: determine number of queues per VF during run time
  2018-01-08  6:00               ` Zhang, Helin
@ 2018-01-09  9:09                 ` Dai, Wei
  0 siblings, 0 replies; 18+ messages in thread
From: Dai, Wei @ 2018-01-09  9:09 UTC (permalink / raw)
  To: Zhang, Helin, Wu, Jingjing, Xing, Beilei; +Cc: dev

Thanks to Helin and Ferruh,
I will submit v10 patch following your guide.

> -----Original Message-----
> From: Zhang, Helin
> Sent: Monday, January 8, 2018 2:01 PM
> To: Dai, Wei <wei.dai@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>;
> Xing, Beilei <beilei.xing@intel.com>
> Cc: dev@dpdk.org
> Subject: RE: [PATCH v9] net/i40e: determine number of queues per VF during
> run time
> 
> 
> 
> > -----Original Message-----
> > From: Dai, Wei
> > Sent: Tuesday, December 26, 2017 11:25 PM
> > To: Wu, Jingjing; Xing, Beilei; Zhang, Helin
> > Cc: dev@dpdk.org; Dai, Wei
> > Subject: [PATCH v9] net/i40e: determine number of queues per VF during
> > run time
> >
> > Without this patch, the number of queues per i40e  VF is defined as 4
> > by
> > CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in
> config/common_base.
> > It is fixed value determined in building time and can't be changed
> > during run time.
> > With this patch, the number of queues per i40e VF can be determinated
> > during 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 8.
> > If there is no "queue-num-per-vf" setting in EAL parameters, it is 4
> > by default as before. And if the value after the "queue-num-per-vf"
> > is invalid, it is set as 4 forcibly. The valid values include 1, 2, 4, 8, 16 .
> >
> > Signed-off-by: Wei Dai <wei.dai@intel.com>
> > Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> > ---
> > v9:
> >     v9 = v8+v7, is a complete version for maintainer's convenience.
> > v8:
> >     As v7 patch has been accepted into dpdk-next-net-intel, this patch
> >     is based on v7 patch.
> >     add description in i40e document
> >     fix the last member of valid_keys[] for rte_kvargs_parse( )
> >     add RTE_PMD_REGISTER_PARAM_STRING for this feature
> > v7:
> >     use the macro instead of natural number
> >     correct git log message as the EAL parameter is only valid for PF
> > v6:
> >     fix a small bug when detecting end character of strtoul
> > v5:
> >     fix git log message and WARNING of coding stype
> > v4:
> >     use rte_kvargs instead of pervious parsing function;
> >     use malloc/free instead of rte_zmalloc/rte_free.
> > v3:
> >     fix WARNING of coding style issues from checkpatch@dpdk.org
> > v2:
> >     fix WARNING of coding style issues from checkpatch@dpdk.org
> > ---
> >  config/common_base             |  1 -
> >  doc/guides/nics/i40e.rst       | 12 ++++---
> >  drivers/net/i40e/i40e_ethdev.c | 75
> > +++++++++++++++++++++++++++++++++++++++---
> >  3 files changed, 78 insertions(+), 10 deletions(-)
> 
> BTW, I think release notes should be updated for your modifications.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [dpdk-dev] [PATCH v10] net/i40e: determine number of queues per VF during run time
  2018-01-09  8:56               ` [dpdk-dev] [PATCH v10] " Wei Dai
@ 2018-01-09 14:36                 ` Zhang, Helin
  0 siblings, 0 replies; 18+ messages in thread
From: Zhang, Helin @ 2018-01-09 14:36 UTC (permalink / raw)
  To: Dai, Wei, Yigit, Ferruh, Wu, Jingjing, Xing, Beilei; +Cc: dev



> -----Original Message-----
> From: Dai, Wei
> Sent: Tuesday, January 9, 2018 4:56 PM
> To: Zhang, Helin; Yigit, Ferruh; Wu, Jingjing; Xing, Beilei
> Cc: dev@dpdk.org; Dai, Wei
> Subject: [PATCH v10] net/i40e: determine number of queues per VF during run
> time
> 
> Without this patch, the number of queues per i40e  VF is defined as 4 by
> CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF=4 in config/common_base.
> It is fixed value determined in building time and can't be changed during run
> time.
> With this patch, the number of queues per i40e VF can be determinated during
> 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 8.
> If there is no "queue-num-per-vf" setting in EAL parameters, it is 4 by default as
> before. And if the value after the "queue-num-per-vf"
> is invalid, it is set as 4 forcibly. The valid values include 1, 2, 4, 8, 16 .
> 
> Signed-off-by: Wei Dai <wei.dai@intel.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Applied to dpdk-next-net-intel with minor commit log changes. Thanks!

/Helin

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2018-01-09 14:36 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-19  7:43 [dpdk-dev] [PATCH v2] net/i40e: determine number of queues per VF during run time Wei Dai
2017-11-19 14:08 ` [dpdk-dev] [PATCH v3] " Wei Dai
2017-11-20 11:32   ` Ananyev, Konstantin
2017-11-22  2:46     ` Dai, Wei
2017-11-22 14:10   ` [dpdk-dev] [PATCH v4] " Wei Dai
2017-11-24  6:12     ` [dpdk-dev] [PATCH v5] " Wei Dai
2017-11-27  8:08       ` [dpdk-dev] [PATCH v6] " Wei Dai
2017-12-03 11:19         ` Ananyev, Konstantin
2017-12-08  1:53         ` [dpdk-dev] [PATCH v7] " Wei Dai
2017-12-11  2:33           ` Peng, Yuan
2017-12-20  5:59           ` Zhang, Helin
2017-12-25 11:45           ` [dpdk-dev] [PATCH v8] " Wei Dai
2017-12-26 15:24             ` [dpdk-dev] [PATCH v9] " Wei Dai
2018-01-08  6:00               ` Zhang, Helin
2018-01-09  9:09                 ` Dai, Wei
2018-01-08 13:23               ` Ferruh Yigit
2018-01-09  8:56               ` [dpdk-dev] [PATCH v10] " Wei Dai
2018-01-09 14:36                 ` Zhang, Helin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).