diff options
Diffstat (limited to 'include/linux/module.h')
-rw-r--r-- | include/linux/module.h | 59 |
1 files changed, 31 insertions, 28 deletions
diff --git a/include/linux/module.h b/include/linux/module.h index 482efc865acf..515d53ae6a79 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> |
@@ -25,8 +25,10 @@ | |||
25 | /* Not Yet Implemented */ | 25 | /* Not Yet Implemented */ |
26 | #define MODULE_SUPPORTED_DEVICE(name) | 26 | #define MODULE_SUPPORTED_DEVICE(name) |
27 | 27 | ||
28 | /* some toolchains uses a `_' prefix for all user symbols */ | 28 | /* Some toolchains use a `_' prefix for all user symbols. */ |
29 | #ifndef MODULE_SYMBOL_PREFIX | 29 | #ifdef CONFIG_SYMBOL_PREFIX |
30 | #define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX | ||
31 | #else | ||
30 | #define MODULE_SYMBOL_PREFIX "" | 32 | #define MODULE_SYMBOL_PREFIX "" |
31 | #endif | 33 | #endif |
32 | 34 | ||
@@ -173,6 +175,7 @@ struct notifier_block; | |||
173 | 175 | ||
174 | #ifdef CONFIG_MODULES | 176 | #ifdef CONFIG_MODULES |
175 | 177 | ||
178 | extern int modules_disabled; /* for sysctl */ | ||
176 | /* Get/put a kernel symbol (calls must be symmetric) */ | 179 | /* Get/put a kernel symbol (calls must be symmetric) */ |
177 | void *__symbol_get(const char *symbol); | 180 | void *__symbol_get(const char *symbol); |
178 | void *__symbol_get_gpl(const char *symbol); | 181 | void *__symbol_get_gpl(const char *symbol); |
@@ -327,8 +330,11 @@ struct module | |||
327 | struct module_notes_attrs *notes_attrs; | 330 | struct module_notes_attrs *notes_attrs; |
328 | #endif | 331 | #endif |
329 | 332 | ||
333 | #ifdef CONFIG_SMP | ||
330 | /* Per-cpu data. */ | 334 | /* Per-cpu data. */ |
331 | void *percpu; | 335 | void __percpu *percpu; |
336 | unsigned int percpu_size; | ||
337 | #endif | ||
332 | 338 | ||
333 | /* The command line arguments (may be mangled). People like | 339 | /* The command line arguments (may be mangled). People like |
334 | keeping pointers to this stuff */ | 340 | keeping pointers to this stuff */ |
@@ -361,11 +367,10 @@ struct module | |||
361 | /* Destruction function. */ | 367 | /* Destruction function. */ |
362 | void (*exit)(void); | 368 | void (*exit)(void); |
363 | 369 | ||
364 | #ifdef CONFIG_SMP | 370 | struct module_ref { |
365 | char *refptr; | 371 | unsigned int incs; |
366 | #else | 372 | unsigned int decs; |
367 | local_t ref; | 373 | } __percpu *refptr; |
368 | #endif | ||
369 | #endif | 374 | #endif |
370 | 375 | ||
371 | #ifdef CONFIG_CONSTRUCTORS | 376 | #ifdef CONFIG_CONSTRUCTORS |
@@ -391,6 +396,7 @@ static inline int module_is_live(struct module *mod) | |||
391 | struct module *__module_text_address(unsigned long addr); | 396 | struct module *__module_text_address(unsigned long addr); |
392 | struct module *__module_address(unsigned long addr); | 397 | struct module *__module_address(unsigned long addr); |
393 | bool is_module_address(unsigned long addr); | 398 | bool is_module_address(unsigned long addr); |
399 | bool is_module_percpu_address(unsigned long addr); | ||
394 | bool is_module_text_address(unsigned long addr); | 400 | bool is_module_text_address(unsigned long addr); |
395 | 401 | ||
396 | static inline int within_module_core(unsigned long addr, struct module *mod) | 402 | static inline int within_module_core(unsigned long addr, struct module *mod) |
@@ -452,25 +458,16 @@ void __symbol_put(const char *symbol); | |||
452 | #define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) | 458 | #define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) |
453 | void symbol_put_addr(void *addr); | 459 | void symbol_put_addr(void *addr); |
454 | 460 | ||
455 | static inline local_t *__module_ref_addr(struct module *mod, int cpu) | ||
456 | { | ||
457 | #ifdef CONFIG_SMP | ||
458 | return (local_t *) (mod->refptr + per_cpu_offset(cpu)); | ||
459 | #else | ||
460 | return &mod->ref; | ||
461 | #endif | ||
462 | } | ||
463 | |||
464 | /* Sometimes we know we already have a refcount, and it's easier not | 461 | /* Sometimes we know we already have a refcount, and it's easier not |
465 | to handle the error case (which only happens with rmmod --wait). */ | 462 | to handle the error case (which only happens with rmmod --wait). */ |
466 | static inline void __module_get(struct module *module) | 463 | static inline void __module_get(struct module *module) |
467 | { | 464 | { |
468 | if (module) { | 465 | if (module) { |
469 | unsigned int cpu = get_cpu(); | 466 | preempt_disable(); |
470 | local_inc(__module_ref_addr(module, cpu)); | 467 | __this_cpu_inc(module->refptr->incs); |
471 | trace_module_get(module, _THIS_IP_, | 468 | trace_module_get(module, _THIS_IP_, |
472 | local_read(__module_ref_addr(module, cpu))); | 469 | __this_cpu_read(module->refptr->incs)); |
473 | put_cpu(); | 470 | preempt_enable(); |
474 | } | 471 | } |
475 | } | 472 | } |
476 | 473 | ||
@@ -479,15 +476,16 @@ static inline int try_module_get(struct module *module) | |||
479 | int ret = 1; | 476 | int ret = 1; |
480 | 477 | ||
481 | if (module) { | 478 | if (module) { |
482 | unsigned int cpu = get_cpu(); | 479 | preempt_disable(); |
480 | |||
483 | if (likely(module_is_live(module))) { | 481 | if (likely(module_is_live(module))) { |
484 | local_inc(__module_ref_addr(module, cpu)); | 482 | __this_cpu_inc(module->refptr->incs); |
485 | trace_module_get(module, _THIS_IP_, | 483 | trace_module_get(module, _THIS_IP_, |
486 | local_read(__module_ref_addr(module, cpu))); | 484 | __this_cpu_read(module->refptr->incs)); |
487 | } | 485 | } else |
488 | else | ||
489 | ret = 0; | 486 | ret = 0; |
490 | put_cpu(); | 487 | |
488 | preempt_enable(); | ||
491 | } | 489 | } |
492 | return ret; | 490 | return ret; |
493 | } | 491 | } |
@@ -569,6 +567,11 @@ static inline bool is_module_address(unsigned long addr) | |||
569 | return false; | 567 | return false; |
570 | } | 568 | } |
571 | 569 | ||
570 | static inline bool is_module_percpu_address(unsigned long addr) | ||
571 | { | ||
572 | return false; | ||
573 | } | ||
574 | |||
572 | static inline bool is_module_text_address(unsigned long addr) | 575 | static inline bool is_module_text_address(unsigned long addr) |
573 | { | 576 | { |
574 | return false; | 577 | return false; |