diff options
Diffstat (limited to 'include/linux/module.h')
| -rw-r--r-- | include/linux/module.h | 104 |
1 files changed, 39 insertions, 65 deletions
diff --git a/include/linux/module.h b/include/linux/module.h index 6cb1a3cab5d3..aace066bad8f 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,11 +175,19 @@ 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); |
| 181 | #define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x))) | 182 | #define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x))) |
| 182 | 183 | ||
| 184 | /* modules using other modules: kdb wants to see this. */ | ||
| 185 | struct module_use { | ||
| 186 | struct list_head source_list; | ||
| 187 | struct list_head target_list; | ||
| 188 | struct module *source, *target; | ||
| 189 | }; | ||
| 190 | |||
| 183 | #ifndef __GENKSYMS__ | 191 | #ifndef __GENKSYMS__ |
| 184 | #ifdef CONFIG_MODVERSIONS | 192 | #ifdef CONFIG_MODVERSIONS |
| 185 | /* Mark the CRC weak since genksyms apparently decides not to | 193 | /* Mark the CRC weak since genksyms apparently decides not to |
| @@ -329,8 +337,11 @@ struct module | |||
| 329 | struct module_notes_attrs *notes_attrs; | 337 | struct module_notes_attrs *notes_attrs; |
| 330 | #endif | 338 | #endif |
| 331 | 339 | ||
| 340 | #ifdef CONFIG_SMP | ||
| 332 | /* Per-cpu data. */ | 341 | /* Per-cpu data. */ |
| 333 | void *percpu; | 342 | void __percpu *percpu; |
| 343 | unsigned int percpu_size; | ||
| 344 | #endif | ||
| 334 | 345 | ||
| 335 | /* The command line arguments (may be mangled). People like | 346 | /* The command line arguments (may be mangled). People like |
| 336 | keeping pointers to this stuff */ | 347 | keeping pointers to this stuff */ |
| @@ -355,7 +366,9 @@ struct module | |||
| 355 | 366 | ||
| 356 | #ifdef CONFIG_MODULE_UNLOAD | 367 | #ifdef CONFIG_MODULE_UNLOAD |
| 357 | /* What modules depend on me? */ | 368 | /* What modules depend on me? */ |
| 358 | struct list_head modules_which_use_me; | 369 | struct list_head source_list; |
| 370 | /* What modules do I depend on? */ | ||
| 371 | struct list_head target_list; | ||
| 359 | 372 | ||
| 360 | /* Who is waiting for us to be unloaded */ | 373 | /* Who is waiting for us to be unloaded */ |
| 361 | struct task_struct *waiter; | 374 | struct task_struct *waiter; |
| @@ -363,11 +376,10 @@ struct module | |||
| 363 | /* Destruction function. */ | 376 | /* Destruction function. */ |
| 364 | void (*exit)(void); | 377 | void (*exit)(void); |
| 365 | 378 | ||
| 366 | #ifdef CONFIG_SMP | 379 | struct module_ref { |
| 367 | char *refptr; | 380 | unsigned int incs; |
| 368 | #else | 381 | unsigned int decs; |
| 369 | local_t ref; | 382 | } __percpu *refptr; |
| 370 | #endif | ||
| 371 | #endif | 383 | #endif |
| 372 | 384 | ||
| 373 | #ifdef CONFIG_CONSTRUCTORS | 385 | #ifdef CONFIG_CONSTRUCTORS |
| @@ -393,6 +405,7 @@ static inline int module_is_live(struct module *mod) | |||
| 393 | struct module *__module_text_address(unsigned long addr); | 405 | struct module *__module_text_address(unsigned long addr); |
| 394 | struct module *__module_address(unsigned long addr); | 406 | struct module *__module_address(unsigned long addr); |
| 395 | bool is_module_address(unsigned long addr); | 407 | bool is_module_address(unsigned long addr); |
| 408 | bool is_module_percpu_address(unsigned long addr); | ||
| 396 | bool is_module_text_address(unsigned long addr); | 409 | bool is_module_text_address(unsigned long addr); |
| 397 | 410 | ||
| 398 | static inline int within_module_core(unsigned long addr, struct module *mod) | 411 | static inline int within_module_core(unsigned long addr, struct module *mod) |
| @@ -454,25 +467,15 @@ void __symbol_put(const char *symbol); | |||
| 454 | #define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) | 467 | #define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) |
| 455 | void symbol_put_addr(void *addr); | 468 | void symbol_put_addr(void *addr); |
| 456 | 469 | ||
| 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 | 470 | /* 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). */ | 471 | to handle the error case (which only happens with rmmod --wait). */ |
| 468 | static inline void __module_get(struct module *module) | 472 | static inline void __module_get(struct module *module) |
| 469 | { | 473 | { |
| 470 | if (module) { | 474 | if (module) { |
| 471 | unsigned int cpu = get_cpu(); | 475 | preempt_disable(); |
| 472 | local_inc(__module_ref_addr(module, cpu)); | 476 | __this_cpu_inc(module->refptr->incs); |
| 473 | trace_module_get(module, _THIS_IP_, | 477 | trace_module_get(module, _THIS_IP_); |
| 474 | local_read(__module_ref_addr(module, cpu))); | 478 | preempt_enable(); |
| 475 | put_cpu(); | ||
| 476 | } | 479 | } |
| 477 | } | 480 | } |
| 478 | 481 | ||
| @@ -481,15 +484,15 @@ static inline int try_module_get(struct module *module) | |||
| 481 | int ret = 1; | 484 | int ret = 1; |
| 482 | 485 | ||
| 483 | if (module) { | 486 | if (module) { |
| 484 | unsigned int cpu = get_cpu(); | 487 | preempt_disable(); |
| 488 | |||
| 485 | if (likely(module_is_live(module))) { | 489 | if (likely(module_is_live(module))) { |
| 486 | local_inc(__module_ref_addr(module, cpu)); | 490 | __this_cpu_inc(module->refptr->incs); |
| 487 | trace_module_get(module, _THIS_IP_, | 491 | trace_module_get(module, _THIS_IP_); |
| 488 | local_read(__module_ref_addr(module, cpu))); | 492 | } else |
| 489 | } | ||
| 490 | else | ||
| 491 | ret = 0; | 493 | ret = 0; |
| 492 | put_cpu(); | 494 | |
| 495 | preempt_enable(); | ||
| 493 | } | 496 | } |
| 494 | return ret; | 497 | return ret; |
| 495 | } | 498 | } |
| @@ -571,6 +574,11 @@ static inline bool is_module_address(unsigned long addr) | |||
| 571 | return false; | 574 | return false; |
| 572 | } | 575 | } |
| 573 | 576 | ||
| 577 | static inline bool is_module_percpu_address(unsigned long addr) | ||
| 578 | { | ||
| 579 | return false; | ||
| 580 | } | ||
| 581 | |||
| 574 | static inline bool is_module_text_address(unsigned long addr) | 582 | static inline bool is_module_text_address(unsigned long addr) |
| 575 | { | 583 | { |
| 576 | return false; | 584 | return false; |
| @@ -664,43 +672,10 @@ static inline int module_get_iter_tracepoints(struct tracepoint_iter *iter) | |||
| 664 | 672 | ||
| 665 | #endif /* CONFIG_MODULES */ | 673 | #endif /* CONFIG_MODULES */ |
| 666 | 674 | ||
| 667 | struct device_driver; | ||
| 668 | #ifdef CONFIG_SYSFS | 675 | #ifdef CONFIG_SYSFS |
| 669 | struct module; | ||
| 670 | |||
| 671 | extern struct kset *module_kset; | 676 | extern struct kset *module_kset; |
| 672 | extern struct kobj_type module_ktype; | 677 | extern struct kobj_type module_ktype; |
| 673 | extern int module_sysfs_initialized; | 678 | extern int module_sysfs_initialized; |
| 674 | |||
| 675 | int mod_sysfs_init(struct module *mod); | ||
| 676 | int mod_sysfs_setup(struct module *mod, | ||
| 677 | struct kernel_param *kparam, | ||
| 678 | unsigned int num_params); | ||
| 679 | int module_add_modinfo_attrs(struct module *mod); | ||
| 680 | void module_remove_modinfo_attrs(struct module *mod); | ||
| 681 | |||
| 682 | #else /* !CONFIG_SYSFS */ | ||
| 683 | |||
| 684 | static inline int mod_sysfs_init(struct module *mod) | ||
| 685 | { | ||
| 686 | return 0; | ||
| 687 | } | ||
| 688 | |||
| 689 | static inline int mod_sysfs_setup(struct module *mod, | ||
| 690 | struct kernel_param *kparam, | ||
| 691 | unsigned int num_params) | ||
| 692 | { | ||
| 693 | return 0; | ||
| 694 | } | ||
| 695 | |||
| 696 | static inline int module_add_modinfo_attrs(struct module *mod) | ||
| 697 | { | ||
| 698 | return 0; | ||
| 699 | } | ||
| 700 | |||
| 701 | static inline void module_remove_modinfo_attrs(struct module *mod) | ||
| 702 | { } | ||
| 703 | |||
| 704 | #endif /* CONFIG_SYSFS */ | 679 | #endif /* CONFIG_SYSFS */ |
| 705 | 680 | ||
| 706 | #define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x) | 681 | #define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x) |
| @@ -711,17 +686,16 @@ static inline void module_remove_modinfo_attrs(struct module *mod) | |||
| 711 | 686 | ||
| 712 | 687 | ||
| 713 | #ifdef CONFIG_GENERIC_BUG | 688 | #ifdef CONFIG_GENERIC_BUG |
| 714 | int module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *, | 689 | void module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *, |
| 715 | struct module *); | 690 | struct module *); |
| 716 | void module_bug_cleanup(struct module *); | 691 | void module_bug_cleanup(struct module *); |
| 717 | 692 | ||
| 718 | #else /* !CONFIG_GENERIC_BUG */ | 693 | #else /* !CONFIG_GENERIC_BUG */ |
| 719 | 694 | ||
| 720 | static inline int module_bug_finalize(const Elf_Ehdr *hdr, | 695 | static inline void module_bug_finalize(const Elf_Ehdr *hdr, |
| 721 | const Elf_Shdr *sechdrs, | 696 | const Elf_Shdr *sechdrs, |
| 722 | struct module *mod) | 697 | struct module *mod) |
| 723 | { | 698 | { |
| 724 | return 0; | ||
| 725 | } | 699 | } |
| 726 | static inline void module_bug_cleanup(struct module *mod) {} | 700 | static inline void module_bug_cleanup(struct module *mod) {} |
| 727 | #endif /* CONFIG_GENERIC_BUG */ | 701 | #endif /* CONFIG_GENERIC_BUG */ |
