aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 20:15:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 20:15:44 -0400
commita8251096b427283c47e7d8f9568be6b388dd68ec (patch)
treeedc9747e30b4b4413aa99acfbd3104d81b1c303b /kernel
parent27a3353a4525afe984f3b793681869d636136b69 (diff)
parent480b02df3aa9f07d1c7df0cd8be7a5ca73893455 (diff)
Merge branch 'modules' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
* 'modules' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus: module: drop the lock while waiting for module to complete initialization. MODULE_DEVICE_TABLE(isapnp, ...) does nothing hisax_fcpcipnp: fix broken isapnp device table. isapnp: move definitions to mod_devicetable.h so file2alias can reach them.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/module.c59
1 files changed, 37 insertions, 22 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 3c4fc4bb4b82..a8014bfb5a4e 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -565,33 +565,26 @@ int use_module(struct module *a, struct module *b)
565 struct module_use *use; 565 struct module_use *use;
566 int no_warn, err; 566 int no_warn, err;
567 567
568 if (b == NULL || already_uses(a, b)) return 1; 568 if (b == NULL || already_uses(a, b))
569
570 /* If we're interrupted or time out, we fail. */
571 if (wait_event_interruptible_timeout(
572 module_wq, (err = strong_try_module_get(b)) != -EBUSY,
573 30 * HZ) <= 0) {
574 printk("%s: gave up waiting for init of module %s.\n",
575 a->name, b->name);
576 return 0; 569 return 0;
577 }
578 570
579 /* If strong_try_module_get() returned a different error, we fail. */ 571 /* If we're interrupted or time out, we fail. */
572 err = strong_try_module_get(b);
580 if (err) 573 if (err)
581 return 0; 574 return err;
582 575
583 DEBUGP("Allocating new usage for %s.\n", a->name); 576 DEBUGP("Allocating new usage for %s.\n", a->name);
584 use = kmalloc(sizeof(*use), GFP_ATOMIC); 577 use = kmalloc(sizeof(*use), GFP_ATOMIC);
585 if (!use) { 578 if (!use) {
586 printk("%s: out of memory loading\n", a->name); 579 printk("%s: out of memory loading\n", a->name);
587 module_put(b); 580 module_put(b);
588 return 0; 581 return -ENOMEM;
589 } 582 }
590 583
591 use->module_which_uses = a; 584 use->module_which_uses = a;
592 list_add(&use->list, &b->modules_which_use_me); 585 list_add(&use->list, &b->modules_which_use_me);
593 no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name); 586 no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name);
594 return 1; 587 return 0;
595} 588}
596EXPORT_SYMBOL_GPL(use_module); 589EXPORT_SYMBOL_GPL(use_module);
597 590
@@ -884,7 +877,7 @@ static inline void module_unload_free(struct module *mod)
884 877
885int use_module(struct module *a, struct module *b) 878int use_module(struct module *a, struct module *b)
886{ 879{
887 return strong_try_module_get(b) == 0; 880 return strong_try_module_get(b);
888} 881}
889EXPORT_SYMBOL_GPL(use_module); 882EXPORT_SYMBOL_GPL(use_module);
890 883
@@ -1055,17 +1048,39 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs,
1055 struct module *owner; 1048 struct module *owner;
1056 const struct kernel_symbol *sym; 1049 const struct kernel_symbol *sym;
1057 const unsigned long *crc; 1050 const unsigned long *crc;
1051 DEFINE_WAIT(wait);
1052 int err;
1053 long timeleft = 30 * HZ;
1058 1054
1055again:
1059 sym = find_symbol(name, &owner, &crc, 1056 sym = find_symbol(name, &owner, &crc,
1060 !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true); 1057 !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);
1061 /* use_module can fail due to OOM, 1058 if (!sym)
1062 or module initialization or unloading */ 1059 return NULL;
1063 if (sym) { 1060
1064 if (!check_version(sechdrs, versindex, name, mod, crc, owner) 1061 if (!check_version(sechdrs, versindex, name, mod, crc, owner))
1065 || !use_module(mod, owner)) 1062 return NULL;
1066 sym = NULL; 1063
1067 } 1064 prepare_to_wait(&module_wq, &wait, TASK_INTERRUPTIBLE);
1068 return sym; 1065 err = use_module(mod, owner);
1066 if (likely(!err) || err != -EBUSY || signal_pending(current)) {
1067 finish_wait(&module_wq, &wait);
1068 return err ? NULL : sym;
1069 }
1070
1071 /* Module is still loading. Drop lock and wait. */
1072 mutex_unlock(&module_mutex);
1073 timeleft = schedule_timeout(timeleft);
1074 mutex_lock(&module_mutex);
1075 finish_wait(&module_wq, &wait);
1076
1077 /* Module might be gone entirely, or replaced. Re-lookup. */
1078 if (timeleft)
1079 goto again;
1080
1081 printk(KERN_WARNING "%s: gave up waiting for init of module %s.\n",
1082 mod->name, owner->name);
1083 return NULL;
1069} 1084}
1070 1085
1071/* 1086/*