diff options
Diffstat (limited to 'include/linux/module.h')
| -rw-r--r-- | include/linux/module.h | 38 |
1 files changed, 15 insertions, 23 deletions
diff --git a/include/linux/module.h b/include/linux/module.h index 6cb1a3cab5d3..5e869ffd34aa 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
| @@ -17,7 +17,7 @@ | |||
| 17 | #include <linux/moduleparam.h> | 17 | #include <linux/moduleparam.h> |
| 18 | #include <linux/tracepoint.h> | 18 | #include <linux/tracepoint.h> |
| 19 | 19 | ||
| 20 | #include <asm/local.h> | 20 | #include <linux/percpu.h> |
| 21 | #include <asm/module.h> | 21 | #include <asm/module.h> |
| 22 | 22 | ||
| 23 | #include <trace/events/module.h> | 23 | #include <trace/events/module.h> |
| @@ -175,6 +175,7 @@ struct notifier_block; | |||
| 175 | 175 | ||
| 176 | #ifdef CONFIG_MODULES | 176 | #ifdef CONFIG_MODULES |
| 177 | 177 | ||
| 178 | extern int modules_disabled; /* for sysctl */ | ||
| 178 | /* Get/put a kernel symbol (calls must be symmetric) */ | 179 | /* Get/put a kernel symbol (calls must be symmetric) */ |
| 179 | void *__symbol_get(const char *symbol); | 180 | void *__symbol_get(const char *symbol); |
| 180 | void *__symbol_get_gpl(const char *symbol); | 181 | void *__symbol_get_gpl(const char *symbol); |
| @@ -363,11 +364,9 @@ struct module | |||
| 363 | /* Destruction function. */ | 364 | /* Destruction function. */ |
| 364 | void (*exit)(void); | 365 | void (*exit)(void); |
| 365 | 366 | ||
| 366 | #ifdef CONFIG_SMP | 367 | struct module_ref { |
| 367 | char *refptr; | 368 | int count; |
| 368 | #else | 369 | } __percpu *refptr; |
| 369 | local_t ref; | ||
| 370 | #endif | ||
| 371 | #endif | 370 | #endif |
| 372 | 371 | ||
| 373 | #ifdef CONFIG_CONSTRUCTORS | 372 | #ifdef CONFIG_CONSTRUCTORS |
| @@ -454,25 +453,16 @@ void __symbol_put(const char *symbol); | |||
| 454 | #define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) | 453 | #define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) |
| 455 | void symbol_put_addr(void *addr); | 454 | void symbol_put_addr(void *addr); |
| 456 | 455 | ||
| 457 | static inline local_t *__module_ref_addr(struct module *mod, int cpu) | ||
| 458 | { | ||
| 459 | #ifdef CONFIG_SMP | ||
| 460 | return (local_t *) (mod->refptr + per_cpu_offset(cpu)); | ||
| 461 | #else | ||
| 462 | return &mod->ref; | ||
| 463 | #endif | ||
| 464 | } | ||
| 465 | |||
| 466 | /* Sometimes we know we already have a refcount, and it's easier not | 456 | /* Sometimes we know we already have a refcount, and it's easier not |
| 467 | to handle the error case (which only happens with rmmod --wait). */ | 457 | to handle the error case (which only happens with rmmod --wait). */ |
| 468 | static inline void __module_get(struct module *module) | 458 | static inline void __module_get(struct module *module) |
| 469 | { | 459 | { |
| 470 | if (module) { | 460 | if (module) { |
| 471 | unsigned int cpu = get_cpu(); | 461 | preempt_disable(); |
| 472 | local_inc(__module_ref_addr(module, cpu)); | 462 | __this_cpu_inc(module->refptr->count); |
| 473 | trace_module_get(module, _THIS_IP_, | 463 | trace_module_get(module, _THIS_IP_, |
| 474 | local_read(__module_ref_addr(module, cpu))); | 464 | __this_cpu_read(module->refptr->count)); |
| 475 | put_cpu(); | 465 | preempt_enable(); |
| 476 | } | 466 | } |
| 477 | } | 467 | } |
| 478 | 468 | ||
| @@ -481,15 +471,17 @@ static inline int try_module_get(struct module *module) | |||
| 481 | int ret = 1; | 471 | int ret = 1; |
| 482 | 472 | ||
| 483 | if (module) { | 473 | if (module) { |
| 484 | unsigned int cpu = get_cpu(); | 474 | preempt_disable(); |
| 475 | |||
| 485 | if (likely(module_is_live(module))) { | 476 | if (likely(module_is_live(module))) { |
| 486 | local_inc(__module_ref_addr(module, cpu)); | 477 | __this_cpu_inc(module->refptr->count); |
| 487 | trace_module_get(module, _THIS_IP_, | 478 | trace_module_get(module, _THIS_IP_, |
| 488 | local_read(__module_ref_addr(module, cpu))); | 479 | __this_cpu_read(module->refptr->count)); |
| 489 | } | 480 | } |
| 490 | else | 481 | else |
| 491 | ret = 0; | 482 | ret = 0; |
| 492 | put_cpu(); | 483 | |
| 484 | preempt_enable(); | ||
| 493 | } | 485 | } |
| 494 | return ret; | 486 | return ret; |
| 495 | } | 487 | } |
