Skip to content

Commit 2124d84

Browse files
committed
module: make waiting for a concurrent module loader interruptible
The recursive aes-arm-bs module load situation reported by Russell King is getting fixed in the crypto layer, but this in the meantime fixes the "recursive load hangs forever" by just making the waiting for the first module load be interruptible. This should now match the old behavior before commit 9b9879f ("modules: catch concurrent module loads, treat them as idempotent"), which used the different "wait for module to be ready" code in module_patient_check_exists(). End result: a recursive module load will still block, but now a signal will interrupt it and fail the second module load, at which point the first module will successfully complete loading. Fixes: 9b9879f ("modules: catch concurrent module loads, treat them as idempotent") Cc: Russell King <[email protected]> Cc: Herbert Xu <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent ee9a43b commit 2124d84

File tree

1 file changed

+25
-15
lines changed

1 file changed

+25
-15
lines changed

kernel/module/main.c

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3104,7 +3104,7 @@ static bool idempotent(struct idempotent *u, const void *cookie)
31043104
struct idempotent *existing;
31053105
bool first;
31063106

3107-
u->ret = 0;
3107+
u->ret = -EINTR;
31083108
u->cookie = cookie;
31093109
init_completion(&u->complete);
31103110

@@ -3140,14 +3140,36 @@ static int idempotent_complete(struct idempotent *u, int ret)
31403140
hlist_for_each_entry_safe(pos, next, head, entry) {
31413141
if (pos->cookie != cookie)
31423142
continue;
3143-
hlist_del(&pos->entry);
3143+
hlist_del_init(&pos->entry);
31443144
pos->ret = ret;
31453145
complete(&pos->complete);
31463146
}
31473147
spin_unlock(&idem_lock);
31483148
return ret;
31493149
}
31503150

3151+
/*
3152+
* Wait for the idempotent worker.
3153+
*
3154+
* If we get interrupted, we need to remove ourselves from the
3155+
* the idempotent list, and the completion may still come in.
3156+
*
3157+
* The 'idem_lock' protects against the race, and 'idem.ret' was
3158+
* initialized to -EINTR and is thus always the right return
3159+
* value even if the idempotent work then completes between
3160+
* the wait_for_completion and the cleanup.
3161+
*/
3162+
static int idempotent_wait_for_completion(struct idempotent *u)
3163+
{
3164+
if (wait_for_completion_interruptible(&u->complete)) {
3165+
spin_lock(&idem_lock);
3166+
if (!hlist_unhashed(&u->entry))
3167+
hlist_del(&u->entry);
3168+
spin_unlock(&idem_lock);
3169+
}
3170+
return u->ret;
3171+
}
3172+
31513173
static int init_module_from_file(struct file *f, const char __user * uargs, int flags)
31523174
{
31533175
struct load_info info = { };
@@ -3191,20 +3213,8 @@ static int idempotent_init_module(struct file *f, const char __user * uargs, int
31913213

31923214
/*
31933215
* Somebody else won the race and is loading the module.
3194-
*
3195-
* We have to wait for it forever, since our 'idem' is
3196-
* on the stack and the list entry stays there until
3197-
* completed (but we could fix it under the idem_lock)
3198-
*
3199-
* It's also unclear what a real timeout might be,
3200-
* but we could maybe at least make this killable
3201-
* and remove the idem entry in that case?
32023216
*/
3203-
for (;;) {
3204-
if (wait_for_completion_timeout(&idem.complete, 10*HZ))
3205-
return idem.ret;
3206-
pr_warn_once("module '%pD' taking a long time to load", f);
3207-
}
3217+
return idempotent_wait_for_completion(&idem);
32083218
}
32093219

32103220
SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)

0 commit comments

Comments
 (0)