Linux driver-core infrastructure
 help / color / mirror / Atom feed
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


             reply	other threads:[~2026-05-14  9:50 UTC|newest]

Thread overview: 2+ 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

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