[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20221019140943.18851-4-simon.horman@corigine.com>
Date: Wed, 19 Oct 2022 16:09:43 +0200
From: Simon Horman <simon.horman@...igine.com>
To: David Miller <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>
Cc: Michael Chan <michael.chan@...adcom.com>,
Andy Gospodarek <andy@...yhouse.net>,
Gal Pressman <gal@...dia.com>,
Saeed Mahameed <saeed@...nel.org>,
Jesse Brandeburg <jesse.brandeburg@...el.com>,
Tony Nguyen <anthony.l.nguyen@...el.com>,
Edward Cree <ecree.xilinx@...il.com>,
Vladimir Oltean <vladimir.oltean@....com>,
Andrew Lunn <andrew@...n.ch>,
Peng Zhang <peng.zhang@...igine.com>, netdev@...r.kernel.org,
oss-drivers@...igine.com
Subject: [PATCH net-next 3/3] nfp: devlink: add the devlink parameter "max_vf_queue" support
From: Peng Zhang <peng.zhang@...igine.com>
VF max-queue-number is the MAX num of queues which the VF has.
Currently, different users need that the number of VF max-queue-number
is different. Configuring the VF max-queue-number dynamically can
better match users. Hence, it is necessary to allow user to configure
the number of the VF max-queue-number.
The string format is V-W-X-Y-Z, the V represents generating
V VFs that have 16 queues, the W represents generating W VFs that
have 8 queues, and so on, the z represents generating Z VF that
has 1 queues. As far, it supports the VF max-queue-number is 16.
For example, to configure
* 1x VF with 16 queue
* 1x VF with 8 queues
* 2x VF with 4 queues
* 2x VF with 2 queues
* 0x VF with 1 queue, execute:
$ devlink dev param set pci/0000:01:00.0 \
name max_vf_queue value "1-1-2-2-0" cmode runtime
The nfp also support the variable-length argument, Y-Z, X-Y-Z, W-X-Y-Z
and Z, it also is right format and represents that the VFs which aren't
configured are all zero.
For example, execute:
$ devlink dev param set pci/0000:01:00.0 \
name max_vf_queue value "1-1" cmode runtime
It represent configure the queue is as follows:
* 0x VF with 16 queue
* 0x VF with 8 queues
* 0x VF with 4 queues
* 1x VF with 2 queues
* 1x VF with 1 queue
When created VF number is bigger than that is configured by this parameter,
the extra VFs' max-queue-number is 1.
If the config doesn't be set, the nfp vf max-queue-number is 2^n which is
round_down the average of the total queue / VF nums. If setting the config
is "0-0-0-0-0", it also is as the default way to generate VF.
Signed-off-by: Peng Zhang <peng.zhang@...igine.com>
Signed-off-by: Simon Horman <simon.horman@...igine.com>
---
Documentation/networking/devlink/nfp.rst | 2 +
.../ethernet/netronome/nfp/devlink_param.c | 114 ++++++++++++++++++
2 files changed, 116 insertions(+)
diff --git a/Documentation/networking/devlink/nfp.rst b/Documentation/networking/devlink/nfp.rst
index a1717db0dfcc..1936cee16dbe 100644
--- a/Documentation/networking/devlink/nfp.rst
+++ b/Documentation/networking/devlink/nfp.rst
@@ -18,6 +18,8 @@ Parameters
- permanent
* - ``reset_dev_on_drv_probe``
- permanent
+ * - ``vf_max_queue``
+ - runtime
Info versions
=============
diff --git a/drivers/net/ethernet/netronome/nfp/devlink_param.c b/drivers/net/ethernet/netronome/nfp/devlink_param.c
index db297ee4d7ad..5856b45601f7 100644
--- a/drivers/net/ethernet/netronome/nfp/devlink_param.c
+++ b/drivers/net/ethernet/netronome/nfp/devlink_param.c
@@ -6,6 +6,7 @@
#include "nfpcore/nfp.h"
#include "nfpcore/nfp_nsp.h"
#include "nfp_main.h"
+#include "nfp_net.h"
/**
* struct nfp_devlink_param_u8_arg - Devlink u8 parameter get/set arguments
@@ -191,7 +192,120 @@ nfp_devlink_param_u8_validate(struct devlink *devlink, u32 id,
return 0;
}
+static int
+nfp_devlink_vq_config_get(struct devlink *devlink, u32 id,
+ struct devlink_param_gset_ctx *ctx)
+{
+ struct nfp_pf *pf = devlink_priv(devlink);
+ char config[4 * NFP_NET_CFG_QUEUE_TYPE];
+ int i, len;
+
+ if (!pf)
+ return -ENODEV;
+
+ for (i = 0, len = 0; i < NFP_NET_CFG_QUEUE_TYPE; i++)
+ len += snprintf(config + len, sizeof(config), "%03d-", pf->config_vfs_queue[i]);
+ config[len - 1] = '\0';
+
+ strscpy(ctx->val.vstr, config, sizeof(ctx->val.vstr));
+
+ return 0;
+}
+
+static int
+nfp_devlink_vq_config_set(struct devlink *devlink, u32 id,
+ struct devlink_param_gset_ctx *ctx)
+{
+ int config_vfs_queue[NFP_NET_CFG_QUEUE_TYPE];
+ char vq[__DEVLINK_PARAM_MAX_STRING_VALUE];
+ struct nfp_pf *pf = devlink_priv(devlink);
+ char *num_vf, *value;
+ u8 config = 0;
+ int i;
+
+ if (!pf)
+ return -ENODEV;
+
+ strscpy(vq, ctx->val.vstr, sizeof(vq));
+ value = vq;
+ memset(config_vfs_queue, 0, sizeof(config_vfs_queue));
+
+ num_vf = strsep(&value, "-");
+ while (num_vf) {
+ if (kstrtouint(num_vf, 10, &config_vfs_queue[config++]))
+ return -EINVAL;
+ num_vf = strsep(&value, "-");
+ }
+
+ pf->default_config_vfs_queue = true;
+ memset(pf->config_vfs_queue, 0, sizeof(pf->config_vfs_queue));
+
+ for (i = NFP_NET_CFG_QUEUE_TYPE - 1; i >= 0; i--) {
+ if (config >= 1) {
+ pf->config_vfs_queue[i] = config_vfs_queue[--config];
+ if (pf->config_vfs_queue[i] && pf->default_config_vfs_queue)
+ pf->default_config_vfs_queue = false;
+ }
+ }
+
+ return 0;
+}
+
+static int
+nfp_devlink_vq_config_validate(struct devlink *devlink, u32 id,
+ union devlink_param_value val,
+ struct netlink_ext_ack *extack)
+{
+ int config_vfs_queue[NFP_NET_CFG_QUEUE_TYPE];
+ char vq[__DEVLINK_PARAM_MAX_STRING_VALUE];
+ struct nfp_pf *pf = devlink_priv(devlink);
+ char *num_vf, *value;
+ u32 total_q_num = 0;
+ u32 config = 0;
+ int i;
+
+ if (!pf) {
+ NL_SET_ERR_MSG_MOD(extack, "Can't find the device.");
+ return -ENODEV;
+ }
+
+ strscpy(vq, val.vstr, sizeof(vq));
+ value = vq;
+ memset(config_vfs_queue, 0, sizeof(config_vfs_queue));
+
+ num_vf = strsep(&value, "-");
+ while (num_vf) {
+ if (kstrtouint(num_vf, 10, &config_vfs_queue[config++])) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "The input format is error, expected format: %d-%d-%d-%d-%d.");
+ return -EINVAL;
+ }
+
+ if (config > NFP_NET_CFG_QUEUE_TYPE) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "The config queue type is more than the max_cfg_queue_type.");
+ return -EINVAL;
+ }
+ num_vf = strsep(&value, "-");
+ }
+
+ for (i = NFP_NET_CFG_QUEUE_TYPE - 1; i >= 0 && config; i--)
+ total_q_num += config_vfs_queue[--config] * NFP_NET_CFG_MAX_Q(i);
+
+ if (total_q_num > pf->max_vf_queues) {
+ NL_SET_ERR_MSG_MOD(extack, "The set queue is more than the MAX queue.");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static const struct devlink_param nfp_devlink_params[] = {
+ DEVLINK_PARAM_GENERIC(MAX_VF_QUEUE,
+ BIT(DEVLINK_PARAM_CMODE_RUNTIME),
+ nfp_devlink_vq_config_get,
+ nfp_devlink_vq_config_set,
+ nfp_devlink_vq_config_validate),
DEVLINK_PARAM_GENERIC(FW_LOAD_POLICY,
BIT(DEVLINK_PARAM_CMODE_PERMANENT),
nfp_devlink_param_u8_get,
--
2.30.2
Powered by blists - more mailing lists