All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mark Bloch <mbloch@nvidia.com>
To: Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Andrew Lunn <andrew+netdev@lunn.ch>,
	"David S. Miller" <davem@davemloft.net>
Cc: Jonathan Corbet <corbet@lwn.net>,
	Shuah Khan <skhan@linuxfoundation.org>,
	Jiri Pirko <jiri@resnulli.us>, Simon Horman <horms@kernel.org>,
	"Saeed Mahameed" <saeedm@nvidia.com>,
	Leon Romanovsky <leon@kernel.org>,
	Tariq Toukan <tariqt@nvidia.com>, Mark Bloch <mbloch@nvidia.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	"Borislav Petkov (AMD)" <bp@alien8.de>,
	"Randy Dunlap" <rdunlap@infradead.org>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	Christian Brauner <brauner@kernel.org>,
	Petr Mladek <pmladek@suse.com>,
	"Peter Zijlstra (Intel)" <peterz@infradead.org>,
	Thomas Gleixner <tglx@kernel.org>,
	Pawan Gupta <pawan.kumar.gupta@linux.intel.com>,
	Dapeng Mi <dapeng1.mi@linux.intel.com>,
	Kees Cook <kees@kernel.org>, Marco Elver <elver@google.com>,
	Eric Biggers <ebiggers@kernel.org>,
	Li RongQing <lirongqing@baidu.com>,
	"Paul E. McKenney" <paulmck@kernel.org>,
	<linux-doc@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<netdev@vger.kernel.org>, <linux-rdma@vger.kernel.org>
Subject: [RFC net-next 2/4] devlink: Add eswitch mode boot default
Date: Wed, 6 May 2026 15:37:37 +0300	[thread overview]
Message-ID: <20260506123739.1959770-3-mbloch@nvidia.com> (raw)
In-Reply-To: <20260506123739.1959770-1-mbloch@nvidia.com>

Add support for configuring the devlink eswitch mode from the
devlink= kernel command line parameter.

The supported syntax is:

  devlink=[<handle>]:esw:mode:<mode>

where <mode> is one of legacy, switchdev or switchdev_inactive. The
default is applied through the existing eswitch_mode_set() devlink
operation, matching the userspace devlink eswitch set command.

Document the devlink= syntax and the eswitch mode default.

Signed-off-by: Mark Bloch <mbloch@nvidia.com>
---
 .../admin-guide/kernel-parameters.txt         |  24 ++++
 .../networking/devlink/devlink-defaults.rst   |  99 +++++++++++++++
 Documentation/networking/devlink/index.rst    |   1 +
 net/devlink/core.c                            | 114 ++++++++++++++++++
 4 files changed, 238 insertions(+)
 create mode 100644 Documentation/networking/devlink/devlink-defaults.rst

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 7834ee927310..150202882870 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1278,6 +1278,30 @@ Kernel parameters
 	dell_smm_hwmon.fan_max=
 			[HW] Maximum configurable fan speed.
 
+	devlink=	[NET]
+			Format:
+			<entry>[,<entry>...]
+
+			<entry>:
+			[<handle>[,<handle>...]]:<cmd>:<cmd-options>
+
+			<handle>:
+			<bus-name>/<dev-name>
+
+			Configure default devlink settings for matching
+			devlink instances during device initialization.
+
+			Currently supported settings:
+			esw:mode:{ legacy | switchdev | switchdev_inactive }
+
+			Examples:
+			devlink=[pci/0000:08:00.0]:esw:mode:switchdev
+			devlink=[pci/0000:08:00.0,pci/0000:08:00.1]:esw:mode:legacy
+			devlink=[pci/0000:08:00.0]:esw:mode:switchdev,[pci/0000:08:00.1]:esw:mode:switchdev_inactive
+
+			See Documentation/networking/devlink/devlink-defaults.rst
+			for the full syntax and duplicate handling rules.
+
 	dfltcc=		[HW,S390]
 			Format: { on | off | def_only | inf_only | always }
 			on:       s390 zlib hardware support for compression on
