aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/module.c79
1 files changed, 48 insertions, 31 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 0129769301e3..be18c3e34684 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -523,7 +523,8 @@ static void module_unload_init(struct module *mod)
523{ 523{
524 int cpu; 524 int cpu;
525 525
526 INIT_LIST_HEAD(&mod->modules_which_use_me); 526 INIT_LIST_HEAD(&mod->source_list);
527 INIT_LIST_HEAD(&mod->target_list);
527 for_each_possible_cpu(cpu) { 528 for_each_possible_cpu(cpu) {
528 per_cpu_ptr(mod->refptr, cpu)->incs = 0; 529 per_cpu_ptr(mod->refptr, cpu)->incs = 0;
529 per_cpu_ptr(mod->refptr, cpu)->decs = 0; 530 per_cpu_ptr(mod->refptr, cpu)->decs = 0;
@@ -538,8 +539,9 @@ static void module_unload_init(struct module *mod)
538/* modules using other modules */ 539/* modules using other modules */
539struct module_use 540struct module_use
540{ 541{
541 struct list_head list; 542 struct list_head source_list;
542 struct module *module_which_uses; 543 struct list_head target_list;
544 struct module *source, *target;
543}; 545};
544 546
545/* Does a already use b? */ 547/* Does a already use b? */
@@ -547,8 +549,8 @@ static int already_uses(struct module *a, struct module *b)
547{ 549{
548 struct module_use *use; 550 struct module_use *use;
549 551
550 list_for_each_entry(use, &b->modules_which_use_me, list) { 552 list_for_each_entry(use, &b->source_list, source_list) {
551 if (use->module_which_uses == a) { 553 if (use->source == a) {
552 DEBUGP("%s uses %s!\n", a->name, b->name); 554 DEBUGP("%s uses %s!\n", a->name, b->name);
553 return 1; 555 return 1;
554 } 556 }
@@ -557,6 +559,33 @@ static int already_uses(struct module *a, struct module *b)
557 return 0; 559 return 0;
558} 560}
559 561
562/*
563 * Module a uses b
564 * - we add 'a' as a "source", 'b' as a "target" of module use
565 * - the module_use is added to the list of 'b' sources (so
566 * 'b' can walk the list to see who sourced them), and of 'a'
567 * targets (so 'a' can see what modules it targets).
568 */
569static int add_module_usage(struct module *a, struct module *b)
570{
571 int no_warn;
572 struct module_use *use;
573
574 DEBUGP("Allocating new usage for %s.\n", a->name);
575 use = kmalloc(sizeof(*use), GFP_ATOMIC);
576 if (!use) {
577 printk(KERN_WARNING "%s: out of memory loading\n", a->name);
578 return -ENOMEM;
579 }
580
581 use->source = a;
582 use->target = b;
583 list_add(&use->source_list, &b->source_list);
584 list_add(&use->target_list, &a->target_list);
585 no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name);
586 return 0;
587}
588
560/* Module a uses b */ 589/* Module a uses b */
561int use_module(struct module *a, struct module *b) 590int use_module(struct module *a, struct module *b)
562{ 591{
@@ -578,17 +607,11 @@ int use_module(struct module *a, struct module *b)
578 if (err) 607 if (err)
579 return 0; 608 return 0;
580 609
581 DEBUGP("Allocating new usage for %s.\n", a->name); 610 err = add_module_usage(a, b);
582 use = kmalloc(sizeof(*use), GFP_ATOMIC); 611 if (err) {
583 if (!use) {
584 printk("%s: out of memory loading\n", a->name);
585 module_put(b); 612 module_put(b);
586 return 0; 613 return 0;
587 } 614 }
588
589 use->module_which_uses = a;
590 list_add(&use->list, &b->modules_which_use_me);
591 no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name);
592 return 1; 615 return 1;
593} 616}
594EXPORT_SYMBOL_GPL(use_module); 617EXPORT_SYMBOL_GPL(use_module);
@@ -596,22 +619,16 @@ EXPORT_SYMBOL_GPL(use_module);
596/* Clear the unload stuff of the module. */ 619/* Clear the unload stuff of the module. */
597static void module_unload_free(struct module *mod) 620static void module_unload_free(struct module *mod)
598{ 621{
599 struct module *i; 622 struct module_use *use, *tmp;
600
601 list_for_each_entry(i, &modules, list) {
602 struct module_use *use;
603 623
604 list_for_each_entry(use, &i->modules_which_use_me, list) { 624 list_for_each_entry_safe(use, tmp, &mod->target_list, target_list) {
605 if (use->module_which_uses == mod) { 625 struct module *i = use->target;
606 DEBUGP("%s unusing %s\n", mod->name, i->name); 626 DEBUGP("%s unusing %s\n", mod->name, i->name);
607 module_put(i); 627 module_put(i);
608 list_del(&use->list); 628 list_del(&use->source_list);
609 kfree(use); 629 list_del(&use->target_list);
610 sysfs_remove_link(i->holders_dir, mod->name); 630 kfree(use);
611 /* There can be at most one match. */ 631 sysfs_remove_link(i->holders_dir, mod->name);
612 break;
613 }
614 }
615 } 632 }
616} 633}
617 634
@@ -735,7 +752,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
735 goto out; 752 goto out;
736 } 753 }
737 754
738 if (!list_empty(&mod->modules_which_use_me)) { 755 if (!list_empty(&mod->source_list)) {
739 /* Other modules depend on us: get rid of them first. */ 756 /* Other modules depend on us: get rid of them first. */
740 ret = -EWOULDBLOCK; 757 ret = -EWOULDBLOCK;
741 goto out; 758 goto out;
@@ -799,9 +816,9 @@ static inline void print_unload_info(struct seq_file *m, struct module *mod)
799 816
800 /* Always include a trailing , so userspace can differentiate 817 /* Always include a trailing , so userspace can differentiate
801 between this and the old multi-field proc format. */ 818 between this and the old multi-field proc format. */
802 list_for_each_entry(use, &mod->modules_which_use_me, list) { 819 list_for_each_entry(use, &mod->source_list, source_list) {
803 printed_something = 1; 820 printed_something = 1;
804 seq_printf(m, "%s,", use->module_which_uses->name); 821 seq_printf(m, "%s,", use->source->name);
805 } 822 }
806 823
807 if (mod->init != NULL && mod->exit == NULL) { 824 if (mod->init != NULL && mod->exit == NULL) {