Linux driver-core infrastructure
 help / color / mirror / Atom feed
* [PATCH] driver core: Add cmdline option to force probe type
@ 2026-05-14  9:49 Jianlin Lv
  2026-05-14 10:16 ` Greg KH
  0 siblings, 1 reply; 4+ messages in thread
From: Jianlin Lv @ 2026-05-14  9:49 UTC (permalink / raw)
  To: corbet, skhan, gregkh, rafael, dakr
  Cc: iecedge, jianlv, linux-kernel, linux-doc, driver-core

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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-05-14 13:49 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-14  9:49 [PATCH] driver core: Add cmdline option to force probe type Jianlin Lv
2026-05-14 10:16 ` Greg KH
2026-05-14 13:35   ` Jianlin Lv
2026-05-14 13:50     ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox