From: Jianlin Lv <iecedge@gmail.com>
To: corbet@lwn.net, skhan@linuxfoundation.org,
gregkh@linuxfoundation.org, rafael@kernel.org, dakr@kernel.org
Cc: iecedge@gmail.com, jianlv@ebay.com, linux-kernel@vger.kernel.org,
linux-doc@vger.kernel.org, driver-core@lists.linux.dev
Subject: [PATCH] driver core: Add cmdline option to force probe type
Date: Thu, 14 May 2026 17:49:55 +0800 [thread overview]
Message-ID: <20260514094955.76305-1-jianlv@ebay.com> (raw)
From: Jianlin Lv <iecedge@gmail.com>
Device drivers that use asynchronous probing can cause non-deterministic
device ordering and naming across reboots. A typical example is storage
drivers (like sd/nvme): asynchronous probing can lead to inconsistent disk
logical names after reboot. In scenarios where disk naming consistency is
critical, the probe type should be set to synchronous.
This patch introduces a driver_probe kernel parameter that overrides any
driver's hard-coded probe type settings and allows runtime control without
requiring kernel recompilation:
driver_probe=PROBE_TYPE_SYNC,nvme,sd # Force specific drivers sync
driver_probe=PROBE_TYPE_ASYNC,*,usb # Force all async except usb
driver_probe=PROBE_TYPE_SYNC,* # Force all drivers synchronous
The implementation replaces the limited driver_async_probe parameter with
a more flexible interface that can force either synchronous or asynchronous
probing as needed.
Signed-off-by: Jianlin Lv <iecedge@gmail.com>
---
.../admin-guide/kernel-parameters.txt | 27 +++++--
drivers/base/dd.c | 71 ++++++++++++++-----
2 files changed, 74 insertions(+), 24 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 4d0f545fb3ec..b43a8bd20356 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1377,12 +1377,27 @@ Kernel parameters
it becomes active and is searched during signature
verification.
- driver_async_probe= [KNL]
- List of driver names to be probed asynchronously. *
- matches with all driver names. If * is specified, the
- rest of the listed driver names are those that will NOT
- match the *.
- Format: <driver_name1>,<driver_name2>...
+ driver_probe= [KNL]
+ Control device driver probe types. This parameter takes
+ precedence over driver hard-coded probe_type settings.
+ Format: <probe_type>,<driver_name1>,<driver_name2>,...
+
+ <probe_type>:
+ PROBE_TYPE_SYNC - Force synchronous probing
+ PROBE_TYPE_ASYNC - Force asynchronous probing
+
+ Driver name patterns:
+ driver1,driver2 - Apply to specific drivers only
+ *,driver1,driver2 - Apply to all drivers except listed ones
+ * (alone) - Apply to all drivers
+
+ Examples:
+ driver_probe=PROBE_TYPE_SYNC,nvme,sd
+ Force synchronous probe for nvme and sd drivers
+ driver_probe=PROBE_TYPE_SYNC,*,graphics,usb-storage
+ Force sync for all drivers except graphics and usb-storage
+ driver_probe=PROBE_TYPE_ASYNC,*
+ Force async probe for all drivers
drm.edid_firmware=[<connector>:]<file>[,[<connector>:]<file>]
Broken monitors, graphic adapters, KVMs and EDIDless
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 1dc1e3528043..7d8e0c932e0b 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -59,9 +59,10 @@ static atomic_t deferred_trigger_count = ATOMIC_INIT(0);
static bool initcalls_done;
/* Save the async probe drivers' name from kernel cmdline */
-#define ASYNC_DRV_NAMES_MAX_LEN 256
-static char async_probe_drv_names[ASYNC_DRV_NAMES_MAX_LEN];
-static bool async_probe_default;
+#define DRIVER_PROBE_NAMES_MAX_LEN 256
+static char driver_probe_names[DRIVER_PROBE_NAMES_MAX_LEN];
+static enum probe_type driver_probe_default = PROBE_DEFAULT_STRATEGY;
+static bool driver_probe_wildcard;
/*
* In some cases, like suspend to RAM or hibernation, It might be reasonable
@@ -914,30 +915,67 @@ static int driver_probe_device(const struct device_driver *drv, struct device *d
return ret;
}
-static inline bool cmdline_requested_async_probing(const char *drv_name)
+static int __init save_driver_probe_options(char *buf)
{
- bool async_drv;
+ if (strlen(buf) >= DRIVER_PROBE_NAMES_MAX_LEN)
+ pr_warn("Too long list of driver names for 'driver_probe'!\n");
+
+ strscpy(driver_probe_names, buf, DRIVER_PROBE_NAMES_MAX_LEN);
+
+ if (parse_option_str(driver_probe_names, "PROBE_TYPE_SYNC"))
+ driver_probe_default = PROBE_FORCE_SYNCHRONOUS;
+ else if (parse_option_str(driver_probe_names, "PROBE_TYPE_ASYNC"))
+ driver_probe_default = PROBE_PREFER_ASYNCHRONOUS;
+ else {
+ pr_warn("driver_probe: invalid type\n");
+ return 1;
+ }
- async_drv = parse_option_str(async_probe_drv_names, drv_name);
+ driver_probe_wildcard = parse_option_str(driver_probe_names, "*");
+ pr_info("driver_probe: %s mode, list=\"%s\"\n",
+ driver_probe_wildcard ? "wildcard" : "specific",
+ driver_probe_names);
- return (async_probe_default != async_drv);
+ return 1;
}
+__setup("driver_probe=", save_driver_probe_options);
-/* The option format is "driver_async_probe=drv_name1,drv_name2,..." */
-static int __init save_async_options(char *buf)
+static int driver_probe_type_override(const char *drv_name)
{
- if (strlen(buf) >= ASYNC_DRV_NAMES_MAX_LEN)
- pr_warn("Too long list of driver names for 'driver_async_probe'!\n");
+ bool driver_listed;
- strscpy(async_probe_drv_names, buf, ASYNC_DRV_NAMES_MAX_LEN);
- async_probe_default = parse_option_str(async_probe_drv_names, "*");
+ if (driver_probe_default == PROBE_DEFAULT_STRATEGY)
+ return -1;
- return 1;
+ driver_listed = parse_option_str(driver_probe_names, drv_name);
+
+ if (driver_probe_wildcard) {
+ /* Wildcard mode: apply default to all, exceptions get opposite */
+ if (driver_listed)
+ return (driver_probe_default == PROBE_PREFER_ASYNCHRONOUS) ? 0 : 1;
+ else
+ return (driver_probe_default == PROBE_PREFER_ASYNCHRONOUS) ? 1 : 0;
+ } else {
+ /* Specific mode: only listed drivers get the specified type */
+ if (driver_listed)
+ return (driver_probe_default == PROBE_PREFER_ASYNCHRONOUS) ? 1 : 0;
+ else
+ return -1; /* Not listed - no override */
+ }
}
-__setup("driver_async_probe=", save_async_options);
static bool driver_allows_async_probing(const struct device_driver *drv)
{
+ int probe_override;
+
+ /* Check driver_probe parameter first (highest priority) */
+ probe_override = driver_probe_type_override(drv->name);
+ if (probe_override >= 0) {
+ pr_info("driver_probe override: %s -> %s\n",
+ drv->name, probe_override ? "async" : "sync");
+ return probe_override;
+ }
+
switch (drv->probe_type) {
case PROBE_PREFER_ASYNCHRONOUS:
return true;
@@ -946,9 +984,6 @@ static bool driver_allows_async_probing(const struct device_driver *drv)
return false;
default:
- if (cmdline_requested_async_probing(drv->name))
- return true;
-
if (module_requested_async_probing(drv->owner))
return true;
--
2.43.0
next reply other threads:[~2026-05-14 9:50 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-14 9:49 Jianlin Lv [this message]
2026-05-14 10:16 ` [PATCH] driver core: Add cmdline option to force probe type Greg KH
2026-05-14 13:35 ` Jianlin Lv
2026-05-14 13:50 ` Greg KH
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=20260514094955.76305-1-jianlv@ebay.com \
--to=iecedge@gmail.com \
--cc=corbet@lwn.net \
--cc=dakr@kernel.org \
--cc=driver-core@lists.linux.dev \
--cc=gregkh@linuxfoundation.org \
--cc=jianlv@ebay.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=rafael@kernel.org \
--cc=skhan@linuxfoundation.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox