diff options
author | Tejun Heo <tj@kernel.org> | 2013-01-22 19:48:03 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2013-01-22 19:48:03 -0500 |
commit | 0fdff3ec6d87856cdcc99e69cf42143fdd6c56b4 (patch) | |
tree | 361b0d7f16f03c4e9f196882df5245faa4ac7138 /kernel | |
parent | 21c3c5d2800733b7a276725b8e1ae49a694adc1a (diff) |
async, kmod: warn on synchronous request_module() from async workers
Synchronous requet_module() from an async worker can lead to deadlock
because module init path may invoke async_synchronize_full(). The
async worker waits for request_module() to complete and the module
loading waits for the async task to finish. This bug happened in the
block layer because of default elevator auto-loading.
Block layer has been updated not to do default elevator auto-loading
and it has been decided to disallow synchronous request_module() from
async workers.
Trigger WARN_ON_ONCE() on synchronous request_module() from async
workers.
For more details, please refer to the following thread.
http://thread.gmane.org/gmane.linux.kernel/1420814
Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Alex Riesen <raa.lkml@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/kmod.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/kernel/kmod.c b/kernel/kmod.c index 1c317e386831..ecd42b484db8 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/suspend.h> | 38 | #include <linux/suspend.h> |
39 | #include <linux/rwsem.h> | 39 | #include <linux/rwsem.h> |
40 | #include <linux/ptrace.h> | 40 | #include <linux/ptrace.h> |
41 | #include <linux/async.h> | ||
41 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
42 | 43 | ||
43 | #include <trace/events/module.h> | 44 | #include <trace/events/module.h> |
@@ -130,6 +131,14 @@ int __request_module(bool wait, const char *fmt, ...) | |||
130 | #define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */ | 131 | #define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */ |
131 | static int kmod_loop_msg; | 132 | static int kmod_loop_msg; |
132 | 133 | ||
134 | /* | ||
135 | * We don't allow synchronous module loading from async. Module | ||
136 | * init may invoke async_synchronize_full() which will end up | ||
137 | * waiting for this task which already is waiting for the module | ||
138 | * loading to complete, leading to a deadlock. | ||
139 | */ | ||
140 | WARN_ON_ONCE(wait && current_is_async()); | ||
141 | |||
133 | va_start(args, fmt); | 142 | va_start(args, fmt); |
134 | ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args); | 143 | ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args); |
135 | va_end(args); | 144 | va_end(args); |