Discussion:
[dpdk-dev] [PATCH v2] net/i40e: determine number of queues per VF during run time
(too old to reply)
Wei Dai
2017-11-19 07:43:45 UTC
Permalink
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 <***@intel.com>

---
v2: fix WARNING of coding style issues from ***@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
Wei Dai
2017-11-19 14:08:04 UTC
Permalink
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 <***@intel.com>

---
v3: fix WARNING of coding style issues from ***@dpdk.org
v2: fix WARNING of coding style issues from ***@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
Ananyev, Konstantin
2017-11-20 11:32:24 UTC
Permalink
-----Original Message-----
Sent: Sunday, November 19, 2017 2:08 PM
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 .
---
---
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
Dai, Wei
2017-11-22 02:46:50 UTC
Permalink
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
Subject: RE: [dpdk-dev] [PATCH v3] net/i40e: determine number of queues
per VF during run time
-----Original Message-----
Sent: Sunday, November 19, 2017 2:08 PM
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 .
---
---
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.
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
+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_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
Wei Dai
2017-11-22 14:10:49 UTC
Permalink
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 <***@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 ***@dpdk.org
v2:
fix WARNING of coding style issues from ***@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
Wei Dai
2017-11-24 06:12:49 UTC
Permalink
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 <***@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 ***@dpdk.org
v2:
fix WARNING of coding style issues from ***@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
Wei Dai
2017-11-27 08:08:59 UTC
Permalink
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 <***@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 ***@dpdk.org
v2:
fix WARNING of coding style issues from ***@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
Ananyev, Konstantin
2017-12-03 11:19:34 UTC
Permalink
Hi Wei,
-----Original Message-----
From: Dai, Wei
Sent: Monday, November 27, 2017 8:09 AM
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 .
---
fix a small bug when detecting end character of strtoul
fix git log message and WARNING of coding stype
use rte_kvargs instead of pervious parsing function;
use malloc/free instead of rte_zmalloc/rte_free.
---
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.
+ 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
Dai, Wei
2017-12-08 02:07:08 UTC
Permalink
-----Original Message-----
From: Ananyev, Konstantin
Sent: Sunday, December 3, 2017 7:20 PM
Subject: RE: [PATCH v6] net/i40e: determine number of queues per VF during
run time
Hi Wei,
-----Original Message-----
From: Dai, Wei
Sent: Monday, November 27, 2017 8:09 AM
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
Here it should be 'if the PCI address of an i40e PF is'
I will correct it in my v7 patch.
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 .
---
fix a small bug when detecting end character of strtoul
fix git log message and WARNING of coding stype
use rte_kvargs instead of pervious parsing function;
use malloc/free instead of rte_zmalloc/rte_free.
---
config/common_base | 1 -
drivers/net/i40e/i40e_ethdev.c | 67
++++++++++++++++++++++++++++++++++++++++--
2 files changed, 65 insertions(+), 3 deletions(-)
+ 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.
Thanks for your Ack, Konstantin.
I will use the macro I40E_MAX_QP_NUM_PER_VF instead of 16 in my v7 patch.
This macro is already defined as 16 in i40e_ethdev.h
+ 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;
+}
Wei Dai
2017-12-08 01:53:46 UTC
Permalink
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 <***@intel.com>
Acked-by: 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 ***@dpdk.org
v2:
fix WARNING of coding style issues from ***@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
Peng, Yuan
2017-12-11 02:33:39 UTC
Permalink
Tested-by: Peng,Yuan<***@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 <***@intel.com>; Wu, Jingjing <***@intel.com>; Xing, Beilei <***@intel.com>; Peng, Yuan <***@intel.com>
Cc: ***@dpdk.org; Dai, Wei <***@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 <***@intel.com>
Acked-by: 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 ***@dpdk.org
v2:
fix WARNING of coding style issues from ***@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
Zhang, Helin
2017-12-20 05:59:54 UTC
Permalink
-----Original Message-----
Sent: Friday, December 8, 2017 9:54 AM
To: Ananyev, Konstantin; Wu, Jingjing; Xing, Beilei; Peng, Yuan
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 .
Applied to next-net-intel. Thanks! /Helin
Wei Dai
2017-12-25 11:45:09 UTC
Permalink
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 <***@intel.com>
Acked-by: 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 ***@dpdk.org
v2:
fix WARNING of coding style issues from ***@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
Wei Dai
2017-12-26 15:24:54 UTC
Permalink
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 <***@intel.com>
Acked-by: 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 ***@dpdk.org
v2:
fix WARNING of coding style issues from ***@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
Zhang, Helin
2018-01-08 06:00:34 UTC
Permalink
-----Original Message-----
From: Dai, Wei
Sent: Tuesday, December 26, 2017 11:25 PM
To: Wu, Jingjing; Xing, Beilei; Zhang, Helin
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 .
---
v9 = v8+v7, is a complete version for maintainer's convenience.
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
use the macro instead of natural number
correct git log message as the EAL parameter is only valid for PF
fix a small bug when detecting end character of strtoul
fix git log message and WARNING of coding stype
use rte_kvargs instead of pervious parsing function;
use malloc/free instead of rte_zmalloc/rte_free.
---
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.
Dai, Wei
2018-01-09 09:09:41 UTC
Permalink
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
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
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 .
---
v9 = v8+v7, is a complete version for maintainer's convenience.
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
use the macro instead of natural number
correct git log message as the EAL parameter is only valid for PF
fix a small bug when detecting end character of strtoul
fix git log message and WARNING of coding stype
use rte_kvargs instead of pervious parsing function;
use malloc/free instead of rte_zmalloc/rte_free.
---
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.
Ferruh Yigit
2018-01-08 13:23:01 UTC
Permalink
Post by 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 .
---
v9 = v8+v7, is a complete version for maintainer's convenience.
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
use the macro instead of natural number
correct git log message as the EAL parameter is only valid for PF
fix a small bug when detecting end character of strtoul
fix git log message and WARNING of coding stype
use rte_kvargs instead of pervious parsing function;
use malloc/free instead of rte_zmalloc/rte_free.
---
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
Wei Dai
2018-01-09 08:56:07 UTC
Permalink
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 <***@intel.com>
Acked-by: 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 ***@dpdk.org
v2:
fix WARNING of coding style issues from ***@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
Zhang, Helin
2018-01-09 14:36:13 UTC
Permalink
-----Original Message-----
From: Dai, Wei
Sent: Tuesday, January 9, 2018 4:56 PM
To: Zhang, Helin; Yigit, Ferruh; Wu, Jingjing; Xing, Beilei
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 .
Applied to dpdk-next-net-intel with minor commit log changes. Thanks!

/Helin

Continue reading on narkive:
Loading...