diff --git a/Documentation/networking/devlink/devlink-defaults.rst b/Documentation/networking/devlink/devlink-defaults.rst
new file mode 100644
index 000000000000..7d6ccaddca86
--- /dev/null
+++ b/Documentation/networking/devlink/devlink-defaults.rst
@@ -0,0 +1,99 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+================
+Devlink Defaults
+================
+
+Devlink defaults allow selected devlink settings to be provided on the
+kernel command line and applied to matching devlink instances during device
+initialization.
+
+The devlink device is selected by its devlink handle. For PCI devices this is
+the same handle shown by ``devlink dev show``, for example
+``pci/0000:08:00.0``.
+
+Kernel command line syntax
+==========================
+
+Defaults are specified with the ``devlink=`` kernel command line parameter.
+
+The general syntax is::
+
+  devlink=<default>[,<default>...]
+
+Each default has the following form::
+
+  [<handle-list>]:<cmd>:<cmd-options>
+
+``<handle-list>`` is one or more devlink handles::
+
+  <bus-name>/<dev-name>[,<bus-name>/<dev-name>...]
+
+All handles in the same ``[]`` list receive the same command setting.
+
+Multiple defaults may be specified by separating complete defaults with a
+comma after the value::
+
+  devlink=[pci/0000:08:00.0]:esw:mode:switchdev,[pci/0000:08:00.1]:esw:mode:legacy
+
+Syntax rules
+------------
+
+The following syntax rules apply:
+
+* Specify all defaults in one ``devlink=`` parameter. Repeated ``devlink=``
+  parameters are not accumulated.
+* The ``devlink=`` value is limited by the kernel command line size.
+* Whitespace is not allowed within the parameter value.
+* ``<bus-name>`` and ``<dev-name>`` must not be empty.
+* ``<bus-name>`` must not contain ``:``.
+* ``<dev-name>`` may contain ``:``. This allows PCI names such as
+  ``0000:08:00.0``.
+* Handles must not contain whitespace, ``[``, ``]`` or more than one ``/``.
+* A comma inside ``[]`` separates handles.
+* A comma after the ``<value>`` separates defaults.
+* Defaults for the same handle are applied in command-line order.
+* The same ``esw`` attribute may be specified only once for a given devlink
+  handle.
+* Duplicate entries for the same handle are rejected and all devlink defaults
+  are ignored.
+
+Supported defaults
+==================
+
+The supported command is ``esw``:
+
+.. list-table::
+   :widths: 10 25 35
+   :header-rows: 1
+
+   * - Command
+     - Options
+     - Values
+   * - ``esw``
+     - ``mode:<mode>``
+     - ``legacy``, ``switchdev``, ``switchdev_inactive``
+
+The ``esw:mode`` default corresponds to the userspace command::
+
+  devlink dev eswitch set <handle> mode <value>
+
+
+Examples
+========
+
+Set one PCI devlink instance to switchdev mode::
+
+  devlink=[pci/0000:08:00.0]:esw:mode:switchdev
+
+Set two PCI devlink instances to legacy mode::
+
+  devlink=[pci/0000:08:00.0,pci/0000:08:00.1]:esw:mode:legacy
+
+Set different modes for different PCI devlink instances::
+
+  devlink=[pci/0000:08:00.0]:esw:mode:switchdev,[pci/0000:08:00.1]:esw:mode:switchdev_inactive
+
+The following is invalid because the same handle receives ``esw:mode`` twice::
+
+  devlink=[pci/0000:08:00.0]:esw:mode:legacy,[pci/0000:08:00.0]:esw:mode:switchdev
diff --git a/Documentation/networking/devlink/index.rst b/Documentation/networking/devlink/index.rst
index f7ba7dcf477d..0d27a7008b14 100644
--- a/Documentation/networking/devlink/index.rst
+++ b/Documentation/networking/devlink/index.rst
@@ -56,6 +56,7 @@ general.
    :maxdepth: 1
 
    devlink-dpipe
+   devlink-defaults
    devlink-eswitch-attr
    devlink-flash
    devlink-health
diff --git a/net/devlink/core.c b/net/devlink/core.c
index 2421a1f8dbb7..4b404135181c 100644
--- a/net/devlink/core.c
+++ b/net/devlink/core.c
@@ -73,9 +73,123 @@ devlink_default_attr_free(struct devlink_default_attr_item *attr)
 	kfree(attr->value.param.value);
 }
 
