Skip to content

Commit

Permalink
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/li…
Browse files Browse the repository at this point in the history
…nux/kernel/git/tip/linux-2.6-tip

* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (470 commits)
  x86: Fix comments of register/stack access functions
  perf tools: Replace %m with %a in sscanf
  hw-breakpoints: Keep track of user disabled breakpoints
  tracing/syscalls: Make syscall events print callbacks static
  tracing: Add DEFINE_EVENT(), DEFINE_SINGLE_EVENT() support to docbook
  perf: Don't free perf_mmap_data until work has been done
  perf_event: Fix compile error
  perf tools: Fix _GNU_SOURCE macro related strndup() build error
  trace_syscalls: Remove unused syscall_name_to_nr()
  trace_syscalls: Simplify syscall profile
  trace_syscalls: Remove duplicate init_enter_##sname()
  trace_syscalls: Add syscall_nr field to struct syscall_metadata
  trace_syscalls: Remove enter_id exit_id
  trace_syscalls: Set event_enter_##sname->data to its metadata
  trace_syscalls: Remove unused event_syscall_enter and event_syscall_exit
  perf_event: Initialize data.period in perf_swevent_hrtimer()
  perf probe: Simplify event naming
  perf probe: Add --list option for listing current probe events
  perf probe: Add argv_split() from lib/argv_split.c
  perf probe: Move probe event utility functions to probe-event.c
  ...
  • Loading branch information
torvalds committed Dec 5, 2009
2 parents 96fa2b5 + d103d01 commit c3fa27d
Show file tree
Hide file tree
Showing 251 changed files with 21,092 additions and 6,102 deletions.
5 changes: 5 additions & 0 deletions Documentation/DocBook/tracepoint.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,9 @@
!Iinclude/trace/events/irq.h
</chapter>

<chapter id="signal">
<title>SIGNAL</title>
!Iinclude/trace/events/signal.h
</chapter>

</book>
149 changes: 149 additions & 0 deletions Documentation/trace/kprobetrace.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
Kprobe-based Event Tracing
==========================

Documentation is written by Masami Hiramatsu


Overview
--------
These events are similar to tracepoint based events. Instead of Tracepoint,
this is based on kprobes (kprobe and kretprobe). So it can probe wherever
kprobes can probe (this means, all functions body except for __kprobes
functions). Unlike the Tracepoint based event, this can be added and removed
dynamically, on the fly.

To enable this feature, build your kernel with CONFIG_KPROBE_TRACING=y.

Similar to the events tracer, this doesn't need to be activated via
current_tracer. Instead of that, add probe points via
/sys/kernel/debug/tracing/kprobe_events, and enable it via
/sys/kernel/debug/tracing/events/kprobes/<EVENT>/enabled.


Synopsis of kprobe_events
-------------------------
p[:[GRP/]EVENT] SYMBOL[+offs]|MEMADDR [FETCHARGS] : Set a probe
r[:[GRP/]EVENT] SYMBOL[+0] [FETCHARGS] : Set a return probe

GRP : Group name. If omitted, use "kprobes" for it.
EVENT : Event name. If omitted, the event name is generated
based on SYMBOL+offs or MEMADDR.
SYMBOL[+offs] : Symbol+offset where the probe is inserted.
MEMADDR : Address where the probe is inserted.

FETCHARGS : Arguments. Each probe can have up to 128 args.
%REG : Fetch register REG
@ADDR : Fetch memory at ADDR (ADDR should be in kernel)
@SYM[+|-offs] : Fetch memory at SYM +|- offs (SYM should be a data symbol)
$stackN : Fetch Nth entry of stack (N >= 0)
$stack : Fetch stack address.
$argN : Fetch function argument. (N >= 0)(*)
$retval : Fetch return value.(**)
+|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(***)
NAME=FETCHARG: Set NAME as the argument name of FETCHARG.

(*) aN may not correct on asmlinkaged functions and at the middle of
function body.
(**) only for return probe.
(***) this is useful for fetching a field of data structures.


Per-Probe Event Filtering
-------------------------
Per-probe event filtering feature allows you to set different filter on each
probe and gives you what arguments will be shown in trace buffer. If an event
name is specified right after 'p:' or 'r:' in kprobe_events, it adds an event
under tracing/events/kprobes/<EVENT>, at the directory you can see 'id',
'enabled', 'format' and 'filter'.

enabled:
You can enable/disable the probe by writing 1 or 0 on it.

format:
This shows the format of this probe event.

filter:
You can write filtering rules of this event.

id:
This shows the id of this probe event.


Event Profiling
---------------
You can check the total number of probe hits and probe miss-hits via
/sys/kernel/debug/tracing/kprobe_profile.
The first column is event name, the second is the number of probe hits,
the third is the number of probe miss-hits.


Usage examples
--------------
To add a probe as a new event, write a new definition to kprobe_events
as below.

echo p:myprobe do_sys_open dfd=$arg0 filename=$arg1 flags=$arg2 mode=$arg3 > /sys/kernel/debug/tracing/kprobe_events

