From: Petr Pavlu <petr.pavlu@suse.com>
To: mcgrof@kernel.org
Cc: pmladek@suse.com, prarit@redhat.com, david@redhat.com,
mwilck@suse.com, petr.pavlu@suse.com,
linux-modules@vger.kernel.org, linux-kernel@vger.kernel.org,
stable@vger.kernel.org
Subject: [PATCH v2] module: Don't wait for GOING modules
Date: Mon, 5 Dec 2022 11:35:57 +0100 [thread overview]
Message-ID: <20221205103557.18363-1-petr.pavlu@suse.com> (raw)
During a system boot, it can happen that the kernel receives a burst of
requests to insert the same module but loading it eventually fails
during its init call. For instance, udev can make a request to insert
a frequency module for each individual CPU when another frequency module
is already loaded which causes the init function of the new module to
return an error.
Since commit 6e6de3dee51a ("kernel/module.c: Only return -EEXIST for
modules that have finished loading"), the kernel waits for modules in
MODULE_STATE_GOING state to finish unloading before making another
attempt to load the same module.
This creates unnecessary work in the described scenario and delays the
boot. In the worst case, it can prevent udev from loading drivers for
other devices and might cause timeouts of services waiting on them and
subsequently a failed boot.
This patch attempts a different solution for the problem 6e6de3dee51a
was trying to solve. Rather than waiting for the unloading to complete,
it returns a different error code (-EBUSY) for modules in the GOING
state. This should avoid the error situation that was described in
6e6de3dee51a (user space attempting to load a dependent module because
the -EEXIST error code would suggest to user space that the first module
had been loaded successfully), while avoiding the delay situation too.
Fixes: 6e6de3dee51a ("kernel/module.c: Only return -EEXIST for modules that have finished loading")
Co-developed-by: Martin Wilck <mwilck@suse.com>
Signed-off-by: Martin Wilck <mwilck@suse.com>
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
Cc: stable@vger.kernel.org
---
Changes since v1 [1]:
- Don't attempt a new module initialization when a same-name module
completely disappeared while waiting on it, which means it went
through the GOING state implicitly already.
[1] https://lore.kernel.org/linux-modules/20221123131226.24359-1-petr.pavlu@suse.com/
kernel/module/main.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/kernel/module/main.c b/kernel/module/main.c
index d02d39c7174e..7a627345d4fd 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -2386,7 +2386,8 @@ static bool finished_loading(const char *name)
sched_annotate_sleep();
mutex_lock(&module_mutex);
mod = find_module_all(name, strlen(name), true);
- ret = !mod || mod->state == MODULE_STATE_LIVE;
+ ret = !mod || mod->state == MODULE_STATE_LIVE
+ || mod->state == MODULE_STATE_GOING;
mutex_unlock(&module_mutex);
return ret;
@@ -2562,20 +2563,35 @@ static int add_unformed_module(struct module *mod)
mod->state = MODULE_STATE_UNFORMED;
-again:
mutex_lock(&module_mutex);
old = find_module_all(mod->name, strlen(mod->name), true);
if (old != NULL) {
- if (old->state != MODULE_STATE_LIVE) {
+ if (old->state == MODULE_STATE_COMING
+ || old->state == MODULE_STATE_UNFORMED) {
/* Wait in case it fails to load. */
mutex_unlock(&module_mutex);
err = wait_event_interruptible(module_wq,
finished_loading(mod->name));
if (err)
goto out_unlocked;
- goto again;
+
+ /* The module might have gone in the meantime. */
+ mutex_lock(&module_mutex);
+ old = find_module_all(mod->name, strlen(mod->name),
+ true);
}
- err = -EEXIST;
+
+ /*
+ * We are here only when the same module was being loaded. Do
+ * not try to load it again right now. It prevents long delays
+ * caused by serialized module load failures. It might happen
+ * when more devices of the same type trigger load of
+ * a particular module.
+ */
+ if (old && old->state == MODULE_STATE_LIVE)
+ err = -EEXIST;
+ else
+ err = -EBUSY;
goto out;
}
mod_update_bounds(mod);
--
2.35.3
next reply other threads:[~2022-12-05 10:36 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-05 10:35 Petr Pavlu [this message]
2022-12-05 19:54 ` [PATCH v2] module: Don't wait for GOING modules Petr Mladek
2022-12-06 16:57 ` Petr Pavlu
2022-12-07 15:15 ` Petr Mladek
2022-12-08 2:44 ` Luis Chamberlain
2022-12-12 11:29 ` Petr Pavlu
2022-12-13 2:58 ` Luis Chamberlain
2022-12-13 5:09 ` Luis Chamberlain
2022-12-13 10:17 ` Petr Mladek
2022-12-13 13:36 ` Petr Pavlu
2023-01-18 0:04 ` Luis Chamberlain
2023-01-18 0:18 ` Luis Chamberlain
2023-01-18 15:12 ` Petr Pavlu
2023-01-18 18:42 ` Luis Chamberlain
2023-01-19 12:26 ` Petr Pavlu
2023-01-19 15:47 ` Petr Mladek
2023-01-20 0:51 ` Luis Chamberlain
2023-01-20 0:58 ` Luis Chamberlain
2023-01-21 22:40 ` Luis Chamberlain
2023-03-11 21:36 ` Luis Chamberlain
2023-03-12 6:25 ` Lucas De Marchi
2023-03-22 22:31 ` Luis Chamberlain
2023-03-23 15:01 ` Lucas De Marchi
2023-03-23 15:08 ` Luis Chamberlain
2023-03-24 6:03 ` Lucas De Marchi
2023-03-24 18:47 ` Luis Chamberlain
2023-01-24 19:58 ` Luis Chamberlain
2023-01-18 20:02 ` Borislav Petkov
2023-01-19 1:23 ` Luis Chamberlain
2023-01-19 23:37 ` Luis Chamberlain
2023-01-19 1:15 ` Lucas De Marchi
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=20221205103557.18363-1-petr.pavlu@suse.com \
--to=petr.pavlu@suse.com \
--cc=david@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-modules@vger.kernel.org \
--cc=mcgrof@kernel.org \
--cc=mwilck@suse.com \
--cc=pmladek@suse.com \
--cc=prarit@redhat.com \
--cc=stable@vger.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