+struct devlink_default_attr_spec {
+	const char *name;
+	enum devlink_attr attr;
+	int (*value_parse)(const char *value,
+			   struct devlink_default_attr_item *attr_item);
+};
+
+static int __init
+devlink_default_attr_parse(char *str,
+			   const struct devlink_default_attr_spec *attrs,
+			   size_t attrs_count,
+			   struct devlink_default_attr_item *attr_item)
+{
+	char *attr_name;
+	char *value;
+	size_t i;
+
+	attr_name = strsep(&str, ":");
+	if (!attr_name || !*attr_name || !str || !*str)
+		return -EINVAL;
+
+	value = str;
+	for (i = 0; i < attrs_count; i++) {
+		if (!strcmp(attr_name, attrs[i].name)) {
+			attr_item->attr = attrs[i].attr;
+			return attrs[i].value_parse(value, attr_item);
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int __init
+devlink_default_esw_mode_to_value(const char *str,
+				  enum devlink_eswitch_mode *mode)
+{
+	if (!strcmp(str, "legacy")) {
+		*mode = DEVLINK_ESWITCH_MODE_LEGACY;
+		return 0;
+	}
+	if (!strcmp(str, "switchdev")) {
+		*mode = DEVLINK_ESWITCH_MODE_SWITCHDEV;
+		return 0;
+	}
+	if (!strcmp(str, "switchdev_inactive")) {
+		*mode = DEVLINK_ESWITCH_MODE_SWITCHDEV_INACTIVE;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int __init
+devlink_default_esw_mode_parse(const char *str,
+			       struct devlink_default_attr_item *attr_item)
+{
+	enum devlink_eswitch_mode mode;
+	int err;
+
+	err = devlink_default_esw_mode_to_value(str, &mode);
+	if (err)
+		return err;
+
+	attr_item->value.eswitch_mode = mode;
+	return 0;
+}
+
+static const struct devlink_default_attr_spec devlink_default_esw_attrs[] __initconst = {
+	{ "mode", DEVLINK_ATTR_ESWITCH_MODE, devlink_default_esw_mode_parse },
+};
+
+static int __init
+devlink_default_esw_attr_parse(char *str,
+			       struct devlink_default_attr_item *attr_item)
+{
+	return devlink_default_attr_parse(str, devlink_default_esw_attrs,
+					  ARRAY_SIZE(devlink_default_esw_attrs),
+					  attr_item);
+}
+
+static int
+devlink_default_eswitch_apply(struct devlink *devlink,
+			      const struct devlink_default_attr_item *attr)
+{
+	const struct devlink_ops *ops = devlink->ops;
+
+	switch (attr->attr) {
+	case DEVLINK_ATTR_ESWITCH_MODE:
+		if (!ops->eswitch_mode_set)
+			return -EOPNOTSUPP;
+
+		return ops->eswitch_mode_set(devlink, attr->value.eswitch_mode,
+					     NULL);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static const struct devlink_default_cmd_spec devlink_default_cmds[] __initconst = {
+	{
+		.name = "esw",
+		.cmd = DEVLINK_CMD_ESWITCH_SET,
+		.run = devlink_default_eswitch_apply,
+		.attr_parse = devlink_default_esw_attr_parse,
+	},
+};
+
 static const struct devlink_default_cmd_spec *__init
 devlink_default_cmd_spec_find(const char *name)
 {
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE(devlink_default_cmds); i++) {
+		if (!strcmp(name, devlink_default_cmds[i].name))
+			return &devlink_default_cmds[i];
+	}
+
 	return NULL;
 }
 
-- 
2.34.1


  parent reply	other threads:[~2026-05-06 12:38 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-06 12:37 [RFC net-next 0/4] devlink: Add boot-time defaults Mark Bloch
2026-05-06 12:37 ` [RFC net-next 1/4] devlink: Add infrastructure for " Mark Bloch
2026-05-06 12:37 ` Mark Bloch [this message]
2026-05-06 12:37 ` [RFC net-next 3/4] devlink: Add runtime parameter boot defaults Mark Bloch
2026-05-06 12:37 ` [RFC net-next 4/4] net/mlx5: Apply devlink boot defaults during init Mark Bloch
2026-05-06 15:22 ` [RFC net-next 0/4] devlink: Add boot-time defaults Jiri Pirko
2026-05-06 17:35   ` Mark Bloch
2026-05-07 11:03     ` Jiri Pirko
2026-05-08 17:59       ` Mark Bloch
2026-05-08 18:07         ` Jiri Pirko
2026-05-09  0:52           ` Jakub Kicinski
2026-05-09  7:01             ` Jiri Pirko
2026-05-10 12:31               ` Mark Bloch
2026-05-11  8:07                 ` Jiri Pirko
2026-05-11 18:21                 ` Parav Pandit
2026-05-12  8:45                   ` Jiri Pirko
2026-05-12 13:48                     ` Parav Pandit
2026-05-12 14:07                       ` Jiri Pirko
2026-05-12 15:25                         ` Parav Pandit
2026-05-12 18:35                           ` Jiri Pirko
2026-05-13  5:53                             ` Mark Bloch
2026-05-13 11:11                               ` Jiri Pirko
2026-05-14 12:34                                 ` Mark Bloch
2026-05-10 16:37               ` Jakub Kicinski
2026-05-11  8:42                 ` Jiri Pirko
2026-05-11 23:41                   ` Jakub Kicinski
2026-05-12  8:42                     ` Jiri Pirko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260506123739.1959770-3-mbloch@nvidia.com \
    --to=mbloch@nvidia.com \
    --cc=akpm@linux-foundation.org \
    --cc=andrew+netdev@lunn.ch \
    --cc=bp@alien8.de \
    --cc=brauner@kernel.org \
    --cc=corbet@lwn.net \
    --cc=dapeng1.mi@linux.intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=davem@davemloft.net \
    --cc=ebiggers@kernel.org \
    --cc=edumazet@google.com \
    --cc=elver@google.com \
    --cc=horms@kernel.org \
    --cc=jiri@resnulli.us \
    --cc=kees@kernel.org \
    --cc=kuba@kernel.org \
    --cc=leon@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rdma@vger.kernel.org \
    --cc=lirongqing@baidu.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=paulmck@kernel.org \
    --cc=pawan.kumar.gupta@linux.intel.com \
    --cc=peterz@infradead.org \
    --cc=pmladek@suse.com \
    --cc=rdunlap@infradead.org \
    --cc=saeedm@nvidia.com \
    --cc=skhan@linuxfoundation.org \
    --cc=tariqt@nvidia.com \
    --cc=tglx@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.