aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2008-05-12 15:20:42 -0400
committerThomas Gleixner <tglx@linutronix.de>2008-05-23 14:32:54 -0400
commit6cd8a4bb2f97527a9ceb30bc77ea4e959c6a95e3 (patch)
tree845af8f3c7f8956b4f3591759a0d67248af243a2 /kernel/sched.c
parent81d68a96a39844853b37f20cc8282d9b65b78ef3 (diff)
ftrace: trace preempt off critical timings
Add preempt off timings. A lot of kernel core code is taken from the RT patch latency trace that was written by Ingo Molnar. This adds "preemptoff" and "preemptirqsoff" to /debugfs/tracing/available_tracers Now instead of just tracing irqs off, preemption off can be selected to be recorded. When this is selected, it shares the same files as irqs off timings. One can either trace preemption off, irqs off, or one or the other off. By echoing "preemptoff" into /debugfs/tracing/current_tracer, recording of preempt off only is performed. "irqsoff" will only record the time irqs are disabled, but "preemptirqsoff" will take the total time irqs or preemption are disabled. Runtime switching of these options is now supported by simpling echoing in the appropriate trace name into /debugfs/tracing/current_tracer. Signed-off-by: Steven Rostedt <srostedt@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index 73e600852365..328494e28df2 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -70,6 +70,7 @@
70#include <linux/bootmem.h> 70#include <linux/bootmem.h>
71#include <linux/debugfs.h> 71#include <linux/debugfs.h>
72#include <linux/ctype.h> 72#include <linux/ctype.h>
73#include <linux/ftrace.h>
73 74
74#include <asm/tlb.h> 75#include <asm/tlb.h>
75#include <asm/irq_regs.h> 76#include <asm/irq_regs.h>
@@ -4365,26 +4366,44 @@ void scheduler_tick(void)
4365#endif 4366#endif
4366} 4367}
4367 4368
4368#if defined(CONFIG_PREEMPT) && defined(CONFIG_DEBUG_PREEMPT) 4369#if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \
4370 defined(CONFIG_PREEMPT_TRACER))
4371
4372static inline unsigned long get_parent_ip(unsigned long addr)
4373{
4374 if (in_lock_functions(addr)) {
4375 addr = CALLER_ADDR2;
4376 if (in_lock_functions(addr))
4377 addr = CALLER_ADDR3;
4378 }
4379 return addr;
4380}
4369 4381
4370void __kprobes add_preempt_count(int val) 4382void __kprobes add_preempt_count(int val)
4371{ 4383{
4384#ifdef CONFIG_DEBUG_PREEMPT
4372 /* 4385 /*
4373 * Underflow? 4386 * Underflow?
4374 */ 4387 */
4375 if (DEBUG_LOCKS_WARN_ON((preempt_count() < 0))) 4388 if (DEBUG_LOCKS_WARN_ON((preempt_count() < 0)))
4376 return; 4389 return;
4390#endif
4377 preempt_count() += val; 4391 preempt_count() += val;
4392#ifdef CONFIG_DEBUG_PREEMPT
4378 /* 4393 /*
4379 * Spinlock count overflowing soon? 4394 * Spinlock count overflowing soon?
4380 */ 4395 */
4381 DEBUG_LOCKS_WARN_ON((preempt_count() & PREEMPT_MASK) >= 4396 DEBUG_LOCKS_WARN_ON((preempt_count() & PREEMPT_MASK) >=
4382 PREEMPT_MASK - 10); 4397 PREEMPT_MASK - 10);
4398#endif
4399 if (preempt_count() == val)
4400 trace_preempt_off(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1));
4383} 4401}
4384EXPORT_SYMBOL(add_preempt_count); 4402EXPORT_SYMBOL(add_preempt_count);
4385 4403
4386void __kprobes sub_preempt_count(int val) 4404void __kprobes sub_preempt_count(int val)
4387{ 4405{
4406#ifdef CONFIG_DEBUG_PREEMPT
4388 /* 4407 /*
4389 * Underflow? 4408 * Underflow?
4390 */ 4409 */
@@ -4396,7 +4415,10 @@ void __kprobes sub_preempt_count(int val)
4396 if (DEBUG_LOCKS_WARN_ON((val < PREEMPT_MASK) && 4415 if (DEBUG_LOCKS_WARN_ON((val < PREEMPT_MASK) &&
4397 !(preempt_count() & PREEMPT_MASK))) 4416 !(preempt_count() & PREEMPT_MASK)))
4398 return; 4417 return;
4418#endif
4399 4419
4420 if (preempt_count() == val)
4421 trace_preempt_on(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1));
4400 preempt_count() -= val; 4422 preempt_count() -= val;
4401} 4423}
4402EXPORT_SYMBOL(sub_preempt_count); 4424EXPORT_SYMBOL(sub_preempt_count);