Replace module_ref per-cpu complex reference counter with an atomic_t simple refcnt. This is for code simplification.
Showing the changes to kernel/module.c (1 of 3 files). Show all
Unified · Split
| @@ -631,15 +631,11 @@ EXPORT_TRACEPOINT_SYMBOL(module_get); · 630 unmodified lines | ||
| 631 | 631 | /* Init the unload section of the module. */ |
| 632 | 632 | static int module_unload_init(struct module *mod) |
| 633 | 633 | { |
| 634 | − mod->refptr = alloc_percpu(struct module_ref); | |
| 635 | − if (!mod->refptr) | |
| 636 | − return -ENOMEM; | |
| 637 | − | |
| 638 | 634 | INIT_LIST_HEAD(&mod->source_list); |
| 639 | 635 | INIT_LIST_HEAD(&mod->target_list); |
| 640 | 636 | |
| 641 | 637 | /* Hold reference count during initialization. */ |
| 642 | − raw_cpu_write(mod->refptr->incs, 1); | |
| 638 | + atomic_set(&mod->refcnt, 1); | |
| 643 | 639 | |
| 644 | 640 | return 0; |
| 645 | 641 | } |
| @@ -721,8 +717,6 @@ static void module_unload_free(struct module *mod) · 75 unmodified lines | ||
| 721 | 717 | kfree(use); |
| 722 | 718 | } |
| 723 | 719 | mutex_unlock(&module_mutex); |
| 724 | − | |
| 725 | − free_percpu(mod->refptr); | |
| 726 | 720 | } |
| 727 | 721 | |
| 728 | 722 | #ifdef CONFIG_MODULE_FORCE_UNLOAD |
| @@ -772,28 +766,7 @@ static int try_stop_module(struct module *mod, int flags, int *forced) · 43 unmodified lines | ||
| 772 | 766 | |
| 773 | 767 | unsigned long module_refcount(struct module *mod) |
| 774 | 768 | { |
| 775 | − unsigned long incs = 0, decs = 0; | |
| 776 | − int cpu; | |
| 777 | − | |
| 778 | − for_each_possible_cpu(cpu) | |
| 779 | − decs += per_cpu_ptr(mod->refptr, cpu)->decs; | |
| 780 | − /* | |
| 781 | − * ensure the incs are added up after the decs. | |
| 782 | − * module_put ensures incs are visible before decs with smp_wmb. | |
| 783 | − * | |
| 784 | − * This 2-count scheme avoids the situation where the refcount | |
| 785 | − * for CPU0 is read, then CPU0 increments the module refcount, | |
| 786 | − * then CPU1 drops that refcount, then the refcount for CPU1 is | |
| 787 | − * read. We would record a decrement but not its corresponding | |
| 788 | − * increment so we would see a low count (disaster). | |
| 789 | − * | |
| 790 | − * Rare situation? But module_refcount can be preempted, and we | |
| 791 | − * might be tallying up 4096+ CPUs. So it is not impossible. | |
| 792 | − */ | |
| 793 | − smp_rmb(); | |
| 794 | − for_each_possible_cpu(cpu) | |
| 795 | − incs += per_cpu_ptr(mod->refptr, cpu)->incs; | |
| 796 | − return incs - decs; | |
| 769 | + return (unsigned long)atomic_read(&mod->refcnt); | |
| 797 | 770 | } |
| 798 | 771 | EXPORT_SYMBOL(module_refcount); |
| 799 | 772 | |
| @@ -935,7 +908,7 @@ void __module_get(struct module *module) · 135 unmodified lines | ||
| 935 | 908 | { |
| 936 | 909 | if (module) { |
| 937 | 910 | preempt_disable(); |
| 938 | − __this_cpu_inc(module->refptr->incs); | |
| 911 | + atomic_inc(&module->refcnt); | |
| 939 | 912 | trace_module_get(module, _RET_IP_); |
| 940 | 913 | preempt_enable(); |
| 941 | 914 | } |
| @@ -950,7 +923,7 @@ bool try_module_get(struct module *module) · 8 unmodified lines | ||
| 950 | 923 | preempt_disable(); |
| 951 | 924 | |
| 952 | 925 | if (likely(module_is_live(module))) { |
| 953 | − __this_cpu_inc(module->refptr->incs); | |
| 926 | + atomic_inc(&module->refcnt); | |
| 954 | 927 | trace_module_get(module, _RET_IP_); |
| 955 | 928 | } else |
| 956 | 929 | ret = false; |
| @@ -965,9 +938,7 @@ void module_put(struct module *module) · 8 unmodified lines | ||
| 965 | 938 | { |
| 966 | 939 | if (module) { |
| 967 | 940 | preempt_disable(); |
| 968 | − smp_wmb(); /* see comment in module_refcount */ | |
| 969 | − __this_cpu_inc(module->refptr->decs); | |
| 970 | − | |
| 941 | + atomic_dec(&module->refcnt); | |
| 971 | 942 | trace_module_put(module, _RET_IP_); |
| 972 | 943 | preempt_enable(); |
| 973 | 944 | } |