This sets a kprobe on the top of do_sys_open() function with recording
1st to 4th arguments as "myprobe" event. As this example shows, users can
choose more familiar names for each arguments.

echo r:myretprobe do_sys_open $retval >> /sys/kernel/debug/tracing/kprobe_events

This sets a kretprobe on the return point of do_sys_open() function with
recording return value as "myretprobe" event.
You can see the format of these events via
/sys/kernel/debug/tracing/events/kprobes/<EVENT>/format.

cat /sys/kernel/debug/tracing/events/kprobes/myprobe/format
name: myprobe
ID: 75
format:
field:unsigned short common_type; offset:0; size:2;
field:unsigned char common_flags; offset:2; size:1;
field:unsigned char common_preempt_count; offset:3; size:1;
field:int common_pid; offset:4; size:4;
field:int common_tgid; offset:8; size:4;

field: unsigned long ip; offset:16;tsize:8;
field: int nargs; offset:24;tsize:4;
field: unsigned long dfd; offset:32;tsize:8;
field: unsigned long filename; offset:40;tsize:8;
field: unsigned long flags; offset:48;tsize:8;
field: unsigned long mode; offset:56;tsize:8;

print fmt: "(%lx) dfd=%lx filename=%lx flags=%lx mode=%lx", REC->ip, REC->dfd, REC->filename, REC->flags, REC->mode


You can see that the event has 4 arguments as in the expressions you specified.

echo > /sys/kernel/debug/tracing/kprobe_events

This clears all probe points.

Right after definition, each event is disabled by default. For tracing these
events, you need to enable it.

echo 1 > /sys/kernel/debug/tracing/events/kprobes/myprobe/enable
echo 1 > /sys/kernel/debug/tracing/events/kprobes/myretprobe/enable

And you can see the traced information via /sys/kernel/debug/tracing/trace.

cat /sys/kernel/debug/tracing/trace
# tracer: nop
#
# TASK-PID CPU# TIMESTAMP FUNCTION
# | | | | |
<...>-1447 [001] 1038282.286875: myprobe: (do_sys_open+0x0/0xd6) dfd=3 filename=7fffd1ec4440 flags=8000 mode=0
<...>-1447 [001] 1038282.286878: myretprobe: (sys_openat+0xc/0xe <- do_sys_open) $retval=fffffffffffffffe
<...>-1447 [001] 1038282.286885: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=40413c flags=8000 mode=1b6
<...>-1447 [001] 1038282.286915: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) $retval=3
<...>-1447 [001] 1038282.286969: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=4041c6 flags=98800 mode=10
<...>-1447 [001] 1038282.286976: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) $retval=3


Each line shows when the kernel hits an event, and <- SYMBOL means kernel
returns from SYMBOL(e.g. "sys_open+0x1b/0x1d <- do_sys_open" means kernel
returns from do_sys_open to sys_open+0x1b).


7 changes: 7 additions & 0 deletions arch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,11 @@ config HAVE_DMA_API_DEBUG
config HAVE_DEFAULT_NO_SPIN_MUTEXES
bool

config HAVE_HW_BREAKPOINT
bool
depends on HAVE_PERF_EVENTS
select ANON_INODES
select PERF_EVENTS


source "kernel/gcov/Kconfig"
2 changes: 1 addition & 1 deletion arch/powerpc/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ config DEBUG_STACK_USAGE

config HCALL_STATS
bool "Hypervisor call instrumentation"
depends on PPC_PSERIES && DEBUG_FS
depends on PPC_PSERIES && DEBUG_FS && TRACEPOINTS
help
Adds code to keep track of the number of hypervisor calls made and
the amount of time spent in hypervisor calls. Wall time spent in
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/configs/pseries_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1683,7 +1683,7 @@ CONFIG_HAVE_ARCH_KGDB=y
CONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_PAGEALLOC is not set
CONFIG_HCALL_STATS=y
# CONFIG_HCALL_STATS is not set
# CONFIG_CODE_PATCHING_SELFTEST is not set
# CONFIG_FTR_FIXUP_SELFTEST is not set
# CONFIG_MSI_BITMAP_SELFTEST is not set
Expand Down
19 changes: 17 additions & 2 deletions arch/powerpc/include/asm/emulated_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#define _ASM_POWERPC_EMULATED_OPS_H

#include <asm/atomic.h>
#include <linux/perf_event.h>


#ifdef CONFIG_PPC_EMULATED_STATS
Expand Down Expand Up @@ -57,7 +58,7 @@ extern u32 ppc_warn_emulated;

extern void ppc_warn_emulated_print(const char *type);

