Skip to content

Commit 948ef7b

Browse files
committed
Merge tag 'modules-6.2-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux
Pull module fix from Luis Chamberlain: "Theis is a fix we have been delaying for v6.2 due to lack of early testing on linux-next. The commit has been sitting in linux-next since December and testing has also been now a bit extensive by a few developers. Since this is a fix which definitely will go to v6.3 it should also apply to v6.2 so if there are any issues we pick them up earlier rather than later. The fix fixes a regression since v5.3, prior to me helping with module maintenance, however, the issue is real in that in the worst case now can prevent boot. We've discussed all possible corner cases [0] and at last do feel this is ready for v6.2-rc6" Link https://lore.kernel.org/all/Y9A4fiobL6IHp%2F%2FP@bombadil.infradead.org/ [0] * tag 'modules-6.2-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux: module: Don't wait for GOING modules
2 parents 246dc53 + 0254127 commit 948ef7b

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

kernel/module/main.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2393,7 +2393,8 @@ static bool finished_loading(const char *name)
23932393
sched_annotate_sleep();
23942394
mutex_lock(&module_mutex);
23952395
mod = find_module_all(name, strlen(name), true);
2396-
ret = !mod || mod->state == MODULE_STATE_LIVE;
2396+
ret = !mod || mod->state == MODULE_STATE_LIVE
2397+
|| mod->state == MODULE_STATE_GOING;
23972398
mutex_unlock(&module_mutex);
23982399

23992400
return ret;
@@ -2569,20 +2570,35 @@ static int add_unformed_module(struct module *mod)
25692570

25702571
mod->state = MODULE_STATE_UNFORMED;
25712572

2572-
again:
25732573
mutex_lock(&module_mutex);
25742574
old = find_module_all(mod->name, strlen(mod->name), true);
25752575
if (old != NULL) {
2576-
if (old->state != MODULE_STATE_LIVE) {
2576+
if (old->state == MODULE_STATE_COMING
2577+
|| old->state == MODULE_STATE_UNFORMED) {
25772578
/* Wait in case it fails to load. */
25782579
mutex_unlock(&module_mutex);
25792580
err = wait_event_interruptible(module_wq,
25802581
finished_loading(mod->name));
25812582
if (err)
25822583
goto out_unlocked;
2583-
goto again;
2584+
2585+
/* The module might have gone in the meantime. */
2586+
mutex_lock(&module_mutex);
2587+
old = find_module_all(mod->name, strlen(mod->name),
2588+
true);
25842589
}
2585-
err = -EEXIST;
2590+
2591+
/*
2592+
* We are here only when the same module was being loaded. Do
2593+
* not try to load it again right now. It prevents long delays
2594+
* caused by serialized module load failures. It might happen
2595+
* when more devices of the same type trigger load of
2596+
* a particular module.
2597+
*/
2598+
if (old && old->state == MODULE_STATE_LIVE)
2599+
err = -EEXIST;
2600+
else
2601+
err = -EBUSY;
25862602
goto out;
25872603
}
25882604
mod_update_bounds(mod);

0 commit comments

Comments
 (0)