diff options
author | Luke Shumaker <LukeShu@sbcglobal.net> | 2012-10-27 12:00:51 -0400 |
---|---|---|
committer | Luke Shumaker <LukeShu@sbcglobal.net> | 2012-10-27 12:00:51 -0400 |
commit | a957024315d06271ceb557b40512d728a15da2b4 (patch) | |
tree | c5561790c4d67e2c1d4ba45392e160b18508463f /libre/linux-libre/module-symbol-waiting-3.6.patch | |
parent | df1af774dc8dc6b26467efb84b04295d2726b8bb (diff) | |
parent | df0201976210a03cbc15d5580a609a62e8cc8b05 (diff) |
Merge branch 'master' of ssh://parabolagnulinux.org:1863/srv/git/abslibre
Diffstat (limited to 'libre/linux-libre/module-symbol-waiting-3.6.patch')
-rw-r--r-- | libre/linux-libre/module-symbol-waiting-3.6.patch | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/libre/linux-libre/module-symbol-waiting-3.6.patch b/libre/linux-libre/module-symbol-waiting-3.6.patch new file mode 100644 index 000000000..b87a38ff5 --- /dev/null +++ b/libre/linux-libre/module-symbol-waiting-3.6.patch @@ -0,0 +1,66 @@ +From: Rusty Russell <rusty@rustcorp.com.au> +Date: Fri, 28 Sep 2012 05:01:03 +0000 (+0930) +Subject: module: fix symbol waiting when module fails before init +X-Git-Tag: v3.7-rc1~2^2~33 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=6f13909f4fe9652f1 + +module: fix symbol waiting when module fails before init + +We use resolve_symbol_wait(), which blocks if the module containing +the symbol is still loading. However: + +1) The module_wq we use is only woken after calling the modules' init + function, but there are other failure paths after the module is + placed in the linked list where we need to do the same thing. + +2) wake_up() only wakes one waiter, and our waitqueue is shared by all + modules, so we need to wake them all. + +3) wake_up_all() doesn't imply a memory barrier: I feel happier calling + it after we've grabbed and dropped the module_mutex, not just after + the state assignment. + +Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> +--- + +diff --git a/kernel/module.c b/kernel/module.c +index 7f2ee45f..63cf6e7 100644 +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -2959,7 +2959,7 @@ static struct module *load_module(void __user *umod, + /* Unlink carefully: kallsyms could be walking list. */ + list_del_rcu(&mod->list); + module_bug_cleanup(mod); +- ++ wake_up_all(&module_wq); + ddebug: + dynamic_debug_remove(info.debug); + unlock: +@@ -3034,7 +3034,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, + blocking_notifier_call_chain(&module_notify_list, + MODULE_STATE_GOING, mod); + free_module(mod); +- wake_up(&module_wq); ++ wake_up_all(&module_wq); + return ret; + } + if (ret > 0) { +@@ -3046,9 +3046,8 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, + dump_stack(); + } + +- /* Now it's a first class citizen! Wake up anyone waiting for it. */ ++ /* Now it's a first class citizen! */ + mod->state = MODULE_STATE_LIVE; +- wake_up(&module_wq); + blocking_notifier_call_chain(&module_notify_list, + MODULE_STATE_LIVE, mod); + +@@ -3071,6 +3070,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, + mod->init_ro_size = 0; + mod->init_text_size = 0; + mutex_unlock(&module_mutex); ++ wake_up_all(&module_wq); + + return 0; + } |