#define PPC_WARN_EMULATED(type) \
#define __PPC_WARN_EMULATED(type) \
do { \
atomic_inc(&ppc_emulated.type.val); \
if (ppc_warn_emulated) \
Expand All @@ -66,8 +67,22 @@ extern void ppc_warn_emulated_print(const char *type);

#else /* !CONFIG_PPC_EMULATED_STATS */

#define PPC_WARN_EMULATED(type) do { } while (0)
#define __PPC_WARN_EMULATED(type) do { } while (0)

#endif /* !CONFIG_PPC_EMULATED_STATS */

#define PPC_WARN_EMULATED(type, regs) \
do { \
perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, \
1, 0, regs, 0); \
__PPC_WARN_EMULATED(type); \
} while (0)

#define PPC_WARN_ALIGNMENT(type, regs) \
do { \
perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, \
1, 0, regs, regs->dar); \
__PPC_WARN_EMULATED(type); \
} while (0)

#endif /* _ASM_POWERPC_EMULATED_OPS_H */
2 changes: 2 additions & 0 deletions arch/powerpc/include/asm/hvcall.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ struct hcall_stats {
unsigned long num_calls; /* number of calls (on this CPU) */
unsigned long tb_total; /* total wall time (mftb) of calls. */
unsigned long purr_total; /* total cpu time (PURR) of calls. */
unsigned long tb_start;
unsigned long purr_start;
};
#define HCALL_STAT_ARRAY_SIZE ((MAX_HCALL_OPCODE >> 2) + 1)

Expand Down
2 changes: 2 additions & 0 deletions arch/powerpc/include/asm/reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,8 @@
#define SPRN_MMCR1 798
#define SPRN_MMCRA 0x312
#define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */
#define MMCRA_SDAR_DCACHE_MISS 0x40000000UL
#define MMCRA_SDAR_ERAT_MISS 0x20000000UL
#define MMCRA_SIHV 0x10000000UL /* state of MSR HV when SIAR set */
#define MMCRA_SIPR 0x08000000UL /* state of MSR PR when SIAR set */
#define MMCRA_SLOT 0x07000000UL /* SLOT bits (37-39) */
Expand Down
133 changes: 133 additions & 0 deletions arch/powerpc/include/asm/trace.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#undef TRACE_SYSTEM
#define TRACE_SYSTEM powerpc

#if !defined(_TRACE_POWERPC_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_POWERPC_H

#include <linux/tracepoint.h>

struct pt_regs;

TRACE_EVENT(irq_entry,

TP_PROTO(struct pt_regs *regs),

TP_ARGS(regs),

TP_STRUCT__entry(
__field(struct pt_regs *, regs)
),

TP_fast_assign(
__entry->regs = regs;
),

TP_printk("pt_regs=%p", __entry->regs)
);

TRACE_EVENT(irq_exit,

TP_PROTO(struct pt_regs *regs),

TP_ARGS(regs),

TP_STRUCT__entry(
__field(struct pt_regs *, regs)
),

TP_fast_assign(
__entry->regs = regs;
),

TP_printk("pt_regs=%p", __entry->regs)
);

TRACE_EVENT(timer_interrupt_entry,

TP_PROTO(struct pt_regs *regs),

TP_ARGS(regs),

TP_STRUCT__entry(
__field(struct pt_regs *, regs)
),

TP_fast_assign(
__entry->regs = regs;
),

TP_printk("pt_regs=%p", __entry->regs)
);

TRACE_EVENT(timer_interrupt_exit,

TP_PROTO(struct pt_regs *regs),

TP_ARGS(regs),

TP_STRUCT__entry(
__field(struct pt_regs *, regs)
),

TP_fast_assign(
__entry->regs = regs;
),

TP_printk("pt_regs=%p", __entry->regs)
);

#ifdef CONFIG_PPC_PSERIES
extern void hcall_tracepoint_regfunc(void);
extern void hcall_tracepoint_unregfunc(void);

TRACE_EVENT_FN(hcall_entry,

TP_PROTO(unsigned long opcode, unsigned long *args),

TP_ARGS(opcode, args),

TP_STRUCT__entry(
__field(unsigned long, opcode)
),

TP_fast_assign(
__entry->opcode = opcode;
),

TP_printk("opcode=%lu", __entry->opcode),

hcall_tracepoint_regfunc, hcall_tracepoint_unregfunc
);

TRACE_EVENT_FN(hcall_exit,

TP_PROTO(unsigned long opcode, unsigned long retval,
unsigned long *retbuf),

TP_ARGS(opcode, retval, retbuf),

TP_STRUCT__entry(
__field(unsigned long, opcode)
__field(unsigned long, retval)
),

TP_fast_assign(
__entry->opcode = opcode;
__entry->retval = retval;
),

TP_printk("opcode=%lu retval=%lu", __entry->opcode, __entry->retval),

hcall_tracepoint_regfunc, hcall_tracepoint_unregfunc
);
#endif

#endif /* _TRACE_POWERPC_H */

#undef TRACE_INCLUDE_PATH
#undef TRACE_INCLUDE_FILE

#define TRACE_INCLUDE_PATH asm
#define TRACE_INCLUDE_FILE trace

#include <trace/define_trace.h>
Loading

0 comments on commit c3fa27d

Please sign in to comment.