aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2015-05-26 21:39:37 -0400
committerRusty Russell <rusty@rustcorp.com.au>2015-05-27 22:02:07 -0400
commit6c9692e2d6a2206d8fd75ea247daa47fb75e4a02 (patch)
tree260a11511b3b629ec1cbcdeb3417e74590028e99 /kernel
parent93c2e105f6bcee231c951ba0e56e84505c4b0483 (diff)
module: Make the mod_tree stuff conditional on PERF_EVENTS || TRACING
Andrew worried about the overhead on small systems; only use the fancy code when either perf or tracing is enabled. Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Steven Rostedt <rostedt@goodmis.org> Requested-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/module.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/kernel/module.c b/kernel/module.c
index e0db5c31cb53..ac3044ceca3f 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -102,6 +102,8 @@ DEFINE_MUTEX(module_mutex);
102EXPORT_SYMBOL_GPL(module_mutex); 102EXPORT_SYMBOL_GPL(module_mutex);
103static LIST_HEAD(modules); 103static LIST_HEAD(modules);
104 104
105#ifdef CONFIG_MODULES_TREE_LOOKUP
106
105/* 107/*
106 * Use a latched RB-tree for __module_address(); this allows us to use 108 * Use a latched RB-tree for __module_address(); this allows us to use
107 * RCU-sched lookups of the address from any context. 109 * RCU-sched lookups of the address from any context.
@@ -112,6 +114,10 @@ static LIST_HEAD(modules);
112 * 114 *
113 * Because init ranges are short lived we mark them unlikely and have placed 115 * Because init ranges are short lived we mark them unlikely and have placed
114 * them outside the critical cacheline in struct module. 116 * them outside the critical cacheline in struct module.
117 *
118 * This is conditional on PERF_EVENTS || TRACING because those can really hit
119 * __module_address() hard by doing a lot of stack unwinding; potentially from
120 * NMI context.
115 */ 121 */
116 122
117static __always_inline unsigned long __mod_tree_val(struct latch_tree_node *n) 123static __always_inline unsigned long __mod_tree_val(struct latch_tree_node *n)
@@ -192,7 +198,7 @@ static void mod_tree_remove(struct module *mod)
192 mod_tree_remove_init(mod); 198 mod_tree_remove_init(mod);
193} 199}
194 200
195static struct module *mod_tree_find(unsigned long addr) 201static struct module *mod_find(unsigned long addr)
196{ 202{
197 struct latch_tree_node *ltn; 203 struct latch_tree_node *ltn;
198 204
@@ -203,6 +209,26 @@ static struct module *mod_tree_find(unsigned long addr)
203 return container_of(ltn, struct mod_tree_node, node)->mod; 209 return container_of(ltn, struct mod_tree_node, node)->mod;
204} 210}
205 211
212#else /* MODULES_TREE_LOOKUP */
213
214static void mod_tree_insert(struct module *mod) { }
215static void mod_tree_remove_init(struct module *mod) { }
216static void mod_tree_remove(struct module *mod) { }
217
218static struct module *mod_find(unsigned long addr)
219{
220 struct module *mod;
221
222 list_for_each_entry_rcu(mod, &modules, list) {
223 if (within_module(addr, mod))
224 return mod;
225 }
226
227 return NULL;
228}
229
230#endif /* MODULES_TREE_LOOKUP */
231
206#ifdef CONFIG_KGDB_KDB 232#ifdef CONFIG_KGDB_KDB
207struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ 233struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
208#endif /* CONFIG_KGDB_KDB */ 234#endif /* CONFIG_KGDB_KDB */
@@ -3966,7 +3992,7 @@ struct module *__module_address(unsigned long addr)
3966 3992
3967 module_assert_mutex_or_preempt(); 3993 module_assert_mutex_or_preempt();
3968 3994
3969 mod = mod_tree_find(addr); 3995 mod = mod_find(addr);
3970 if (mod) { 3996 if (mod) {
3971 BUG_ON(!within_module(addr, mod)); 3997 BUG_ON(!within_module(addr, mod));
3972 if (mod->state == MODULE_STATE_UNFORMED) 3998 if (mod->state == MODULE_STATE_UNFORMED)