Skip to content

Commit f71afa6

Browse files
committed
module: extract patient module check into helper
The patient module check inside add_unformed_module() is large enough as we need it. It is a bit hard to read too, so just move it to a helper and do the inverse checks first to help shift the code and make it easier to read. The new helper then is module_patient_check_exists(). To make this work we need to mvoe the finished_loading() up, we do that without making any functional changes to that routine. Reviewed-by: David Hildenbrand <david@redhat.com> Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
1 parent 25a1b5b commit f71afa6

File tree

1 file changed

+60
-52
lines changed

1 file changed

+60
-52
lines changed

kernel/module/main.c

Lines changed: 60 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2447,27 +2447,6 @@ static int post_relocation(struct module *mod, const struct load_info *info)
24472447
return module_finalize(info->hdr, info->sechdrs, mod);
24482448
}
24492449

2450-
/* Is this module of this name done loading? No locks held. */
2451-
static bool finished_loading(const char *name)
2452-
{
2453-
struct module *mod;
2454-
bool ret;
2455-
2456-
/*
2457-
* The module_mutex should not be a heavily contended lock;
2458-
* if we get the occasional sleep here, we'll go an extra iteration
2459-
* in the wait_event_interruptible(), which is harmless.
2460-
*/
2461-
sched_annotate_sleep();
2462-
mutex_lock(&module_mutex);
2463-
mod = find_module_all(name, strlen(name), true);
2464-
ret = !mod || mod->state == MODULE_STATE_LIVE
2465-
|| mod->state == MODULE_STATE_GOING;
2466-
mutex_unlock(&module_mutex);
2467-
2468-
return ret;
2469-
}
2470-
24712450
/* Call module constructors. */
24722451
static void do_mod_ctors(struct module *mod)
24732452
{
@@ -2631,6 +2610,63 @@ static int may_init_module(void)
26312610
return 0;
26322611
}
26332612

2613+
/* Is this module of this name done loading? No locks held. */
2614+
static bool finished_loading(const char *name)
2615+
{
2616+
struct module *mod;
2617+
bool ret;
2618+
2619+
/*
2620+
* The module_mutex should not be a heavily contended lock;
2621+
* if we get the occasional sleep here, we'll go an extra iteration
2622+
* in the wait_event_interruptible(), which is harmless.
2623+
*/
2624+
sched_annotate_sleep();
2625+
mutex_lock(&module_mutex);
2626+
mod = find_module_all(name, strlen(name), true);
2627+
ret = !mod || mod->state == MODULE_STATE_LIVE
2628+
|| mod->state == MODULE_STATE_GOING;
2629+
mutex_unlock(&module_mutex);
2630+
2631+
return ret;
2632+
}
2633+
2634+
/* Must be called with module_mutex held */
2635+
static int module_patient_check_exists(const char *name)
2636+
{
2637+
struct module *old;
2638+
int err = 0;
2639+
2640+
old = find_module_all(name, strlen(name), true);
2641+
if (old == NULL)
2642+
return 0;
2643+
2644+
if (old->state == MODULE_STATE_COMING ||
2645+
old->state == MODULE_STATE_UNFORMED) {
2646+
/* Wait in case it fails to load. */
2647+
mutex_unlock(&module_mutex);
2648+
err = wait_event_interruptible(module_wq,
2649+
finished_loading(name));
2650+
mutex_lock(&module_mutex);
2651+
if (err)
2652+
return err;
2653+
2654+
/* The module might have gone in the meantime. */
2655+
old = find_module_all(name, strlen(name), true);
2656+
}
2657+
2658+
/*
2659+
* We are here only when the same module was being loaded. Do
2660+
* not try to load it again right now. It prevents long delays
2661+
* caused by serialized module load failures. It might happen
2662+
* when more devices of the same type trigger load of
2663+
* a particular module.
2664+
*/
2665+
if (old && old->state == MODULE_STATE_LIVE)
2666+
return -EEXIST;
2667+
return -EBUSY;
2668+
}
2669+
26342670
/*
26352671
* We try to place it in the list now to make sure it's unique before
26362672
* we dedicate too many resources. In particular, temporary percpu
@@ -2639,49 +2675,21 @@ static int may_init_module(void)
26392675
static int add_unformed_module(struct module *mod)
26402676
{
26412677
int err;
2642-
struct module *old;
26432678

26442679
mod->state = MODULE_STATE_UNFORMED;
26452680

26462681
mutex_lock(&module_mutex);
2647-
old = find_module_all(mod->name, strlen(mod->name), true);
2648-
if (old != NULL) {
2649-
if (old->state == MODULE_STATE_COMING
2650-
|| old->state == MODULE_STATE_UNFORMED) {
2651-
/* Wait in case it fails to load. */
2652-
mutex_unlock(&module_mutex);
2653-
err = wait_event_interruptible(module_wq,
2654-
finished_loading(mod->name));
2655-
if (err)
2656-
goto out_unlocked;
2657-
2658-
/* The module might have gone in the meantime. */
2659-
mutex_lock(&module_mutex);
2660-
old = find_module_all(mod->name, strlen(mod->name),
2661-
true);
2662-
}
2663-
2664-
/*
2665-
* We are here only when the same module was being loaded. Do
2666-
* not try to load it again right now. It prevents long delays
2667-
* caused by serialized module load failures. It might happen
2668-
* when more devices of the same type trigger load of
2669-
* a particular module.
2670-
*/
2671-
if (old && old->state == MODULE_STATE_LIVE)
2672-
err = -EEXIST;
2673-
else
2674-
err = -EBUSY;
2682+
err = module_patient_check_exists(mod->name);
2683+
if (err)
26752684
goto out;
2676-
}
2685+
26772686
mod_update_bounds(mod);
26782687
list_add_rcu(&mod->list, &modules);
26792688
mod_tree_insert(mod);
26802689
err = 0;
26812690

26822691
out:
26832692
mutex_unlock(&module_mutex);
2684-
out_unlocked:
26852693
return err;
26862694
}
26872695

0 commit comments

Comments
 (0)