aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/module.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/module.h')
-rw-r--r--include/linux/module.h59
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
178extern 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) */
177void *__symbol_get(const char *symbol); 180void *__symbol_get(const char *symbol);
178void *__symbol_get_gpl(const char *symbol); 181void *__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)
391struct module *__module_text_address(unsigned long addr); 396struct module *__module_text_address(unsigned long addr);
392struct module *__module_address(unsigned long addr); 397struct module *__module_address(unsigned long addr);
393bool is_module_address(unsigned long addr); 398bool is_module_address(unsigned long addr);
399bool is_module_percpu_address(unsigned long addr);
394bool is_module_text_address(unsigned long addr); 400bool is_module_text_address(unsigned long addr);
395 401
396static inline int within_module_core(unsigned long addr, struct module *mod) 402static 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)
453void symbol_put_addr(void *addr); 459void symbol_put_addr(void *addr);
454 460
455static 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). */
466static inline void __module_get(struct module *module) 463static 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
570static inline bool is_module_percpu_address(unsigned long addr)
571{
572 return false;
573}
574
572static inline bool is_module_text_address(unsigned long addr) 575static inline bool is_module_text_address(unsigned long addr)
573{ 576{
574 return false; 577 return false;