summaryrefslogtreecommitdiffstats
path: root/include/linux/module.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/module.h')
-rw-r--r--include/linux/module.h99
1 files changed, 37 insertions, 62 deletions
diff --git a/include/linux/module.h b/include/linux/module.h
index 6cb1a3cab5d..8a6b9fdc7ff 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -17,7 +17,7 @@
#include <linux/moduleparam.h>
#include <linux/tracepoint.h>
-#include <asm/local.h>
+#include <linux/percpu.h>
#include <asm/module.h>
#include <trace/events/module.h>
@@ -175,11 +175,19 @@ struct notifier_block;
#ifdef CONFIG_MODULES
+extern int modules_disabled; /* for sysctl */
/* Get/put a kernel symbol (calls must be symmetric) */
void *__symbol_get(const char *symbol);
void *__symbol_get_gpl(const char *symbol);
#define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x)))
+/* modules using other modules: kdb wants to see this. */
+struct module_use {
+ struct list_head source_list;
+ struct list_head target_list;
+ struct module *source, *target;
+};
+
#ifndef __GENKSYMS__
#ifdef CONFIG_MODVERSIONS
/* Mark the CRC weak since genksyms apparently decides not to
@@ -329,8 +337,11 @@ struct module
struct module_notes_attrs *notes_attrs;
#endif
+#ifdef CONFIG_SMP
/* Per-cpu data. */
- void *percpu;
+ void __percpu *percpu;
+ unsigned int percpu_size;
+#endif
/* The command line arguments (may be mangled). People like
keeping pointers to this stuff */
@@ -355,7 +366,9 @@ struct module
#ifdef CONFIG_MODULE_UNLOAD
/* What modules depend on me? */
- struct list_head modules_which_use_me;
+ struct list_head source_list;
+ /* What modules do I depend on? */
+ struct list_head target_list;
/* Who is waiting for us to be unloaded */
struct task_struct *waiter;
@@ -363,11 +376,10 @@ struct module
/* Destruction function. */
void (*exit)(void);
-#ifdef CONFIG_SMP
- char *refptr;
-#else
- local_t ref;
-#endif
+ struct module_ref {
+ unsigned int incs;
+ unsigned int decs;
+ } __percpu *refptr;
#endif
#ifdef CONFIG_CONSTRUCTORS
@@ -393,6 +405,7 @@ static inline int module_is_live(struct module *mod)
struct module *__module_text_address(unsigned long addr);
struct module *__module_address(unsigned long addr);
bool is_module_address(unsigned long addr);
+bool is_module_percpu_address(unsigned long addr);
bool is_module_text_address(unsigned long addr);
static inline int within_module_core(unsigned long addr, struct module *mod)
@@ -454,25 +467,15 @@ void __symbol_put(const char *symbol);
#define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x)
void symbol_put_addr(void *addr);
-static inline local_t *__module_ref_addr(struct module *mod, int cpu)
-{
-#ifdef CONFIG_SMP
- return (local_t *) (mod->refptr + per_cpu_offset(cpu));
-#else
- return &mod->ref;
-#endif
-}
-
/* Sometimes we know we already have a refcount, and it's easier not
to handle the error case (which only happens with rmmod --wait). */
static inline void __module_get(struct module *module)
{
if (module) {
- unsigned int cpu = get_cpu();
- local_inc(__module_ref_addr(module, cpu));
- trace_module_get(module, _THIS_IP_,
- local_read(__module_ref_addr(module, cpu)));
- put_cpu();
+ preempt_disable();
+ __this_cpu_inc(module->refptr->incs);
+ trace_module_get(module, _THIS_IP_);
+ preempt_enable();
}
}
@@ -481,15 +484,15 @@ static inline int try_module_get(struct module *module)
int ret = 1;
if (module) {
- unsigned int cpu = get_cpu();
+ preempt_disable();
+
if (likely(module_is_live(module))) {
- local_inc(__module_ref_addr(module, cpu));
- trace_module_get(module, _THIS_IP_,
- local_read(__module_ref_addr(module, cpu)));
- }
- else
+ __this_cpu_inc(module->refptr->incs);
+ trace_module_get(module, _THIS_IP_);
+ } else
ret = 0;
- put_cpu();
+
+ preempt_enable();
}
return ret;
}
@@ -571,6 +574,11 @@ static inline bool is_module_address(unsigned long addr)
return false;
}
+static inline bool is_module_percpu_address(unsigned long addr)
+{
+ return false;
+}
+
static inline bool is_module_text_address(unsigned long addr)
{
return false;
@@ -664,43 +672,10 @@ static inline int module_get_iter_tracepoints(struct tracepoint_iter *iter)
#endif /* CONFIG_MODULES */
-struct device_driver;
#ifdef CONFIG_SYSFS
-struct module;
-
extern struct kset *module_kset;
extern struct kobj_type module_ktype;
extern int module_sysfs_initialized;
-
-int mod_sysfs_init(struct module *mod);
-int mod_sysfs_setup(struct module *mod,
- struct kernel_param *kparam,
- unsigned int num_params);
-int module_add_modinfo_attrs(struct module *mod);
-void module_remove_modinfo_attrs(struct module *mod);
-
-#else /* !CONFIG_SYSFS */
-
-static inline int mod_sysfs_init(struct module *mod)
-{
- return 0;
-}
-
-static inline int mod_sysfs_setup(struct module *mod,
- struct kernel_param *kparam,
- unsigned int num_params)
-{
- return 0;
-}
-
-static inline int module_add_modinfo_attrs(struct module *mod)
-{
- return 0;
-}
-
-static inline void module_remove_modinfo_attrs(struct module *mod)
-{ }
-
#endif /* CONFIG_SYSFS */
#define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x)