aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2011-06-24 23:28:13 -0400
committerSteven Rostedt <rostedt@goodmis.org>2011-07-07 22:39:38 -0400
commit4376cac66778b25e599be3f5d54f33f58ba8ead7 (patch)
tree9cf05820586f140bafcde67cd2cd80a4391ef7eb /kernel/trace
parente4a3f541f0b67fdad98b326c851dfe7f4b6b6dad (diff)
ftrace: Do not disable interrupts for modules in mcount update
When I mounted an NFS directory, it caused several modules to be loaded. At the time I was running the preemptirqsoff tracer, and it showed the following output: # tracer: preemptirqsoff # # preemptirqsoff latency trace v1.1.5 on 2.6.33.9-rt30-mrg-test # -------------------------------------------------------------------- # latency: 1177 us, #4/4, CPU#3 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:4) # ----------------- # | task: modprobe-19370 (uid:0 nice:0 policy:0 rt_prio:0) # ----------------- # => started at: ftrace_module_notify # => ended at: ftrace_module_notify # # # _------=> CPU# # / _-----=> irqs-off # | / _----=> need-resched # || / _---=> hardirq/softirq # ||| / _--=> preempt-depth # |||| /_--=> lock-depth # |||||/ delay # cmd pid |||||| time | caller # \ / |||||| \ | / modprobe-19370 3d.... 0us!: ftrace_process_locs <-ftrace_module_notify modprobe-19370 3d.... 1176us : ftrace_process_locs <-ftrace_module_notify modprobe-19370 3d.... 1178us : trace_hardirqs_on <-ftrace_module_notify modprobe-19370 3d.... 1178us : <stack trace> => ftrace_process_locs => ftrace_module_notify => notifier_call_chain => __blocking_notifier_call_chain => blocking_notifier_call_chain => sys_init_module => system_call_fastpath That's over 1ms that interrupts are disabled on a Real-Time kernel! Looking at the cause (being the ftrace author helped), I found that the interrupts are disabled before the code modification of mcounts into nops. The interrupts only need to be disabled on start up around this code, not when modules are being loaded. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/ftrace.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index c997f7371c65..df93392aad89 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -3318,7 +3318,7 @@ static int ftrace_process_locs(struct module *mod,
3318{ 3318{
3319 unsigned long *p; 3319 unsigned long *p;
3320 unsigned long addr; 3320 unsigned long addr;
3321 unsigned long flags; 3321 unsigned long flags = 0; /* Shut up gcc */
3322 3322
3323 mutex_lock(&ftrace_lock); 3323 mutex_lock(&ftrace_lock);
3324 p = start; 3324 p = start;
@@ -3336,12 +3336,18 @@ static int ftrace_process_locs(struct module *mod,
3336 } 3336 }
3337 3337
3338 /* 3338 /*
3339 * Disable interrupts to prevent interrupts from executing 3339 * We only need to disable interrupts on start up
3340 * code that is being modified. 3340 * because we are modifying code that an interrupt
3341 * may execute, and the modification is not atomic.
3342 * But for modules, nothing runs the code we modify
3343 * until we are finished with it, and there's no
3344 * reason to cause large interrupt latencies while we do it.
3341 */ 3345 */
3342 local_irq_save(flags); 3346 if (!mod)
3347 local_irq_save(flags);
3343 ftrace_update_code(mod); 3348 ftrace_update_code(mod);
3344 local_irq_restore(flags); 3349 if (!mod)
3350 local_irq_restore(flags);
3345 mutex_unlock(&ftrace_lock); 3351 mutex_unlock(&ftrace_lock);
3346 3352
3347 return 0; 3353 return 0;