1 |
From 6f13909f4fe9652f189b462c6c98767309000321 Mon Sep 17 00:00:00 2001 |
2 |
From: Rusty Russell <rusty@rustcorp.com.au> |
3 |
Date: Fri, 28 Sep 2012 14:31:03 +0930 |
4 |
Subject: [PATCH] module: fix symbol waiting when module fails before init |
5 |
|
6 |
We use resolve_symbol_wait(), which blocks if the module containing |
7 |
the symbol is still loading. However: |
8 |
|
9 |
1) The module_wq we use is only woken after calling the modules' init |
10 |
function, but there are other failure paths after the module is |
11 |
placed in the linked list where we need to do the same thing. |
12 |
|
13 |
2) wake_up() only wakes one waiter, and our waitqueue is shared by all |
14 |
modules, so we need to wake them all. |
15 |
|
16 |
3) wake_up_all() doesn't imply a memory barrier: I feel happier calling |
17 |
it after we've grabbed and dropped the module_mutex, not just after |
18 |
the state assignment. |
19 |
|
20 |
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> |
21 |
--- |
22 |
kernel/module.c | 8 ++++---- |
23 |
1 file changed, 4 insertions(+), 4 deletions(-) |
24 |
|
25 |
diff --git a/kernel/module.c b/kernel/module.c |
26 |
index 7f2ee45f..63cf6e7 100644 |
27 |
--- a/kernel/module.c |
28 |
+++ b/kernel/module.c |
29 |
@@ -2959,7 +2959,7 @@ static struct module *load_module(void __user *umod, |
30 |
/* Unlink carefully: kallsyms could be walking list. */ |
31 |
list_del_rcu(&mod->list); |
32 |
module_bug_cleanup(mod); |
33 |
- |
34 |
+ wake_up_all(&module_wq); |
35 |
ddebug: |
36 |
dynamic_debug_remove(info.debug); |
37 |
unlock: |
38 |
@@ -3034,7 +3034,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, |
39 |
blocking_notifier_call_chain(&module_notify_list, |
40 |
MODULE_STATE_GOING, mod); |
41 |
free_module(mod); |
42 |
- wake_up(&module_wq); |
43 |
+ wake_up_all(&module_wq); |
44 |
return ret; |
45 |
} |
46 |
if (ret > 0) { |
47 |
@@ -3046,9 +3046,8 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, |
48 |
dump_stack(); |
49 |
} |
50 |
|
51 |
- /* Now it's a first class citizen! Wake up anyone waiting for it. */ |
52 |
+ /* Now it's a first class citizen! */ |
53 |
mod->state = MODULE_STATE_LIVE; |
54 |
- wake_up(&module_wq); |
55 |
blocking_notifier_call_chain(&module_notify_list, |
56 |
MODULE_STATE_LIVE, mod); |
57 |
|
58 |
@@ -3071,6 +3070,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, |
59 |
mod->init_ro_size = 0; |
60 |
mod->init_text_size = 0; |
61 |
mutex_unlock(&module_mutex); |
62 |
+ wake_up_all(&module_wq); |
63 |
|
64 |
return 0; |
65 |
} |
66 |
-- |
67 |
1.7.12.4 |
68 |
|