Skip to content

Commit

Permalink
Merge branch 'tracing/ftrace' into tracing/core
Browse files Browse the repository at this point in the history
  • Loading branch information
Ingo Molnar committed Jan 22, 2009
2 parents b43f709 + 3690b5e commit 03b30d1
Show file tree
Hide file tree
Showing 7 changed files with 280 additions and 82 deletions.
74 changes: 74 additions & 0 deletions Documentation/ftrace.txt
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ Here is the list of current tracers that may be configured.
nop - This is not a tracer. To remove all tracers from tracing
simply echo "nop" into current_tracer.

hw-branch-tracer - traces branches on all cpu's in a circular buffer.


Examples of using the tracer
----------------------------
Expand Down Expand Up @@ -1152,6 +1154,78 @@ int main (int argc, char **argv)
return 0;
}


hw-branch-tracer (x86 only)
---------------------------

This tracer uses the x86 last branch tracing hardware feature to
collect a branch trace on all cpus with relatively low overhead.

The tracer uses a fixed-size circular buffer per cpu and only
traces ring 0 branches. The trace file dumps that buffer in the
following format:

# tracer: hw-branch-tracer
#
# CPU# TO <- FROM
0 scheduler_tick+0xb5/0x1bf <- task_tick_idle+0x5/0x6
2 run_posix_cpu_timers+0x2b/0x72a <- run_posix_cpu_timers+0x25/0x72a
0 scheduler_tick+0x139/0x1bf <- scheduler_tick+0xed/0x1bf
0 scheduler_tick+0x17c/0x1bf <- scheduler_tick+0x148/0x1bf
2 run_posix_cpu_timers+0x9e/0x72a <- run_posix_cpu_timers+0x5e/0x72a
0 scheduler_tick+0x1b6/0x1bf <- scheduler_tick+0x1aa/0x1bf


The tracer may be used to dump the trace for the oops'ing cpu on a
kernel oops into the system log. To enable this, ftrace_dump_on_oops
must be set. To set ftrace_dump_on_oops, one can either use the sysctl
function or set it via the proc system interface.

sysctl kernel.ftrace_dump_on_oops=1

or

echo 1 > /proc/sys/kernel/ftrace_dump_on_oops


Here's an example of such a dump after a null pointer dereference in a
kernel module:

[57848.105921] BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
[57848.106019] IP: [<ffffffffa0000006>] open+0x6/0x14 [oops]
[57848.106019] PGD 2354e9067 PUD 2375e7067 PMD 0
[57848.106019] Oops: 0002 [#1] SMP
[57848.106019] last sysfs file: /sys/devices/pci0000:00/0000:00:1e.0/0000:20:05.0/local_cpus
[57848.106019] Dumping ftrace buffer:
[57848.106019] ---------------------------------
[...]
[57848.106019] 0 chrdev_open+0xe6/0x165 <- cdev_put+0x23/0x24
[57848.106019] 0 chrdev_open+0x117/0x165 <- chrdev_open+0xfa/0x165
[57848.106019] 0 chrdev_open+0x120/0x165 <- chrdev_open+0x11c/0x165
[57848.106019] 0 chrdev_open+0x134/0x165 <- chrdev_open+0x12b/0x165
[57848.106019] 0 open+0x0/0x14 [oops] <- chrdev_open+0x144/0x165
[57848.106019] 0 page_fault+0x0/0x30 <- open+0x6/0x14 [oops]
[57848.106019] 0 error_entry+0x0/0x5b <- page_fault+0x4/0x30
[57848.106019] 0 error_kernelspace+0x0/0x31 <- error_entry+0x59/0x5b
[57848.106019] 0 error_sti+0x0/0x1 <- error_kernelspace+0x2d/0x31
[57848.106019] 0 page_fault+0x9/0x30 <- error_sti+0x0/0x1
[57848.106019] 0 do_page_fault+0x0/0x881 <- page_fault+0x1a/0x30
[...]
[57848.106019] 0 do_page_fault+0x66b/0x881 <- is_prefetch+0x1ee/0x1f2
[57848.106019] 0 do_page_fault+0x6e0/0x881 <- do_page_fault+0x67a/0x881
[57848.106019] 0 oops_begin+0x0/0x96 <- do_page_fault+0x6e0/0x881
[57848.106019] 0 trace_hw_branch_oops+0x0/0x2d <- oops_begin+0x9/0x96
[...]
[57848.106019] 0 ds_suspend_bts+0x2a/0xe3 <- ds_suspend_bts+0x1a/0xe3
[57848.106019] ---------------------------------
[57848.106019] CPU 0
[57848.106019] Modules linked in: oops
[57848.106019] Pid: 5542, comm: cat Tainted: G W 2.6.28 #23
[57848.106019] RIP: 0010:[<ffffffffa0000006>] [<ffffffffa0000006>] open+0x6/0x14 [oops]
[57848.106019] RSP: 0018:ffff880235457d48 EFLAGS: 00010246
[...]


dynamic ftrace
--------------

Expand Down
31 changes: 17 additions & 14 deletions arch/x86/kernel/ds.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
* - buffer allocation (memory accounting)
*
*
* Copyright (C) 2007-2008 Intel Corporation.
* Markus Metzger <markus.t.metzger@intel.com>, 2007-2008
* Copyright (C) 2007-2009 Intel Corporation.
* Markus Metzger <markus.t.metzger@intel.com>, 2007-2009
*/


Expand Down Expand Up @@ -890,7 +890,7 @@ int ds_set_pebs_reset(struct pebs_tracer *tracer, u64 value)
}

