aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2014-09-24 04:18:53 -0400
committerIngo Molnar <mingo@kernel.org>2014-10-28 05:56:30 -0400
commit3c9b2c3d64a49f264422d7743599cf7f6535972d (patch)
tree72e5230f01883c626c4d9415b7c53f9cbc9f6365 /kernel/module.c
parent7d4d26966e0b6443c78123a8a8b602e8eaf67694 (diff)
sched, modules: Fix nested sleep in add_unformed_module()
This is a genuine bug in add_unformed_module(), we cannot use blocking primitives inside a wait loop. So rewrite the wait_event_interruptible() usage to use the fresh wait_woken() stuff. Reported-by: Fengguang Wu <fengguang.wu@intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: tglx@linutronix.de Cc: ilya.dryomov@inktank.com Cc: umgwanakikbuti@gmail.com Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: oleg@redhat.com Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Link: http://lkml.kernel.org/r/20140924082242.458562904@infradead.org [ So this is probably complex to backport and the race wasn't reported AFAIK, so not marked for -stable. ] Signed-off-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 88cec1ddb1e3..e52a8739361a 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3097,6 +3097,32 @@ static int may_init_module(void)
3097} 3097}
3098 3098
3099/* 3099/*
3100 * Can't use wait_event_interruptible() because our condition
3101 * 'finished_loading()' contains a blocking primitive itself (mutex_lock).
3102 */
3103static int wait_finished_loading(struct module *mod)
3104{
3105 DEFINE_WAIT_FUNC(wait, woken_wake_function);
3106 int ret = 0;
3107
3108 add_wait_queue(&module_wq, &wait);
3109 for (;;) {
3110 if (finished_loading(mod->name))
3111 break;
3112
3113 if (signal_pending(current)) {
3114 ret = -ERESTARTSYS;
3115 break;
3116 }
3117
3118 wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
3119 }
3120 remove_wait_queue(&module_wq, &wait);
3121
3122 return ret;
3123}
3124
3125/*
3100 * We try to place it in the list now to make sure it's unique before 3126 * We try to place it in the list now to make sure it's unique before
3101 * we dedicate too many resources. In particular, temporary percpu 3127 * we dedicate too many resources. In particular, temporary percpu
3102 * memory exhaustion. 3128 * memory exhaustion.
@@ -3116,8 +3142,8 @@ again:
3116 || old->state == MODULE_STATE_UNFORMED) { 3142 || old->state == MODULE_STATE_UNFORMED) {
3117 /* Wait in case it fails to load. */ 3143 /* Wait in case it fails to load. */
3118 mutex_unlock(&module_mutex); 3144 mutex_unlock(&module_mutex);
3119 err = wait_event_interruptible(module_wq, 3145
3120 finished_loading(mod->name)); 3146 err = wait_finished_loading(mod);
3121 if (err) 3147 if (err)
3122 goto out_unlocked; 3148 goto out_unlocked;
3123 goto again; 3149 goto again;