public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Yafang Shao <laoar.shao@gmail.com>
To: gregkh@linuxfoundation.org, rafael@kernel.org
Cc: linux-kernel@vger.kernel.org, Yafang Shao <laoar.shao@gmail.com>
Subject: [PATCH] drivers: base: Introduce a new kernel parameter driver_sync_probe=
Date: Wed,  6 Dec 2023 11:53:55 +0000	[thread overview]
Message-ID: <20231206115355.4319-1-laoar.shao@gmail.com> (raw)

After upgrading our kernel from version 4.19 to 6.1, certain regressions
occurred due to the driver's asynchronous probe behavior. Specifically,
the SCSI driver transitioned to an asynchronous probe by default, resulting
in a non-fixed root disk behavior. In the prior 4.19 kernel, the root disk
was consistently identified as /dev/sda. However, with kernel 6.1, the root
disk can be any of /dev/sdX, leading to issues for applications reliant on
/dev/sda, notably impacting monitoring systems monitoring the root disk.

To address this, a new kernel parameter 'driver_sync_probe=' is introduced
to enforce synchronous probe behavior for specific drivers.

For instance, using the following kernel parameter:

  driver_sync_probe=sd,nvme

The sd (SCSI) and nvme disks will undergo synchronous probing. This ensures
that these disks maintain consistent identification behavior despite the
default asynchronous probe, mitigating the issues experienced by
applications reliant on fixed disk identification.

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 .../admin-guide/kernel-parameters.txt         | 10 +++++
 drivers/base/dd.c                             | 41 ++++++++++++++-----
 2 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 65731b060e3f..9b1a12b24f65 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1144,6 +1144,16 @@
 			match the *.
 			Format: <driver_name1>,<driver_name2>...
 
+	driver_sync_probe=  [KNL]
+			List of driver names to be probed synchronously. *
+			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>...
+
+			Note that 'driver_sync_probe=' takes precedence over
+			'driver_async_probe=' if both parameters are set.
+
 	drm.edid_firmware=[<connector>:]<file>[,[<connector>:]<file>]
 			Broken monitors, graphic adapters, KVMs and EDIDless
 			panels may send no or incorrect EDID data sets.
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 0c3725c3eefa..f4d8f0b76b26 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -58,9 +58,11 @@ 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];
+#define PROBE_DRV_NAMES_MAX_LEN	256
+static char async_probe_drv_names[PROBE_DRV_NAMES_MAX_LEN];
 static bool async_probe_default;
+static char sync_probe_drv_names[PROBE_DRV_NAMES_MAX_LEN];
+static bool sync_probe_default;
 
 /*
  * In some cases, like suspend to RAM or hibernation, It might be reasonable
@@ -843,30 +845,48 @@ static int driver_probe_device(struct device_driver *drv, struct device *dev)
 	return ret;
 }
 
-static inline bool cmdline_requested_async_probing(const char *drv_name)
+static inline bool
+cmdline_requested_probing(const char *drv_name, const char *drv_names, bool all_drv)
 {
-	bool async_drv;
+	bool probe_drv;
 
-	async_drv = parse_option_str(async_probe_drv_names, drv_name);
-
-	return (async_probe_default != async_drv);
+	probe_drv = parse_option_str(drv_names, drv_name);
+	return (all_drv != probe_drv);
 }
 
 /* The option format is "driver_async_probe=drv_name1,drv_name2,..." */
 static int __init save_async_options(char *buf)
 {
-	if (strlen(buf) >= ASYNC_DRV_NAMES_MAX_LEN)
+	if (strlen(buf) >= PROBE_DRV_NAMES_MAX_LEN)
 		pr_warn("Too long list of driver names for 'driver_async_probe'!\n");
 
-	strscpy(async_probe_drv_names, buf, ASYNC_DRV_NAMES_MAX_LEN);
+	strscpy(async_probe_drv_names, buf, PROBE_DRV_NAMES_MAX_LEN);
 	async_probe_default = parse_option_str(async_probe_drv_names, "*");
 
 	return 1;
 }
 __setup("driver_async_probe=", save_async_options);
 
+/* The option format is "driver_sync_probe=drv_name1,drv_name2,..."
+ * driver_sync_probe is prior to driver_async_probe if both of them are set.
+ */
+static int __init save_sync_options(char *buf)
+{
+	if (strlen(buf) >= PROBE_DRV_NAMES_MAX_LEN)
+		pr_warn("Too long list of driver names for 'driver_sync_probe'!\n");
+
+	strscpy(sync_probe_drv_names, buf, PROBE_DRV_NAMES_MAX_LEN);
+	sync_probe_default = parse_option_str(sync_probe_drv_names, "*");
+
+	return 1;
+}
+__setup("driver_sync_probe=", save_sync_options);
+
 static bool driver_allows_async_probing(struct device_driver *drv)
 {
+	if (cmdline_requested_probing(drv->name, sync_probe_drv_names, sync_probe_default))
+		return false;
+
 	switch (drv->probe_type) {
 	case PROBE_PREFER_ASYNCHRONOUS:
 		return true;
@@ -875,7 +895,8 @@ static bool driver_allows_async_probing(struct device_driver *drv)
 		return false;
 
 	default:
-		if (cmdline_requested_async_probing(drv->name))
+		if (cmdline_requested_probing(drv->name, async_probe_drv_names,
+					      async_probe_default))
 			return true;
 
 		if (module_requested_async_probing(drv->owner))
-- 
2.30.1 (Apple Git-130)


             reply	other threads:[~2023-12-06 11:54 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-06 11:53 Yafang Shao [this message]
2023-12-06 13:31 ` [PATCH] drivers: base: Introduce a new kernel parameter driver_sync_probe= Greg KH
2023-12-06 14:08   ` Yafang Shao
2023-12-07 10:19     ` Greg KH
2023-12-07 11:59       ` Yafang Shao
2023-12-07 12:12         ` Greg KH
2023-12-07 12:36           ` Yafang Shao
2023-12-08  5:36             ` Greg KH
2023-12-08  6:49               ` Yafang Shao
2023-12-08  7:15                 ` Greg KH
2023-12-08  7:26                   ` Yafang Shao

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=20231206115355.4319-1-laoar.shao@gmail.com \
    --to=laoar.shao@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rafael@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox