Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 100424
b: refs/heads/master
c: 6cd8a4b
h: refs/heads/master
v: v3
  • Loading branch information
Steven Rostedt authored and Thomas Gleixner committed May 23, 2008
1 parent e9279be commit bfd9702
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 54 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 81d68a96a39844853b37f20cc8282d9b65b78ef3
refs/heads/master: 6cd8a4bb2f97527a9ceb30bc77ea4e959c6a95e3
3 changes: 3 additions & 0 deletions trunk/arch/x86/kernel/process_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,10 @@ void cpu_idle(void)

local_irq_disable();
__get_cpu_var(irq_stat).idle_timestamp = jiffies;
/* Don't trace irqs off for idle */
stop_critical_timings();
idle();
start_critical_timings();
}
tick_nohz_restart_sched_tick();
preempt_enable_no_resched();
Expand Down
8 changes: 8 additions & 0 deletions trunk/include/linux/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,12 @@ extern void mcount(void);
# define time_hardirqs_off(a0, a1) do { } while (0)
#endif

#ifdef CONFIG_PREEMPT_TRACER
extern void notrace trace_preempt_on(unsigned long a0, unsigned long a1);
extern void notrace trace_preempt_off(unsigned long a0, unsigned long a1);
#else
# define trace_preempt_on(a0, a1) do { } while (0)
# define trace_preempt_off(a0, a1) do { } while (0)
#endif

#endif /* _LINUX_FTRACE_H */
3 changes: 2 additions & 1 deletion trunk/include/linux/irqflags.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
# define INIT_TRACE_IRQFLAGS
#endif

#ifdef CONFIG_IRQSOFF_TRACER
#if defined(CONFIG_IRQSOFF_TRACER) || \
defined(CONFIG_PREEMPT_TRACER)
extern void stop_critical_timings(void);
extern void start_critical_timings(void);
#else
Expand Down
2 changes: 1 addition & 1 deletion trunk/include/linux/preempt.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <linux/linkage.h>
#include <linux/list.h>

#ifdef CONFIG_DEBUG_PREEMPT
#if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_PREEMPT_TRACER)
extern void add_preempt_count(int val);
extern void sub_preempt_count(int val);
#else
Expand Down
24 changes: 23 additions & 1 deletion trunk/kernel/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
#include <linux/bootmem.h>
#include <linux/debugfs.h>
#include <linux/ctype.h>
#include <linux/ftrace.h>

#include <asm/tlb.h>
#include <asm/irq_regs.h>
Expand Down Expand Up @@ -4365,26 +4366,44 @@ void scheduler_tick(void)
#endif
}

#if defined(CONFIG_PREEMPT) && defined(CONFIG_DEBUG_PREEMPT)
#if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \
defined(CONFIG_PREEMPT_TRACER))

static inline unsigned long get_parent_ip(unsigned long addr)
{
if (in_lock_functions(addr)) {
addr = CALLER_ADDR2;
if (in_lock_functions(addr))
addr = CALLER_ADDR3;
}
return addr;
}

void __kprobes add_preempt_count(int val)
{
#ifdef CONFIG_DEBUG_PREEMPT
/*
* Underflow?
*/
if (DEBUG_LOCKS_WARN_ON((preempt_count() < 0)))
return;
#endif
preempt_count() += val;
#ifdef CONFIG_DEBUG_PREEMPT
/*
* Spinlock count overflowing soon?
*/
DEBUG_LOCKS_WARN_ON((preempt_count() & PREEMPT_MASK) >=
PREEMPT_MASK - 10);
#endif
if (preempt_count() == val)
trace_preempt_off(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1));
}
EXPORT_SYMBOL(add_preempt_count);

void __kprobes sub_preempt_count(int val)
{
#ifdef CONFIG_DEBUG_PREEMPT
/*
* Underflow?
*/
Expand All @@ -4396,7 +4415,10 @@ void __kprobes sub_preempt_count(int val)
if (DEBUG_LOCKS_WARN_ON((val < PREEMPT_MASK) &&
!(preempt_count() & PREEMPT_MASK)))
return;
#endif

if (preempt_count() == val)
trace_preempt_on(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1));
preempt_count() -= val;
}
EXPORT_SYMBOL(sub_preempt_count);
Expand Down
25 changes: 25 additions & 0 deletions trunk/kernel/trace/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,31 @@ config IRQSOFF_TRACER

echo 0 > /debugfs/tracing/tracing_max_latency

(Note that kernel size and overhead increases with this option
enabled. This option and the preempt-off timing option can be
used together or separately.)

config PREEMPT_TRACER
bool "Preemption-off Latency Tracer"
default n
depends on GENERIC_TIME
depends on PREEMPT
select TRACING
select TRACER_MAX_TRACE
help
This option measures the time spent in preemption off critical
sections, with microsecond accuracy.

The default measurement method is a maximum search, which is
disabled by default and can be runtime (re-)started
via:

echo 0 > /debugfs/tracing/tracing_max_latency

(Note that kernel size and overhead increases with this option
enabled. This option and the irqs-off timing option can be
used together or separately.)

config SCHED_TRACER
bool "Scheduling Latency Tracer"
depends on DEBUG_KERNEL
Expand Down
1 change: 1 addition & 0 deletions trunk/kernel/trace/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ obj-$(CONFIG_TRACING) += trace.o
obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o
obj-$(CONFIG_FTRACE) += trace_functions.o
obj-$(CONFIG_IRQSOFF_TRACER) += trace_irqsoff.o
obj-$(CONFIG_PREEMPT_TRACER) += trace_irqsoff.o
obj-$(CONFIG_SCHED_TRACER) += trace_sched_wakeup.o

libftrace-y := ftrace.o
Loading

0 comments on commit bfd9702

Please sign in to comment.