aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-01-29 17:13:18 -0500
committerRusty Russell <rusty@rustcorp.com.au>2008-01-29 01:13:20 -0500
commitc9a3ba55bb5da03fc7d707709a7fe078fe1aa0a0 (patch)
tree3d25d1783ad794b7bc64f5f36f5289f7f51a56fc
parenta2da4052f1df6bc77749f84496fe731ab8b458f7 (diff)
module: wait for dependent modules doing init.
There have been reports of modules failing to load because the modules they depend on are still loading. This changes the modules to wait for a reasonable length of time in that case. We time out eventually, because there can be module loops or broken modules. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r--kernel/module.c28
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 @@
65static DEFINE_MUTEX(module_mutex); 65static DEFINE_MUTEX(module_mutex);
66static LIST_HEAD(modules); 66static LIST_HEAD(modules);
67 67
68/* Waiting for a module to finish initializing? */
69static DECLARE_WAIT_QUEUE_HEAD(module_wq);
70
68static BLOCKING_NOTIFIER_HEAD(module_notify_list); 71static BLOCKING_NOTIFIER_HEAD(module_notify_list);
69 72
70int register_module_notifier(struct notifier_block * nb) 73int register_module_notifier(struct notifier_block * nb)
@@ -84,8 +87,11 @@ EXPORT_SYMBOL(unregister_module_notifier);
84static inline int strong_try_module_get(struct module *mod) 87static 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
91static inline void add_taint_module(struct module *mod, unsigned flag) 97static inline void add_taint_module(struct module *mod, unsigned flag)
@@ -539,11 +545,21 @@ static int already_uses(struct module *a, struct module *b)
539static int use_module(struct module *a, struct module *b) 545static 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
817static inline int use_module(struct module *a, struct module *b) 833static 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
822static inline void module_unload_init(struct module *mod) 838static 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}