| @@ -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 | } |