diff options
| author | David Woodhouse <David.Woodhouse@intel.com> | 2010-04-09 18:17:41 +0400 |
|---|---|---|
| committer | David Woodhouse <David.Woodhouse@intel.com> | 2010-04-09 18:21:12 +0400 |
| commit | 87d8a69709d971913e6cc7210450fcb8be963667 (patch) | |
| tree | 4f8eb95c588f7df84554dcf97d67540664333a7b /include/linux/module.h | |
| parent | 0b8973a81876d90f916507ac40d1381068dc986a (diff) | |
| parent | 2eaa9cfdf33b8d7fb7aff27792192e0019ae8fc6 (diff) | |
| download | linux-87d8a69709d971913e6cc7210450fcb8be963667.tar.xz | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'include/linux/module.h')
| -rw-r--r-- | include/linux/module.h | 44 |
1 files changed, 19 insertions, 25 deletions
diff --git a/include/linux/module.h b/include/linux/module.h index 482efc865acf..5e869ffd34aa 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -17,7 +17,7 @@ #include <linux/moduleparam.h> #include <linux/tracepoint.h> -#include <asm/local.h> +#include <linux/percpu.h> #include <asm/module.h> #include <trace/events/module.h> @@ -25,8 +25,10 @@ /* Not Yet Implemented */ #define MODULE_SUPPORTED_DEVICE(name) -/* some toolchains uses a `_' prefix for all user symbols */ -#ifndef MODULE_SYMBOL_PREFIX +/* Some toolchains use a `_' prefix for all user symbols. */ +#ifdef CONFIG_SYMBOL_PREFIX +#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX +#else #define MODULE_SYMBOL_PREFIX "" #endif @@ -173,6 +175,7 @@ struct notifier_block; #ifdef CONFIG_MODULES +extern int modules_disabled; /* for sysctl */ /* Get/put a kernel symbol (calls must be symmetric) */ void *__symbol_get(const char *symbol); void *__symbol_get_gpl(const char *symbol); @@ -361,11 +364,9 @@ struct module /* Destruction function. */ void (*exit)(void); -#ifdef CONFIG_SMP - char *refptr; -#else - local_t ref; -#endif + struct module_ref { + int count; + } __percpu *refptr; #endif #ifdef CONFIG_CONSTRUCTORS @@ -452,25 +453,16 @@ void __symbol_put(const char *symbol); #define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) void symbol_put_addr(void *addr); -static inline local_t *__module_ref_addr(struct module *mod, int cpu) -{ -#ifdef CONFIG_SMP - return (local_t *) (mod->refptr + per_cpu_offset(cpu)); -#else - return &mod->ref; -#endif -} - /* Sometimes we know we already have a refcount, and it's easier not to handle the error case (which only happens with rmmod --wait). */ static inline void __module_get(struct module *module) { if (module) { - unsigned int cpu = get_cpu(); - local_inc(__module_ref_addr(module, cpu)); + preempt_disable(); + __this_cpu_inc(module->refptr->count); trace_module_get(module, _THIS_IP_, - local_read(__module_ref_addr(module, cpu))); - put_cpu(); + __this_cpu_read(module->refptr->count)); + preempt_enable(); } } @@ -479,15 +471,17 @@ static inline int try_module_get(struct module *module) int ret = 1; if (module) { - unsigned int cpu = get_cpu(); + preempt_disable(); + if (likely(module_is_live(module))) { - local_inc(__module_ref_addr(module, cpu)); + __this_cpu_inc(module->refptr->count); trace_module_get(module, _THIS_IP_, - local_read(__module_ref_addr(module, cpu))); + __this_cpu_read(module->refptr->count)); } else ret = 0; - put_cpu(); + + preempt_enable(); } return ret; } |
