History

module: Replace module_ref with atomic_t refcnt

Replace module_ref per-cpu complex reference counter with an atomic_t simple refcnt. This is for code simplification.

Masami Hiramatsu committed 12 years ago

Commit 2f35c411 parent 0286b5e3 files · +7 −50Browse files

Showing the changes to kernel/module.c (1 of 3 files). Show all

Unified · Split

kernel/module.c+5−34
@@ -631,15 +631,11 @@ EXPORT_TRACEPOINT_SYMBOL(module_get); · 630 unmodified lines
631/* Init the unload section of the module. */631/* Init the unload section of the module. */
632static int module_unload_init(struct module *mod)632static 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 INIT_LIST_HEAD(&mod->source_list);634 INIT_LIST_HEAD(&mod->source_list);
639 INIT_LIST_HEAD(&mod->target_list);635 INIT_LIST_HEAD(&mod->target_list);
640 636
641 /* Hold reference count during initialization. */637 /* Hold reference count during initialization. */
642 raw_cpu_write(mod->refptr->incs, 1);638 atomic_set(&mod->refcnt, 1);
643 639
644 return 0;640 return 0;
645}641}
@@ -721,8 +717,6 @@ static void module_unload_free(struct module *mod) · 75 unmodified lines
721 kfree(use);717 kfree(use);
722 }718 }
723 mutex_unlock(&module_mutex);719 mutex_unlock(&module_mutex);
724
725 free_percpu(mod->refptr);
726}720}
727 721
728#ifdef CONFIG_MODULE_FORCE_UNLOAD722#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
773unsigned long module_refcount(struct module *mod)767unsigned long module_refcount(struct module *mod)
774{768{
775 unsigned long incs = 0, decs = 0;769 return (unsigned long)atomic_read(&mod->refcnt);
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;
797}770}
798EXPORT_SYMBOL(module_refcount);771EXPORT_SYMBOL(module_refcount);
799 772
@@ -935,7 +908,7 @@ void __module_get(struct module *module) · 135 unmodified lines
935{908{
936 if (module) {909 if (module) {
937 preempt_disable();910 preempt_disable();
938 __this_cpu_inc(module->refptr->incs);911 atomic_inc(&module->refcnt);
939 trace_module_get(module, _RET_IP_);912 trace_module_get(module, _RET_IP_);
940 preempt_enable();913 preempt_enable();
941 }914 }
@@ -950,7 +923,7 @@ bool try_module_get(struct module *module) · 8 unmodified lines
950 preempt_disable();923 preempt_disable();
951 924
952 if (likely(module_is_live(module))) {925 if (likely(module_is_live(module))) {
953 __this_cpu_inc(module->refptr->incs);926 atomic_inc(&module->refcnt);
954 trace_module_get(module, _RET_IP_);927 trace_module_get(module, _RET_IP_);
955 } else928 } else
956 ret = false;929 ret = false;
@@ -965,9 +938,7 @@ void module_put(struct module *module) · 8 unmodified lines
965{938{
966 if (module) {939 if (module) {
967 preempt_disable();940 preempt_disable();
968 smp_wmb(); /* see comment in module_refcount */941 atomic_dec(&module->refcnt);
969 __this_cpu_inc(module->refptr->decs);
970
971 trace_module_put(module, _RET_IP_);942 trace_module_put(module, _RET_IP_);
972 preempt_enable();943 preempt_enable();
973 }944 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t