diff options
-rw-r--r-- | kernel/module.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/kernel/module.c b/kernel/module.c index 1bb4c5e0d56e..17314691d3cc 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -65,6 +65,9 @@ | |||
65 | static DEFINE_MUTEX(module_mutex); | 65 | static DEFINE_MUTEX(module_mutex); |
66 | static LIST_HEAD(modules); | 66 | static LIST_HEAD(modules); |
67 | 67 | ||
68 | /* Waiting for a module to finish initializing? */ | ||
69 | static DECLARE_WAIT_QUEUE_HEAD(module_wq); | ||
70 | |||
68 | static BLOCKING_NOTIFIER_HEAD(module_notify_list); | 71 | static BLOCKING_NOTIFIER_HEAD(module_notify_list); |
69 | 72 | ||
70 | int register_module_notifier(struct notifier_block * nb) | 73 | int register_module_notifier(struct notifier_block * nb) |
@@ -84,8 +87,11 @@ EXPORT_SYMBOL(unregister_module_notifier); | |||
84 | static inline int strong_try_module_get(struct module *mod) | 87 | static inline int strong_try_module_get(struct module *mod) |
85 | { | 88 | { |
86 | if (mod && mod->state == MODULE_STATE_COMING) | 89 | if (mod && mod->state == MODULE_STATE_COMING) |
90 | return -EBUSY; | ||
91 | if (try_module_get(mod)) | ||
87 | return 0; | 92 | return 0; |
88 | return try_module_get(mod); | 93 | else |
94 | return -ENOENT; | ||
89 | } | 95 | } |
90 | 96 | ||
91 | static inline void add_taint_module(struct module *mod, unsigned flag) | 97 | static inline void add_taint_module(struct module *mod, unsigned flag) |
@@ -539,11 +545,21 @@ static int already_uses(struct module *a, struct module *b) | |||
539 | static int use_module(struct module *a, struct module *b) | 545 | static int use_module(struct module *a, struct module *b) |
540 | { | 546 | { |
541 | struct module_use *use; | 547 | struct module_use *use; |
542 | int no_warn; | 548 | int no_warn, err; |
543 | 549 | ||
544 | if (b == NULL || already_uses(a, b)) return 1; | 550 | if (b == NULL || already_uses(a, b)) return 1; |
545 | 551 | ||
546 | if (!strong_try_module_get(b)) | 552 | /* If we're interrupted or time out, we fail. */ |
553 | if (wait_event_interruptible_timeout( | ||
554 | module_wq, (err = strong_try_module_get(b)) != -EBUSY, | ||
555 | 30 * HZ) <= 0) { | ||
556 | printk("%s: gave up waiting for init of module %s.\n", | ||
557 | a->name, b->name); | ||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | /* If strong_try_module_get() returned a different error, we fail. */ | ||
562 | if (err) | ||
547 | return 0; | 563 | return 0; |
548 | 564 | ||
549 | DEBUGP("Allocating new usage for %s.\n", a->name); | 565 | DEBUGP("Allocating new usage for %s.\n", a->name); |
@@ -816,7 +832,7 @@ static inline void module_unload_free(struct module *mod) | |||
816 | 832 | ||
817 | static inline int use_module(struct module *a, struct module *b) | 833 | static inline int use_module(struct module *a, struct module *b) |
818 | { | 834 | { |
819 | return strong_try_module_get(b); | 835 | return strong_try_module_get(b) == 0; |
820 | } | 836 | } |
821 | 837 | ||
822 | static inline void module_unload_init(struct module *mod) | 838 | static inline void module_unload_init(struct module *mod) |
@@ -1326,7 +1342,7 @@ void *__symbol_get(const char *symbol) | |||
1326 | 1342 | ||
1327 | preempt_disable(); | 1343 | preempt_disable(); |
1328 | value = __find_symbol(symbol, &owner, &crc, 1); | 1344 | value = __find_symbol(symbol, &owner, &crc, 1); |
1329 | if (value && !strong_try_module_get(owner)) | 1345 | if (value && strong_try_module_get(owner) != 0) |
1330 | value = 0; | 1346 | value = 0; |
1331 | preempt_enable(); | 1347 | preempt_enable(); |
1332 | 1348 | ||
@@ -2132,6 +2148,7 @@ sys_init_module(void __user *umod, | |||
2132 | mutex_lock(&module_mutex); | 2148 | mutex_lock(&module_mutex); |
2133 | free_module(mod); | 2149 | free_module(mod); |
2134 | mutex_unlock(&module_mutex); | 2150 | mutex_unlock(&module_mutex); |
2151 | wake_up(&module_wq); | ||
2135 | return ret; | 2152 | return ret; |
2136 | } | 2153 | } |
2137 | 2154 | ||
@@ -2146,6 +2163,7 @@ sys_init_module(void __user *umod, | |||
2146 | mod->init_size = 0; | 2163 | mod->init_size = 0; |
2147 | mod->init_text_size = 0; | 2164 | mod->init_text_size = 0; |
2148 | mutex_unlock(&module_mutex); | 2165 | mutex_unlock(&module_mutex); |
2166 | wake_up(&module_wq); | ||
2149 | 2167 | ||
2150 | return 0; | 2168 | return 0; |
2151 | } | 2169 | } |