History

Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: perf session: Make events_stats u64 to avoid overflow on 32-bit arches hw-breakpoints: Fix hardware breakpoints -> perf events dependency perf events: Dont report side-band events on each cpu for per-task-per-cpu events perf events, x86/stacktrace: Fix performance/softlockup by providing a special frame pointer-only stack walker perf events, x86/stacktrace: Make stack walking optional perf events: Remove unused perf_counter.h header file perf probe: Check new event name kprobe-tracer: Check new event/group name perf probe: Check whether debugfs path is correct perf probe: Fix libdwarf include path for Debian

Linus Torvalds committed 16 years ago

Commit eca9dfc2 parents 3981e15 b5b60fd20 files · +175 −523Browse files

Unified · Split

20 files
  1. arch/Kconfig +1 −3
  2. arch/x86/Kconfig +2 −0
  3. arch/x86/include/asm/stacktrace.h +24 −0
  4. arch/x86/kernel/cpu/perf_event.c +1 −0
  5. arch/x86/kernel/dumpstack.c +29 −4
  6. arch/x86/kernel/dumpstack.h +0 −6
  7. arch/x86/kernel/dumpstack_32.c +1 −1
  8. arch/x86/kernel/dumpstack_64.c +2 −2
  9. arch/x86/kernel/stacktrace.c +10 −8
  10. arch/x86/oprofile/backtrace.c +5 −4
  11. include/linux/perf_counter.h +0 −444
  12. kernel/perf_event.c +18 −14
  13. kernel/trace/trace_kprobe.c +25 −6
  14. kernel/trace/trace_sysprof.c +1 −0
  15. tools/perf/Makefile +2 −1
  16. tools/perf/builtin-probe.c +4 −0
  17. tools/perf/builtin-report.c +1 −1
  18. tools/perf/util/event.h +2 −2
  19. tools/perf/util/probe-event.c +15 −0
  20. tools/perf/util/probe-finder.h +32 −27
arch/Kconfig+1−3
@@ -135,9 +135,7 @@ config HAVE_DEFAULT_NO_SPIN_MUTEXES · 134 unmodified lines
135 135
136config HAVE_HW_BREAKPOINT136config HAVE_HW_BREAKPOINT
137 bool137 bool
138 depends on HAVE_PERF_EVENTS138 depends on PERF_EVENTS
139 select ANON_INODES
140 select PERF_EVENTS
141 139
142config HAVE_USER_RETURN_NOTIFIER140config HAVE_USER_RETURN_NOTIFIER
143 bool141 bool
arch/x86/Kconfig+2−0
@@ -50,6 +50,8 @@ config X86 · 49 unmodified lines
50 select HAVE_KERNEL_BZIP250 select HAVE_KERNEL_BZIP2
51 select HAVE_KERNEL_LZMA51 select HAVE_KERNEL_LZMA
52 select HAVE_HW_BREAKPOINT52 select HAVE_HW_BREAKPOINT
53 select PERF_EVENTS
54 select ANON_INODES
53 select HAVE_ARCH_KMEMCHECK55 select HAVE_ARCH_KMEMCHECK
54 select HAVE_USER_RETURN_NOTIFIER56 select HAVE_USER_RETURN_NOTIFIER
55 57
arch/x86/include/asm/stacktrace.h+24−0
@@ -5,6 +5,29 @@ extern int kstack_depth_to_print; · 4 unmodified lines
5 5
6int x86_is_stack_id(int id, char *name);6int x86_is_stack_id(int id, char *name);
7 7
8struct thread_info;
9struct stacktrace_ops;
10
11typedef unsigned long (*walk_stack_t)(struct thread_info *tinfo,
12 unsigned long *stack,
13 unsigned long bp,
14 const struct stacktrace_ops *ops,
15 void *data,
16 unsigned long *end,
17 int *graph);
18
19extern unsigned long
20print_context_stack(struct thread_info *tinfo,
21 unsigned long *stack, unsigned long bp,
22 const struct stacktrace_ops *ops, void *data,
23 unsigned long *end, int *graph);
24
25extern unsigned long
26print_context_stack_bp(struct thread_info *tinfo,
27 unsigned long *stack, unsigned long bp,
28 const struct stacktrace_ops *ops, void *data,
29 unsigned long *end, int *graph);
30
8/* Generic stack tracer with callbacks */31/* Generic stack tracer with callbacks */
9 32
10struct stacktrace_ops {33struct stacktrace_ops {
@@ -14,6 +37,7 @@ struct stacktrace_ops { · 3 unmodified lines
14 void (*address)(void *data, unsigned long address, int reliable);37 void (*address)(void *data, unsigned long address, int reliable);
15 /* On negative return stop dumping */38 /* On negative return stop dumping */
16 int (*stack)(void *data, char *name);39 int (*stack)(void *data, char *name);
40 walk_stack_t walk_stack;
17};41};
18 42
19void dump_trace(struct task_struct *tsk, struct pt_regs *regs,43void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
arch/x86/kernel/cpu/perf_event.c+1−0
@@ -2336,6 +2336,7 @@ static const struct stacktrace_ops backtrace_ops = { · 2335 unmodified lines
2336 .warning_symbol = backtrace_warning_symbol,2336 .warning_symbol = backtrace_warning_symbol,
2337 .stack = backtrace_stack,2337 .stack = backtrace_stack,
2338 .address = backtrace_address,2338 .address = backtrace_address,
2339 .walk_stack = print_context_stack_bp,
2339};2340};
2340 2341
2341#include "../dumpstack.h"2342#include "../dumpstack.h"
arch/x86/kernel/dumpstack.c+29−4
@@ -109,6 +109,30 @@ print_context_stack(struct thread_info *tinfo, · 108 unmodified lines
109 }109 }
110 return bp;110 return bp;
111}111}
112EXPORT_SYMBOL_GPL(print_context_stack);
113
114unsigned long
115print_context_stack_bp(struct thread_info *tinfo,
116 unsigned long *stack, unsigned long bp,
117 const struct stacktrace_ops *ops, void *data,
118 unsigned long *end, int *graph)
119{
120 struct stack_frame *frame = (struct stack_frame *)bp;
121 unsigned long *ret_addr = &frame->return_address;
122
123 while (valid_stack_ptr(tinfo, ret_addr, sizeof(*ret_addr), end)) {
124 unsigned long addr = *ret_addr;
125
126 if (__kernel_text_address(addr)) {
127 ops->address(data, addr, 1);
128 frame = frame->next_frame;
129 ret_addr = &frame->return_address;
130 print_ftrace_graph_addr(addr, data, ops, tinfo, graph);
131 }
132 }
133 return (unsigned long)frame;
134}
135EXPORT_SYMBOL_GPL(print_context_stack_bp);
112 136
113 137
114static void138static void
@@ -141,10 +165,11 @@ static void print_trace_address(void *data, unsigned long addr, int reliable) · 26 unmodified lines
141}165}
142 166
143static const struct stacktrace_ops print_trace_ops = {167static const struct stacktrace_ops print_trace_ops = {
144 .warning = print_trace_warning,168 .warning = print_trace_warning,
145 .warning_symbol = print_trace_warning_symbol,169 .warning_symbol = print_trace_warning_symbol,
146 .stack = print_trace_stack,170 .stack = print_trace_stack,
147 .address = print_trace_address,171 .address = print_trace_address,
172 .walk_stack = print_context_stack,
148};173};
149 174
150void175void
arch/x86/kernel/dumpstack.h+0−6
@@ -14,12 +14,6 @@ · 13 unmodified lines
14#define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :)14#define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :)
15#endif15#endif
16 16
17extern unsigned long
18print_context_stack(struct thread_info *tinfo,
19 unsigned long *stack, unsigned long bp,
20 const struct stacktrace_ops *ops, void *data,
21 unsigned long *end, int *graph);
22
23extern void17extern void
24show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,18show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
25 unsigned long *stack, unsigned long bp, char *log_lvl);19 unsigned long *stack, unsigned long bp, char *log_lvl);
arch/x86/kernel/dumpstack_32.c+1−1
@@ -58,7 +58,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, · 57 unmodified lines
58 58
59 context = (struct thread_info *)59 context = (struct thread_info *)
60 ((unsigned long)stack & (~(THREAD_SIZE - 1)));60 ((unsigned long)stack & (~(THREAD_SIZE - 1)));
61 bp = print_context_stack(context, stack, bp, ops, data, NULL, &graph);61 bp = ops->walk_stack(context, stack, bp, ops, data, NULL, &graph);
62 62
63 stack = (unsigned long *)context->previous_esp;63 stack = (unsigned long *)context->previous_esp;
64 if (!stack)64 if (!stack)
arch/x86/kernel/dumpstack_64.c+2−2
@@ -188,8 +188,8 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, · 187 unmodified lines
188 if (ops->stack(data, id) < 0)188 if (ops->stack(data, id) < 0)
189 break;189 break;
190 190
191 bp = print_context_stack(tinfo, stack, bp, ops,191 bp = ops->walk_stack(tinfo, stack, bp, ops,
192 data, estack_end, &graph);192 data, estack_end, &graph);
193 ops->stack(data, "<EOE>");193 ops->stack(data, "<EOE>");
194 /*194 /*
195 * We link to the next stack via the195 * We link to the next stack via the
arch/x86/kernel/stacktrace.c+10−8
@@ -53,17 +53,19 @@ save_stack_address_nosched(void *data, unsigned long addr, int reliable) · 52 unmodified lines
53}53}
54 54
55static const struct stacktrace_ops save_stack_ops = {55static const struct stacktrace_ops save_stack_ops = {
56 .warning = save_stack_warning,56 .warning = save_stack_warning,
57 .warning_symbol = save_stack_warning_symbol,57 .warning_symbol = save_stack_warning_symbol,
58 .stack = save_stack_stack,58 .stack = save_stack_stack,
59 .address = save_stack_address,59 .address = save_stack_address,
60 .walk_stack = print_context_stack,
60};61};
61 62
62static const struct stacktrace_ops save_stack_ops_nosched = {63static const struct stacktrace_ops save_stack_ops_nosched = {
63 .warning = save_stack_warning,64 .warning = save_stack_warning,
64 .warning_symbol = save_stack_warning_symbol,65 .warning_symbol = save_stack_warning_symbol,
65 .stack = save_stack_stack,66 .stack = save_stack_stack,
66 .address = save_stack_address_nosched,67 .address = save_stack_address_nosched,
68 .walk_stack = print_context_stack,
67};69};
68 70
69/*71/*
arch/x86/oprofile/backtrace.c+5−4
@@ -41,10 +41,11 @@ static void backtrace_address(void *data, unsigned long addr, int reliable) · 40 unmodified lines
41}41}
42 42
43static struct stacktrace_ops backtrace_ops = {43static struct stacktrace_ops backtrace_ops = {
44 .warning = backtrace_warning,44 .warning = backtrace_warning,
45 .warning_symbol = backtrace_warning_symbol,45 .warning_symbol = backtrace_warning_symbol,
46 .stack = backtrace_stack,46 .stack = backtrace_stack,
47 .address = backtrace_address,47 .address = backtrace_address,
48 .walk_stack = print_context_stack,
48};49};
49 50
50struct frame_head {51struct frame_head {
include/linux/perf_counter.h+0−444
@@ -1,444 +0,0 @@
1/*
2 * NOTE: this file will be removed in a future kernel release, it is
3 * provided as a courtesy copy of user-space code that relies on the
4 * old (pre-rename) symbols and constants.
5 *
6 * Performance events:
7 *
8 * Copyright (C) 2008-2009, Thomas Gleixner <tglx@linutronix.de>
9 * Copyright (C) 2008-2009, Red Hat, Inc., Ingo Molnar
10 * Copyright (C) 2008-2009, Red Hat, Inc., Peter Zijlstra
11 *
12 * Data type definitions, declarations, prototypes.
13 *
14 * Started by: Thomas Gleixner and Ingo Molnar
15 *
16 * For licencing details see kernel-base/COPYING
17 */
18#ifndef _LINUX_PERF_COUNTER_H
19#define _LINUX_PERF_COUNTER_H
20
21#include <linux/types.h>
22#include <linux/ioctl.h>
23#include <asm/byteorder.h>
24
25/*
26 * User-space ABI bits:
27 */
28
29/*
30 * attr.type
31 */
32enum perf_type_id {
33 PERF_TYPE_HARDWARE = 0,
34 PERF_TYPE_SOFTWARE = 1,
35 PERF_TYPE_TRACEPOINT = 2,
36 PERF_TYPE_HW_CACHE = 3,
37 PERF_TYPE_RAW = 4,
38
39 PERF_TYPE_MAX, /* non-ABI */
40};
41
42/*
43 * Generalized performance counter event types, used by the
44 * attr.event_id parameter of the sys_perf_counter_open()
45 * syscall:
46 */
47enum perf_hw_id {
48 /*
49 * Common hardware events, generalized by the kernel:
50 */
51 PERF_COUNT_HW_CPU_CYCLES = 0,
52 PERF_COUNT_HW_INSTRUCTIONS = 1,
53 PERF_COUNT_HW_CACHE_REFERENCES = 2,
54 PERF_COUNT_HW_CACHE_MISSES = 3,
55 PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4,
56 PERF_COUNT_HW_BRANCH_MISSES = 5,
57 PERF_COUNT_HW_BUS_CYCLES = 6,
58
59 PERF_COUNT_HW_MAX, /* non-ABI */
60};
61
62/*
63 * Generalized hardware cache counters:
64 *
65 * { L1-D, L1-I, LLC, ITLB, DTLB, BPU } x
66 * { read, write, prefetch } x
67 * { accesses, misses }
68 */
69enum perf_hw_cache_id {
70 PERF_COUNT_HW_CACHE_L1D = 0,
71 PERF_COUNT_HW_CACHE_L1I = 1,
72 PERF_COUNT_HW_CACHE_LL = 2,
73 PERF_COUNT_HW_CACHE_DTLB = 3,
74 PERF_COUNT_HW_CACHE_ITLB = 4,
75 PERF_COUNT_HW_CACHE_BPU = 5,
76
77 PERF_COUNT_HW_CACHE_MAX, /* non-ABI */
78};
79
80enum perf_hw_cache_op_id {
81 PERF_COUNT_HW_CACHE_OP_READ = 0,
82 PERF_COUNT_HW_CACHE_OP_WRITE = 1,
83 PERF_COUNT_HW_CACHE_OP_PREFETCH = 2,
84
85 PERF_COUNT_HW_CACHE_OP_MAX, /* non-ABI */
86};
87
88enum perf_hw_cache_op_result_id {
89 PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0,
90 PERF_COUNT_HW_CACHE_RESULT_MISS = 1,
91
92 PERF_COUNT_HW_CACHE_RESULT_MAX, /* non-ABI */
93};
94
95/*
96 * Special "software" counters provided by the kernel, even if the hardware
97 * does not support performance counters. These counters measure various
98 * physical and sw events of the kernel (and allow the profiling of them as
99 * well):
100 */
101enum perf_sw_ids {
102 PERF_COUNT_SW_CPU_CLOCK = 0,
103 PERF_COUNT_SW_TASK_CLOCK = 1,
104 PERF_COUNT_SW_PAGE_FAULTS = 2,
105 PERF_COUNT_SW_CONTEXT_SWITCHES = 3,
106 PERF_COUNT_SW_CPU_MIGRATIONS = 4,
107 PERF_COUNT_SW_PAGE_FAULTS_MIN = 5,
108 PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6,
109 PERF_COUNT_SW_ALIGNMENT_FAULTS = 7,
110 PERF_COUNT_SW_EMULATION_FAULTS = 8,
111
112 PERF_COUNT_SW_MAX, /* non-ABI */
113};
114
115/*
116 * Bits that can be set in attr.sample_type to request information
117 * in the overflow packets.
118 */
119enum perf_counter_sample_format {
120 PERF_SAMPLE_IP = 1U << 0,
121 PERF_SAMPLE_TID = 1U << 1,
122 PERF_SAMPLE_TIME = 1U << 2,
123 PERF_SAMPLE_ADDR = 1U << 3,
124 PERF_SAMPLE_READ = 1U << 4,
125 PERF_SAMPLE_CALLCHAIN = 1U << 5,
126 PERF_SAMPLE_ID = 1U << 6,
127 PERF_SAMPLE_CPU = 1U << 7,
128 PERF_SAMPLE_PERIOD = 1U << 8,
129 PERF_SAMPLE_STREAM_ID = 1U << 9,
130 PERF_SAMPLE_RAW = 1U << 10,
131
132 PERF_SAMPLE_MAX = 1U << 11, /* non-ABI */
133};
134
135/*
136 * The format of the data returned by read() on a perf counter fd,
137 * as specified by attr.read_format:
138 *
139 * struct read_format {
140 * { u64 value;
141 * { u64 time_enabled; } && PERF_FORMAT_ENABLED
142 * { u64 time_running; } && PERF_FORMAT_RUNNING
143 * { u64 id; } && PERF_FORMAT_ID
144 * } && !PERF_FORMAT_GROUP
145 *
146 * { u64 nr;
147 * { u64 time_enabled; } && PERF_FORMAT_ENABLED
148 * { u64 time_running; } && PERF_FORMAT_RUNNING
149 * { u64 value;
150 * { u64 id; } && PERF_FORMAT_ID
151 * } cntr[nr];
152 * } && PERF_FORMAT_GROUP
153 * };
154 */
155enum perf_counter_read_format {
156 PERF_FORMAT_TOTAL_TIME_ENABLED = 1U << 0,
157 PERF_FORMAT_TOTAL_TIME_RUNNING = 1U << 1,
158 PERF_FORMAT_ID = 1U << 2,
159 PERF_FORMAT_GROUP = 1U << 3,
160
161 PERF_FORMAT_MAX = 1U << 4, /* non-ABI */
162};
163
164#define PERF_ATTR_SIZE_VER0 64 /* sizeof first published struct */
165
166/*
167 * Hardware event to monitor via a performance monitoring counter:
168 */
169struct perf_counter_attr {
170
171 /*
172 * Major type: hardware/software/tracepoint/etc.
173 */
174 __u32 type;
175
176 /*
177 * Size of the attr structure, for fwd/bwd compat.
178 */
179 __u32 size;
180
181 /*
182 * Type specific configuration information.
183 */
184 __u64 config;
185
186 union {
187 __u64 sample_period;
188 __u64 sample_freq;
189 };
190
191 __u64 sample_type;
192 __u64 read_format;
193
194 __u64 disabled : 1, /* off by default */
195 inherit : 1, /* children inherit it */
196 pinned : 1, /* must always be on PMU */
197 exclusive : 1, /* only group on PMU */
198 exclude_user : 1, /* don't count user */
199 exclude_kernel : 1, /* ditto kernel */
200 exclude_hv : 1, /* ditto hypervisor */
201 exclude_idle : 1, /* don't count when idle */
202 mmap : 1, /* include mmap data */
203 comm : 1, /* include comm data */
204 freq : 1, /* use freq, not period */
205 inherit_stat : 1, /* per task counts */
206 enable_on_exec : 1, /* next exec enables */
207 task : 1, /* trace fork/exit */
208 watermark : 1, /* wakeup_watermark */
209
210 __reserved_1 : 49;
211
212 union {
213 __u32 wakeup_events; /* wakeup every n events */
214 __u32 wakeup_watermark; /* bytes before wakeup */
215 };
216 __u32 __reserved_2;
217
218 __u64 __reserved_3;
219};
220
221/*
222 * Ioctls that can be done on a perf counter fd:
223 */
224#define PERF_COUNTER_IOC_ENABLE _IO ('$', 0)
225#define PERF_COUNTER_IOC_DISABLE _IO ('$', 1)
226#define PERF_COUNTER_IOC_REFRESH _IO ('$', 2)
227#define PERF_COUNTER_IOC_RESET _IO ('$', 3)
228#define PERF_COUNTER_IOC_PERIOD _IOW('$', 4, u64)
229#define PERF_COUNTER_IOC_SET_OUTPUT _IO ('$', 5)
230#define PERF_COUNTER_IOC_SET_FILTER _IOW('$', 6, char *)
231
232enum perf_counter_ioc_flags {
233 PERF_IOC_FLAG_GROUP = 1U << 0,
234};
235
236/*
237 * Structure of the page that can be mapped via mmap
238 */
239struct perf_counter_mmap_page {
240 __u32 version; /* version number of this structure */
241 __u32 compat_version; /* lowest version this is compat with */
242
243 /*
244 * Bits needed to read the hw counters in user-space.
245 *
246 * u32 seq;
247 * s64 count;
248 *
249 * do {
250 * seq = pc->lock;
251 *
252 * barrier()
253 * if (pc->index) {
254 * count = pmc_read(pc->index - 1);
255 * count += pc->offset;
256 * } else
257 * goto regular_read;
258 *
259 * barrier();
260 * } while (pc->lock != seq);
261 *
262 * NOTE: for obvious reason this only works on self-monitoring
263 * processes.
264 */
265 __u32 lock; /* seqlock for synchronization */
266 __u32 index; /* hardware counter identifier */
267 __s64 offset; /* add to hardware counter value */
268 __u64 time_enabled; /* time counter active */
269 __u64 time_running; /* time counter on cpu */
270
271 /*
272 * Hole for extension of the self monitor capabilities
273 */
274
275 __u64 __reserved[123]; /* align to 1k */
276
277 /*
278 * Control data for the mmap() data buffer.
279 *
280 * User-space reading the @data_head value should issue an rmb(), on
281 * SMP capable platforms, after reading this value -- see
282 * perf_counter_wakeup().
283 *
284 * When the mapping is PROT_WRITE the @data_tail value should be
285 * written by userspace to reflect the last read data. In this case
286 * the kernel will not over-write unread data.
287 */
288 __u64 data_head; /* head in the data section */
289 __u64 data_tail; /* user-space written tail */
290};
291
292#define PERF_EVENT_MISC_CPUMODE_MASK (3 << 0)
293#define PERF_EVENT_MISC_CPUMODE_UNKNOWN (0 << 0)
294#define PERF_EVENT_MISC_KERNEL (1 << 0)
295#define PERF_EVENT_MISC_USER (2 << 0)
296#define PERF_EVENT_MISC_HYPERVISOR (3 << 0)
297
298struct perf_event_header {
299 __u32 type;
300 __u16 misc;
301 __u16 size;
302};
303
304enum perf_event_type {
305
306 /*
307 * The MMAP events record the PROT_EXEC mappings so that we can
308 * correlate userspace IPs to code. They have the following structure:
309 *
310 * struct {
311 * struct perf_event_header header;
312 *
313 * u32 pid, tid;
314 * u64 addr;
315 * u64 len;
316 * u64 pgoff;
317 * char filename[];
318 * };
319 */
320 PERF_EVENT_MMAP = 1,
321
322 /*
323 * struct {
324 * struct perf_event_header header;
325 * u64 id;
326 * u64 lost;
327 * };
328 */
329 PERF_EVENT_LOST = 2,
330
331 /*
332 * struct {
333 * struct perf_event_header header;
334 *
335 * u32 pid, tid;
336 * char comm[];
337 * };
338 */
339 PERF_EVENT_COMM = 3,
340
341 /*
342 * struct {
343 * struct perf_event_header header;
344 * u32 pid, ppid;
345 * u32 tid, ptid;
346 * u64 time;
347 * };
348 */
349 PERF_EVENT_EXIT = 4,
350
351 /*
352 * struct {
353 * struct perf_event_header header;
354 * u64 time;
355 * u64 id;
356 * u64 stream_id;
357 * };
358 */
359 PERF_EVENT_THROTTLE = 5,
360 PERF_EVENT_UNTHROTTLE = 6,
361
362 /*
363 * struct {
364 * struct perf_event_header header;
365 * u32 pid, ppid;
366 * u32 tid, ptid;
367 * u64 time;
368 * };
369 */
370 PERF_EVENT_FORK = 7,
371
372 /*
373 * struct {
374 * struct perf_event_header header;
375 * u32 pid, tid;
376 *
377 * struct read_format values;
378 * };
379 */
380 PERF_EVENT_READ = 8,
381
382 /*
383 * struct {
384 * struct perf_event_header header;
385 *
386 * { u64 ip; } && PERF_SAMPLE_IP
387 * { u32 pid, tid; } && PERF_SAMPLE_TID
388 * { u64 time; } && PERF_SAMPLE_TIME
389 * { u64 addr; } && PERF_SAMPLE_ADDR
390 * { u64 id; } && PERF_SAMPLE_ID
391 * { u64 stream_id;} && PERF_SAMPLE_STREAM_ID
392 * { u32 cpu, res; } && PERF_SAMPLE_CPU
393 * { u64 period; } && PERF_SAMPLE_PERIOD
394 *
395 * { struct read_format values; } && PERF_SAMPLE_READ
396 *
397 * { u64 nr,
398 * u64 ips[nr]; } && PERF_SAMPLE_CALLCHAIN
399 *
400 * #
401 * # The RAW record below is opaque data wrt the ABI
402 * #
403 * # That is, the ABI doesn't make any promises wrt to
404 * # the stability of its content, it may vary depending
405 * # on event, hardware, kernel version and phase of
406 * # the moon.
407 * #
408 * # In other words, PERF_SAMPLE_RAW contents are not an ABI.
409 * #
410 *
411 * { u32 size;
412 * char data[size];}&& PERF_SAMPLE_RAW
413 * };
414 */
415 PERF_EVENT_SAMPLE = 9,
416
417 PERF_EVENT_MAX, /* non-ABI */
418};
419
420enum perf_callchain_context {
421 PERF_CONTEXT_HV = (__u64)-32,
422 PERF_CONTEXT_KERNEL = (__u64)-128,
423 PERF_CONTEXT_USER = (__u64)-512,
424
425 PERF_CONTEXT_GUEST = (__u64)-2048,
426 PERF_CONTEXT_GUEST_KERNEL = (__u64)-2176,
427 PERF_CONTEXT_GUEST_USER = (__u64)-2560,
428
429 PERF_CONTEXT_MAX = (__u64)-4095,
430};
431
432#define PERF_FLAG_FD_NO_GROUP (1U << 0)
433#define PERF_FLAG_FD_OUTPUT (1U << 1)
434
435/*
436 * In case some app still references the old symbols:
437 */
438
439#define __NR_perf_counter_open __NR_perf_event_open
440
441#define PR_TASK_PERF_COUNTERS_DISABLE PR_TASK_PERF_EVENTS_DISABLE
442#define PR_TASK_PERF_COUNTERS_ENABLE PR_TASK_PERF_EVENTS_ENABLE
443
444#endif /* _LINUX_PERF_COUNTER_H */
kernel/perf_event.c+18−14
@@ -1381,6 +1381,9 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx) · 1380 unmodified lines
1381 if (event->state != PERF_EVENT_STATE_ACTIVE)1381 if (event->state != PERF_EVENT_STATE_ACTIVE)
1382 continue;1382 continue;
1383 1383
1384 if (event->cpu != -1 && event->cpu != smp_processor_id())
1385 continue;
1386
1384 hwc = &event->hw;1387 hwc = &event->hw;
1385 1388
1386 interrupts = hwc->interrupts;1389 interrupts = hwc->interrupts;
@@ -3265,6 +3268,9 @@ static void perf_event_task_output(struct perf_event *event, · 1878 unmodified lines
3265 3268
3266static int perf_event_task_match(struct perf_event *event)3269static int perf_event_task_match(struct perf_event *event)
3267{3270{
3271 if (event->cpu != -1 && event->cpu != smp_processor_id())
3272 return 0;
3273
3268 if (event->attr.comm || event->attr.mmap || event->attr.task)3274 if (event->attr.comm || event->attr.mmap || event->attr.task)
3269 return 1;3275 return 1;
3270 3276
@@ -3290,12 +3296,11 @@ static void perf_event_task_event(struct perf_task_event *task_event) · 19 unmodified lines
3290 rcu_read_lock();3296 rcu_read_lock();
3291 cpuctx = &get_cpu_var(perf_cpu_context);3297 cpuctx = &get_cpu_var(perf_cpu_context);
3292 perf_event_task_ctx(&cpuctx->ctx, task_event);3298 perf_event_task_ctx(&cpuctx->ctx, task_event);
3293 put_cpu_var(perf_cpu_context);
3294
3295 if (!ctx)3299 if (!ctx)
3296 ctx = rcu_dereference(task_event->task->perf_event_ctxp);3300 ctx = rcu_dereference(task_event->task->perf_event_ctxp);
3297 if (ctx)3301 if (ctx)
3298 perf_event_task_ctx(ctx, task_event);3302 perf_event_task_ctx(ctx, task_event);
3303 put_cpu_var(perf_cpu_context);
3299 rcu_read_unlock();3304 rcu_read_unlock();
3300}3305}
3301 3306
@@ -3372,6 +3377,9 @@ static void perf_event_comm_output(struct perf_event *event, · 70 unmodified lines
3372 3377
3373static int perf_event_comm_match(struct perf_event *event)3378static int perf_event_comm_match(struct perf_event *event)
3374{3379{
3380 if (event->cpu != -1 && event->cpu != smp_processor_id())
3381 return 0;
3382
3375 if (event->attr.comm)3383 if (event->attr.comm)
3376 return 1;3384 return 1;
3377 3385
@@ -3408,15 +3416,10 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event) · 30 unmodified lines
3408 rcu_read_lock();3416 rcu_read_lock();
3409 cpuctx = &get_cpu_var(perf_cpu_context);3417 cpuctx = &get_cpu_var(perf_cpu_context);
3410 perf_event_comm_ctx(&cpuctx->ctx, comm_event);3418 perf_event_comm_ctx(&cpuctx->ctx, comm_event);
3411 put_cpu_var(perf_cpu_context);
3412
3413 /*
3414 * doesn't really matter which of the child contexts the
3415 * events ends up in.
3416 */
3417 ctx = rcu_dereference(current->perf_event_ctxp);3419 ctx = rcu_dereference(current->perf_event_ctxp);
3418 if (ctx)3420 if (ctx)
3419 perf_event_comm_ctx(ctx, comm_event);3421 perf_event_comm_ctx(ctx, comm_event);
3422 put_cpu_var(perf_cpu_context);
3420 rcu_read_unlock();3423 rcu_read_unlock();
3421}3424}
3422 3425
@@ -3491,6 +3494,9 @@ static void perf_event_mmap_output(struct perf_event *event, · 68 unmodified lines
3491static int perf_event_mmap_match(struct perf_event *event,3494static int perf_event_mmap_match(struct perf_event *event,
3492 struct perf_mmap_event *mmap_event)3495 struct perf_mmap_event *mmap_event)
3493{3496{
3497 if (event->cpu != -1 && event->cpu != smp_processor_id())
3498 return 0;
3499
3494 if (event->attr.mmap)3500 if (event->attr.mmap)
3495 return 1;3501 return 1;
3496 3502
@@ -3564,15 +3570,10 @@ got_name: · 67 unmodified lines
3564 rcu_read_lock();3570 rcu_read_lock();
3565 cpuctx = &get_cpu_var(perf_cpu_context);3571 cpuctx = &get_cpu_var(perf_cpu_context);
3566 perf_event_mmap_ctx(&cpuctx->ctx, mmap_event);3572 perf_event_mmap_ctx(&cpuctx->ctx, mmap_event);
3567 put_cpu_var(perf_cpu_context);
3568
3569 /*
3570 * doesn't really matter which of the child contexts the
3571 * events ends up in.
3572 */
3573 ctx = rcu_dereference(current->perf_event_ctxp);3573 ctx = rcu_dereference(current->perf_event_ctxp);
3574 if (ctx)3574 if (ctx)
3575 perf_event_mmap_ctx(ctx, mmap_event);3575 perf_event_mmap_ctx(ctx, mmap_event);
3576 put_cpu_var(perf_cpu_context);
3576 rcu_read_unlock();3577 rcu_read_unlock();
3577 3578
3578 kfree(buf);3579 kfree(buf);
@@ -3863,6 +3864,9 @@ static int perf_swevent_match(struct perf_event *event, · 284 unmodified lines
3863 struct perf_sample_data *data,3864 struct perf_sample_data *data,
3864 struct pt_regs *regs)3865 struct pt_regs *regs)
3865{3866{
3867 if (event->cpu != -1 && event->cpu != smp_processor_id())
3868 return 0;
3869
3866 if (!perf_swevent_is_counting(event))3870 if (!perf_swevent_is_counting(event))
3867 return 0;3871 return 0;
3868 3872
kernel/trace/trace_kprobe.c+25−6
@@ -282,6 +282,18 @@ static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs); · 281 unmodified lines
282static int kretprobe_dispatcher(struct kretprobe_instance *ri,282static int kretprobe_dispatcher(struct kretprobe_instance *ri,
283 struct pt_regs *regs);283 struct pt_regs *regs);
284 284
285/* Check the name is good for event/group */
286static int check_event_name(const char *name)
287{
288 if (!isalpha(*name) && *name != '_')
289 return 0;
290 while (*++name != '\0') {
291 if (!isalpha(*name) && !isdigit(*name) && *name != '_')
292 return 0;
293 }
294 return 1;
295}
296
285/*297/*
286 * Allocate new trace_probe and initialize it (including kprobes).298 * Allocate new trace_probe and initialize it (including kprobes).
287 */299 */
@@ -293,10 +305,11 @@ static struct trace_probe *alloc_trace_probe(const char *group, · 5 unmodified lines
293 int nargs, int is_return)305 int nargs, int is_return)
294{306{
295 struct trace_probe *tp;307 struct trace_probe *tp;
308 int ret = -ENOMEM;
296 309
297 tp = kzalloc(SIZEOF_TRACE_PROBE(nargs), GFP_KERNEL);310 tp = kzalloc(SIZEOF_TRACE_PROBE(nargs), GFP_KERNEL);
298 if (!tp)311 if (!tp)
299 return ERR_PTR(-ENOMEM);312 return ERR_PTR(ret);
300 313
301 if (symbol) {314 if (symbol) {
302 tp->symbol = kstrdup(symbol, GFP_KERNEL);315 tp->symbol = kstrdup(symbol, GFP_KERNEL);
@@ -312,14 +325,20 @@ static struct trace_probe *alloc_trace_probe(const char *group, · 9 unmodified lines
312 else325 else
313 tp->rp.kp.pre_handler = kprobe_dispatcher;326 tp->rp.kp.pre_handler = kprobe_dispatcher;
314 327
315 if (!event)328 if (!event || !check_event_name(event)) {
329 ret = -EINVAL;
316 goto error;330 goto error;
331 }
332
317 tp->call.name = kstrdup(event, GFP_KERNEL);333 tp->call.name = kstrdup(event, GFP_KERNEL);
318 if (!tp->call.name)334 if (!tp->call.name)
319 goto error;335 goto error;
320 336
321 if (!group)337 if (!group || !check_event_name(group)) {
338 ret = -EINVAL;
322 goto error;339 goto error;
340 }
341
323 tp->call.system = kstrdup(group, GFP_KERNEL);342 tp->call.system = kstrdup(group, GFP_KERNEL);
324 if (!tp->call.system)343 if (!tp->call.system)
325 goto error;344 goto error;
@@ -330,7 +349,7 @@ error: · 4 unmodified lines
330 kfree(tp->call.name);349 kfree(tp->call.name);
331 kfree(tp->symbol);350 kfree(tp->symbol);
332 kfree(tp);351 kfree(tp);
333 return ERR_PTR(-ENOMEM);352 return ERR_PTR(ret);
334}353}
335 354
336static void free_probe_arg(struct probe_arg *arg)355static void free_probe_arg(struct probe_arg *arg)
@@ -695,10 +714,10 @@ static int create_trace_probe(int argc, char **argv) · 358 unmodified lines
695 if (!event) {714 if (!event) {
696 /* Make a new event name */715 /* Make a new event name */
697 if (symbol)716 if (symbol)
698 snprintf(buf, MAX_EVENT_NAME_LEN, "%c@%s%+ld",717 snprintf(buf, MAX_EVENT_NAME_LEN, "%c_%s_%ld",
699 is_return ? 'r' : 'p', symbol, offset);718 is_return ? 'r' : 'p', symbol, offset);
700 else719 else
701 snprintf(buf, MAX_EVENT_NAME_LEN, "%c@0x%p",720 snprintf(buf, MAX_EVENT_NAME_LEN, "%c_0x%p",
702 is_return ? 'r' : 'p', addr);721 is_return ? 'r' : 'p', addr);
703 event = buf;722 event = buf;
704 }723 }
kernel/trace/trace_sysprof.c+1−0
@@ -93,6 +93,7 @@ static const struct stacktrace_ops backtrace_ops = { · 92 unmodified lines
93 .warning_symbol = backtrace_warning_symbol,93 .warning_symbol = backtrace_warning_symbol,
94 .stack = backtrace_stack,94 .stack = backtrace_stack,
95 .address = backtrace_address,95 .address = backtrace_address,
96 .walk_stack = print_context_stack,
96};97};
97 98
98static int99static int
tools/perf/Makefile+2−1
@@ -487,10 +487,11 @@ else · 486 unmodified lines
487 msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);487 msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
488endif488endif
489 489
490ifneq ($(shell sh -c "(echo '\#include <libdwarf/dwarf.h>'; echo '\#include <libdwarf/libdwarf.h>'; echo 'int main(void) { Dwarf_Debug dbg; Dwarf_Error err; Dwarf_Ranges *rng; dwarf_init(0, DW_DLC_READ, 0, 0, &dbg, &err); dwarf_get_ranges(dbg, 0, &rng, 0, 0, &err); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -ldwarf -lelf -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)490ifneq ($(shell sh -c "(echo '\#ifndef _MIPS_SZLONG'; echo '\#define _MIPS_SZLONG 0'; echo '\#endif'; echo '\#include <dwarf.h>'; echo '\#include <libdwarf.h>'; echo 'int main(void) { Dwarf_Debug dbg; Dwarf_Error err; Dwarf_Ranges *rng; dwarf_init(0, DW_DLC_READ, 0, 0, &dbg, &err); dwarf_get_ranges(dbg, 0, &rng, 0, 0, &err); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/libdwarf -ldwarf -lelf -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
491 msg := $(warning No libdwarf.h found or old libdwarf.h found, disables dwarf support. Please install libdwarf-dev/libdwarf-devel >= 20081231);491 msg := $(warning No libdwarf.h found or old libdwarf.h found, disables dwarf support. Please install libdwarf-dev/libdwarf-devel >= 20081231);
492 BASIC_CFLAGS += -DNO_LIBDWARF492 BASIC_CFLAGS += -DNO_LIBDWARF
493else493else
494 BASIC_CFLAGS += -I/usr/include/libdwarf
494 EXTLIBS += -lelf -ldwarf495 EXTLIBS += -lelf -ldwarf
495 LIB_OBJS += util/probe-finder.o496 LIB_OBJS += util/probe-finder.o
496endif497endif
tools/perf/builtin-probe.c+4−0
@@ -38,6 +38,7 @@ · 37 unmodified lines
38#include "util/strlist.h"38#include "util/strlist.h"
39#include "util/event.h"39#include "util/event.h"
40#include "util/debug.h"40#include "util/debug.h"
41#include "util/debugfs.h"
41#include "util/symbol.h"42#include "util/symbol.h"
42#include "util/thread.h"43#include "util/thread.h"
43#include "util/session.h"44#include "util/session.h"
@@ -205,6 +206,9 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used) · 161 unmodified lines
205 if ((!session.nr_probe && !session.dellist && !session.list_events))206 if ((!session.nr_probe && !session.dellist && !session.list_events))
206 usage_with_options(probe_usage, options);207 usage_with_options(probe_usage, options);
207 208
209 if (debugfs_valid_mountpoint(debugfs_path) < 0)
210 die("Failed to find debugfs path.");
211
208 if (session.list_events) {212 if (session.list_events) {
209 if (session.nr_probe != 0 || session.dellist) {213 if (session.nr_probe != 0 || session.dellist) {
210 pr_warning(" Error: Don't use --list with"214 pr_warning(" Error: Don't use --list with"
tools/perf/builtin-report.c+1−1
@@ -224,7 +224,7 @@ static int __cmd_report(void) · 223 unmodified lines
224 224
225 perf_session__collapse_resort(session);225 perf_session__collapse_resort(session);
226 perf_session__output_resort(session, session->events_stats.total);226 perf_session__output_resort(session, session->events_stats.total);
227 fprintf(stdout, "# Samples: %ld\n#\n", session->events_stats.total);227 fprintf(stdout, "# Samples: %Ld\n#\n", session->events_stats.total);
228 perf_session__fprintf_hists(session, NULL, false, stdout);228 perf_session__fprintf_hists(session, NULL, false, stdout);
229 if (sort_order == default_sort_order &&229 if (sort_order == default_sort_order &&
230 parent_pattern == default_parent_pattern)230 parent_pattern == default_parent_pattern)
tools/perf/util/event.h+2−2
@@ -95,8 +95,8 @@ typedef union event_union { · 94 unmodified lines
95} event_t;95} event_t;
96 96
97struct events_stats {97struct events_stats {
98 unsigned long total;98 u64 total;
99 unsigned long lost;99 u64 lost;
100};100};
101 101
102void event__print_totals(void);102void event__print_totals(void);
tools/perf/util/probe-event.c+15−0
@@ -62,6 +62,18 @@ static int e_snprintf(char *str, size_t size, const char *format, ...) · 61 unmodified lines
62 return ret;62 return ret;
63}63}
64 64
65/* Check the name is good for event/group */
66static bool check_event_name(const char *name)
67{
68 if (!isalpha(*name) && *name != '_')
69 return false;
70 while (*++name != '\0') {
71 if (!isalpha(*name) && !isdigit(*name) && *name != '_')
72 return false;
73 }
74 return true;
75}
76
65/* Parse probepoint definition. */77/* Parse probepoint definition. */
66static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)78static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
67{79{
@@ -82,6 +94,9 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp) · 14 unmodified lines
82 ptr = strchr(arg, ':');94 ptr = strchr(arg, ':');
83 if (ptr) /* Group name is not supported yet. */95 if (ptr) /* Group name is not supported yet. */
84 semantic_error("Group name is not supported yet.");96 semantic_error("Group name is not supported yet.");
97 if (!check_event_name(arg))
98 semantic_error("%s is bad for event name -it must "
99 "follow C symbol-naming rule.", arg);
85 pp->event = strdup(arg);100 pp->event = strdup(arg);
86 arg = tmp;101 arg = tmp;
87 }102 }
tools/perf/util/probe-finder.h+32−27
@@ -1,9 +1,9 @@
1#ifndef _PROBE_FINDER_H1#ifndef _PROBE_FINDER_H
2#define _PROBE_FINDER_H2#define _PROBE_FINDER_H
3 3
4#define MAX_PATH_LEN 2564#define MAX_PATH_LEN 256
5#define MAX_PROBE_BUFFER 10245#define MAX_PROBE_BUFFER 1024
6#define MAX_PROBES 1286#define MAX_PROBES 128
7 7
8static inline int is_c_varname(const char *name)8static inline int is_c_varname(const char *name)
9{9{
@@ -12,48 +12,53 @@ static inline int is_c_varname(const char *name) · 2 unmodified lines
12}12}
13 13
14struct probe_point {14struct probe_point {
15 char *event; /* Event name */15 char *event; /* Event name */
16 char *group; /* Event group */16 char *group; /* Event group */
17 17
18 /* Inputs */18 /* Inputs */
19 char *file; /* File name */19 char *file; /* File name */
20 int line; /* Line number */20 int line; /* Line number */
21 21
22 char *function; /* Function name */22 char *function; /* Function name */
23 int offset; /* Offset bytes */23 int offset; /* Offset bytes */
24 24
25 int nr_args; /* Number of arguments */25 int nr_args; /* Number of arguments */
26 char **args; /* Arguments */26 char **args; /* Arguments */
27 27
28 int retprobe; /* Return probe */28 int retprobe; /* Return probe */
29 29
30 /* Output */30 /* Output */
31 int found; /* Number of found probe points */31 int found; /* Number of found probe points */
32 char *probes[MAX_PROBES]; /* Output buffers (will be allocated)*/32 char *probes[MAX_PROBES]; /* Output buffers (will be allocated)*/
33};33};
34 34
35#ifndef NO_LIBDWARF35#ifndef NO_LIBDWARF
36extern int find_probepoint(int fd, struct probe_point *pp);36extern int find_probepoint(int fd, struct probe_point *pp);
37 37
38#include <libdwarf/dwarf.h>38/* Workaround for undefined _MIPS_SZLONG bug in libdwarf.h: */
39#include <libdwarf/libdwarf.h>39#ifndef _MIPS_SZLONG
40# define _MIPS_SZLONG 0
41#endif
42
43#include <dwarf.h>
44#include <libdwarf.h>
40 45
41struct probe_finder {46struct probe_finder {
42 struct probe_point *pp; /* Target probe point */47 struct probe_point *pp; /* Target probe point */
43 48
44 /* For function searching */49 /* For function searching */
45 Dwarf_Addr addr; /* Address */50 Dwarf_Addr addr; /* Address */
46 Dwarf_Unsigned fno; /* File number */51 Dwarf_Unsigned fno; /* File number */
47 Dwarf_Unsigned lno; /* Line number */52 Dwarf_Unsigned lno; /* Line number */
48 Dwarf_Off inl_offs; /* Inline offset */53 Dwarf_Off inl_offs; /* Inline offset */
49 Dwarf_Die cu_die; /* Current CU */54 Dwarf_Die cu_die; /* Current CU */
50 55
51 /* For variable searching */56 /* For variable searching */
52 Dwarf_Addr cu_base; /* Current CU base address */57 Dwarf_Addr cu_base; /* Current CU base address */
53 Dwarf_Locdesc fbloc; /* Location of Current Frame Base */58 Dwarf_Locdesc fbloc; /* Location of Current Frame Base */
54 const char *var; /* Current variable name */59 const char *var; /* Current variable name */
55 char *buf; /* Current output buffer */60 char *buf; /* Current output buffer */
56 int len; /* Length of output buffer */61 int len; /* Length of output buffer */
57};62};
58#endif /* NO_LIBDWARF */63#endif /* NO_LIBDWARF */
59 64