diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 87 |
1 files changed, 47 insertions, 40 deletions
diff --git a/kernel/module.c b/kernel/module.c index 1016b75b026a..625985e70e9d 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -59,8 +59,6 @@ | |||
59 | #define CREATE_TRACE_POINTS | 59 | #define CREATE_TRACE_POINTS |
60 | #include <trace/events/module.h> | 60 | #include <trace/events/module.h> |
61 | 61 | ||
62 | EXPORT_TRACEPOINT_SYMBOL(module_get); | ||
63 | |||
64 | #if 0 | 62 | #if 0 |
65 | #define DEBUGP printk | 63 | #define DEBUGP printk |
66 | #else | 64 | #else |
@@ -79,6 +77,10 @@ EXPORT_TRACEPOINT_SYMBOL(module_get); | |||
79 | DEFINE_MUTEX(module_mutex); | 77 | DEFINE_MUTEX(module_mutex); |
80 | EXPORT_SYMBOL_GPL(module_mutex); | 78 | EXPORT_SYMBOL_GPL(module_mutex); |
81 | static LIST_HEAD(modules); | 79 | static LIST_HEAD(modules); |
80 | #ifdef CONFIG_KGDB_KDB | ||
81 | struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ | ||
82 | #endif /* CONFIG_KGDB_KDB */ | ||
83 | |||
82 | 84 | ||
83 | /* Block module loading/unloading? */ | 85 | /* Block module loading/unloading? */ |
84 | int modules_disabled = 0; | 86 | int modules_disabled = 0; |
@@ -178,8 +180,6 @@ extern const struct kernel_symbol __start___ksymtab_gpl[]; | |||
178 | extern const struct kernel_symbol __stop___ksymtab_gpl[]; | 180 | extern const struct kernel_symbol __stop___ksymtab_gpl[]; |
179 | extern const struct kernel_symbol __start___ksymtab_gpl_future[]; | 181 | extern const struct kernel_symbol __start___ksymtab_gpl_future[]; |
180 | extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; | 182 | extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; |
181 | extern const struct kernel_symbol __start___ksymtab_gpl_future[]; | ||
182 | extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; | ||
183 | extern const unsigned long __start___kcrctab[]; | 183 | extern const unsigned long __start___kcrctab[]; |
184 | extern const unsigned long __start___kcrctab_gpl[]; | 184 | extern const unsigned long __start___kcrctab_gpl[]; |
185 | extern const unsigned long __start___kcrctab_gpl_future[]; | 185 | extern const unsigned long __start___kcrctab_gpl_future[]; |
@@ -515,6 +515,9 @@ MODINFO_ATTR(srcversion); | |||
515 | static char last_unloaded_module[MODULE_NAME_LEN+1]; | 515 | static char last_unloaded_module[MODULE_NAME_LEN+1]; |
516 | 516 | ||
517 | #ifdef CONFIG_MODULE_UNLOAD | 517 | #ifdef CONFIG_MODULE_UNLOAD |
518 | |||
519 | EXPORT_TRACEPOINT_SYMBOL(module_get); | ||
520 | |||
518 | /* Init the unload section of the module. */ | 521 | /* Init the unload section of the module. */ |
519 | static void module_unload_init(struct module *mod) | 522 | static void module_unload_init(struct module *mod) |
520 | { | 523 | { |
@@ -560,33 +563,26 @@ int use_module(struct module *a, struct module *b) | |||
560 | struct module_use *use; | 563 | struct module_use *use; |
561 | int no_warn, err; | 564 | int no_warn, err; |
562 | 565 | ||
563 | if (b == NULL || already_uses(a, b)) return 1; | 566 | if (b == NULL || already_uses(a, b)) |
564 | |||
565 | /* If we're interrupted or time out, we fail. */ | ||
566 | if (wait_event_interruptible_timeout( | ||
567 | module_wq, (err = strong_try_module_get(b)) != -EBUSY, | ||
568 | 30 * HZ) <= 0) { | ||
569 | printk("%s: gave up waiting for init of module %s.\n", | ||
570 | a->name, b->name); | ||
571 | return 0; | 567 | return 0; |
572 | } | ||
573 | 568 | ||
574 | /* If strong_try_module_get() returned a different error, we fail. */ | 569 | /* If we're interrupted or time out, we fail. */ |
570 | err = strong_try_module_get(b); | ||
575 | if (err) | 571 | if (err) |
576 | return 0; | 572 | return err; |
577 | 573 | ||
578 | DEBUGP("Allocating new usage for %s.\n", a->name); | 574 | DEBUGP("Allocating new usage for %s.\n", a->name); |
579 | use = kmalloc(sizeof(*use), GFP_ATOMIC); | 575 | use = kmalloc(sizeof(*use), GFP_ATOMIC); |
580 | if (!use) { | 576 | if (!use) { |
581 | printk("%s: out of memory loading\n", a->name); | 577 | printk("%s: out of memory loading\n", a->name); |
582 | module_put(b); | 578 | module_put(b); |
583 | return 0; | 579 | return -ENOMEM; |
584 | } | 580 | } |
585 | 581 | ||
586 | use->module_which_uses = a; | 582 | use->module_which_uses = a; |
587 | list_add(&use->list, &b->modules_which_use_me); | 583 | list_add(&use->list, &b->modules_which_use_me); |
588 | no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name); | 584 | no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name); |
589 | return 1; | 585 | return 0; |
590 | } | 586 | } |
591 | EXPORT_SYMBOL_GPL(use_module); | 587 | EXPORT_SYMBOL_GPL(use_module); |
592 | 588 | ||
@@ -723,16 +719,8 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, | |||
723 | return -EFAULT; | 719 | return -EFAULT; |
724 | name[MODULE_NAME_LEN-1] = '\0'; | 720 | name[MODULE_NAME_LEN-1] = '\0'; |
725 | 721 | ||
726 | /* Create stop_machine threads since free_module relies on | 722 | if (mutex_lock_interruptible(&module_mutex) != 0) |
727 | * a non-failing stop_machine call. */ | 723 | return -EINTR; |
728 | ret = stop_machine_create(); | ||
729 | if (ret) | ||
730 | return ret; | ||
731 | |||
732 | if (mutex_lock_interruptible(&module_mutex) != 0) { | ||
733 | ret = -EINTR; | ||
734 | goto out_stop; | ||
735 | } | ||
736 | 724 | ||
737 | mod = find_module(name); | 725 | mod = find_module(name); |
738 | if (!mod) { | 726 | if (!mod) { |
@@ -792,8 +780,6 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, | |||
792 | 780 | ||
793 | out: | 781 | out: |
794 | mutex_unlock(&module_mutex); | 782 | mutex_unlock(&module_mutex); |
795 | out_stop: | ||
796 | stop_machine_destroy(); | ||
797 | return ret; | 783 | return ret; |
798 | } | 784 | } |
799 | 785 | ||
@@ -867,8 +853,7 @@ void module_put(struct module *module) | |||
867 | smp_wmb(); /* see comment in module_refcount */ | 853 | smp_wmb(); /* see comment in module_refcount */ |
868 | __this_cpu_inc(module->refptr->decs); | 854 | __this_cpu_inc(module->refptr->decs); |
869 | 855 | ||
870 | trace_module_put(module, _RET_IP_, | 856 | trace_module_put(module, _RET_IP_); |
871 | __this_cpu_read(module->refptr->decs)); | ||
872 | /* Maybe they're waiting for us to drop reference? */ | 857 | /* Maybe they're waiting for us to drop reference? */ |
873 | if (unlikely(!module_is_live(module))) | 858 | if (unlikely(!module_is_live(module))) |
874 | wake_up_process(module->waiter); | 859 | wake_up_process(module->waiter); |
@@ -890,7 +875,7 @@ static inline void module_unload_free(struct module *mod) | |||
890 | 875 | ||
891 | int use_module(struct module *a, struct module *b) | 876 | int use_module(struct module *a, struct module *b) |
892 | { | 877 | { |
893 | return strong_try_module_get(b) == 0; | 878 | return strong_try_module_get(b); |
894 | } | 879 | } |
895 | EXPORT_SYMBOL_GPL(use_module); | 880 | EXPORT_SYMBOL_GPL(use_module); |
896 | 881 | ||
@@ -1061,17 +1046,39 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs, | |||
1061 | struct module *owner; | 1046 | struct module *owner; |
1062 | const struct kernel_symbol *sym; | 1047 | const struct kernel_symbol *sym; |
1063 | const unsigned long *crc; | 1048 | const unsigned long *crc; |
1049 | DEFINE_WAIT(wait); | ||
1050 | int err; | ||
1051 | long timeleft = 30 * HZ; | ||
1064 | 1052 | ||
1053 | again: | ||
1065 | sym = find_symbol(name, &owner, &crc, | 1054 | sym = find_symbol(name, &owner, &crc, |
1066 | !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true); | 1055 | !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true); |
1067 | /* use_module can fail due to OOM, | 1056 | if (!sym) |
1068 | or module initialization or unloading */ | 1057 | return NULL; |
1069 | if (sym) { | 1058 | |
1070 | if (!check_version(sechdrs, versindex, name, mod, crc, owner) | 1059 | if (!check_version(sechdrs, versindex, name, mod, crc, owner)) |
1071 | || !use_module(mod, owner)) | 1060 | return NULL; |
1072 | sym = NULL; | 1061 | |
1062 | prepare_to_wait(&module_wq, &wait, TASK_INTERRUPTIBLE); | ||
1063 | err = use_module(mod, owner); | ||
1064 | if (likely(!err) || err != -EBUSY || signal_pending(current)) { | ||
1065 | finish_wait(&module_wq, &wait); | ||
1066 | return err ? NULL : sym; | ||
1073 | } | 1067 | } |
1074 | return sym; | 1068 | |
1069 | /* Module is still loading. Drop lock and wait. */ | ||
1070 | mutex_unlock(&module_mutex); | ||
1071 | timeleft = schedule_timeout(timeleft); | ||
1072 | mutex_lock(&module_mutex); | ||
1073 | finish_wait(&module_wq, &wait); | ||
1074 | |||
1075 | /* Module might be gone entirely, or replaced. Re-lookup. */ | ||
1076 | if (timeleft) | ||
1077 | goto again; | ||
1078 | |||
1079 | printk(KERN_WARNING "%s: gave up waiting for init of module %s.\n", | ||
1080 | mod->name, owner->name); | ||
1081 | return NULL; | ||
1075 | } | 1082 | } |
1076 | 1083 | ||
1077 | /* | 1084 | /* |
@@ -1192,7 +1199,7 @@ struct module_notes_attrs { | |||
1192 | struct bin_attribute attrs[0]; | 1199 | struct bin_attribute attrs[0]; |
1193 | }; | 1200 | }; |
1194 | 1201 | ||
1195 | static ssize_t module_notes_read(struct kobject *kobj, | 1202 | static ssize_t module_notes_read(struct file *filp, struct kobject *kobj, |
1196 | struct bin_attribute *bin_attr, | 1203 | struct bin_attribute *bin_attr, |
1197 | char *buf, loff_t pos, size_t count) | 1204 | char *buf, loff_t pos, size_t count) |
1198 | { | 1205 | { |