diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-07-01 13:49:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-07-01 13:49:25 -0400 |
commit | 02201e3f1b46aed7c6348f406b7b40de80ba6de3 (patch) | |
tree | 2392c9098359725c195dd82a72b20ccedc1a1509 /include/linux/module.h | |
parent | 0890a264794f33df540fbaf274699146903b4e6b (diff) | |
parent | 20bdc2cfdbc484777b30b96fcdbb8994038f3ce1 (diff) |
Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux
Pull module updates from Rusty Russell:
"Main excitement here is Peter Zijlstra's lockless rbtree optimization
to speed module address lookup. He found some abusers of the module
lock doing that too.
A little bit of parameter work here too; including Dan Streetman's
breaking up the big param mutex so writing a parameter can load
another module (yeah, really). Unfortunately that broke the usual
suspects, !CONFIG_MODULES and !CONFIG_SYSFS, so those fixes were
appended too"
* tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux: (26 commits)
modules: only use mod->param_lock if CONFIG_MODULES
param: fix module param locks when !CONFIG_SYSFS.
rcu: merge fix for Convert ACCESS_ONCE() to READ_ONCE() and WRITE_ONCE()
module: add per-module param_lock
module: make perm const
params: suppress unused variable error, warn once just in case code changes.
modules: clarify CONFIG_MODULE_COMPRESS help, suggest 'N'.
kernel/module.c: avoid ifdefs for sig_enforce declaration
kernel/workqueue.c: remove ifdefs over wq_power_efficient
kernel/params.c: export param_ops_bool_enable_only
kernel/params.c: generalize bool_enable_only
kernel/module.c: use generic module param operaters for sig_enforce
kernel/params: constify struct kernel_param_ops uses
sysfs: tightened sysfs permission checks
module: Rework module_addr_{min,max}
module: Use __module_address() for module_address_lookup()
module: Make the mod_tree stuff conditional on PERF_EVENTS || TRACING
module: Optimize __module_address() using a latched RB-tree
rbtree: Implement generic latch_tree
seqlock: Introduce raw_read_seqcount_latch()
...
Diffstat (limited to 'include/linux/module.h')
-rw-r--r-- | include/linux/module.h | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/include/linux/module.h b/include/linux/module.h index 7ffe0851d244..d67b1932cc59 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/moduleparam.h> | 17 | #include <linux/moduleparam.h> |
18 | #include <linux/jump_label.h> | 18 | #include <linux/jump_label.h> |
19 | #include <linux/export.h> | 19 | #include <linux/export.h> |
20 | #include <linux/rbtree_latch.h> | ||
20 | 21 | ||
21 | #include <linux/percpu.h> | 22 | #include <linux/percpu.h> |
22 | #include <asm/module.h> | 23 | #include <asm/module.h> |
@@ -210,6 +211,13 @@ enum module_state { | |||
210 | MODULE_STATE_UNFORMED, /* Still setting it up. */ | 211 | MODULE_STATE_UNFORMED, /* Still setting it up. */ |
211 | }; | 212 | }; |
212 | 213 | ||
214 | struct module; | ||
215 | |||
216 | struct mod_tree_node { | ||
217 | struct module *mod; | ||
218 | struct latch_tree_node node; | ||
219 | }; | ||
220 | |||
213 | struct module { | 221 | struct module { |
214 | enum module_state state; | 222 | enum module_state state; |
215 | 223 | ||
@@ -232,6 +240,9 @@ struct module { | |||
232 | unsigned int num_syms; | 240 | unsigned int num_syms; |
233 | 241 | ||
234 | /* Kernel parameters. */ | 242 | /* Kernel parameters. */ |
243 | #ifdef CONFIG_SYSFS | ||
244 | struct mutex param_lock; | ||
245 | #endif | ||
235 | struct kernel_param *kp; | 246 | struct kernel_param *kp; |
236 | unsigned int num_kp; | 247 | unsigned int num_kp; |
237 | 248 | ||
@@ -271,8 +282,15 @@ struct module { | |||
271 | /* Startup function. */ | 282 | /* Startup function. */ |
272 | int (*init)(void); | 283 | int (*init)(void); |
273 | 284 | ||
274 | /* If this is non-NULL, vfree after init() returns */ | 285 | /* |
275 | void *module_init; | 286 | * If this is non-NULL, vfree() after init() returns. |
287 | * | ||
288 | * Cacheline align here, such that: | ||
289 | * module_init, module_core, init_size, core_size, | ||
290 | * init_text_size, core_text_size and mtn_core::{mod,node[0]} | ||
291 | * are on the same cacheline. | ||
292 | */ | ||
293 | void *module_init ____cacheline_aligned; | ||
276 | 294 | ||
277 | /* Here is the actual code + data, vfree'd on unload. */ | 295 | /* Here is the actual code + data, vfree'd on unload. */ |
278 | void *module_core; | 296 | void *module_core; |
@@ -283,6 +301,16 @@ struct module { | |||
283 | /* The size of the executable code in each section. */ | 301 | /* The size of the executable code in each section. */ |
284 | unsigned int init_text_size, core_text_size; | 302 | unsigned int init_text_size, core_text_size; |
285 | 303 | ||
304 | #ifdef CONFIG_MODULES_TREE_LOOKUP | ||
305 | /* | ||
306 | * We want mtn_core::{mod,node[0]} to be in the same cacheline as the | ||
307 | * above entries such that a regular lookup will only touch one | ||
308 | * cacheline. | ||
309 | */ | ||
310 | struct mod_tree_node mtn_core; | ||
311 | struct mod_tree_node mtn_init; | ||
312 | #endif | ||
313 | |||
286 | /* Size of RO sections of the module (text+rodata) */ | 314 | /* Size of RO sections of the module (text+rodata) */ |
287 | unsigned int init_ro_size, core_ro_size; | 315 | unsigned int init_ro_size, core_ro_size; |
288 | 316 | ||
@@ -369,7 +397,7 @@ struct module { | |||
369 | ctor_fn_t *ctors; | 397 | ctor_fn_t *ctors; |
370 | unsigned int num_ctors; | 398 | unsigned int num_ctors; |
371 | #endif | 399 | #endif |
372 | }; | 400 | } ____cacheline_aligned; |
373 | #ifndef MODULE_ARCH_INIT | 401 | #ifndef MODULE_ARCH_INIT |
374 | #define MODULE_ARCH_INIT {} | 402 | #define MODULE_ARCH_INIT {} |
375 | #endif | 403 | #endif |
@@ -423,14 +451,22 @@ struct symsearch { | |||
423 | bool unused; | 451 | bool unused; |
424 | }; | 452 | }; |
425 | 453 | ||
426 | /* Search for an exported symbol by name. */ | 454 | /* |
455 | * Search for an exported symbol by name. | ||
456 | * | ||
457 | * Must be called with module_mutex held or preemption disabled. | ||
458 | */ | ||
427 | const struct kernel_symbol *find_symbol(const char *name, | 459 | const struct kernel_symbol *find_symbol(const char *name, |
428 | struct module **owner, | 460 | struct module **owner, |
429 | const unsigned long **crc, | 461 | const unsigned long **crc, |
430 | bool gplok, | 462 | bool gplok, |
431 | bool warn); | 463 | bool warn); |
432 | 464 | ||
433 | /* Walk the exported symbol table */ | 465 | /* |
466 | * Walk the exported symbol table | ||
467 | * | ||
468 | * Must be called with module_mutex held or preemption disabled. | ||
469 | */ | ||
434 | bool each_symbol_section(bool (*fn)(const struct symsearch *arr, | 470 | bool each_symbol_section(bool (*fn)(const struct symsearch *arr, |
435 | struct module *owner, | 471 | struct module *owner, |
436 | void *data), void *data); | 472 | void *data), void *data); |