From: Mark Bloch <mbloch@nvidia.com>
To: Jiri Pirko <jiri@resnulli.us>, Eric Dumazet <edumazet@google.com>,
"Jakub Kicinski" <kuba@kernel.org>,
Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>
Cc: Saeed Mahameed <saeedm@nvidia.com>,
Leon Romanovsky <leon@kernel.org>,
Tariq Toukan <tariqt@nvidia.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
Jonathan Corbet <corbet@lwn.net>,
Shuah Khan <skhan@linuxfoundation.org>, <netdev@vger.kernel.org>,
<linux-rdma@vger.kernel.org>, <linux-doc@vger.kernel.org>,
Mark Bloch <mbloch@nvidia.com>
Subject: [PATCH net-next V6 4/4] devlink: Apply eswitch mode boot defaults
Date: Tue, 14 Jul 2026 09:17:30 +0300 [thread overview]
Message-ID: <20260714061731.531849-5-mbloch@nvidia.com> (raw)
In-Reply-To: <20260714061731.531849-1-mbloch@nvidia.com>
Apply parsed devlink_eswitch_mode= defaults after devlink registration
and after successful reload.
Mark the default mode as pending when a devlink instance is allocated.
Before devl_unlock() releases the instance lock, apply a pending default
when the instance is registered.
Clear the pending state before calling into the driver so the boot
default remains a one-shot operation even if the mode change fails.
For successful reloads that performed DRIVER_REINIT, devlink_reload()
already holds the devlink instance lock and the driver has completed
reload_up(). Clear the pending state and apply the default directly from
the reload path.
Treat an explicit user eswitch mode request as consuming the pending
default mode.
Signed-off-by: Mark Bloch <mbloch@nvidia.com>
---
net/devlink/core.c | 3 ++
net/devlink/default.c | 70 +++++++++++++++++++++++++++++++++++--
net/devlink/dev.c | 6 ++++
net/devlink/devl_internal.h | 5 +++
4 files changed, 82 insertions(+), 2 deletions(-)
diff --git a/net/devlink/core.c b/net/devlink/core.c
index fc14ee5d9dcf..cea4afc27dd9 100644
--- a/net/devlink/core.c
+++ b/net/devlink/core.c
@@ -317,6 +317,7 @@ EXPORT_SYMBOL_GPL(devl_trylock);
void devl_unlock(struct devlink *devlink)
{
+ devlink_default_esw_mode_apply_pending(devlink);
mutex_unlock(&devlink->lock);
}
EXPORT_SYMBOL_GPL(devl_unlock);
@@ -429,6 +430,7 @@ void devl_unregister(struct devlink *devlink)
ASSERT_DEVLINK_REGISTERED(devlink);
devl_assert_locked(devlink);
+ devlink_default_esw_mode_apply_pending_clear(devlink);
devlink_notify_unregister(devlink);
xa_clear_mark(&devlinks, devlink->index, DEVLINK_REGISTERED);
devlink_rel_put(devlink);
@@ -490,6 +492,7 @@ struct devlink *__devlink_alloc(const struct devlink_ops *ops, size_t priv_size,
INIT_LIST_HEAD(&devlink->trap_group_list);
INIT_LIST_HEAD(&devlink->trap_policer_list);
INIT_RCU_WORK(&devlink->rwork, devlink_release);
+ devlink_default_esw_mode_instance_init(devlink);
lockdep_register_key(&devlink->lock_key);
mutex_init(&devlink->lock);
lockdep_set_class(&devlink->lock, &devlink->lock_key);
diff --git a/net/devlink/default.c b/net/devlink/default.c
index 8434af83ea69..77cc356dfac9 100644
--- a/net/devlink/default.c
+++ b/net/devlink/default.c
@@ -10,6 +10,7 @@
static char *devlink_default_esw_mode_param;
static bool devlink_default_esw_mode_match_all;
+static bool devlink_default_esw_mode_enabled;
static enum devlink_eswitch_mode devlink_default_esw_mode;
static LIST_HEAD(devlink_default_esw_mode_nodes);
@@ -154,6 +155,7 @@ static void __init devlink_default_esw_mode_nodes_clear(void)
}
devlink_default_esw_mode_match_all = false;
+ devlink_default_esw_mode_enabled = false;
}
static int __init devlink_default_esw_mode_parse(char *str)
@@ -180,14 +182,78 @@ static int __init devlink_default_esw_mode_parse(char *str)
return err;
err = devlink_default_esw_mode_handles_parse(handles);
- if (err)
+ if (err) {
devlink_default_esw_mode_nodes_clear();
- else
+ } else {
devlink_default_esw_mode = esw_mode;
+ devlink_default_esw_mode_enabled = true;
+ }
return err;
}
+static bool devlink_default_esw_mode_match(struct devlink *devlink)
+{
+ const char *bus_name = devlink_bus_name(devlink);
+ const char *dev_name = devlink_dev_name(devlink);
+ struct devlink_default_esw_mode_node *node;
+
+ if (devlink_default_esw_mode_match_all)
+ return true;
+
+ node = devlink_default_esw_mode_node_find(bus_name, dev_name);
+ return !!node;
+}
+
+void devlink_default_esw_mode_apply_locked(struct devlink *devlink)
+{
+ const struct devlink_ops *ops = devlink->ops;
+ int err;
+
+ devl_assert_locked(devlink);
+
+ if (!devlink_default_esw_mode_match(devlink))
+ return;
+
+ if (!ops->eswitch_mode_set) {
+ if (!devlink_default_esw_mode_match_all)
+ devl_warn(devlink,
+ "devlink_eswitch_mode= selected this device but eswitch mode setting is not supported\n");
+ return;
+ }
+
+ err = devlink_eswitch_mode_set(devlink, devlink_default_esw_mode, NULL);
+ if (err)
+ devl_warn(devlink,
+ "Couldn't apply default eswitch mode, err %d\n",
+ err);
+}
+
+void devlink_default_esw_mode_apply_pending(struct devlink *devlink)
+{
+ devl_assert_locked(devlink);
+
+ if (!devlink->default_esw_mode_apply_pending ||
+ !__devl_is_registered(devlink))
+ return;
+
+ devlink->default_esw_mode_apply_pending = false;
+ devlink_default_esw_mode_apply_locked(devlink);
+}
+
+void devlink_default_esw_mode_instance_init(struct devlink *devlink)
+{
+ devlink->default_esw_mode_apply_pending =
+ devlink_default_esw_mode_enabled;
+}
+
+void devlink_default_esw_mode_apply_pending_clear(struct devlink *devlink)
+{
+ devl_assert_locked(devlink);
+
+ devlink->default_esw_mode_apply_pending = false;
+}
+
static int __init devlink_default_esw_mode_setup(char *str)
{
devlink_default_esw_mode_param = str;
diff --git a/net/devlink/dev.c b/net/devlink/dev.c
index 119ef105d0a7..611bb6bfd492 100644
--- a/net/devlink/dev.c
+++ b/net/devlink/dev.c
@@ -478,6 +478,11 @@ int devlink_reload(struct devlink *devlink, struct net *dest_net,
return err;
WARN_ON(!(*actions_performed & BIT(action)));
+ if (*actions_performed & BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT)) {
+ devlink_default_esw_mode_apply_pending_clear(devlink);
+ devlink_default_esw_mode_apply_locked(devlink);
+ }
+
/* Catch driver on updating the remote action within devlink reload */
WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats,
sizeof(remote_reload_stats)));
@@ -731,6 +736,7 @@ int devlink_nl_eswitch_set_doit(struct sk_buff *skb, struct genl_info *info)
u16 mode;
if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
+ devlink_default_esw_mode_apply_pending_clear(devlink);
mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
err = devlink_eswitch_mode_set(devlink, mode, info->extack);
if (err)
diff --git a/net/devlink/devl_internal.h b/net/devlink/devl_internal.h
index fe9ad58515d4..97f53394b1c0 100644
--- a/net/devlink/devl_internal.h
+++ b/net/devlink/devl_internal.h
@@ -58,6 +58,7 @@ struct devlink {
struct mutex lock;
struct lock_class_key lock_key;
u8 reload_failed:1;
+ u8 default_esw_mode_apply_pending:1;
refcount_t refcount;
struct rcu_work rwork;
struct devlink_rel *rel;
@@ -73,6 +74,10 @@ struct devlink *__devlink_alloc(const struct devlink_ops *ops, size_t priv_size,
const struct device_driver *dev_driver);
int devlink_default_esw_mode_init(void);
void devlink_default_esw_mode_cleanup(void);
+void devlink_default_esw_mode_instance_init(struct devlink *devlink);
+void devlink_default_esw_mode_apply_locked(struct devlink *devlink);
+void devlink_default_esw_mode_apply_pending(struct devlink *devlink);
+void devlink_default_esw_mode_apply_pending_clear(struct devlink *devlink);
#define devl_warn(devlink, format, args...) \
do { \
--
2.43.0
next prev parent reply other threads:[~2026-07-14 6:18 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-14 6:17 [PATCH net-next V6 0/4] devlink: Add boot-time eswitch mode defaults Mark Bloch
2026-07-14 6:17 ` [PATCH net-next V6 1/4] net/mlx5: Clear FW reset-in-progress bit before reload Mark Bloch
2026-07-14 6:17 ` [PATCH net-next V6 2/4] devlink: Factor out eswitch mode setting Mark Bloch
2026-07-14 12:58 ` Jiri Pirko
2026-07-14 6:17 ` [PATCH net-next V6 3/4] devlink: Parse eswitch mode boot defaults Mark Bloch
2026-07-14 12:58 ` Jiri Pirko
2026-07-14 6:17 ` Mark Bloch [this message]
2026-07-14 12:02 ` [PATCH net-next V6 4/4] devlink: Apply " 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=20260714061731.531849-5-mbloch@nvidia.com \
--to=mbloch@nvidia.com \
--cc=andrew+netdev@lunn.ch \
--cc=corbet@lwn.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=jiri@resnulli.us \
--cc=kuba@kernel.org \
--cc=leon@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=saeedm@nvidia.com \
--cc=skhan@linuxfoundation.org \
--cc=tariqt@nvidia.com \
/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.