Skip to content

Commit

Permalink
Merge tag 'modules-6.2-rc6' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/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
  • Loading branch information
Linus Torvalds committed Jan 25, 2023
2 parents 246dc53 + 0254127 commit 948ef7b
Showing 1 changed file with 21 additions and 5 deletions.
26 changes: 21 additions & 5 deletions kernel/module/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2393,7 +2393,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;
Expand Down Expand Up @@ -2569,20 +2570,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);
Expand Down

0 comments on commit 948ef7b

Please sign in to comment.