aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ftrace.c
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@redhat.com>2009-10-13 16:33:53 -0400
committerIngo Molnar <mingo@elte.hu>2009-10-14 02:13:54 -0400
commit5cb084bb1f3fd4dcdaf7e4cf564994346ec8f783 (patch)
tree0faf55a8a91ff69ae7cd0dff349dc5fbe27a53da /kernel/trace/ftrace.c
parent756d17ee7ee4fbc8238bdf97100af63e6ac441ef (diff)
tracing: Enable records during the module load
I was debuging some module using "function" and "function_graph" tracers and noticed, that if you load module after you enabled tracing, the module's hooks will convert only to NOP instructions. The attached patch enables modules' hooks if there's function trace allready on, thus allowing to trace module functions. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> LKML-Reference: <20091013203425.896285120@goodmis.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r--kernel/trace/ftrace.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 0c799d1af702..aaea9cda8781 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1270,12 +1270,34 @@ static int ftrace_update_code(struct module *mod)
1270 ftrace_new_addrs = p->newlist; 1270 ftrace_new_addrs = p->newlist;
1271 p->flags = 0L; 1271 p->flags = 0L;
1272 1272
1273 /* convert record (i.e, patch mcount-call with NOP) */ 1273 /*
1274 if (ftrace_code_disable(mod, p)) { 1274 * Do the initial record convertion from mcount jump
1275 p->flags |= FTRACE_FL_CONVERTED; 1275 * to the NOP instructions.
1276 ftrace_update_cnt++; 1276 */
1277 } else 1277 if (!ftrace_code_disable(mod, p)) {
1278 ftrace_free_rec(p); 1278 ftrace_free_rec(p);
1279 continue;
1280 }
1281
1282 p->flags |= FTRACE_FL_CONVERTED;
1283 ftrace_update_cnt++;
1284
1285 /*
1286 * If the tracing is enabled, go ahead and enable the record.
1287 *
1288 * The reason not to enable the record immediatelly is the
1289 * inherent check of ftrace_make_nop/ftrace_make_call for
1290 * correct previous instructions. Making first the NOP
1291 * conversion puts the module to the correct state, thus
1292 * passing the ftrace_make_call check.
1293 */
1294 if (ftrace_start_up) {
1295 int failed = __ftrace_replace_code(p, 1);
1296 if (failed) {
1297 ftrace_bug(failed, p->ip);
1298 ftrace_free_rec(p);
1299 }
1300 }
1279 } 1301 }
1280 1302
1281 stop = ftrace_now(raw_smp_processor_id()); 1303 stop = ftrace_now(raw_smp_processor_id());
@@ -2609,7 +2631,7 @@ static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer)
2609 return 0; 2631 return 0;
2610} 2632}
2611 2633
2612static int ftrace_convert_nops(struct module *mod, 2634static int ftrace_process_locs(struct module *mod,
2613 unsigned long *start, 2635 unsigned long *start,
2614 unsigned long *end) 2636 unsigned long *end)
2615{ 2637{
@@ -2669,7 +2691,7 @@ static void ftrace_init_module(struct module *mod,
2669{ 2691{
2670 if (ftrace_disabled || start == end) 2692 if (ftrace_disabled || start == end)
2671 return; 2693 return;
2672 ftrace_convert_nops(mod, start, end); 2694 ftrace_process_locs(mod, start, end);
2673} 2695}
2674 2696
2675static int ftrace_module_notify(struct notifier_block *self, 2697static int ftrace_module_notify(struct notifier_block *self,
@@ -2730,7 +2752,7 @@ void __init ftrace_init(void)
2730 2752
2731 last_ftrace_enabled = ftrace_enabled = 1; 2753 last_ftrace_enabled = ftrace_enabled = 1;
2732 2754
2733 ret = ftrace_convert_nops(NULL, 2755 ret = ftrace_process_locs(NULL,
2734 __start_mcount_loc, 2756 __start_mcount_loc,
2735 __stop_mcount_loc); 2757 __stop_mcount_loc);
2736 2758