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.h43
1 files changed, 18 insertions, 25 deletions
diff --git a/include/linux/module.h b/include/linux/module.h
index 482efc865acf..dd618eb026aa 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
@@ -361,11 +363,9 @@ struct module
361 /* Destruction function. */ 363 /* Destruction function. */
362 void (*exit)(void); 364 void (*exit)(void);
363 365
364#ifdef CONFIG_SMP 366 struct module_ref {
365 char *refptr; 367 int count;
366#else 368 } __percpu *refptr;
367 local_t ref;
368#endif
369#endif 369#endif
370 370
371#ifdef CONFIG_CONSTRUCTORS 371#ifdef CONFIG_CONSTRUCTORS
@@ -452,25 +452,16 @@ void __symbol_put(const char *symbol);
452#define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) 452#define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x)
453void symbol_put_addr(void *addr); 453void symbol_put_addr(void *addr);
454 454
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 455/* 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). */ 456 to handle the error case (which only happens with rmmod --wait). */
466static inline void __module_get(struct module *module) 457static inline void __module_get(struct module *module)
467{ 458{
468 if (module) { 459 if (module) {
469 unsigned int cpu = get_cpu(); 460 preempt_disable();
470 local_inc(__module_ref_addr(module, cpu)); 461 __this_cpu_inc(module->refptr->count);
471 trace_module_get(module, _THIS_IP_, 462 trace_module_get(module, _THIS_IP_,
472 local_read(__module_ref_addr(module, cpu))); 463 __this_cpu_read(module->refptr->count));
473 put_cpu(); 464 preempt_enable();
474 } 465 }
475} 466}
476 467
@@ -479,15 +470,17 @@ static inline int try_module_get(struct module *module)
479 int ret = 1; 470 int ret = 1;
480 471
481 if (module) { 472 if (module) {
482 unsigned int cpu = get_cpu(); 473 preempt_disable();
474
483 if (likely(module_is_live(module))) { 475 if (likely(module_is_live(module))) {
484 local_inc(__module_ref_addr(module, cpu)); 476 __this_cpu_inc(module->refptr->count);
485 trace_module_get(module, _THIS_IP_, 477 trace_module_get(module, _THIS_IP_,
486 local_read(__module_ref_addr(module, cpu))); 478 __this_cpu_read(module->refptr->count));
487 } 479 }
488 else 480 else
489 ret = 0; 481 ret = 0;
490 put_cpu(); 482
483 preempt_enable();
491 } 484 }
492 return ret; 485 return ret;
493} 486}