static const struct ds_configuration ds_cfg_netburst = {
.name = "netburst",
.name = "Netburst",
.ctl[dsf_bts] = (1 << 2) | (1 << 3),
.ctl[dsf_bts_kernel] = (1 << 5),
.ctl[dsf_bts_user] = (1 << 6),
Expand All @@ -904,7 +904,7 @@ static const struct ds_configuration ds_cfg_netburst = {
#endif
};
static const struct ds_configuration ds_cfg_pentium_m = {
.name = "pentium m",
.name = "Pentium M",
.ctl[dsf_bts] = (1 << 6) | (1 << 7),

.sizeof_field = sizeof(long),
Expand All @@ -915,8 +915,8 @@ static const struct ds_configuration ds_cfg_pentium_m = {
.sizeof_rec[ds_pebs] = sizeof(long) * 18,
#endif
};
static const struct ds_configuration ds_cfg_core2 = {
.name = "core 2",
static const struct ds_configuration ds_cfg_core2_atom = {
.name = "Core 2/Atom",
.ctl[dsf_bts] = (1 << 6) | (1 << 7),
.ctl[dsf_bts_kernel] = (1 << 9),
.ctl[dsf_bts_user] = (1 << 10),
Expand Down Expand Up @@ -949,19 +949,22 @@ void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
switch (c->x86) {
case 0x6:
switch (c->x86_model) {
case 0 ... 0xC:
/* sorry, don't know about them */
break;
case 0xD:
case 0xE: /* Pentium M */
case 0x9:
case 0xd: /* Pentium M */
ds_configure(&ds_cfg_pentium_m);
break;
default: /* Core2, Atom, ... */
ds_configure(&ds_cfg_core2);
case 0xf:
case 0x17: /* Core2 */
case 0x1c: /* Atom */
ds_configure(&ds_cfg_core2_atom);
break;
case 0x1a: /* i7 */
default:
/* sorry, don't know about them */
break;
}
break;
case 0xF:
case 0xf:
switch (c->x86_model) {
case 0x0:
case 0x1:
Expand Down
6 changes: 6 additions & 0 deletions arch/x86/kernel/dumpstack.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/bug.h>
#include <linux/nmi.h>
#include <linux/sysfs.h>
#include <linux/ftrace.h>

#include <asm/stacktrace.h>

Expand Down Expand Up @@ -195,6 +196,11 @@ unsigned __kprobes long oops_begin(void)
int cpu;
unsigned long flags;

/* notify the hw-branch tracer so it may disable tracing and
add the last trace to the trace buffer -
the earlier this happens, the more useful the trace. */
trace_hw_branch_oops();

oops_enter();

/* racy, but better than risking deadlock. */
Expand Down
13 changes: 13 additions & 0 deletions include/linux/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -496,4 +496,17 @@ static inline int test_tsk_trace_graph(struct task_struct *tsk)

#endif /* CONFIG_TRACING */


#ifdef CONFIG_HW_BRANCH_TRACER

void trace_hw_branch(u64 from, u64 to);
void trace_hw_branch_oops(void);

#else /* CONFIG_HW_BRANCH_TRACER */

static inline void trace_hw_branch(u64 from, u64 to) {}
static inline void trace_hw_branch_oops(void) {}

#endif /* CONFIG_HW_BRANCH_TRACER */

#endif /* _LINUX_FTRACE_H */
1 change: 0 additions & 1 deletion kernel/trace/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,6 @@ void trace_function(struct trace_array *tr,

void trace_graph_return(struct ftrace_graph_ret *trace);
int trace_graph_entry(struct ftrace_graph_ent *trace);
void trace_hw_branch(struct trace_array *tr, u64 from, u64 to);

void tracing_start_cmdline_record(void);
void tracing_stop_cmdline_record(void);
Expand Down
Loading

0 comments on commit 03b30d1

Please sign in to comment.