aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/Kconfig.debug4
-rw-r--r--arch/x86/kernel/cpu/perf_event.c31
-rw-r--r--arch/x86/kernel/dumpstack_64.c33
-rw-r--r--arch/x86/kernel/entry_64.S6
-rw-r--r--arch/x86/kernel/hw_breakpoint.c5
-rw-r--r--arch/x86/kernel/ptrace.c68
-rw-r--r--arch/x86/lib/Makefile4
-rw-r--r--arch/x86/tools/test_get_len.c2
-rw-r--r--include/linux/hw_breakpoint.h40
-rw-r--r--include/linux/perf_event.h41
-rw-r--r--include/linux/sched.h3
-rw-r--r--kernel/hw_breakpoint.c146
-rw-r--r--kernel/perf_event.c75
-rw-r--r--kernel/trace/trace_kprobe.c41
-rw-r--r--kernel/trace/trace_ksym.c5
-rw-r--r--samples/hw_breakpoint/data_breakpoint.c7
-rw-r--r--tools/perf/Documentation/perf-kmem.txt13
-rw-r--r--tools/perf/Documentation/perf-probe.txt21
-rw-r--r--tools/perf/builtin-buildid-list.c2
-rw-r--r--tools/perf/builtin-kmem.c123
-rw-r--r--tools/perf/builtin-probe.c80
-rw-r--r--tools/perf/builtin-report.c39
-rw-r--r--tools/perf/builtin-sched.c212
-rw-r--r--tools/perf/builtin-timechart.c54
-rw-r--r--tools/perf/builtin-trace.c48
-rw-r--r--tools/perf/util/data_map.c4
-rw-r--r--tools/perf/util/data_map.h2
-rw-r--r--tools/perf/util/event.c67
-rw-r--r--tools/perf/util/event.h17
-rw-r--r--tools/perf/util/header.c9
-rw-r--r--tools/perf/util/parse-events.c17
-rw-r--r--tools/perf/util/parse-options.c3
-rw-r--r--tools/perf/util/probe-event.c133
-rw-r--r--tools/perf/util/probe-event.h1
-rw-r--r--tools/perf/util/probe-finder.c2
-rw-r--r--tools/perf/util/symbol.c5
-rw-r--r--tools/perf/util/trace-event-parse.c4
-rw-r--r--tools/perf/util/trace-event-perl.c67
-rw-r--r--tools/perf/util/trace-event-perl.h4
-rw-r--r--tools/perf/util/trace-event-read.c3
40 files changed, 877 insertions, 564 deletions
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index 731318e5ac1d..bc01e3ebfeb2 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -187,8 +187,8 @@ config HAVE_MMIOTRACE_SUPPORT
187 def_bool y 187 def_bool y
188 188
189config X86_DECODER_SELFTEST 189config X86_DECODER_SELFTEST
190 bool "x86 instruction decoder selftest" 190 bool "x86 instruction decoder selftest"
191 depends on DEBUG_KERNEL 191 depends on DEBUG_KERNEL && KPROBES
192 ---help--- 192 ---help---
193 Perform x86 instruction decoder selftests at build time. 193 Perform x86 instruction decoder selftests at build time.
194 This option is useful for checking the sanity of x86 instruction 194 This option is useful for checking the sanity of x86 instruction
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index ab1a8a89b984..45506d5dd8df 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -1632,6 +1632,7 @@ static void intel_pmu_drain_bts_buffer(struct cpu_hw_events *cpuc)
1632 1632
1633 data.period = event->hw.last_period; 1633 data.period = event->hw.last_period;
1634 data.addr = 0; 1634 data.addr = 0;
1635 data.raw = NULL;
1635 regs.ip = 0; 1636 regs.ip = 0;
1636 1637
1637 /* 1638 /*
@@ -1749,6 +1750,7 @@ static int p6_pmu_handle_irq(struct pt_regs *regs)
1749 u64 val; 1750 u64 val;
1750 1751
1751 data.addr = 0; 1752 data.addr = 0;
1753 data.raw = NULL;
1752 1754
1753 cpuc = &__get_cpu_var(cpu_hw_events); 1755 cpuc = &__get_cpu_var(cpu_hw_events);
1754 1756
@@ -1794,6 +1796,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
1794 u64 ack, status; 1796 u64 ack, status;
1795 1797
1796 data.addr = 0; 1798 data.addr = 0;
1799 data.raw = NULL;
1797 1800
1798 cpuc = &__get_cpu_var(cpu_hw_events); 1801 cpuc = &__get_cpu_var(cpu_hw_events);
1799 1802
@@ -1857,6 +1860,7 @@ static int amd_pmu_handle_irq(struct pt_regs *regs)
1857 u64 val; 1860 u64 val;
1858 1861
1859 data.addr = 0; 1862 data.addr = 0;
1863 data.raw = NULL;
1860 1864
1861 cpuc = &__get_cpu_var(cpu_hw_events); 1865 cpuc = &__get_cpu_var(cpu_hw_events);
1862 1866
@@ -2062,12 +2066,6 @@ static __init int p6_pmu_init(void)
2062 2066
2063 x86_pmu = p6_pmu; 2067 x86_pmu = p6_pmu;
2064 2068
2065 if (!cpu_has_apic) {
2066 pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n");
2067 pr_info("no hardware sampling interrupt available.\n");
2068 x86_pmu.apic = 0;
2069 }
2070
2071 return 0; 2069 return 0;
2072} 2070}
2073 2071
@@ -2159,6 +2157,16 @@ static __init int amd_pmu_init(void)
2159 return 0; 2157 return 0;
2160} 2158}
2161 2159
2160static void __init pmu_check_apic(void)
2161{
2162 if (cpu_has_apic)
2163 return;
2164
2165 x86_pmu.apic = 0;
2166 pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n");
2167 pr_info("no hardware sampling interrupt available.\n");
2168}
2169
2162void __init init_hw_perf_events(void) 2170void __init init_hw_perf_events(void)
2163{ 2171{
2164 int err; 2172 int err;
@@ -2180,6 +2188,8 @@ void __init init_hw_perf_events(void)
2180 return; 2188 return;
2181 } 2189 }
2182 2190
2191 pmu_check_apic();
2192
2183 pr_cont("%s PMU driver.\n", x86_pmu.name); 2193 pr_cont("%s PMU driver.\n", x86_pmu.name);
2184 2194
2185 if (x86_pmu.num_events > X86_PMC_MAX_GENERIC) { 2195 if (x86_pmu.num_events > X86_PMC_MAX_GENERIC) {
@@ -2287,7 +2297,7 @@ void callchain_store(struct perf_callchain_entry *entry, u64 ip)
2287 2297
2288static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry); 2298static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry);
2289static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_nmi_entry); 2299static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_nmi_entry);
2290static DEFINE_PER_CPU(int, in_nmi_frame); 2300static DEFINE_PER_CPU(int, in_ignored_frame);
2291 2301
2292 2302
2293static void 2303static void
@@ -2303,8 +2313,9 @@ static void backtrace_warning(void *data, char *msg)
2303 2313
2304static int backtrace_stack(void *data, char *name) 2314static int backtrace_stack(void *data, char *name)
2305{ 2315{
2306 per_cpu(in_nmi_frame, smp_processor_id()) = 2316 per_cpu(in_ignored_frame, smp_processor_id()) =
2307 x86_is_stack_id(NMI_STACK, name); 2317 x86_is_stack_id(NMI_STACK, name) ||
2318 x86_is_stack_id(DEBUG_STACK, name);
2308 2319
2309 return 0; 2320 return 0;
2310} 2321}
@@ -2313,7 +2324,7 @@ static void backtrace_address(void *data, unsigned long addr, int reliable)
2313{ 2324{
2314 struct perf_callchain_entry *entry = data; 2325 struct perf_callchain_entry *entry = data;
2315 2326
2316 if (per_cpu(in_nmi_frame, smp_processor_id())) 2327 if (per_cpu(in_ignored_frame, smp_processor_id()))
2317 return; 2328 return;
2318 2329
2319 if (reliable) 2330 if (reliable)
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
index 8e740934bd1f..b13af53883aa 100644
--- a/arch/x86/kernel/dumpstack_64.c
+++ b/arch/x86/kernel/dumpstack_64.c
@@ -103,6 +103,35 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
103 return NULL; 103 return NULL;
104} 104}
105 105
106static inline int
107in_irq_stack(unsigned long *stack, unsigned long *irq_stack,
108 unsigned long *irq_stack_end)
109{
110 return (stack >= irq_stack && stack < irq_stack_end);
111}
112
113/*
114 * We are returning from the irq stack and go to the previous one.
115 * If the previous stack is also in the irq stack, then bp in the first
116 * frame of the irq stack points to the previous, interrupted one.
117 * Otherwise we have another level of indirection: We first save
118 * the bp of the previous stack, then we switch the stack to the irq one
119 * and save a new bp that links to the previous one.
120 * (See save_args())
121 */
122static inline unsigned long
123fixup_bp_irq_link(unsigned long bp, unsigned long *stack,
124 unsigned long *irq_stack, unsigned long *irq_stack_end)
125{
126#ifdef CONFIG_FRAME_POINTER
127 struct stack_frame *frame = (struct stack_frame *)bp;
128
129 if (!in_irq_stack(stack, irq_stack, irq_stack_end))
130 return (unsigned long)frame->next_frame;
131#endif
132 return bp;
133}
134
106/* 135/*
107 * x86-64 can have up to three kernel stacks: 136 * x86-64 can have up to three kernel stacks:
108 * process stack 137 * process stack
@@ -175,7 +204,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
175 irq_stack = irq_stack_end - 204 irq_stack = irq_stack_end -
176 (IRQ_STACK_SIZE - 64) / sizeof(*irq_stack); 205 (IRQ_STACK_SIZE - 64) / sizeof(*irq_stack);
177 206
178 if (stack >= irq_stack && stack < irq_stack_end) { 207 if (in_irq_stack(stack, irq_stack, irq_stack_end)) {
179 if (ops->stack(data, "IRQ") < 0) 208 if (ops->stack(data, "IRQ") < 0)
180 break; 209 break;
181 bp = print_context_stack(tinfo, stack, bp, 210 bp = print_context_stack(tinfo, stack, bp,
@@ -186,6 +215,8 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
186 * pointer (index -1 to end) in the IRQ stack: 215 * pointer (index -1 to end) in the IRQ stack:
187 */ 216 */
188 stack = (unsigned long *) (irq_stack_end[-1]); 217 stack = (unsigned long *) (irq_stack_end[-1]);
218 bp = fixup_bp_irq_link(bp, stack, irq_stack,
219 irq_stack_end);
189 irq_stack_end = NULL; 220 irq_stack_end = NULL;
190 ops->stack(data, "EOI"); 221 ops->stack(data, "EOI");
191 continue; 222 continue;
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 63bca794c8f9..673f693fb451 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -1076,10 +1076,10 @@ ENTRY(\sym)
1076 TRACE_IRQS_OFF 1076 TRACE_IRQS_OFF
1077 movq %rsp,%rdi /* pt_regs pointer */ 1077 movq %rsp,%rdi /* pt_regs pointer */
1078 xorl %esi,%esi /* no error code */ 1078 xorl %esi,%esi /* no error code */
1079 PER_CPU(init_tss, %rbp) 1079 PER_CPU(init_tss, %r12)
1080 subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp) 1080 subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%r12)
1081 call \do_sym 1081 call \do_sym
1082 addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp) 1082 addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%r12)
1083 jmp paranoid_exit /* %ebx: no swapgs flag */ 1083 jmp paranoid_exit /* %ebx: no swapgs flag */
1084 CFI_ENDPROC 1084 CFI_ENDPROC
1085END(\sym) 1085END(\sym)
diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c
index d42f65ac4927..05d5fec64a94 100644
--- a/arch/x86/kernel/hw_breakpoint.c
+++ b/arch/x86/kernel/hw_breakpoint.c
@@ -362,8 +362,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp,
362 return ret; 362 return ret;
363 } 363 }
364 364
365 if (bp->callback) 365 ret = arch_store_info(bp);
366 ret = arch_store_info(bp);
367 366
368 if (ret < 0) 367 if (ret < 0)
369 return ret; 368 return ret;
@@ -519,7 +518,7 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args)
519 break; 518 break;
520 } 519 }
521 520
522 (bp->callback)(bp, args->regs); 521 perf_bp_event(bp, args->regs);
523 522
524 rcu_read_unlock(); 523 rcu_read_unlock();
525 } 524 }
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 04d182a7cfdb..7079ddaf0731 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -555,7 +555,9 @@ static int genregs_set(struct task_struct *target,
555 return ret; 555 return ret;
556} 556}
557 557
558static void ptrace_triggered(struct perf_event *bp, void *data) 558static void ptrace_triggered(struct perf_event *bp, int nmi,
559 struct perf_sample_data *data,
560 struct pt_regs *regs)
559{ 561{
560 int i; 562 int i;
561 struct thread_struct *thread = &(current->thread); 563 struct thread_struct *thread = &(current->thread);
@@ -593,13 +595,13 @@ static unsigned long ptrace_get_dr7(struct perf_event *bp[])
593 return dr7; 595 return dr7;
594} 596}
595 597
596static struct perf_event * 598static int
597ptrace_modify_breakpoint(struct perf_event *bp, int len, int type, 599ptrace_modify_breakpoint(struct perf_event *bp, int len, int type,
598 struct task_struct *tsk, int disabled) 600 struct task_struct *tsk, int disabled)
599{ 601{
600 int err; 602 int err;
601 int gen_len, gen_type; 603 int gen_len, gen_type;
602 DEFINE_BREAKPOINT_ATTR(attr); 604 struct perf_event_attr attr;
603 605
604 /* 606 /*
605 * We shoud have at least an inactive breakpoint at this 607 * We shoud have at least an inactive breakpoint at this
@@ -607,18 +609,18 @@ ptrace_modify_breakpoint(struct perf_event *bp, int len, int type,
607 * written the address register first 609 * written the address register first
608 */ 610 */
609 if (!bp) 611 if (!bp)
610 return ERR_PTR(-EINVAL); 612 return -EINVAL;
611 613
612 err = arch_bp_generic_fields(len, type, &gen_len, &gen_type); 614 err = arch_bp_generic_fields(len, type, &gen_len, &gen_type);
613 if (err) 615 if (err)
614 return ERR_PTR(err); 616 return err;
615 617
616 attr = bp->attr; 618 attr = bp->attr;
617 attr.bp_len = gen_len; 619 attr.bp_len = gen_len;
618 attr.bp_type = gen_type; 620 attr.bp_type = gen_type;
619 attr.disabled = disabled; 621 attr.disabled = disabled;
620 622
621 return modify_user_hw_breakpoint(bp, &attr, bp->callback, tsk); 623 return modify_user_hw_breakpoint(bp, &attr);
622} 624}
623 625
624/* 626/*
@@ -656,28 +658,17 @@ restore:
656 if (!second_pass) 658 if (!second_pass)
657 continue; 659 continue;
658 660
659 thread->ptrace_bps[i] = NULL; 661 rc = ptrace_modify_breakpoint(bp, len, type,
660 bp = ptrace_modify_breakpoint(bp, len, type,
661 tsk, 1); 662 tsk, 1);
662 if (IS_ERR(bp)) { 663 if (rc)
663 rc = PTR_ERR(bp);
664 thread->ptrace_bps[i] = NULL;
665 break; 664 break;
666 }
667 thread->ptrace_bps[i] = bp;
668 } 665 }
669 continue; 666 continue;
670 } 667 }
671 668
672 bp = ptrace_modify_breakpoint(bp, len, type, tsk, 0); 669 rc = ptrace_modify_breakpoint(bp, len, type, tsk, 0);
673 670 if (rc)
674 /* Incorrect bp, or we have a bug in bp API */
675 if (IS_ERR(bp)) {
676 rc = PTR_ERR(bp);
677 thread->ptrace_bps[i] = NULL;
678 break; 671 break;
679 }
680 thread->ptrace_bps[i] = bp;
681 } 672 }
682 /* 673 /*
683 * Make a second pass to free the remaining unused breakpoints 674 * Make a second pass to free the remaining unused breakpoints
@@ -721,9 +712,10 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr,
721{ 712{
722 struct perf_event *bp; 713 struct perf_event *bp;
723 struct thread_struct *t = &tsk->thread; 714 struct thread_struct *t = &tsk->thread;
724 DEFINE_BREAKPOINT_ATTR(attr); 715 struct perf_event_attr attr;
725 716
726 if (!t->ptrace_bps[nr]) { 717 if (!t->ptrace_bps[nr]) {
718 hw_breakpoint_init(&attr);
727 /* 719 /*
728 * Put stub len and type to register (reserve) an inactive but 720 * Put stub len and type to register (reserve) an inactive but
729 * correct bp 721 * correct bp
@@ -734,26 +726,32 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr,
734 attr.disabled = 1; 726 attr.disabled = 1;
735 727
736 bp = register_user_hw_breakpoint(&attr, ptrace_triggered, tsk); 728 bp = register_user_hw_breakpoint(&attr, ptrace_triggered, tsk);
729
730 /*
731 * CHECKME: the previous code returned -EIO if the addr wasn't
732 * a valid task virtual addr. The new one will return -EINVAL in
733 * this case.
734 * -EINVAL may be what we want for in-kernel breakpoints users,
735 * but -EIO looks better for ptrace, since we refuse a register
736 * writing for the user. And anyway this is the previous
737 * behaviour.
738 */
739 if (IS_ERR(bp))
740 return PTR_ERR(bp);
741
742 t->ptrace_bps[nr] = bp;
737 } else { 743 } else {
744 int err;
745
738 bp = t->ptrace_bps[nr]; 746 bp = t->ptrace_bps[nr];
739 t->ptrace_bps[nr] = NULL;
740 747
741 attr = bp->attr; 748 attr = bp->attr;
742 attr.bp_addr = addr; 749 attr.bp_addr = addr;
743 bp = modify_user_hw_breakpoint(bp, &attr, bp->callback, tsk); 750 err = modify_user_hw_breakpoint(bp, &attr);
751 if (err)
752 return err;
744 } 753 }
745 /*
746 * CHECKME: the previous code returned -EIO if the addr wasn't a
747 * valid task virtual addr. The new one will return -EINVAL in this
748 * case.
749 * -EINVAL may be what we want for in-kernel breakpoints users, but
750 * -EIO looks better for ptrace, since we refuse a register writing
751 * for the user. And anyway this is the previous behaviour.
752 */
753 if (IS_ERR(bp))
754 return PTR_ERR(bp);
755 754
756 t->ptrace_bps[nr] = bp;
757 755
758 return 0; 756 return 0;
759} 757}
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index a2d6472895fb..45b20e486c2f 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -5,7 +5,7 @@
5inat_tables_script = $(srctree)/arch/x86/tools/gen-insn-attr-x86.awk 5inat_tables_script = $(srctree)/arch/x86/tools/gen-insn-attr-x86.awk
6inat_tables_maps = $(srctree)/arch/x86/lib/x86-opcode-map.txt 6inat_tables_maps = $(srctree)/arch/x86/lib/x86-opcode-map.txt
7quiet_cmd_inat_tables = GEN $@ 7quiet_cmd_inat_tables = GEN $@
8 cmd_inat_tables = $(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@ 8 cmd_inat_tables = $(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@ || rm -f $@
9 9
10$(obj)/inat-tables.c: $(inat_tables_script) $(inat_tables_maps) 10$(obj)/inat-tables.c: $(inat_tables_script) $(inat_tables_maps)
11 $(call cmd,inat_tables) 11 $(call cmd,inat_tables)
@@ -20,7 +20,7 @@ lib-y := delay.o
20lib-y += thunk_$(BITS).o 20lib-y += thunk_$(BITS).o
21lib-y += usercopy_$(BITS).o getuser.o putuser.o 21lib-y += usercopy_$(BITS).o getuser.o putuser.o
22lib-y += memcpy_$(BITS).o 22lib-y += memcpy_$(BITS).o
23lib-y += insn.o inat.o 23lib-$(CONFIG_KPROBES) += insn.o inat.o
24 24
25obj-y += msr-reg.o msr-reg-export.o 25obj-y += msr-reg.o msr-reg-export.o
26 26
diff --git a/arch/x86/tools/test_get_len.c b/arch/x86/tools/test_get_len.c
index d8214dc03fa7..bee8d6ac2691 100644
--- a/arch/x86/tools/test_get_len.c
+++ b/arch/x86/tools/test_get_len.c
@@ -113,7 +113,7 @@ int main(int argc, char **argv)
113 char line[BUFSIZE], sym[BUFSIZE] = "<unknown>"; 113 char line[BUFSIZE], sym[BUFSIZE] = "<unknown>";
114 unsigned char insn_buf[16]; 114 unsigned char insn_buf[16];
115 struct insn insn; 115 struct insn insn;
116 int insns = 0, c; 116 int insns = 0;
117 int warnings = 0; 117 int warnings = 0;
118 118
119 parse_args(argc, argv); 119 parse_args(argc, argv);
diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h
index a03daed08c59..69f07a9f1277 100644
--- a/include/linux/hw_breakpoint.h
+++ b/include/linux/hw_breakpoint.h
@@ -20,19 +20,18 @@ enum {
20 20
21#ifdef CONFIG_HAVE_HW_BREAKPOINT 21#ifdef CONFIG_HAVE_HW_BREAKPOINT
22 22
23/* As it's for in-kernel or ptrace use, we want it to be pinned */
24#define DEFINE_BREAKPOINT_ATTR(name) \
25struct perf_event_attr name = { \
26 .type = PERF_TYPE_BREAKPOINT, \
27 .size = sizeof(name), \
28 .pinned = 1, \
29};
30
31static inline void hw_breakpoint_init(struct perf_event_attr *attr) 23static inline void hw_breakpoint_init(struct perf_event_attr *attr)
32{ 24{
25 memset(attr, 0, sizeof(*attr));
26
33 attr->type = PERF_TYPE_BREAKPOINT; 27 attr->type = PERF_TYPE_BREAKPOINT;
34 attr->size = sizeof(*attr); 28 attr->size = sizeof(*attr);
29 /*
30 * As it's for in-kernel or ptrace use, we want it to be pinned
31 * and to call its callback every hits.
32 */
35 attr->pinned = 1; 33 attr->pinned = 1;
34 attr->sample_period = 1;
36} 35}
37 36
38static inline unsigned long hw_breakpoint_addr(struct perf_event *bp) 37static inline unsigned long hw_breakpoint_addr(struct perf_event *bp)
@@ -52,27 +51,24 @@ static inline int hw_breakpoint_len(struct perf_event *bp)
52 51
53extern struct perf_event * 52extern struct perf_event *
54register_user_hw_breakpoint(struct perf_event_attr *attr, 53register_user_hw_breakpoint(struct perf_event_attr *attr,
55 perf_callback_t triggered, 54 perf_overflow_handler_t triggered,
56 struct task_struct *tsk); 55 struct task_struct *tsk);
57 56
58/* FIXME: only change from the attr, and don't unregister */ 57/* FIXME: only change from the attr, and don't unregister */
59extern struct perf_event * 58extern int
60modify_user_hw_breakpoint(struct perf_event *bp, 59modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr);
61 struct perf_event_attr *attr,
62 perf_callback_t triggered,
63 struct task_struct *tsk);
64 60
65/* 61/*
66 * Kernel breakpoints are not associated with any particular thread. 62 * Kernel breakpoints are not associated with any particular thread.
67 */ 63 */
68extern struct perf_event * 64extern struct perf_event *
69register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, 65register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr,
70 perf_callback_t triggered, 66 perf_overflow_handler_t triggered,
71 int cpu); 67 int cpu);
72 68
73extern struct perf_event ** 69extern struct perf_event **
74register_wide_hw_breakpoint(struct perf_event_attr *attr, 70register_wide_hw_breakpoint(struct perf_event_attr *attr,
75 perf_callback_t triggered); 71 perf_overflow_handler_t triggered);
76 72
77extern int register_perf_hw_breakpoint(struct perf_event *bp); 73extern int register_perf_hw_breakpoint(struct perf_event *bp);
78extern int __register_perf_hw_breakpoint(struct perf_event *bp); 74extern int __register_perf_hw_breakpoint(struct perf_event *bp);
@@ -93,20 +89,18 @@ static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp)
93 89
94static inline struct perf_event * 90static inline struct perf_event *
95register_user_hw_breakpoint(struct perf_event_attr *attr, 91register_user_hw_breakpoint(struct perf_event_attr *attr,
96 perf_callback_t triggered, 92 perf_overflow_handler_t triggered,
97 struct task_struct *tsk) { return NULL; } 93 struct task_struct *tsk) { return NULL; }
98static inline struct perf_event * 94static inline int
99modify_user_hw_breakpoint(struct perf_event *bp, 95modify_user_hw_breakpoint(struct perf_event *bp,
100 struct perf_event_attr *attr, 96 struct perf_event_attr *attr) { return NULL; }
101 perf_callback_t triggered,
102 struct task_struct *tsk) { return NULL; }
103static inline struct perf_event * 97static inline struct perf_event *
104register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, 98register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr,
105 perf_callback_t triggered, 99 perf_overflow_handler_t triggered,
106 int cpu) { return NULL; } 100 int cpu) { return NULL; }
107static inline struct perf_event ** 101static inline struct perf_event **
108register_wide_hw_breakpoint(struct perf_event_attr *attr, 102register_wide_hw_breakpoint(struct perf_event_attr *attr,
109 perf_callback_t triggered) { return NULL; } 103 perf_overflow_handler_t triggered) { return NULL; }
110static inline int 104static inline int
111register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } 105register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; }
112static inline int 106static inline int
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 43adbd7f0010..64a53f74c9a9 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -18,10 +18,6 @@
18#include <linux/ioctl.h> 18#include <linux/ioctl.h>
19#include <asm/byteorder.h> 19#include <asm/byteorder.h>
20 20
21#ifdef CONFIG_HAVE_HW_BREAKPOINT
22#include <asm/hw_breakpoint.h>
23#endif
24
25/* 21/*
26 * User-space ABI bits: 22 * User-space ABI bits:
27 */ 23 */
@@ -215,12 +211,12 @@ struct perf_event_attr {
215 __u32 wakeup_watermark; /* bytes before wakeup */ 211 __u32 wakeup_watermark; /* bytes before wakeup */
216 }; 212 };
217 213
218 union { 214 struct { /* Hardware breakpoint info */
219 struct { /* Hardware breakpoint info */ 215 __u64 bp_addr;
220 __u64 bp_addr; 216 __u32 bp_type;
221 __u32 bp_type; 217 __u32 bp_len;
222 __u32 bp_len; 218 __u64 __bp_reserved_1;
223 }; 219 __u64 __bp_reserved_2;
224 }; 220 };
225 221
226 __u32 __reserved_2; 222 __u32 __reserved_2;
@@ -451,6 +447,10 @@ enum perf_callchain_context {
451# include <asm/perf_event.h> 447# include <asm/perf_event.h>
452#endif 448#endif
453 449
450#ifdef CONFIG_HAVE_HW_BREAKPOINT
451#include <asm/hw_breakpoint.h>
452#endif
453
454#include <linux/list.h> 454#include <linux/list.h>
455#include <linux/mutex.h> 455#include <linux/mutex.h>
456#include <linux/rculist.h> 456#include <linux/rculist.h>
@@ -565,10 +565,12 @@ struct perf_pending_entry {
565 void (*func)(struct perf_pending_entry *); 565 void (*func)(struct perf_pending_entry *);
566}; 566};
567 567
568typedef void (*perf_callback_t)(struct perf_event *, void *);
569
570struct perf_sample_data; 568struct perf_sample_data;
571 569
570typedef void (*perf_overflow_handler_t)(struct perf_event *, int,
571 struct perf_sample_data *,
572 struct pt_regs *regs);
573
572/** 574/**
573 * struct perf_event - performance event kernel representation: 575 * struct perf_event - performance event kernel representation:
574 */ 576 */
@@ -660,18 +662,12 @@ struct perf_event {
660 struct pid_namespace *ns; 662 struct pid_namespace *ns;
661 u64 id; 663 u64 id;
662 664
663 void (*overflow_handler)(struct perf_event *event, 665 perf_overflow_handler_t overflow_handler;
664 int nmi, struct perf_sample_data *data,
665 struct pt_regs *regs);
666 666
667#ifdef CONFIG_EVENT_PROFILE 667#ifdef CONFIG_EVENT_PROFILE
668 struct event_filter *filter; 668 struct event_filter *filter;
669#endif 669#endif
670 670
671 perf_callback_t callback;
672
673 perf_callback_t event_callback;
674
675#endif /* CONFIG_PERF_EVENTS */ 671#endif /* CONFIG_PERF_EVENTS */
676}; 672};
677 673
@@ -781,7 +777,7 @@ extern struct perf_event *
781perf_event_create_kernel_counter(struct perf_event_attr *attr, 777perf_event_create_kernel_counter(struct perf_event_attr *attr,
782 int cpu, 778 int cpu,
783 pid_t pid, 779 pid_t pid,
784 perf_callback_t callback); 780 perf_overflow_handler_t callback);
785extern u64 perf_event_read_value(struct perf_event *event, 781extern u64 perf_event_read_value(struct perf_event *event,
786 u64 *enabled, u64 *running); 782 u64 *enabled, u64 *running);
787 783
@@ -876,6 +872,8 @@ extern void perf_output_copy(struct perf_output_handle *handle,
876 const void *buf, unsigned int len); 872 const void *buf, unsigned int len);
877extern int perf_swevent_get_recursion_context(void); 873extern int perf_swevent_get_recursion_context(void);
878extern void perf_swevent_put_recursion_context(int rctx); 874extern void perf_swevent_put_recursion_context(int rctx);
875extern void perf_event_enable(struct perf_event *event);
876extern void perf_event_disable(struct perf_event *event);
879#else 877#else
880static inline void 878static inline void
881perf_event_task_sched_in(struct task_struct *task, int cpu) { } 879perf_event_task_sched_in(struct task_struct *task, int cpu) { }
@@ -906,7 +904,8 @@ static inline void perf_event_fork(struct task_struct *tsk) { }
906static inline void perf_event_init(void) { } 904static inline void perf_event_init(void) { }
907static inline int perf_swevent_get_recursion_context(void) { return -1; } 905static inline int perf_swevent_get_recursion_context(void) { return -1; }
908static inline void perf_swevent_put_recursion_context(int rctx) { } 906static inline void perf_swevent_put_recursion_context(int rctx) { }
909 907static inline void perf_event_enable(struct perf_event *event) { }
908static inline void perf_event_disable(struct perf_event *event) { }
910#endif 909#endif
911 910
912#define perf_output_put(handle, x) \ 911#define perf_output_put(handle, x) \
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 89115ec7d43f..3f4fa73b512a 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1840,7 +1840,8 @@ static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask)
1840extern int sched_clock_stable; 1840extern int sched_clock_stable;
1841#endif 1841#endif
1842 1842
1843extern unsigned long long sched_clock(void); 1843/* ftrace calls sched_clock() directly */
1844extern unsigned long long notrace sched_clock(void);
1844 1845
1845extern void sched_clock_init(void); 1846extern void sched_clock_init(void);
1846extern u64 sched_clock_cpu(int cpu); 1847extern u64 sched_clock_cpu(int cpu);
diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c
index cf5ee1628411..366eedf949c0 100644
--- a/kernel/hw_breakpoint.c
+++ b/kernel/hw_breakpoint.c
@@ -52,7 +52,7 @@
52static DEFINE_PER_CPU(unsigned int, nr_cpu_bp_pinned); 52static DEFINE_PER_CPU(unsigned int, nr_cpu_bp_pinned);
53 53
54/* Number of pinned task breakpoints in a cpu */ 54/* Number of pinned task breakpoints in a cpu */
55static DEFINE_PER_CPU(unsigned int, task_bp_pinned[HBP_NUM]); 55static DEFINE_PER_CPU(unsigned int, nr_task_bp_pinned[HBP_NUM]);
56 56
57/* Number of non-pinned cpu/task breakpoints in a cpu */ 57/* Number of non-pinned cpu/task breakpoints in a cpu */
58static DEFINE_PER_CPU(unsigned int, nr_bp_flexible); 58static DEFINE_PER_CPU(unsigned int, nr_bp_flexible);
@@ -73,7 +73,7 @@ static DEFINE_MUTEX(nr_bp_mutex);
73static unsigned int max_task_bp_pinned(int cpu) 73static unsigned int max_task_bp_pinned(int cpu)
74{ 74{
75 int i; 75 int i;
76 unsigned int *tsk_pinned = per_cpu(task_bp_pinned, cpu); 76 unsigned int *tsk_pinned = per_cpu(nr_task_bp_pinned, cpu);
77 77
78 for (i = HBP_NUM -1; i >= 0; i--) { 78 for (i = HBP_NUM -1; i >= 0; i--) {
79 if (tsk_pinned[i] > 0) 79 if (tsk_pinned[i] > 0)
@@ -83,15 +83,51 @@ static unsigned int max_task_bp_pinned(int cpu)
83 return 0; 83 return 0;
84} 84}
85 85
86static int task_bp_pinned(struct task_struct *tsk)
87{
88 struct perf_event_context *ctx = tsk->perf_event_ctxp;
89 struct list_head *list;
90 struct perf_event *bp;
91 unsigned long flags;
92 int count = 0;
93
94 if (WARN_ONCE(!ctx, "No perf context for this task"))
95 return 0;
96
97 list = &ctx->event_list;
98
99 spin_lock_irqsave(&ctx->lock, flags);
100
101 /*
102 * The current breakpoint counter is not included in the list
103 * at the open() callback time
104 */
105 list_for_each_entry(bp, list, event_entry) {
106 if (bp->attr.type == PERF_TYPE_BREAKPOINT)
107 count++;
108 }
109
110 spin_unlock_irqrestore(&ctx->lock, flags);
111
112 return count;
113}
114
86/* 115/*
87 * Report the number of pinned/un-pinned breakpoints we have in 116 * Report the number of pinned/un-pinned breakpoints we have in
88 * a given cpu (cpu > -1) or in all of them (cpu = -1). 117 * a given cpu (cpu > -1) or in all of them (cpu = -1).
89 */ 118 */
90static void fetch_bp_busy_slots(struct bp_busy_slots *slots, int cpu) 119static void
120fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp)
91{ 121{
122 int cpu = bp->cpu;
123 struct task_struct *tsk = bp->ctx->task;
124
92 if (cpu >= 0) { 125 if (cpu >= 0) {
93 slots->pinned = per_cpu(nr_cpu_bp_pinned, cpu); 126 slots->pinned = per_cpu(nr_cpu_bp_pinned, cpu);
94 slots->pinned += max_task_bp_pinned(cpu); 127 if (!tsk)
128 slots->pinned += max_task_bp_pinned(cpu);
129 else
130 slots->pinned += task_bp_pinned(tsk);
95 slots->flexible = per_cpu(nr_bp_flexible, cpu); 131 slots->flexible = per_cpu(nr_bp_flexible, cpu);
96 132
97 return; 133 return;
@@ -101,7 +137,10 @@ static void fetch_bp_busy_slots(struct bp_busy_slots *slots, int cpu)
101 unsigned int nr; 137 unsigned int nr;
102 138
103 nr = per_cpu(nr_cpu_bp_pinned, cpu); 139 nr = per_cpu(nr_cpu_bp_pinned, cpu);
104 nr += max_task_bp_pinned(cpu); 140 if (!tsk)
141 nr += max_task_bp_pinned(cpu);
142 else
143 nr += task_bp_pinned(tsk);
105 144
106 if (nr > slots->pinned) 145 if (nr > slots->pinned)
107 slots->pinned = nr; 146 slots->pinned = nr;
@@ -118,35 +157,12 @@ static void fetch_bp_busy_slots(struct bp_busy_slots *slots, int cpu)
118 */ 157 */
119static void toggle_bp_task_slot(struct task_struct *tsk, int cpu, bool enable) 158static void toggle_bp_task_slot(struct task_struct *tsk, int cpu, bool enable)
120{ 159{
121 int count = 0;
122 struct perf_event *bp;
123 struct perf_event_context *ctx = tsk->perf_event_ctxp;
124 unsigned int *tsk_pinned; 160 unsigned int *tsk_pinned;
125 struct list_head *list; 161 int count = 0;
126 unsigned long flags;
127
128 if (WARN_ONCE(!ctx, "No perf context for this task"))
129 return;
130
131 list = &ctx->event_list;
132
133 spin_lock_irqsave(&ctx->lock, flags);
134
135 /*
136 * The current breakpoint counter is not included in the list
137 * at the open() callback time
138 */
139 list_for_each_entry(bp, list, event_entry) {
140 if (bp->attr.type == PERF_TYPE_BREAKPOINT)
141 count++;
142 }
143 162
144 spin_unlock_irqrestore(&ctx->lock, flags); 163 count = task_bp_pinned(tsk);
145 164
146 if (WARN_ONCE(count < 0, "No breakpoint counter found in the counter list")) 165 tsk_pinned = per_cpu(nr_task_bp_pinned, cpu);
147 return;
148
149 tsk_pinned = per_cpu(task_bp_pinned, cpu);
150 if (enable) { 166 if (enable) {
151 tsk_pinned[count]++; 167 tsk_pinned[count]++;
152 if (count > 0) 168 if (count > 0)
@@ -193,7 +209,7 @@ static void toggle_bp_slot(struct perf_event *bp, bool enable)
193 * - If attached to a single cpu, check: 209 * - If attached to a single cpu, check:
194 * 210 *
195 * (per_cpu(nr_bp_flexible, cpu) || (per_cpu(nr_cpu_bp_pinned, cpu) 211 * (per_cpu(nr_bp_flexible, cpu) || (per_cpu(nr_cpu_bp_pinned, cpu)
196 * + max(per_cpu(task_bp_pinned, cpu)))) < HBP_NUM 212 * + max(per_cpu(nr_task_bp_pinned, cpu)))) < HBP_NUM
197 * 213 *
198 * -> If there are already non-pinned counters in this cpu, it means 214 * -> If there are already non-pinned counters in this cpu, it means
199 * there is already a free slot for them. 215 * there is already a free slot for them.
@@ -204,7 +220,7 @@ static void toggle_bp_slot(struct perf_event *bp, bool enable)
204 * - If attached to every cpus, check: 220 * - If attached to every cpus, check:
205 * 221 *
206 * (per_cpu(nr_bp_flexible, *) || (max(per_cpu(nr_cpu_bp_pinned, *)) 222 * (per_cpu(nr_bp_flexible, *) || (max(per_cpu(nr_cpu_bp_pinned, *))
207 * + max(per_cpu(task_bp_pinned, *)))) < HBP_NUM 223 * + max(per_cpu(nr_task_bp_pinned, *)))) < HBP_NUM
208 * 224 *
209 * -> This is roughly the same, except we check the number of per cpu 225 * -> This is roughly the same, except we check the number of per cpu
210 * bp for every cpu and we keep the max one. Same for the per tasks 226 * bp for every cpu and we keep the max one. Same for the per tasks
@@ -216,7 +232,7 @@ static void toggle_bp_slot(struct perf_event *bp, bool enable)
216 * - If attached to a single cpu, check: 232 * - If attached to a single cpu, check:
217 * 233 *
218 * ((per_cpu(nr_bp_flexible, cpu) > 1) + per_cpu(nr_cpu_bp_pinned, cpu) 234 * ((per_cpu(nr_bp_flexible, cpu) > 1) + per_cpu(nr_cpu_bp_pinned, cpu)
219 * + max(per_cpu(task_bp_pinned, cpu))) < HBP_NUM 235 * + max(per_cpu(nr_task_bp_pinned, cpu))) < HBP_NUM
220 * 236 *
221 * -> Same checks as before. But now the nr_bp_flexible, if any, must keep 237 * -> Same checks as before. But now the nr_bp_flexible, if any, must keep
222 * one register at least (or they will never be fed). 238 * one register at least (or they will never be fed).
@@ -224,7 +240,7 @@ static void toggle_bp_slot(struct perf_event *bp, bool enable)
224 * - If attached to every cpus, check: 240 * - If attached to every cpus, check:
225 * 241 *
226 * ((per_cpu(nr_bp_flexible, *) > 1) + max(per_cpu(nr_cpu_bp_pinned, *)) 242 * ((per_cpu(nr_bp_flexible, *) > 1) + max(per_cpu(nr_cpu_bp_pinned, *))
227 * + max(per_cpu(task_bp_pinned, *))) < HBP_NUM 243 * + max(per_cpu(nr_task_bp_pinned, *))) < HBP_NUM
228 */ 244 */
229int reserve_bp_slot(struct perf_event *bp) 245int reserve_bp_slot(struct perf_event *bp)
230{ 246{
@@ -233,7 +249,7 @@ int reserve_bp_slot(struct perf_event *bp)
233 249
234 mutex_lock(&nr_bp_mutex); 250 mutex_lock(&nr_bp_mutex);
235 251
236 fetch_bp_busy_slots(&slots, bp->cpu); 252 fetch_bp_busy_slots(&slots, bp);
237 253
238 /* Flexible counters need to keep at least one slot */ 254 /* Flexible counters need to keep at least one slot */
239 if (slots.pinned + (!!slots.flexible) == HBP_NUM) { 255 if (slots.pinned + (!!slots.flexible) == HBP_NUM) {
@@ -259,7 +275,7 @@ void release_bp_slot(struct perf_event *bp)
259} 275}
260 276
261 277
262int __register_perf_hw_breakpoint(struct perf_event *bp) 278int register_perf_hw_breakpoint(struct perf_event *bp)
263{ 279{
264 int ret; 280 int ret;
265 281
@@ -276,19 +292,12 @@ int __register_perf_hw_breakpoint(struct perf_event *bp)
276 * This is a quick hack that will be removed soon, once we remove 292 * This is a quick hack that will be removed soon, once we remove
277 * the tmp breakpoints from ptrace 293 * the tmp breakpoints from ptrace
278 */ 294 */
279 if (!bp->attr.disabled || bp->callback == perf_bp_event) 295 if (!bp->attr.disabled || !bp->overflow_handler)
280 ret = arch_validate_hwbkpt_settings(bp, bp->ctx->task); 296 ret = arch_validate_hwbkpt_settings(bp, bp->ctx->task);
281 297
282 return ret; 298 return ret;
283} 299}
284 300
285int register_perf_hw_breakpoint(struct perf_event *bp)
286{
287 bp->callback = perf_bp_event;
288
289 return __register_perf_hw_breakpoint(bp);
290}
291
292/** 301/**
293 * register_user_hw_breakpoint - register a hardware breakpoint for user space 302 * register_user_hw_breakpoint - register a hardware breakpoint for user space
294 * @attr: breakpoint attributes 303 * @attr: breakpoint attributes
@@ -297,7 +306,7 @@ int register_perf_hw_breakpoint(struct perf_event *bp)
297 */ 306 */
298struct perf_event * 307struct perf_event *
299register_user_hw_breakpoint(struct perf_event_attr *attr, 308register_user_hw_breakpoint(struct perf_event_attr *attr,
300 perf_callback_t triggered, 309 perf_overflow_handler_t triggered,
301 struct task_struct *tsk) 310 struct task_struct *tsk)
302{ 311{
303 return perf_event_create_kernel_counter(attr, -1, tsk->pid, triggered); 312 return perf_event_create_kernel_counter(attr, -1, tsk->pid, triggered);
@@ -311,19 +320,40 @@ EXPORT_SYMBOL_GPL(register_user_hw_breakpoint);
311 * @triggered: callback to trigger when we hit the breakpoint 320 * @triggered: callback to trigger when we hit the breakpoint
312 * @tsk: pointer to 'task_struct' of the process to which the address belongs 321 * @tsk: pointer to 'task_struct' of the process to which the address belongs
313 */ 322 */
314struct perf_event * 323int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr)
315modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr,
316 perf_callback_t triggered,
317 struct task_struct *tsk)
318{ 324{
319 /* 325 u64 old_addr = bp->attr.bp_addr;
320 * FIXME: do it without unregistering 326 int old_type = bp->attr.bp_type;
321 * - We don't want to lose our slot 327 int old_len = bp->attr.bp_len;
322 * - If the new bp is incorrect, don't lose the older one 328 int err = 0;
323 */
324 unregister_hw_breakpoint(bp);
325 329
326 return perf_event_create_kernel_counter(attr, -1, tsk->pid, triggered); 330 perf_event_disable(bp);
331
332 bp->attr.bp_addr = attr->bp_addr;
333 bp->attr.bp_type = attr->bp_type;
334 bp->attr.bp_len = attr->bp_len;
335
336 if (attr->disabled)
337 goto end;
338
339 err = arch_validate_hwbkpt_settings(bp, bp->ctx->task);
340 if (!err)
341 perf_event_enable(bp);
342
343 if (err) {
344 bp->attr.bp_addr = old_addr;
345 bp->attr.bp_type = old_type;
346 bp->attr.bp_len = old_len;
347 if (!bp->attr.disabled)
348 perf_event_enable(bp);
349
350 return err;
351 }
352
353end:
354 bp->attr.disabled = attr->disabled;
355
356 return 0;
327} 357}
328EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint); 358EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint);
329 359
@@ -348,7 +378,7 @@ EXPORT_SYMBOL_GPL(unregister_hw_breakpoint);
348 */ 378 */
349struct perf_event ** 379struct perf_event **
350register_wide_hw_breakpoint(struct perf_event_attr *attr, 380register_wide_hw_breakpoint(struct perf_event_attr *attr,
351 perf_callback_t triggered) 381 perf_overflow_handler_t triggered)
352{ 382{
353 struct perf_event **cpu_events, **pevent, *bp; 383 struct perf_event **cpu_events, **pevent, *bp;
354 long err; 384 long err;
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 40a996ec39fa..e73e53c7582f 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -36,7 +36,7 @@
36/* 36/*
37 * Each CPU has a list of per CPU events: 37 * Each CPU has a list of per CPU events:
38 */ 38 */
39DEFINE_PER_CPU(struct perf_cpu_context, perf_cpu_context); 39static DEFINE_PER_CPU(struct perf_cpu_context, perf_cpu_context);
40 40
41int perf_max_events __read_mostly = 1; 41int perf_max_events __read_mostly = 1;
42static int perf_reserved_percpu __read_mostly; 42static int perf_reserved_percpu __read_mostly;
@@ -567,7 +567,7 @@ static void __perf_event_disable(void *info)
567 * is the current context on this CPU and preemption is disabled, 567 * is the current context on this CPU and preemption is disabled,
568 * hence we can't get into perf_event_task_sched_out for this context. 568 * hence we can't get into perf_event_task_sched_out for this context.
569 */ 569 */
570static void perf_event_disable(struct perf_event *event) 570void perf_event_disable(struct perf_event *event)
571{ 571{
572 struct perf_event_context *ctx = event->ctx; 572 struct perf_event_context *ctx = event->ctx;
573 struct task_struct *task = ctx->task; 573 struct task_struct *task = ctx->task;
@@ -971,7 +971,7 @@ static void __perf_event_enable(void *info)
971 * perf_event_for_each_child or perf_event_for_each as described 971 * perf_event_for_each_child or perf_event_for_each as described
972 * for perf_event_disable. 972 * for perf_event_disable.
973 */ 973 */
974static void perf_event_enable(struct perf_event *event) 974void perf_event_enable(struct perf_event *event)
975{ 975{
976 struct perf_event_context *ctx = event->ctx; 976 struct perf_event_context *ctx = event->ctx;
977 struct task_struct *task = ctx->task; 977 struct task_struct *task = ctx->task;
@@ -1579,7 +1579,6 @@ static void
1579__perf_event_init_context(struct perf_event_context *ctx, 1579__perf_event_init_context(struct perf_event_context *ctx,
1580 struct task_struct *task) 1580 struct task_struct *task)
1581{ 1581{
1582 memset(ctx, 0, sizeof(*ctx));
1583 spin_lock_init(&ctx->lock); 1582 spin_lock_init(&ctx->lock);
1584 mutex_init(&ctx->mutex); 1583 mutex_init(&ctx->mutex);
1585 INIT_LIST_HEAD(&ctx->group_list); 1584 INIT_LIST_HEAD(&ctx->group_list);
@@ -1654,7 +1653,7 @@ static struct perf_event_context *find_get_context(pid_t pid, int cpu)
1654 } 1653 }
1655 1654
1656 if (!ctx) { 1655 if (!ctx) {
1657 ctx = kmalloc(sizeof(struct perf_event_context), GFP_KERNEL); 1656 ctx = kzalloc(sizeof(struct perf_event_context), GFP_KERNEL);
1658 err = -ENOMEM; 1657 err = -ENOMEM;
1659 if (!ctx) 1658 if (!ctx)
1660 goto errout; 1659 goto errout;
@@ -4011,6 +4010,7 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer)
4011 event->pmu->read(event); 4010 event->pmu->read(event);
4012 4011
4013 data.addr = 0; 4012 data.addr = 0;
4013 data.raw = NULL;
4014 data.period = event->hw.last_period; 4014 data.period = event->hw.last_period;
4015 regs = get_irq_regs(); 4015 regs = get_irq_regs();
4016 /* 4016 /*
@@ -4080,8 +4080,7 @@ static void cpu_clock_perf_event_update(struct perf_event *event)
4080 u64 now; 4080 u64 now;
4081 4081
4082 now = cpu_clock(cpu); 4082 now = cpu_clock(cpu);
4083 prev = atomic64_read(&event->hw.prev_count); 4083 prev = atomic64_xchg(&event->hw.prev_count, now);
4084 atomic64_set(&event->hw.prev_count, now);
4085 atomic64_add(now - prev, &event->count); 4084 atomic64_add(now - prev, &event->count);
4086} 4085}
4087 4086
@@ -4286,15 +4285,8 @@ static void bp_perf_event_destroy(struct perf_event *event)
4286static const struct pmu *bp_perf_event_init(struct perf_event *bp) 4285static const struct pmu *bp_perf_event_init(struct perf_event *bp)
4287{ 4286{
4288 int err; 4287 int err;
4289 /* 4288
4290 * The breakpoint is already filled if we haven't created the counter 4289 err = register_perf_hw_breakpoint(bp);
4291 * through perf syscall
4292 * FIXME: manage to get trigerred to NULL if it comes from syscalls
4293 */
4294 if (!bp->callback)
4295 err = register_perf_hw_breakpoint(bp);
4296 else
4297 err = __register_perf_hw_breakpoint(bp);
4298 if (err) 4290 if (err)
4299 return ERR_PTR(err); 4291 return ERR_PTR(err);
4300 4292
@@ -4308,6 +4300,7 @@ void perf_bp_event(struct perf_event *bp, void *data)
4308 struct perf_sample_data sample; 4300 struct perf_sample_data sample;
4309 struct pt_regs *regs = data; 4301 struct pt_regs *regs = data;
4310 4302
4303 sample.raw = NULL;
4311 sample.addr = bp->attr.bp_addr; 4304 sample.addr = bp->attr.bp_addr;
4312 4305
4313 if (!perf_exclude_event(bp, regs)) 4306 if (!perf_exclude_event(bp, regs))
@@ -4390,7 +4383,7 @@ perf_event_alloc(struct perf_event_attr *attr,
4390 struct perf_event_context *ctx, 4383 struct perf_event_context *ctx,
4391 struct perf_event *group_leader, 4384 struct perf_event *group_leader,
4392 struct perf_event *parent_event, 4385 struct perf_event *parent_event,
4393 perf_callback_t callback, 4386 perf_overflow_handler_t overflow_handler,
4394 gfp_t gfpflags) 4387 gfp_t gfpflags)
4395{ 4388{
4396 const struct pmu *pmu; 4389 const struct pmu *pmu;
@@ -4433,10 +4426,10 @@ perf_event_alloc(struct perf_event_attr *attr,
4433 4426
4434 event->state = PERF_EVENT_STATE_INACTIVE; 4427 event->state = PERF_EVENT_STATE_INACTIVE;
4435 4428
4436 if (!callback && parent_event) 4429 if (!overflow_handler && parent_event)
4437 callback = parent_event->callback; 4430 overflow_handler = parent_event->overflow_handler;
4438 4431
4439 event->callback = callback; 4432 event->overflow_handler = overflow_handler;
4440 4433
4441 if (attr->disabled) 4434 if (attr->disabled)
4442 event->state = PERF_EVENT_STATE_OFF; 4435 event->state = PERF_EVENT_STATE_OFF;
@@ -4776,7 +4769,8 @@ err_put_context:
4776 */ 4769 */
4777struct perf_event * 4770struct perf_event *
4778perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, 4771perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
4779 pid_t pid, perf_callback_t callback) 4772 pid_t pid,
4773 perf_overflow_handler_t overflow_handler)
4780{ 4774{
4781 struct perf_event *event; 4775 struct perf_event *event;
4782 struct perf_event_context *ctx; 4776 struct perf_event_context *ctx;
@@ -4793,7 +4787,7 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
4793 } 4787 }
4794 4788
4795 event = perf_event_alloc(attr, cpu, ctx, NULL, 4789 event = perf_event_alloc(attr, cpu, ctx, NULL,
4796 NULL, callback, GFP_KERNEL); 4790 NULL, overflow_handler, GFP_KERNEL);
4797 if (IS_ERR(event)) { 4791 if (IS_ERR(event)) {
4798 err = PTR_ERR(event); 4792 err = PTR_ERR(event);
4799 goto err_put_context; 4793 goto err_put_context;
@@ -5090,7 +5084,7 @@ again:
5090 */ 5084 */
5091int perf_event_init_task(struct task_struct *child) 5085int perf_event_init_task(struct task_struct *child)
5092{ 5086{
5093 struct perf_event_context *child_ctx, *parent_ctx; 5087 struct perf_event_context *child_ctx = NULL, *parent_ctx;
5094 struct perf_event_context *cloned_ctx; 5088 struct perf_event_context *cloned_ctx;
5095 struct perf_event *event; 5089 struct perf_event *event;
5096 struct task_struct *parent = current; 5090 struct task_struct *parent = current;
@@ -5106,20 +5100,6 @@ int perf_event_init_task(struct task_struct *child)
5106 return 0; 5100 return 0;
5107 5101
5108 /* 5102 /*
5109 * This is executed from the parent task context, so inherit
5110 * events that have been marked for cloning.
5111 * First allocate and initialize a context for the child.
5112 */
5113
5114 child_ctx = kmalloc(sizeof(struct perf_event_context), GFP_KERNEL);
5115 if (!child_ctx)
5116 return -ENOMEM;
5117
5118 __perf_event_init_context(child_ctx, child);
5119 child->perf_event_ctxp = child_ctx;
5120 get_task_struct(child);
5121
5122 /*
5123 * If the parent's context is a clone, pin it so it won't get 5103 * If the parent's context is a clone, pin it so it won't get
5124 * swapped under us. 5104 * swapped under us.
5125 */ 5105 */
@@ -5149,6 +5129,26 @@ int perf_event_init_task(struct task_struct *child)
5149 continue; 5129 continue;
5150 } 5130 }
5151 5131
5132 if (!child->perf_event_ctxp) {
5133 /*
5134 * This is executed from the parent task context, so
5135 * inherit events that have been marked for cloning.
5136 * First allocate and initialize a context for the
5137 * child.
5138 */
5139
5140 child_ctx = kzalloc(sizeof(struct perf_event_context),
5141 GFP_KERNEL);
5142 if (!child_ctx) {
5143 ret = -ENOMEM;
5144 goto exit;
5145 }
5146
5147 __perf_event_init_context(child_ctx, child);
5148 child->perf_event_ctxp = child_ctx;
5149 get_task_struct(child);
5150 }
5151
5152 ret = inherit_group(event, parent, parent_ctx, 5152 ret = inherit_group(event, parent, parent_ctx,
5153 child, child_ctx); 5153 child, child_ctx);
5154 if (ret) { 5154 if (ret) {
@@ -5177,6 +5177,7 @@ int perf_event_init_task(struct task_struct *child)
5177 get_ctx(child_ctx->parent_ctx); 5177 get_ctx(child_ctx->parent_ctx);
5178 } 5178 }
5179 5179
5180exit:
5180 mutex_unlock(&parent_ctx->mutex); 5181 mutex_unlock(&parent_ctx->mutex);
5181 5182
5182 perf_unpin_context(parent_ctx); 5183 perf_unpin_context(parent_ctx);
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index aff5f80b59b8..b52d397e57eb 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -606,23 +606,22 @@ static int create_trace_probe(int argc, char **argv)
606 */ 606 */
607 struct trace_probe *tp; 607 struct trace_probe *tp;
608 int i, ret = 0; 608 int i, ret = 0;
609 int is_return = 0; 609 int is_return = 0, is_delete = 0;
610 char *symbol = NULL, *event = NULL, *arg = NULL, *group = NULL; 610 char *symbol = NULL, *event = NULL, *arg = NULL, *group = NULL;
611 unsigned long offset = 0; 611 unsigned long offset = 0;
612 void *addr = NULL; 612 void *addr = NULL;
613 char buf[MAX_EVENT_NAME_LEN]; 613 char buf[MAX_EVENT_NAME_LEN];
614 614
615 if (argc < 2) { 615 /* argc must be >= 1 */
616 pr_info("Probe point is not specified.\n");
617 return -EINVAL;
618 }
619
620 if (argv[0][0] == 'p') 616 if (argv[0][0] == 'p')
621 is_return = 0; 617 is_return = 0;
622 else if (argv[0][0] == 'r') 618 else if (argv[0][0] == 'r')
623 is_return = 1; 619 is_return = 1;
620 else if (argv[0][0] == '-')
621 is_delete = 1;
624 else { 622 else {
625 pr_info("Probe definition must be started with 'p' or 'r'.\n"); 623 pr_info("Probe definition must be started with 'p', 'r' or"
624 " '-'.\n");
626 return -EINVAL; 625 return -EINVAL;
627 } 626 }
628 627
@@ -642,7 +641,29 @@ static int create_trace_probe(int argc, char **argv)
642 return -EINVAL; 641 return -EINVAL;
643 } 642 }
644 } 643 }
644 if (!group)
645 group = KPROBE_EVENT_SYSTEM;
645 646
647 if (is_delete) {
648 if (!event) {
649 pr_info("Delete command needs an event name.\n");
650 return -EINVAL;
651 }
652 tp = find_probe_event(event, group);
653 if (!tp) {
654 pr_info("Event %s/%s doesn't exist.\n", group, event);
655 return -ENOENT;
656 }
657 /* delete an event */
658 unregister_trace_probe(tp);
659 free_trace_probe(tp);
660 return 0;
661 }
662
663 if (argc < 2) {
664 pr_info("Probe point is not specified.\n");
665 return -EINVAL;
666 }
646 if (isdigit(argv[1][0])) { 667 if (isdigit(argv[1][0])) {
647 if (is_return) { 668 if (is_return) {
648 pr_info("Return probe point must be a symbol.\n"); 669 pr_info("Return probe point must be a symbol.\n");
@@ -671,8 +692,6 @@ static int create_trace_probe(int argc, char **argv)
671 argc -= 2; argv += 2; 692 argc -= 2; argv += 2;
672 693
673 /* setup a probe */ 694 /* setup a probe */
674 if (!group)
675 group = KPROBE_EVENT_SYSTEM;
676 if (!event) { 695 if (!event) {
677 /* Make a new event name */ 696 /* Make a new event name */
678 if (symbol) 697 if (symbol)
@@ -1114,7 +1133,7 @@ static int kprobe_event_define_fields(struct ftrace_event_call *event_call)
1114 struct trace_probe *tp = (struct trace_probe *)event_call->data; 1133 struct trace_probe *tp = (struct trace_probe *)event_call->data;
1115 1134
1116 ret = trace_define_common_fields(event_call); 1135 ret = trace_define_common_fields(event_call);
1117 if (!ret) 1136 if (ret)
1118 return ret; 1137 return ret;
1119 1138
1120 DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0); 1139 DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0);
@@ -1132,7 +1151,7 @@ static int kretprobe_event_define_fields(struct ftrace_event_call *event_call)
1132 struct trace_probe *tp = (struct trace_probe *)event_call->data; 1151 struct trace_probe *tp = (struct trace_probe *)event_call->data;
1133 1152
1134 ret = trace_define_common_fields(event_call); 1153 ret = trace_define_common_fields(event_call);
1135 if (!ret) 1154 if (ret)
1136 return ret; 1155 return ret;
1137 1156
1138 DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0); 1157 DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0);
diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c
index ddfa0fd43bc0..acb87d4a4ac1 100644
--- a/kernel/trace/trace_ksym.c
+++ b/kernel/trace/trace_ksym.c
@@ -79,11 +79,12 @@ void ksym_collect_stats(unsigned long hbp_hit_addr)
79} 79}
80#endif /* CONFIG_PROFILE_KSYM_TRACER */ 80#endif /* CONFIG_PROFILE_KSYM_TRACER */
81 81
82void ksym_hbp_handler(struct perf_event *hbp, void *data) 82void ksym_hbp_handler(struct perf_event *hbp, int nmi,
83 struct perf_sample_data *data,
84 struct pt_regs *regs)
83{ 85{
84 struct ring_buffer_event *event; 86 struct ring_buffer_event *event;
85 struct ksym_trace_entry *entry; 87 struct ksym_trace_entry *entry;
86 struct pt_regs *regs = data;
87 struct ring_buffer *buffer; 88 struct ring_buffer *buffer;
88 int pc; 89 int pc;
89 90
diff --git a/samples/hw_breakpoint/data_breakpoint.c b/samples/hw_breakpoint/data_breakpoint.c
index 29525500df00..c69cbe9b2426 100644
--- a/samples/hw_breakpoint/data_breakpoint.c
+++ b/samples/hw_breakpoint/data_breakpoint.c
@@ -41,7 +41,9 @@ module_param_string(ksym, ksym_name, KSYM_NAME_LEN, S_IRUGO);
41MODULE_PARM_DESC(ksym, "Kernel symbol to monitor; this module will report any" 41MODULE_PARM_DESC(ksym, "Kernel symbol to monitor; this module will report any"
42 " write operations on the kernel symbol"); 42 " write operations on the kernel symbol");
43 43
44static void sample_hbp_handler(struct perf_event *temp, void *data) 44static void sample_hbp_handler(struct perf_event *bp, int nmi,
45 struct perf_sample_data *data,
46 struct pt_regs *regs)
45{ 47{
46 printk(KERN_INFO "%s value is changed\n", ksym_name); 48 printk(KERN_INFO "%s value is changed\n", ksym_name);
47 dump_stack(); 49 dump_stack();
@@ -51,8 +53,9 @@ static void sample_hbp_handler(struct perf_event *temp, void *data)
51static int __init hw_break_module_init(void) 53static int __init hw_break_module_init(void)
52{ 54{
53 int ret; 55 int ret;
54 DEFINE_BREAKPOINT_ATTR(attr); 56 struct perf_event_attr attr;
55 57
58 hw_breakpoint_init(&attr);
56 attr.bp_addr = kallsyms_lookup_name(ksym_name); 59 attr.bp_addr = kallsyms_lookup_name(ksym_name);
57 attr.bp_len = HW_BREAKPOINT_LEN_4; 60 attr.bp_len = HW_BREAKPOINT_LEN_4;
58 attr.bp_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R; 61 attr.bp_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
diff --git a/tools/perf/Documentation/perf-kmem.txt b/tools/perf/Documentation/perf-kmem.txt
index 44b0ce35c28a..eac4d852e7cd 100644
--- a/tools/perf/Documentation/perf-kmem.txt
+++ b/tools/perf/Documentation/perf-kmem.txt
@@ -8,16 +8,16 @@ perf-kmem - Tool to trace/measure kernel memory(slab) properties
8SYNOPSIS 8SYNOPSIS
9-------- 9--------
10[verse] 10[verse]
11'perf kmem' {record} [<options>] 11'perf kmem' {record|stat} [<options>]
12 12
13DESCRIPTION 13DESCRIPTION
14----------- 14-----------
15There's two variants of perf kmem: 15There are two variants of perf kmem:
16 16
17 'perf kmem record <command>' to record the kmem events 17 'perf kmem record <command>' to record the kmem events
18 of an arbitrary workload. 18 of an arbitrary workload.
19 19
20 'perf kmem' to report kernel memory statistics. 20 'perf kmem stat' to report kernel memory statistics.
21 21
22OPTIONS 22OPTIONS
23------- 23-------
@@ -25,8 +25,11 @@ OPTIONS
25--input=<file>:: 25--input=<file>::
26 Select the input file (default: perf.data) 26 Select the input file (default: perf.data)
27 27
28--stat=<caller|alloc>:: 28--caller::
29 Select per callsite or per allocation statistics 29 Show per-callsite statistics
30
31--alloc::
32 Show per-allocation statistics
30 33
31-s <key[,key2...]>:: 34-s <key[,key2...]>::
32--sort=<key[,key2...]>:: 35--sort=<key[,key2...]>::
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 9270594e6dfd..8fa6bf99fcb5 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -8,10 +8,13 @@ perf-probe - Define new dynamic tracepoints
8SYNOPSIS 8SYNOPSIS
9-------- 9--------
10[verse] 10[verse]
11'perf probe' [options] --add 'PROBE' [--add 'PROBE' ...] 11'perf probe' [options] --add='PROBE' [...]
12or 12or
13'perf probe' [options] 'PROBE' ['PROBE' ...] 13'perf probe' [options] PROBE
14 14or
15'perf probe' [options] --del='[GROUP:]EVENT' [...]
16or
17'perf probe' --list
15 18
16DESCRIPTION 19DESCRIPTION
17----------- 20-----------
@@ -31,8 +34,16 @@ OPTIONS
31 Be more verbose (show parsed arguments, etc). 34 Be more verbose (show parsed arguments, etc).
32 35
33-a:: 36-a::
34--add:: 37--add=::
35 Define a probe point (see PROBE SYNTAX for detail) 38 Define a probe event (see PROBE SYNTAX for detail).
39
40-d::
41--del=::
42 Delete a probe event.
43
44-l::
45--list::
46 List up current probe events.
36 47
37PROBE SYNTAX 48PROBE SYNTAX
38------------ 49------------
diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c
index 7dee9d19ab7a..dcb6143a0002 100644
--- a/tools/perf/builtin-buildid-list.c
+++ b/tools/perf/builtin-buildid-list.c
@@ -19,7 +19,7 @@ static char const *input_name = "perf.data";
19static int force; 19static int force;
20 20
21static const char *const buildid_list_usage[] = { 21static const char *const buildid_list_usage[] = {
22 "perf report [<options>]", 22 "perf buildid-list [<options>]",
23 NULL 23 NULL
24}; 24};
25 25
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 047fef74bd52..5f209514f657 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -57,11 +57,6 @@ static struct rb_root root_caller_sorted;
57static unsigned long total_requested, total_allocated; 57static unsigned long total_requested, total_allocated;
58static unsigned long nr_allocs, nr_cross_allocs; 58static unsigned long nr_allocs, nr_cross_allocs;
59 59
60struct raw_event_sample {
61 u32 size;
62 char data[0];
63};
64
65#define PATH_SYS_NODE "/sys/devices/system/node" 60#define PATH_SYS_NODE "/sys/devices/system/node"
66 61
67static void init_cpunode_map(void) 62static void init_cpunode_map(void)
@@ -201,7 +196,7 @@ static void insert_caller_stat(unsigned long call_site,
201 } 196 }
202} 197}
203 198
204static void process_alloc_event(struct raw_event_sample *raw, 199static void process_alloc_event(void *data,
205 struct event *event, 200 struct event *event,
206 int cpu, 201 int cpu,
207 u64 timestamp __used, 202 u64 timestamp __used,
@@ -214,10 +209,10 @@ static void process_alloc_event(struct raw_event_sample *raw,
214 int bytes_alloc; 209 int bytes_alloc;
215 int node1, node2; 210 int node1, node2;
216 211
217 ptr = raw_field_value(event, "ptr", raw->data); 212 ptr = raw_field_value(event, "ptr", data);
218 call_site = raw_field_value(event, "call_site", raw->data); 213 call_site = raw_field_value(event, "call_site", data);
219 bytes_req = raw_field_value(event, "bytes_req", raw->data); 214 bytes_req = raw_field_value(event, "bytes_req", data);
220 bytes_alloc = raw_field_value(event, "bytes_alloc", raw->data); 215 bytes_alloc = raw_field_value(event, "bytes_alloc", data);
221 216
222 insert_alloc_stat(call_site, ptr, bytes_req, bytes_alloc, cpu); 217 insert_alloc_stat(call_site, ptr, bytes_req, bytes_alloc, cpu);
223 insert_caller_stat(call_site, bytes_req, bytes_alloc); 218 insert_caller_stat(call_site, bytes_req, bytes_alloc);
@@ -227,7 +222,7 @@ static void process_alloc_event(struct raw_event_sample *raw,
227 222
228 if (node) { 223 if (node) {
229 node1 = cpunode_map[cpu]; 224 node1 = cpunode_map[cpu];
230 node2 = raw_field_value(event, "node", raw->data); 225 node2 = raw_field_value(event, "node", data);
231 if (node1 != node2) 226 if (node1 != node2)
232 nr_cross_allocs++; 227 nr_cross_allocs++;
233 } 228 }
@@ -262,7 +257,7 @@ static struct alloc_stat *search_alloc_stat(unsigned long ptr,
262 return NULL; 257 return NULL;
263} 258}
264 259
265static void process_free_event(struct raw_event_sample *raw, 260static void process_free_event(void *data,
266 struct event *event, 261 struct event *event,
267 int cpu, 262 int cpu,
268 u64 timestamp __used, 263 u64 timestamp __used,
@@ -271,7 +266,7 @@ static void process_free_event(struct raw_event_sample *raw,
271 unsigned long ptr; 266 unsigned long ptr;
272 struct alloc_stat *s_alloc, *s_caller; 267 struct alloc_stat *s_alloc, *s_caller;
273 268
274 ptr = raw_field_value(event, "ptr", raw->data); 269 ptr = raw_field_value(event, "ptr", data);
275 270
276 s_alloc = search_alloc_stat(ptr, 0, &root_alloc_stat, ptr_cmp); 271 s_alloc = search_alloc_stat(ptr, 0, &root_alloc_stat, ptr_cmp);
277 if (!s_alloc) 272 if (!s_alloc)
@@ -289,66 +284,53 @@ static void process_free_event(struct raw_event_sample *raw,
289} 284}
290 285
291static void 286static void
292process_raw_event(event_t *raw_event __used, void *more_data, 287process_raw_event(event_t *raw_event __used, void *data,
293 int cpu, u64 timestamp, struct thread *thread) 288 int cpu, u64 timestamp, struct thread *thread)
294{ 289{
295 struct raw_event_sample *raw = more_data;
296 struct event *event; 290 struct event *event;
297 int type; 291 int type;
298 292
299 type = trace_parse_common_type(raw->data); 293 type = trace_parse_common_type(data);
300 event = trace_find_event(type); 294 event = trace_find_event(type);
301 295
302 if (!strcmp(event->name, "kmalloc") || 296 if (!strcmp(event->name, "kmalloc") ||
303 !strcmp(event->name, "kmem_cache_alloc")) { 297 !strcmp(event->name, "kmem_cache_alloc")) {
304 process_alloc_event(raw, event, cpu, timestamp, thread, 0); 298 process_alloc_event(data, event, cpu, timestamp, thread, 0);
305 return; 299 return;
306 } 300 }
307 301
308 if (!strcmp(event->name, "kmalloc_node") || 302 if (!strcmp(event->name, "kmalloc_node") ||
309 !strcmp(event->name, "kmem_cache_alloc_node")) { 303 !strcmp(event->name, "kmem_cache_alloc_node")) {
310 process_alloc_event(raw, event, cpu, timestamp, thread, 1); 304 process_alloc_event(data, event, cpu, timestamp, thread, 1);
311 return; 305 return;
312 } 306 }
313 307
314 if (!strcmp(event->name, "kfree") || 308 if (!strcmp(event->name, "kfree") ||
315 !strcmp(event->name, "kmem_cache_free")) { 309 !strcmp(event->name, "kmem_cache_free")) {
316 process_free_event(raw, event, cpu, timestamp, thread); 310 process_free_event(data, event, cpu, timestamp, thread);
317 return; 311 return;
318 } 312 }
319} 313}
320 314
321static int process_sample_event(event_t *event) 315static int process_sample_event(event_t *event)
322{ 316{
323 u64 ip = event->ip.ip; 317 struct sample_data data;
324 u64 timestamp = -1; 318 struct thread *thread;
325 u32 cpu = -1;
326 u64 period = 1;
327 void *more_data = event->ip.__more_data;
328 struct thread *thread = threads__findnew(event->ip.pid);
329 319
330 if (sample_type & PERF_SAMPLE_TIME) { 320 memset(&data, 0, sizeof(data));
331 timestamp = *(u64 *)more_data; 321 data.time = -1;
332 more_data += sizeof(u64); 322 data.cpu = -1;
333 } 323 data.period = 1;
334
335 if (sample_type & PERF_SAMPLE_CPU) {
336 cpu = *(u32 *)more_data;
337 more_data += sizeof(u32);
338 more_data += sizeof(u32); /* reserved */
339 }
340 324
341 if (sample_type & PERF_SAMPLE_PERIOD) { 325 event__parse_sample(event, sample_type, &data);
342 period = *(u64 *)more_data;
343 more_data += sizeof(u64);
344 }
345 326
346 dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", 327 dump_printf("(IP, %d): %d/%d: %p period: %Ld\n",
347 event->header.misc, 328 event->header.misc,
348 event->ip.pid, event->ip.tid, 329 data.pid, data.tid,
349 (void *)(long)ip, 330 (void *)(long)data.ip,
350 (long long)period); 331 (long long)data.period);
351 332
333 thread = threads__findnew(event->ip.pid);
352 if (thread == NULL) { 334 if (thread == NULL) {
353 pr_debug("problem processing %d event, skipping it.\n", 335 pr_debug("problem processing %d event, skipping it.\n",
354 event->header.type); 336 event->header.type);
@@ -357,7 +339,8 @@ static int process_sample_event(event_t *event)
357 339
358 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); 340 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
359 341
360 process_raw_event(event, more_data, cpu, timestamp, thread); 342 process_raw_event(event, data.raw_data, data.cpu,
343 data.time, thread);
361 344
362 return 0; 345 return 0;
363} 346}
@@ -543,7 +526,7 @@ static int __cmd_kmem(void)
543} 526}
544 527
545static const char * const kmem_usage[] = { 528static const char * const kmem_usage[] = {
546 "perf kmem [<options>] {record}", 529 "perf kmem [<options>] {record|stat}",
547 NULL 530 NULL
548}; 531};
549 532
@@ -703,18 +686,17 @@ static int parse_sort_opt(const struct option *opt __used,
703 return 0; 686 return 0;
704} 687}
705 688
706static int parse_stat_opt(const struct option *opt __used, 689static int parse_caller_opt(const struct option *opt __used,
707 const char *arg, int unset __used) 690 const char *arg __used, int unset __used)
708{ 691{
709 if (!arg) 692 caller_flag = (alloc_flag + 1);
710 return -1; 693 return 0;
694}
711 695
712 if (strcmp(arg, "alloc") == 0) 696static int parse_alloc_opt(const struct option *opt __used,
713 alloc_flag = (caller_flag + 1); 697 const char *arg __used, int unset __used)
714 else if (strcmp(arg, "caller") == 0) 698{
715 caller_flag = (alloc_flag + 1); 699 alloc_flag = (caller_flag + 1);
716 else
717 return -1;
718 return 0; 700 return 0;
719} 701}
720 702
@@ -739,14 +721,17 @@ static int parse_line_opt(const struct option *opt __used,
739static const struct option kmem_options[] = { 721static const struct option kmem_options[] = {
740 OPT_STRING('i', "input", &input_name, "file", 722 OPT_STRING('i', "input", &input_name, "file",
741 "input file name"), 723 "input file name"),
742 OPT_CALLBACK(0, "stat", NULL, "<alloc>|<caller>", 724 OPT_CALLBACK_NOOPT(0, "caller", NULL, NULL,
743 "stat selector, Pass 'alloc' or 'caller'.", 725 "show per-callsite statistics",
744 parse_stat_opt), 726 parse_caller_opt),
727 OPT_CALLBACK_NOOPT(0, "alloc", NULL, NULL,
728 "show per-allocation statistics",
729 parse_alloc_opt),
745 OPT_CALLBACK('s', "sort", NULL, "key[,key2...]", 730 OPT_CALLBACK('s', "sort", NULL, "key[,key2...]",
746 "sort by keys: ptr, call_site, bytes, hit, pingpong, frag", 731 "sort by keys: ptr, call_site, bytes, hit, pingpong, frag",
747 parse_sort_opt), 732 parse_sort_opt),
748 OPT_CALLBACK('l', "line", NULL, "num", 733 OPT_CALLBACK('l', "line", NULL, "num",
749 "show n lins", 734 "show n lines",
750 parse_line_opt), 735 parse_line_opt),
751 OPT_BOOLEAN(0, "raw-ip", &raw_ip, "show raw ip instead of symbol"), 736 OPT_BOOLEAN(0, "raw-ip", &raw_ip, "show raw ip instead of symbol"),
752 OPT_END() 737 OPT_END()
@@ -790,18 +775,22 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __used)
790 775
791 argc = parse_options(argc, argv, kmem_options, kmem_usage, 0); 776 argc = parse_options(argc, argv, kmem_options, kmem_usage, 0);
792 777
793 if (argc && !strncmp(argv[0], "rec", 3)) 778 if (!argc)
794 return __cmd_record(argc, argv);
795 else if (argc)
796 usage_with_options(kmem_usage, kmem_options); 779 usage_with_options(kmem_usage, kmem_options);
797 780
798 if (list_empty(&caller_sort)) 781 if (!strncmp(argv[0], "rec", 3)) {
799 setup_sorting(&caller_sort, default_sort_order); 782 return __cmd_record(argc, argv);
800 if (list_empty(&alloc_sort)) 783 } else if (!strcmp(argv[0], "stat")) {
801 setup_sorting(&alloc_sort, default_sort_order); 784 setup_cpunode_map();
785
786 if (list_empty(&caller_sort))
787 setup_sorting(&caller_sort, default_sort_order);
788 if (list_empty(&alloc_sort))
789 setup_sorting(&alloc_sort, default_sort_order);
802 790
803 setup_cpunode_map(); 791 return __cmd_kmem();
792 }
804 793
805 return __cmd_kmem(); 794 return 0;
806} 795}
807 796
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index a58e11b7ea80..5a47c1e11f77 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -35,6 +35,7 @@
35#include "perf.h" 35#include "perf.h"
36#include "builtin.h" 36#include "builtin.h"
37#include "util/util.h" 37#include "util/util.h"
38#include "util/strlist.h"
38#include "util/event.h" 39#include "util/event.h"
39#include "util/debug.h" 40#include "util/debug.h"
40#include "util/parse-options.h" 41#include "util/parse-options.h"
@@ -43,11 +44,12 @@
43#include "util/probe-event.h" 44#include "util/probe-event.h"
44 45
45/* Default vmlinux search paths */ 46/* Default vmlinux search paths */
46#define NR_SEARCH_PATH 3 47#define NR_SEARCH_PATH 4
47const char *default_search_path[NR_SEARCH_PATH] = { 48const char *default_search_path[NR_SEARCH_PATH] = {
48"/lib/modules/%s/build/vmlinux", /* Custom build kernel */ 49"/lib/modules/%s/build/vmlinux", /* Custom build kernel */
49"/usr/lib/debug/lib/modules/%s/vmlinux", /* Red Hat debuginfo */ 50"/usr/lib/debug/lib/modules/%s/vmlinux", /* Red Hat debuginfo */
50"/boot/vmlinux-debug-%s", /* Ubuntu */ 51"/boot/vmlinux-debug-%s", /* Ubuntu */
52"./vmlinux", /* CWD */
51}; 53};
52 54
53#define MAX_PATH_LEN 256 55#define MAX_PATH_LEN 256
@@ -60,6 +62,7 @@ static struct {
60 int need_dwarf; 62 int need_dwarf;
61 int nr_probe; 63 int nr_probe;
62 struct probe_point probes[MAX_PROBES]; 64 struct probe_point probes[MAX_PROBES];
65 struct strlist *dellist;
63} session; 66} session;
64 67
65static bool listing; 68static bool listing;
@@ -79,6 +82,25 @@ static void parse_probe_event(const char *str)
79 pr_debug("%d arguments\n", pp->nr_args); 82 pr_debug("%d arguments\n", pp->nr_args);
80} 83}
81 84
85static void parse_probe_event_argv(int argc, const char **argv)
86{
87 int i, len;
88 char *buf;
89
90 /* Bind up rest arguments */
91 len = 0;
92 for (i = 0; i < argc; i++)
93 len += strlen(argv[i]) + 1;
94 buf = zalloc(len + 1);
95 if (!buf)
96 die("Failed to allocate memory for binding arguments.");
97 len = 0;
98 for (i = 0; i < argc; i++)
99 len += sprintf(&buf[len], "%s ", argv[i]);
100 parse_probe_event(buf);
101 free(buf);
102}
103
82static int opt_add_probe_event(const struct option *opt __used, 104static int opt_add_probe_event(const struct option *opt __used,
83 const char *str, int unset __used) 105 const char *str, int unset __used)
84{ 106{
@@ -87,6 +109,17 @@ static int opt_add_probe_event(const struct option *opt __used,
87 return 0; 109 return 0;
88} 110}
89 111
112static int opt_del_probe_event(const struct option *opt __used,
113 const char *str, int unset __used)
114{
115 if (str) {
116 if (!session.dellist)
117 session.dellist = strlist__new(true, NULL);
118 strlist__add(session.dellist, str);
119 }
120 return 0;
121}
122
90#ifndef NO_LIBDWARF 123#ifndef NO_LIBDWARF
91static int open_default_vmlinux(void) 124static int open_default_vmlinux(void)
92{ 125{
@@ -121,6 +154,7 @@ static int open_default_vmlinux(void)
121static const char * const probe_usage[] = { 154static const char * const probe_usage[] = {
122 "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]", 155 "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]",
123 "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]", 156 "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
157 "perf probe [<options>] --del '[GROUP:]EVENT' ...",
124 "perf probe --list", 158 "perf probe --list",
125 NULL 159 NULL
126}; 160};
@@ -132,7 +166,9 @@ static const struct option options[] = {
132 OPT_STRING('k', "vmlinux", &session.vmlinux, "file", 166 OPT_STRING('k', "vmlinux", &session.vmlinux, "file",
133 "vmlinux/module pathname"), 167 "vmlinux/module pathname"),
134#endif 168#endif
135 OPT_BOOLEAN('l', "list", &listing, "list up current probes"), 169 OPT_BOOLEAN('l', "list", &listing, "list up current probe events"),
170 OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.",
171 opt_del_probe_event),
136 OPT_CALLBACK('a', "add", NULL, 172 OPT_CALLBACK('a', "add", NULL,
137#ifdef NO_LIBDWARF 173#ifdef NO_LIBDWARF
138 "FUNC[+OFFS|%return] [ARG ...]", 174 "FUNC[+OFFS|%return] [ARG ...]",
@@ -160,7 +196,7 @@ static const struct option options[] = {
160 196
161int cmd_probe(int argc, const char **argv, const char *prefix __used) 197int cmd_probe(int argc, const char **argv, const char *prefix __used)
162{ 198{
163 int i, j, ret; 199 int i, ret;
164#ifndef NO_LIBDWARF 200#ifndef NO_LIBDWARF
165 int fd; 201 int fd;
166#endif 202#endif
@@ -168,40 +204,52 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
168 204
169 argc = parse_options(argc, argv, options, probe_usage, 205 argc = parse_options(argc, argv, options, probe_usage,
170 PARSE_OPT_STOP_AT_NON_OPTION); 206 PARSE_OPT_STOP_AT_NON_OPTION);
171 for (i = 0; i < argc; i++) 207 if (argc > 0)
172 parse_probe_event(argv[i]); 208 parse_probe_event_argv(argc, argv);
173 209
174 if ((session.nr_probe == 0 && !listing) || 210 if ((session.nr_probe == 0 && !session.dellist && !listing))
175 (session.nr_probe != 0 && listing))
176 usage_with_options(probe_usage, options); 211 usage_with_options(probe_usage, options);
177 212
178 if (listing) { 213 if (listing) {
214 if (session.nr_probe != 0 || session.dellist) {
215 pr_warning(" Error: Don't use --list with"
216 " --add/--del.\n");
217 usage_with_options(probe_usage, options);
218 }
179 show_perf_probe_events(); 219 show_perf_probe_events();
180 return 0; 220 return 0;
181 } 221 }
182 222
223 if (session.dellist) {
224 del_trace_kprobe_events(session.dellist);
225 strlist__delete(session.dellist);
226 if (session.nr_probe == 0)
227 return 0;
228 }
229
183 if (session.need_dwarf) 230 if (session.need_dwarf)
184#ifdef NO_LIBDWARF 231#ifdef NO_LIBDWARF
185 die("Debuginfo-analysis is not supported"); 232 die("Debuginfo-analysis is not supported");
186#else /* !NO_LIBDWARF */ 233#else /* !NO_LIBDWARF */
187 pr_debug("Some probes require debuginfo.\n"); 234 pr_debug("Some probes require debuginfo.\n");
188 235
189 if (session.vmlinux) 236 if (session.vmlinux) {
237 pr_debug("Try to open %s.", session.vmlinux);
190 fd = open(session.vmlinux, O_RDONLY); 238 fd = open(session.vmlinux, O_RDONLY);
191 else 239 } else
192 fd = open_default_vmlinux(); 240 fd = open_default_vmlinux();
193 if (fd < 0) { 241 if (fd < 0) {
194 if (session.need_dwarf) 242 if (session.need_dwarf)
195 die("Could not open vmlinux/module file."); 243 die("Could not open debuginfo file.");
196 244
197 pr_warning("Could not open vmlinux/module file." 245 pr_debug("Could not open vmlinux/module file."
198 " Try to use symbols.\n"); 246 " Try to use symbols.\n");
199 goto end_dwarf; 247 goto end_dwarf;
200 } 248 }
201 249
202 /* Searching probe points */ 250 /* Searching probe points */
203 for (j = 0; j < session.nr_probe; j++) { 251 for (i = 0; i < session.nr_probe; i++) {
204 pp = &session.probes[j]; 252 pp = &session.probes[i];
205 if (pp->found) 253 if (pp->found)
206 continue; 254 continue;
207 255
@@ -223,8 +271,8 @@ end_dwarf:
223#endif /* !NO_LIBDWARF */ 271#endif /* !NO_LIBDWARF */
224 272
225 /* Synthesize probes without dwarf */ 273 /* Synthesize probes without dwarf */
226 for (j = 0; j < session.nr_probe; j++) { 274 for (i = 0; i < session.nr_probe; i++) {
227 pp = &session.probes[j]; 275 pp = &session.probes[i];
228 if (pp->found) /* This probe is already found. */ 276 if (pp->found) /* This probe is already found. */
229 continue; 277 continue;
230 278
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 383c4ab4f9af..2b9eb3a553ed 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -605,44 +605,41 @@ static int validate_chain(struct ip_callchain *chain, event_t *event)
605 605
606static int process_sample_event(event_t *event) 606static int process_sample_event(event_t *event)
607{ 607{
608 u64 ip = event->ip.ip; 608 struct sample_data data;
609 u64 period = 1;
610 void *more_data = event->ip.__more_data;
611 struct ip_callchain *chain = NULL;
612 int cpumode; 609 int cpumode;
613 struct addr_location al; 610 struct addr_location al;
614 struct thread *thread = threads__findnew(event->ip.pid); 611 struct thread *thread;
615 612
616 if (sample_type & PERF_SAMPLE_PERIOD) { 613 memset(&data, 0, sizeof(data));
617 period = *(u64 *)more_data; 614 data.period = 1;
618 more_data += sizeof(u64); 615
619 } 616 event__parse_sample(event, sample_type, &data);
620 617
621 dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", 618 dump_printf("(IP, %d): %d/%d: %p period: %Ld\n",
622 event->header.misc, 619 event->header.misc,
623 event->ip.pid, event->ip.tid, 620 data.pid, data.tid,
624 (void *)(long)ip, 621 (void *)(long)data.ip,
625 (long long)period); 622 (long long)data.period);
626 623
627 if (sample_type & PERF_SAMPLE_CALLCHAIN) { 624 if (sample_type & PERF_SAMPLE_CALLCHAIN) {
628 unsigned int i; 625 unsigned int i;
629 626
630 chain = (void *)more_data; 627 dump_printf("... chain: nr:%Lu\n", data.callchain->nr);
631
632 dump_printf("... chain: nr:%Lu\n", chain->nr);
633 628
634 if (validate_chain(chain, event) < 0) { 629 if (validate_chain(data.callchain, event) < 0) {
635 pr_debug("call-chain problem with event, " 630 pr_debug("call-chain problem with event, "
636 "skipping it.\n"); 631 "skipping it.\n");
637 return 0; 632 return 0;
638 } 633 }
639 634
640 if (dump_trace) { 635 if (dump_trace) {
641 for (i = 0; i < chain->nr; i++) 636 for (i = 0; i < data.callchain->nr; i++)
642 dump_printf("..... %2d: %016Lx\n", i, chain->ips[i]); 637 dump_printf("..... %2d: %016Lx\n",
638 i, data.callchain->ips[i]);
643 } 639 }
644 } 640 }
645 641
642 thread = threads__findnew(data.pid);
646 if (thread == NULL) { 643 if (thread == NULL) {
647 pr_debug("problem processing %d event, skipping it.\n", 644 pr_debug("problem processing %d event, skipping it.\n",
648 event->header.type); 645 event->header.type);
@@ -657,7 +654,7 @@ static int process_sample_event(event_t *event)
657 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 654 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
658 655
659 thread__find_addr_location(thread, cpumode, 656 thread__find_addr_location(thread, cpumode,
660 MAP__FUNCTION, ip, &al, NULL); 657 MAP__FUNCTION, data.ip, &al, NULL);
661 /* 658 /*
662 * We have to do this here as we may have a dso with no symbol hit that 659 * We have to do this here as we may have a dso with no symbol hit that
663 * has a name longer than the ones with symbols sampled. 660 * has a name longer than the ones with symbols sampled.
@@ -675,12 +672,12 @@ static int process_sample_event(event_t *event)
675 if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name)) 672 if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name))
676 return 0; 673 return 0;
677 674
678 if (hist_entry__add(&al, chain, period)) { 675 if (hist_entry__add(&al, data.callchain, data.period)) {
679 pr_debug("problem incrementing symbol count, skipping event\n"); 676 pr_debug("problem incrementing symbol count, skipping event\n");
680 return -1; 677 return -1;
681 } 678 }
682 679
683 event__stats.total += period; 680 event__stats.total += data.period;
684 681
685 return 0; 682 return 0;
686} 683}
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 26b782f26ee1..7cca7c15b40a 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -13,7 +13,6 @@
13#include "util/debug.h" 13#include "util/debug.h"
14#include "util/data_map.h" 14#include "util/data_map.h"
15 15
16#include <sys/types.h>
17#include <sys/prctl.h> 16#include <sys/prctl.h>
18 17
19#include <semaphore.h> 18#include <semaphore.h>
@@ -141,6 +140,7 @@ struct work_atoms {
141 struct thread *thread; 140 struct thread *thread;
142 struct rb_node node; 141 struct rb_node node;
143 u64 max_lat; 142 u64 max_lat;
143 u64 max_lat_at;
144 u64 total_lat; 144 u64 total_lat;
145 u64 nb_atoms; 145 u64 nb_atoms;
146 u64 total_runtime; 146 u64 total_runtime;
@@ -414,34 +414,33 @@ static u64 get_cpu_usage_nsec_parent(void)
414 return sum; 414 return sum;
415} 415}
416 416
417static u64 get_cpu_usage_nsec_self(void) 417static int self_open_counters(void)
418{ 418{
419 char filename [] = "/proc/1234567890/sched"; 419 struct perf_event_attr attr;
420 unsigned long msecs, nsecs; 420 int fd;
421 char *line = NULL;
422 u64 total = 0;
423 size_t len = 0;
424 ssize_t chars;
425 FILE *file;
426 int ret;
427 421
428 sprintf(filename, "/proc/%d/sched", getpid()); 422 memset(&attr, 0, sizeof(attr));
429 file = fopen(filename, "r");
430 BUG_ON(!file);
431 423
432 while ((chars = getline(&line, &len, file)) != -1) { 424 attr.type = PERF_TYPE_SOFTWARE;
433 ret = sscanf(line, "se.sum_exec_runtime : %ld.%06ld\n", 425 attr.config = PERF_COUNT_SW_TASK_CLOCK;
434 &msecs, &nsecs); 426
435 if (ret == 2) { 427 fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
436 total = msecs*1e6 + nsecs;
437 break;
438 }
439 }
440 if (line)
441 free(line);
442 fclose(file);
443 428
444 return total; 429 if (fd < 0)
430 die("Error: sys_perf_event_open() syscall returned"
431 "with %d (%s)\n", fd, strerror(errno));
432 return fd;
433}
434
435static u64 get_cpu_usage_nsec_self(int fd)
436{
437 u64 runtime;
438 int ret;
439
440 ret = read(fd, &runtime, sizeof(runtime));
441 BUG_ON(ret != sizeof(runtime));
442
443 return runtime;
445} 444}
446 445
447static void *thread_func(void *ctx) 446static void *thread_func(void *ctx)
@@ -450,9 +449,11 @@ static void *thread_func(void *ctx)
450 u64 cpu_usage_0, cpu_usage_1; 449 u64 cpu_usage_0, cpu_usage_1;
451 unsigned long i, ret; 450 unsigned long i, ret;
452 char comm2[22]; 451 char comm2[22];
452 int fd;
453 453
454 sprintf(comm2, ":%s", this_task->comm); 454 sprintf(comm2, ":%s", this_task->comm);
455 prctl(PR_SET_NAME, comm2); 455 prctl(PR_SET_NAME, comm2);
456 fd = self_open_counters();
456 457
457again: 458again:
458 ret = sem_post(&this_task->ready_for_work); 459 ret = sem_post(&this_task->ready_for_work);
@@ -462,16 +463,15 @@ again:
462 ret = pthread_mutex_unlock(&start_work_mutex); 463 ret = pthread_mutex_unlock(&start_work_mutex);
463 BUG_ON(ret); 464 BUG_ON(ret);
464 465
465 cpu_usage_0 = get_cpu_usage_nsec_self(); 466 cpu_usage_0 = get_cpu_usage_nsec_self(fd);
466 467
467 for (i = 0; i < this_task->nr_events; i++) { 468 for (i = 0; i < this_task->nr_events; i++) {
468 this_task->curr_event = i; 469 this_task->curr_event = i;
469 process_sched_event(this_task, this_task->atoms[i]); 470 process_sched_event(this_task, this_task->atoms[i]);
470 } 471 }
471 472
472 cpu_usage_1 = get_cpu_usage_nsec_self(); 473 cpu_usage_1 = get_cpu_usage_nsec_self(fd);
473 this_task->cpu_usage = cpu_usage_1 - cpu_usage_0; 474 this_task->cpu_usage = cpu_usage_1 - cpu_usage_0;
474
475 ret = sem_post(&this_task->work_done_sem); 475 ret = sem_post(&this_task->work_done_sem);
476 BUG_ON(ret); 476 BUG_ON(ret);
477 477
@@ -628,11 +628,6 @@ static void test_calibrations(void)
628 printf("the sleep test took %Ld nsecs\n", T1-T0); 628 printf("the sleep test took %Ld nsecs\n", T1-T0);
629} 629}
630 630
631struct raw_event_sample {
632 u32 size;
633 char data[0];
634};
635
636#define FILL_FIELD(ptr, field, event, data) \ 631#define FILL_FIELD(ptr, field, event, data) \
637 ptr.field = (typeof(ptr.field)) raw_field_value(event, #field, data) 632 ptr.field = (typeof(ptr.field)) raw_field_value(event, #field, data)
638 633
@@ -1019,8 +1014,10 @@ add_sched_in_event(struct work_atoms *atoms, u64 timestamp)
1019 1014
1020 delta = atom->sched_in_time - atom->wake_up_time; 1015 delta = atom->sched_in_time - atom->wake_up_time;
1021 atoms->total_lat += delta; 1016 atoms->total_lat += delta;
1022 if (delta > atoms->max_lat) 1017 if (delta > atoms->max_lat) {
1023 atoms->max_lat = delta; 1018 atoms->max_lat = delta;
1019 atoms->max_lat_at = timestamp;
1020 }
1024 atoms->nb_atoms++; 1021 atoms->nb_atoms++;
1025} 1022}
1026 1023
@@ -1216,10 +1213,11 @@ static void output_lat_thread(struct work_atoms *work_list)
1216 1213
1217 avg = work_list->total_lat / work_list->nb_atoms; 1214 avg = work_list->total_lat / work_list->nb_atoms;
1218 1215
1219 printf("|%11.3f ms |%9llu | avg:%9.3f ms | max:%9.3f ms |\n", 1216 printf("|%11.3f ms |%9llu | avg:%9.3f ms | max:%9.3f ms | max at: %9.6f s\n",
1220 (double)work_list->total_runtime / 1e6, 1217 (double)work_list->total_runtime / 1e6,
1221 work_list->nb_atoms, (double)avg / 1e6, 1218 work_list->nb_atoms, (double)avg / 1e6,
1222 (double)work_list->max_lat / 1e6); 1219 (double)work_list->max_lat / 1e6,
1220 (double)work_list->max_lat_at / 1e9);
1223} 1221}
1224 1222
1225static int pid_cmp(struct work_atoms *l, struct work_atoms *r) 1223static int pid_cmp(struct work_atoms *l, struct work_atoms *r)
@@ -1356,7 +1354,7 @@ static void sort_lat(void)
1356static struct trace_sched_handler *trace_handler; 1354static struct trace_sched_handler *trace_handler;
1357 1355
1358static void 1356static void
1359process_sched_wakeup_event(struct raw_event_sample *raw, 1357process_sched_wakeup_event(void *data,
1360 struct event *event, 1358 struct event *event,
1361 int cpu __used, 1359 int cpu __used,
1362 u64 timestamp __used, 1360 u64 timestamp __used,
@@ -1364,13 +1362,13 @@ process_sched_wakeup_event(struct raw_event_sample *raw,
1364{ 1362{
1365 struct trace_wakeup_event wakeup_event; 1363 struct trace_wakeup_event wakeup_event;
1366 1364
1367 FILL_COMMON_FIELDS(wakeup_event, event, raw->data); 1365 FILL_COMMON_FIELDS(wakeup_event, event, data);
1368 1366
1369 FILL_ARRAY(wakeup_event, comm, event, raw->data); 1367 FILL_ARRAY(wakeup_event, comm, event, data);
1370 FILL_FIELD(wakeup_event, pid, event, raw->data); 1368 FILL_FIELD(wakeup_event, pid, event, data);
1371 FILL_FIELD(wakeup_event, prio, event, raw->data); 1369 FILL_FIELD(wakeup_event, prio, event, data);
1372 FILL_FIELD(wakeup_event, success, event, raw->data); 1370 FILL_FIELD(wakeup_event, success, event, data);
1373 FILL_FIELD(wakeup_event, cpu, event, raw->data); 1371 FILL_FIELD(wakeup_event, cpu, event, data);
1374 1372
1375 if (trace_handler->wakeup_event) 1373 if (trace_handler->wakeup_event)
1376 trace_handler->wakeup_event(&wakeup_event, event, cpu, timestamp, thread); 1374 trace_handler->wakeup_event(&wakeup_event, event, cpu, timestamp, thread);
@@ -1469,7 +1467,7 @@ map_switch_event(struct trace_switch_event *switch_event,
1469 1467
1470 1468
1471static void 1469static void
1472process_sched_switch_event(struct raw_event_sample *raw, 1470process_sched_switch_event(void *data,
1473 struct event *event, 1471 struct event *event,
1474 int this_cpu, 1472 int this_cpu,
1475 u64 timestamp __used, 1473 u64 timestamp __used,
@@ -1477,15 +1475,15 @@ process_sched_switch_event(struct raw_event_sample *raw,
1477{ 1475{
1478 struct trace_switch_event switch_event; 1476 struct trace_switch_event switch_event;
1479 1477
1480 FILL_COMMON_FIELDS(switch_event, event, raw->data); 1478 FILL_COMMON_FIELDS(switch_event, event, data);
1481 1479
1482 FILL_ARRAY(switch_event, prev_comm, event, raw->data); 1480 FILL_ARRAY(switch_event, prev_comm, event, data);
1483 FILL_FIELD(switch_event, prev_pid, event, raw->data); 1481 FILL_FIELD(switch_event, prev_pid, event, data);
1484 FILL_FIELD(switch_event, prev_prio, event, raw->data); 1482 FILL_FIELD(switch_event, prev_prio, event, data);
1485 FILL_FIELD(switch_event, prev_state, event, raw->data); 1483 FILL_FIELD(switch_event, prev_state, event, data);
1486 FILL_ARRAY(switch_event, next_comm, event, raw->data); 1484 FILL_ARRAY(switch_event, next_comm, event, data);
1487 FILL_FIELD(switch_event, next_pid, event, raw->data); 1485 FILL_FIELD(switch_event, next_pid, event, data);
1488 FILL_FIELD(switch_event, next_prio, event, raw->data); 1486 FILL_FIELD(switch_event, next_prio, event, data);
1489 1487
1490 if (curr_pid[this_cpu] != (u32)-1) { 1488 if (curr_pid[this_cpu] != (u32)-1) {
1491 /* 1489 /*
@@ -1502,7 +1500,7 @@ process_sched_switch_event(struct raw_event_sample *raw,
1502} 1500}
1503 1501
1504static void 1502static void
1505process_sched_runtime_event(struct raw_event_sample *raw, 1503process_sched_runtime_event(void *data,
1506 struct event *event, 1504 struct event *event,
1507 int cpu __used, 1505 int cpu __used,
1508 u64 timestamp __used, 1506 u64 timestamp __used,
@@ -1510,17 +1508,17 @@ process_sched_runtime_event(struct raw_event_sample *raw,
1510{ 1508{
1511 struct trace_runtime_event runtime_event; 1509 struct trace_runtime_event runtime_event;
1512 1510
1513 FILL_ARRAY(runtime_event, comm, event, raw->data); 1511 FILL_ARRAY(runtime_event, comm, event, data);
1514 FILL_FIELD(runtime_event, pid, event, raw->data); 1512 FILL_FIELD(runtime_event, pid, event, data);
1515 FILL_FIELD(runtime_event, runtime, event, raw->data); 1513 FILL_FIELD(runtime_event, runtime, event, data);
1516 FILL_FIELD(runtime_event, vruntime, event, raw->data); 1514 FILL_FIELD(runtime_event, vruntime, event, data);
1517 1515
1518 if (trace_handler->runtime_event) 1516 if (trace_handler->runtime_event)
1519 trace_handler->runtime_event(&runtime_event, event, cpu, timestamp, thread); 1517 trace_handler->runtime_event(&runtime_event, event, cpu, timestamp, thread);
1520} 1518}
1521 1519
1522static void 1520static void
1523process_sched_fork_event(struct raw_event_sample *raw, 1521process_sched_fork_event(void *data,
1524 struct event *event, 1522 struct event *event,
1525 int cpu __used, 1523 int cpu __used,
1526 u64 timestamp __used, 1524 u64 timestamp __used,
@@ -1528,12 +1526,12 @@ process_sched_fork_event(struct raw_event_sample *raw,
1528{ 1526{
1529 struct trace_fork_event fork_event; 1527 struct trace_fork_event fork_event;
1530 1528
1531 FILL_COMMON_FIELDS(fork_event, event, raw->data); 1529 FILL_COMMON_FIELDS(fork_event, event, data);
1532 1530
1533 FILL_ARRAY(fork_event, parent_comm, event, raw->data); 1531 FILL_ARRAY(fork_event, parent_comm, event, data);
1534 FILL_FIELD(fork_event, parent_pid, event, raw->data); 1532 FILL_FIELD(fork_event, parent_pid, event, data);
1535 FILL_ARRAY(fork_event, child_comm, event, raw->data); 1533 FILL_ARRAY(fork_event, child_comm, event, data);
1536 FILL_FIELD(fork_event, child_pid, event, raw->data); 1534 FILL_FIELD(fork_event, child_pid, event, data);
1537 1535
1538 if (trace_handler->fork_event) 1536 if (trace_handler->fork_event)
1539 trace_handler->fork_event(&fork_event, event, cpu, timestamp, thread); 1537 trace_handler->fork_event(&fork_event, event, cpu, timestamp, thread);
@@ -1550,7 +1548,7 @@ process_sched_exit_event(struct event *event,
1550} 1548}
1551 1549
1552static void 1550static void
1553process_sched_migrate_task_event(struct raw_event_sample *raw, 1551process_sched_migrate_task_event(void *data,
1554 struct event *event, 1552 struct event *event,
1555 int cpu __used, 1553 int cpu __used,
1556 u64 timestamp __used, 1554 u64 timestamp __used,
@@ -1558,80 +1556,66 @@ process_sched_migrate_task_event(struct raw_event_sample *raw,
1558{ 1556{
1559 struct trace_migrate_task_event migrate_task_event; 1557 struct trace_migrate_task_event migrate_task_event;
1560 1558
1561 FILL_COMMON_FIELDS(migrate_task_event, event, raw->data); 1559 FILL_COMMON_FIELDS(migrate_task_event, event, data);
1562 1560
1563 FILL_ARRAY(migrate_task_event, comm, event, raw->data); 1561 FILL_ARRAY(migrate_task_event, comm, event, data);
1564 FILL_FIELD(migrate_task_event, pid, event, raw->data); 1562 FILL_FIELD(migrate_task_event, pid, event, data);
1565 FILL_FIELD(migrate_task_event, prio, event, raw->data); 1563 FILL_FIELD(migrate_task_event, prio, event, data);
1566 FILL_FIELD(migrate_task_event, cpu, event, raw->data); 1564 FILL_FIELD(migrate_task_event, cpu, event, data);
1567 1565
1568 if (trace_handler->migrate_task_event) 1566 if (trace_handler->migrate_task_event)
1569 trace_handler->migrate_task_event(&migrate_task_event, event, cpu, timestamp, thread); 1567 trace_handler->migrate_task_event(&migrate_task_event, event, cpu, timestamp, thread);
1570} 1568}
1571 1569
1572static void 1570static void
1573process_raw_event(event_t *raw_event __used, void *more_data, 1571process_raw_event(event_t *raw_event __used, void *data,
1574 int cpu, u64 timestamp, struct thread *thread) 1572 int cpu, u64 timestamp, struct thread *thread)
1575{ 1573{
1576 struct raw_event_sample *raw = more_data;
1577 struct event *event; 1574 struct event *event;
1578 int type; 1575 int type;
1579 1576
1580 type = trace_parse_common_type(raw->data); 1577
1578 type = trace_parse_common_type(data);
1581 event = trace_find_event(type); 1579 event = trace_find_event(type);
1582 1580
1583 if (!strcmp(event->name, "sched_switch")) 1581 if (!strcmp(event->name, "sched_switch"))
1584 process_sched_switch_event(raw, event, cpu, timestamp, thread); 1582 process_sched_switch_event(data, event, cpu, timestamp, thread);
1585 if (!strcmp(event->name, "sched_stat_runtime")) 1583 if (!strcmp(event->name, "sched_stat_runtime"))
1586 process_sched_runtime_event(raw, event, cpu, timestamp, thread); 1584 process_sched_runtime_event(data, event, cpu, timestamp, thread);
1587 if (!strcmp(event->name, "sched_wakeup")) 1585 if (!strcmp(event->name, "sched_wakeup"))
1588 process_sched_wakeup_event(raw, event, cpu, timestamp, thread); 1586 process_sched_wakeup_event(data, event, cpu, timestamp, thread);
1589 if (!strcmp(event->name, "sched_wakeup_new")) 1587 if (!strcmp(event->name, "sched_wakeup_new"))
1590 process_sched_wakeup_event(raw, event, cpu, timestamp, thread); 1588 process_sched_wakeup_event(data, event, cpu, timestamp, thread);
1591 if (!strcmp(event->name, "sched_process_fork")) 1589 if (!strcmp(event->name, "sched_process_fork"))
1592 process_sched_fork_event(raw, event, cpu, timestamp, thread); 1590 process_sched_fork_event(data, event, cpu, timestamp, thread);
1593 if (!strcmp(event->name, "sched_process_exit")) 1591 if (!strcmp(event->name, "sched_process_exit"))
1594 process_sched_exit_event(event, cpu, timestamp, thread); 1592 process_sched_exit_event(event, cpu, timestamp, thread);
1595 if (!strcmp(event->name, "sched_migrate_task")) 1593 if (!strcmp(event->name, "sched_migrate_task"))
1596 process_sched_migrate_task_event(raw, event, cpu, timestamp, thread); 1594 process_sched_migrate_task_event(data, event, cpu, timestamp, thread);
1597} 1595}
1598 1596
1599static int process_sample_event(event_t *event) 1597static int process_sample_event(event_t *event)
1600{ 1598{
1599 struct sample_data data;
1601 struct thread *thread; 1600 struct thread *thread;
1602 u64 ip = event->ip.ip;
1603 u64 timestamp = -1;
1604 u32 cpu = -1;
1605 u64 period = 1;
1606 void *more_data = event->ip.__more_data;
1607 1601
1608 if (!(sample_type & PERF_SAMPLE_RAW)) 1602 if (!(sample_type & PERF_SAMPLE_RAW))
1609 return 0; 1603 return 0;
1610 1604
1611 thread = threads__findnew(event->ip.pid); 1605 memset(&data, 0, sizeof(data));
1606 data.time = -1;
1607 data.cpu = -1;
1608 data.period = -1;
1612 1609
1613 if (sample_type & PERF_SAMPLE_TIME) { 1610 event__parse_sample(event, sample_type, &data);
1614 timestamp = *(u64 *)more_data;
1615 more_data += sizeof(u64);
1616 }
1617
1618 if (sample_type & PERF_SAMPLE_CPU) {
1619 cpu = *(u32 *)more_data;
1620 more_data += sizeof(u32);
1621 more_data += sizeof(u32); /* reserved */
1622 }
1623
1624 if (sample_type & PERF_SAMPLE_PERIOD) {
1625 period = *(u64 *)more_data;
1626 more_data += sizeof(u64);
1627 }
1628 1611
1629 dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", 1612 dump_printf("(IP, %d): %d/%d: %p period: %Ld\n",
1630 event->header.misc, 1613 event->header.misc,
1631 event->ip.pid, event->ip.tid, 1614 data.pid, data.tid,
1632 (void *)(long)ip, 1615 (void *)(long)data.ip,
1633 (long long)period); 1616 (long long)data.period);
1634 1617
1618 thread = threads__findnew(data.pid);
1635 if (thread == NULL) { 1619 if (thread == NULL) {
1636 pr_debug("problem processing %d event, skipping it.\n", 1620 pr_debug("problem processing %d event, skipping it.\n",
1637 event->header.type); 1621 event->header.type);
@@ -1640,10 +1624,10 @@ static int process_sample_event(event_t *event)
1640 1624
1641 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); 1625 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
1642 1626
1643 if (profile_cpu != -1 && profile_cpu != (int) cpu) 1627 if (profile_cpu != -1 && profile_cpu != (int)data.cpu)
1644 return 0; 1628 return 0;
1645 1629
1646 process_raw_event(event, more_data, cpu, timestamp, thread); 1630 process_raw_event(event, data.raw_data, data.cpu, data.time, thread);
1647 1631
1648 return 0; 1632 return 0;
1649} 1633}
@@ -1724,9 +1708,9 @@ static void __cmd_lat(void)
1724 read_events(); 1708 read_events();
1725 sort_lat(); 1709 sort_lat();
1726 1710
1727 printf("\n -----------------------------------------------------------------------------------------\n"); 1711 printf("\n ---------------------------------------------------------------------------------------------------------------\n");
1728 printf(" Task | Runtime ms | Switches | Average delay ms | Maximum delay ms |\n"); 1712 printf(" Task | Runtime ms | Switches | Average delay ms | Maximum delay ms | Maximum delay at |\n");
1729 printf(" -----------------------------------------------------------------------------------------\n"); 1713 printf(" ---------------------------------------------------------------------------------------------------------------\n");
1730 1714
1731 next = rb_first(&sorted_atom_root); 1715 next = rb_first(&sorted_atom_root);
1732 1716
@@ -1902,13 +1886,18 @@ static int __cmd_record(int argc, const char **argv)
1902 1886
1903int cmd_sched(int argc, const char **argv, const char *prefix __used) 1887int cmd_sched(int argc, const char **argv, const char *prefix __used)
1904{ 1888{
1905 symbol__init(0);
1906
1907 argc = parse_options(argc, argv, sched_options, sched_usage, 1889 argc = parse_options(argc, argv, sched_options, sched_usage,
1908 PARSE_OPT_STOP_AT_NON_OPTION); 1890 PARSE_OPT_STOP_AT_NON_OPTION);
1909 if (!argc) 1891 if (!argc)
1910 usage_with_options(sched_usage, sched_options); 1892 usage_with_options(sched_usage, sched_options);
1911 1893
1894 /*
1895 * Aliased to 'perf trace' for now:
1896 */
1897 if (!strcmp(argv[0], "trace"))
1898 return cmd_trace(argc, argv, prefix);
1899
1900 symbol__init(0);
1912 if (!strncmp(argv[0], "rec", 3)) { 1901 if (!strncmp(argv[0], "rec", 3)) {
1913 return __cmd_record(argc, argv); 1902 return __cmd_record(argc, argv);
1914 } else if (!strncmp(argv[0], "lat", 3)) { 1903 } else if (!strncmp(argv[0], "lat", 3)) {
@@ -1932,11 +1921,6 @@ int cmd_sched(int argc, const char **argv, const char *prefix __used)
1932 usage_with_options(replay_usage, replay_options); 1921 usage_with_options(replay_usage, replay_options);
1933 } 1922 }
1934 __cmd_replay(); 1923 __cmd_replay();
1935 } else if (!strcmp(argv[0], "trace")) {
1936 /*
1937 * Aliased to 'perf trace' for now:
1938 */
1939 return cmd_trace(argc, argv, prefix);
1940 } else { 1924 } else {
1941 usage_with_options(sched_usage, sched_options); 1925 usage_with_options(sched_usage, sched_options);
1942 } 1926 }
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index cb58b6605fcc..f472df9561ee 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -302,12 +302,11 @@ process_exit_event(event_t *event)
302} 302}
303 303
304struct trace_entry { 304struct trace_entry {
305 u32 size;
306 unsigned short type; 305 unsigned short type;
307 unsigned char flags; 306 unsigned char flags;
308 unsigned char preempt_count; 307 unsigned char preempt_count;
309 int pid; 308 int pid;
310 int tgid; 309 int lock_depth;
311}; 310};
312 311
313struct power_entry { 312struct power_entry {
@@ -484,43 +483,22 @@ static void sched_switch(int cpu, u64 timestamp, struct trace_entry *te)
484static int 483static int
485process_sample_event(event_t *event) 484process_sample_event(event_t *event)
486{ 485{
487 int cursor = 0; 486 struct sample_data data;
488 u64 addr = 0;
489 u64 stamp = 0;
490 u32 cpu = 0;
491 u32 pid = 0;
492 struct trace_entry *te; 487 struct trace_entry *te;
493 488
494 if (sample_type & PERF_SAMPLE_IP) 489 memset(&data, 0, sizeof(data));
495 cursor++;
496
497 if (sample_type & PERF_SAMPLE_TID) {
498 pid = event->sample.array[cursor]>>32;
499 cursor++;
500 }
501 if (sample_type & PERF_SAMPLE_TIME) {
502 stamp = event->sample.array[cursor++];
503 490
504 if (!first_time || first_time > stamp) 491 event__parse_sample(event, sample_type, &data);
505 first_time = stamp;
506 if (last_time < stamp)
507 last_time = stamp;
508 492
493 if (sample_type & PERF_SAMPLE_TIME) {
494 if (!first_time || first_time > data.time)
495 first_time = data.time;
496 if (last_time < data.time)
497 last_time = data.time;
509 } 498 }
510 if (sample_type & PERF_SAMPLE_ADDR)
511 addr = event->sample.array[cursor++];
512 if (sample_type & PERF_SAMPLE_ID)
513 cursor++;
514 if (sample_type & PERF_SAMPLE_STREAM_ID)
515 cursor++;
516 if (sample_type & PERF_SAMPLE_CPU)
517 cpu = event->sample.array[cursor++] & 0xFFFFFFFF;
518 if (sample_type & PERF_SAMPLE_PERIOD)
519 cursor++;
520
521 te = (void *)&event->sample.array[cursor];
522 499
523 if (sample_type & PERF_SAMPLE_RAW && te->size > 0) { 500 te = (void *)data.raw_data;
501 if (sample_type & PERF_SAMPLE_RAW && data.raw_size > 0) {
524 char *event_str; 502 char *event_str;
525 struct power_entry *pe; 503 struct power_entry *pe;
526 504
@@ -532,19 +510,19 @@ process_sample_event(event_t *event)
532 return 0; 510 return 0;
533 511
534 if (strcmp(event_str, "power:power_start") == 0) 512 if (strcmp(event_str, "power:power_start") == 0)
535 c_state_start(cpu, stamp, pe->value); 513 c_state_start(data.cpu, data.time, pe->value);
536 514
537 if (strcmp(event_str, "power:power_end") == 0) 515 if (strcmp(event_str, "power:power_end") == 0)
538 c_state_end(cpu, stamp); 516 c_state_end(data.cpu, data.time);
539 517
540 if (strcmp(event_str, "power:power_frequency") == 0) 518 if (strcmp(event_str, "power:power_frequency") == 0)
541 p_state_change(cpu, stamp, pe->value); 519 p_state_change(data.cpu, data.time, pe->value);
542 520
543 if (strcmp(event_str, "sched:sched_wakeup") == 0) 521 if (strcmp(event_str, "sched:sched_wakeup") == 0)
544 sched_wakeup(cpu, stamp, pid, te); 522 sched_wakeup(data.cpu, data.time, data.pid, te);
545 523
546 if (strcmp(event_str, "sched:sched_switch") == 0) 524 if (strcmp(event_str, "sched:sched_switch") == 0)
547 sched_switch(cpu, stamp, te); 525 sched_switch(data.cpu, data.time, te);
548 } 526 }
549 return 0; 527 return 0;
550} 528}
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index abb914aa7be6..c2fcc34486f5 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -66,58 +66,40 @@ static u64 sample_type;
66 66
67static int process_sample_event(event_t *event) 67static int process_sample_event(event_t *event)
68{ 68{
69 u64 ip = event->ip.ip; 69 struct sample_data data;
70 u64 timestamp = -1; 70 struct thread *thread;
71 u32 cpu = -1;
72 u64 period = 1;
73 void *more_data = event->ip.__more_data;
74 struct thread *thread = threads__findnew(event->ip.pid);
75
76 if (sample_type & PERF_SAMPLE_TIME) {
77 timestamp = *(u64 *)more_data;
78 more_data += sizeof(u64);
79 }
80 71
81 if (sample_type & PERF_SAMPLE_CPU) { 72 memset(&data, 0, sizeof(data));
82 cpu = *(u32 *)more_data; 73 data.time = -1;
83 more_data += sizeof(u32); 74 data.cpu = -1;
84 more_data += sizeof(u32); /* reserved */ 75 data.period = 1;
85 }
86 76
87 if (sample_type & PERF_SAMPLE_PERIOD) { 77 event__parse_sample(event, sample_type, &data);
88 period = *(u64 *)more_data;
89 more_data += sizeof(u64);
90 }
91 78
92 dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", 79 dump_printf("(IP, %d): %d/%d: %p period: %Ld\n",
93 event->header.misc, 80 event->header.misc,
94 event->ip.pid, event->ip.tid, 81 data.pid, data.tid,
95 (void *)(long)ip, 82 (void *)(long)data.ip,
96 (long long)period); 83 (long long)data.period);
97 84
85 thread = threads__findnew(event->ip.pid);
98 if (thread == NULL) { 86 if (thread == NULL) {
99 pr_debug("problem processing %d event, skipping it.\n", 87 pr_debug("problem processing %d event, skipping it.\n",
100 event->header.type); 88 event->header.type);
101 return -1; 89 return -1;
102 } 90 }
103 91
104 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
105
106 if (sample_type & PERF_SAMPLE_RAW) { 92 if (sample_type & PERF_SAMPLE_RAW) {
107 struct {
108 u32 size;
109 char data[0];
110 } *raw = more_data;
111
112 /* 93 /*
113 * FIXME: better resolve from pid from the struct trace_entry 94 * FIXME: better resolve from pid from the struct trace_entry
114 * field, although it should be the same than this perf 95 * field, although it should be the same than this perf
115 * event pid 96 * event pid
116 */ 97 */
117 scripting_ops->process_event(cpu, raw->data, raw->size, 98 scripting_ops->process_event(data.cpu, data.raw_data,
118 timestamp, thread->comm); 99 data.raw_size,
100 data.time, thread->comm);
119 } 101 }
120 event__stats.total += period; 102 event__stats.total += data.period;
121 103
122 return 0; 104 return 0;
123} 105}
diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c
index ca0bedf637c2..59b65d0bd7c1 100644
--- a/tools/perf/util/data_map.c
+++ b/tools/perf/util/data_map.c
@@ -100,11 +100,11 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
100 } 100 }
101} 101}
102 102
103int perf_header__read_build_ids(int input, off_t offset, off_t size) 103int perf_header__read_build_ids(int input, u64 offset, u64 size)
104{ 104{
105 struct build_id_event bev; 105 struct build_id_event bev;
106 char filename[PATH_MAX]; 106 char filename[PATH_MAX];
107 off_t limit = offset + size; 107 u64 limit = offset + size;
108 int err = -1; 108 int err = -1;
109 109
110 while (offset < limit) { 110 while (offset < limit) {
diff --git a/tools/perf/util/data_map.h b/tools/perf/util/data_map.h
index 3180ff7e3633..258a87bcc4fb 100644
--- a/tools/perf/util/data_map.h
+++ b/tools/perf/util/data_map.h
@@ -27,6 +27,6 @@ int mmap_dispatch_perf_file(struct perf_header **pheader,
27 int full_paths, 27 int full_paths,
28 int *cwdlen, 28 int *cwdlen,
29 char **cwd); 29 char **cwd);
30int perf_header__read_build_ids(int input, off_t offset, off_t file_size); 30int perf_header__read_build_ids(int input, u64 offset, u64 file_size);
31 31
32#endif 32#endif
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 414b89d1bde9..4dcecafa85dc 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -310,3 +310,70 @@ int event__preprocess_sample(const event_t *self, struct addr_location *al,
310 al->level == 'H' ? "[hypervisor]" : "<not found>"); 310 al->level == 'H' ? "[hypervisor]" : "<not found>");
311 return 0; 311 return 0;
312} 312}
313
314int event__parse_sample(event_t *event, u64 type, struct sample_data *data)
315{
316 u64 *array = event->sample.array;
317
318 if (type & PERF_SAMPLE_IP) {
319 data->ip = event->ip.ip;
320 array++;
321 }
322
323 if (type & PERF_SAMPLE_TID) {
324 u32 *p = (u32 *)array;
325 data->pid = p[0];
326 data->tid = p[1];
327 array++;
328 }
329
330 if (type & PERF_SAMPLE_TIME) {
331 data->time = *array;
332 array++;
333 }
334
335 if (type & PERF_SAMPLE_ADDR) {
336 data->addr = *array;
337 array++;
338 }
339
340 if (type & PERF_SAMPLE_ID) {
341 data->id = *array;
342 array++;
343 }
344
345 if (type & PERF_SAMPLE_STREAM_ID) {
346 data->stream_id = *array;
347 array++;
348 }
349
350 if (type & PERF_SAMPLE_CPU) {
351 u32 *p = (u32 *)array;
352 data->cpu = *p;
353 array++;
354 }
355
356 if (type & PERF_SAMPLE_PERIOD) {
357 data->period = *array;
358 array++;
359 }
360
361 if (type & PERF_SAMPLE_READ) {
362 pr_debug("PERF_SAMPLE_READ is unsuported for now\n");
363 return -1;
364 }
365
366 if (type & PERF_SAMPLE_CALLCHAIN) {
367 data->callchain = (struct ip_callchain *)array;
368 array += 1 + data->callchain->nr;
369 }
370
371 if (type & PERF_SAMPLE_RAW) {
372 u32 *p = (u32 *)array;
373 data->raw_size = *p;
374 p++;
375 data->raw_data = p;
376 }
377
378 return 0;
379}
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index a4cc8105cf67..c7a78eef8e52 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -56,11 +56,25 @@ struct read_event {
56 u64 id; 56 u64 id;
57}; 57};
58 58
59struct sample_event{ 59struct sample_event {
60 struct perf_event_header header; 60 struct perf_event_header header;
61 u64 array[]; 61 u64 array[];
62}; 62};
63 63
64struct sample_data {
65 u64 ip;
66 u32 pid, tid;
67 u64 time;
68 u64 addr;
69 u64 id;
70 u64 stream_id;
71 u32 cpu;
72 u64 period;
73 struct ip_callchain *callchain;
74 u32 raw_size;
75 void *raw_data;
76};
77
64#define BUILD_ID_SIZE 20 78#define BUILD_ID_SIZE 20
65 79
66struct build_id_event { 80struct build_id_event {
@@ -155,5 +169,6 @@ int event__process_task(event_t *self);
155struct addr_location; 169struct addr_location;
156int event__preprocess_sample(const event_t *self, struct addr_location *al, 170int event__preprocess_sample(const event_t *self, struct addr_location *al,
157 symbol_filter_t filter); 171 symbol_filter_t filter);
172int event__parse_sample(event_t *event, u64 type, struct sample_data *data);
158 173
159#endif /* __PERF_RECORD_H */ 174#endif /* __PERF_RECORD_H */
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 4805e6dfd23c..59a9c0b3033e 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -187,7 +187,9 @@ static int do_write(int fd, const void *buf, size_t size)
187 187
188static int __dsos__write_buildid_table(struct list_head *head, int fd) 188static int __dsos__write_buildid_table(struct list_head *head, int fd)
189{ 189{
190#define NAME_ALIGN 64
190 struct dso *pos; 191 struct dso *pos;
192 static const char zero_buf[NAME_ALIGN];
191 193
192 list_for_each_entry(pos, head, node) { 194 list_for_each_entry(pos, head, node) {
193 int err; 195 int err;
@@ -197,14 +199,17 @@ static int __dsos__write_buildid_table(struct list_head *head, int fd)
197 if (!pos->has_build_id) 199 if (!pos->has_build_id)
198 continue; 200 continue;
199 len = pos->long_name_len + 1; 201 len = pos->long_name_len + 1;
200 len = ALIGN(len, 64); 202 len = ALIGN(len, NAME_ALIGN);
201 memset(&b, 0, sizeof(b)); 203 memset(&b, 0, sizeof(b));
202 memcpy(&b.build_id, pos->build_id, sizeof(pos->build_id)); 204 memcpy(&b.build_id, pos->build_id, sizeof(pos->build_id));
203 b.header.size = sizeof(b) + len; 205 b.header.size = sizeof(b) + len;
204 err = do_write(fd, &b, sizeof(b)); 206 err = do_write(fd, &b, sizeof(b));
205 if (err < 0) 207 if (err < 0)
206 return err; 208 return err;
207 err = do_write(fd, pos->long_name, len); 209 err = do_write(fd, pos->long_name, pos->long_name_len + 1);
210 if (err < 0)
211 return err;
212 err = do_write(fd, zero_buf, len - pos->long_name_len - 1);
208 if (err < 0) 213 if (err < 0)
209 return err; 214 return err;
210 } 215 }
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 9e5dbd66d34d..e5bc0fb016b2 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -197,7 +197,7 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
197 if (id == config) { 197 if (id == config) {
198 closedir(evt_dir); 198 closedir(evt_dir);
199 closedir(sys_dir); 199 closedir(sys_dir);
200 path = zalloc(sizeof(path)); 200 path = zalloc(sizeof(*path));
201 path->system = malloc(MAX_EVENT_LENGTH); 201 path->system = malloc(MAX_EVENT_LENGTH);
202 if (!path->system) { 202 if (!path->system) {
203 free(path); 203 free(path);
@@ -467,7 +467,6 @@ parse_subsystem_tracepoint_event(char *sys_name, char *flags)
467 while ((evt_ent = readdir(evt_dir))) { 467 while ((evt_ent = readdir(evt_dir))) {
468 char event_opt[MAX_EVOPT_LEN + 1]; 468 char event_opt[MAX_EVOPT_LEN + 1];
469 int len; 469 int len;
470 unsigned int rem = MAX_EVOPT_LEN;
471 470
472 if (!strcmp(evt_ent->d_name, ".") 471 if (!strcmp(evt_ent->d_name, ".")
473 || !strcmp(evt_ent->d_name, "..") 472 || !strcmp(evt_ent->d_name, "..")
@@ -475,20 +474,12 @@ parse_subsystem_tracepoint_event(char *sys_name, char *flags)
475 || !strcmp(evt_ent->d_name, "filter")) 474 || !strcmp(evt_ent->d_name, "filter"))
476 continue; 475 continue;
477 476
478 len = snprintf(event_opt, MAX_EVOPT_LEN, "%s:%s", sys_name, 477 len = snprintf(event_opt, MAX_EVOPT_LEN, "%s:%s%s%s", sys_name,
479 evt_ent->d_name); 478 evt_ent->d_name, flags ? ":" : "",
479 flags ?: "");
480 if (len < 0) 480 if (len < 0)
481 return EVT_FAILED; 481 return EVT_FAILED;
482 482
483 rem -= len;
484 if (flags) {
485 if (rem < strlen(flags) + 1)
486 return EVT_FAILED;
487
488 strcat(event_opt, ":");
489 strcat(event_opt, flags);
490 }
491
492 if (parse_events(NULL, event_opt, 0)) 483 if (parse_events(NULL, event_opt, 0))
493 return EVT_FAILED; 484 return EVT_FAILED;
494 } 485 }
diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c
index 6d8af48c925e..efebd5b476b3 100644
--- a/tools/perf/util/parse-options.c
+++ b/tools/perf/util/parse-options.c
@@ -430,6 +430,9 @@ int usage_with_options_internal(const char * const *usagestr,
430 pos = fprintf(stderr, " "); 430 pos = fprintf(stderr, " ");
431 if (opts->short_name) 431 if (opts->short_name)
432 pos += fprintf(stderr, "-%c", opts->short_name); 432 pos += fprintf(stderr, "-%c", opts->short_name);
433 else
434 pos += fprintf(stderr, " ");
435
433 if (opts->long_name && opts->short_name) 436 if (opts->long_name && opts->short_name)
434 pos += fprintf(stderr, ", "); 437 pos += fprintf(stderr, ", ");
435 if (opts->long_name) 438 if (opts->long_name)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index cd7fbda5e2a5..d14a4585bcaf 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -48,6 +48,9 @@
48 48
49/* If there is no space to write, returns -E2BIG. */ 49/* If there is no space to write, returns -E2BIG. */
50static int e_snprintf(char *str, size_t size, const char *format, ...) 50static int e_snprintf(char *str, size_t size, const char *format, ...)
51 __attribute__((format(printf, 3, 4)));
52
53static int e_snprintf(char *str, size_t size, const char *format, ...)
51{ 54{
52 int ret; 55 int ret;
53 va_list ap; 56 va_list ap;
@@ -258,7 +261,7 @@ int synthesize_perf_probe_event(struct probe_point *pp)
258 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s", pp->function, 261 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s", pp->function,
259 offs, pp->retprobe ? "%return" : "", line); 262 offs, pp->retprobe ? "%return" : "", line);
260 else 263 else
261 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s", pp->file, line); 264 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", pp->file, line);
262 if (ret <= 0) 265 if (ret <= 0)
263 goto error; 266 goto error;
264 len = ret; 267 len = ret;
@@ -373,14 +376,32 @@ static void clear_probe_point(struct probe_point *pp)
373 free(pp->args); 376 free(pp->args);
374 for (i = 0; i < pp->found; i++) 377 for (i = 0; i < pp->found; i++)
375 free(pp->probes[i]); 378 free(pp->probes[i]);
376 memset(pp, 0, sizeof(pp)); 379 memset(pp, 0, sizeof(*pp));
380}
381
382/* Show an event */
383static void show_perf_probe_event(const char *group, const char *event,
384 const char *place, struct probe_point *pp)
385{
386 int i;
387 char buf[128];
388
389 e_snprintf(buf, 128, "%s:%s", group, event);
390 printf(" %-40s (on %s", buf, place);
391
392 if (pp->nr_args > 0) {
393 printf(" with");
394 for (i = 0; i < pp->nr_args; i++)
395 printf(" %s", pp->args[i]);
396 }
397 printf(")\n");
377} 398}
378 399
379/* List up current perf-probe events */ 400/* List up current perf-probe events */
380void show_perf_probe_events(void) 401void show_perf_probe_events(void)
381{ 402{
382 unsigned int i; 403 unsigned int i;
383 int fd; 404 int fd, nr;
384 char *group, *event; 405 char *group, *event;
385 struct probe_point pp; 406 struct probe_point pp;
386 struct strlist *rawlist; 407 struct strlist *rawlist;
@@ -393,8 +414,13 @@ void show_perf_probe_events(void)
393 for (i = 0; i < strlist__nr_entries(rawlist); i++) { 414 for (i = 0; i < strlist__nr_entries(rawlist); i++) {
394 ent = strlist__entry(rawlist, i); 415 ent = strlist__entry(rawlist, i);
395 parse_trace_kprobe_event(ent->s, &group, &event, &pp); 416 parse_trace_kprobe_event(ent->s, &group, &event, &pp);
417 /* Synthesize only event probe point */
418 nr = pp.nr_args;
419 pp.nr_args = 0;
396 synthesize_perf_probe_event(&pp); 420 synthesize_perf_probe_event(&pp);
397 printf("[%s:%s]\t%s\n", group, event, pp.probes[0]); 421 pp.nr_args = nr;
422 /* Show an event */
423 show_perf_probe_event(group, event, pp.probes[0], &pp);
398 free(group); 424 free(group);
399 free(event); 425 free(event);
400 clear_probe_point(&pp); 426 clear_probe_point(&pp);
@@ -404,21 +430,28 @@ void show_perf_probe_events(void)
404} 430}
405 431
406/* Get current perf-probe event names */ 432/* Get current perf-probe event names */
407static struct strlist *get_perf_event_names(int fd) 433static struct strlist *get_perf_event_names(int fd, bool include_group)
408{ 434{
409 unsigned int i; 435 unsigned int i;
410 char *group, *event; 436 char *group, *event;
437 char buf[128];
411 struct strlist *sl, *rawlist; 438 struct strlist *sl, *rawlist;
412 struct str_node *ent; 439 struct str_node *ent;
413 440
414 rawlist = get_trace_kprobe_event_rawlist(fd); 441 rawlist = get_trace_kprobe_event_rawlist(fd);
415 442
416 sl = strlist__new(false, NULL); 443 sl = strlist__new(true, NULL);
417 for (i = 0; i < strlist__nr_entries(rawlist); i++) { 444 for (i = 0; i < strlist__nr_entries(rawlist); i++) {
418 ent = strlist__entry(rawlist, i); 445 ent = strlist__entry(rawlist, i);
419 parse_trace_kprobe_event(ent->s, &group, &event, NULL); 446 parse_trace_kprobe_event(ent->s, &group, &event, NULL);
420 strlist__add(sl, event); 447 if (include_group) {
448 if (e_snprintf(buf, 128, "%s:%s", group, event) < 0)
449 die("Failed to copy group:event name.");
450 strlist__add(sl, buf);
451 } else
452 strlist__add(sl, event);
421 free(group); 453 free(group);
454 free(event);
422 } 455 }
423 456
424 strlist__delete(rawlist); 457 strlist__delete(rawlist);
@@ -426,24 +459,30 @@ static struct strlist *get_perf_event_names(int fd)
426 return sl; 459 return sl;
427} 460}
428 461
429static int write_trace_kprobe_event(int fd, const char *buf) 462static void write_trace_kprobe_event(int fd, const char *buf)
430{ 463{
431 int ret; 464 int ret;
432 465
466 pr_debug("Writing event: %s\n", buf);
433 ret = write(fd, buf, strlen(buf)); 467 ret = write(fd, buf, strlen(buf));
434 if (ret <= 0) 468 if (ret <= 0)
435 die("Failed to create event."); 469 die("Failed to write event: %s", strerror(errno));
436 else
437 printf("Added new event: %s\n", buf);
438
439 return ret;
440} 470}
441 471
442static void get_new_event_name(char *buf, size_t len, const char *base, 472static void get_new_event_name(char *buf, size_t len, const char *base,
443 struct strlist *namelist) 473 struct strlist *namelist)
444{ 474{
445 int i, ret; 475 int i, ret;
446 for (i = 0; i < MAX_EVENT_INDEX; i++) { 476
477 /* Try no suffix */
478 ret = e_snprintf(buf, len, "%s", base);
479 if (ret < 0)
480 die("snprintf() failed: %s", strerror(-ret));
481 if (!strlist__has_entry(namelist, buf))
482 return;
483
484 /* Try to add suffix */
485 for (i = 1; i < MAX_EVENT_INDEX; i++) {
447 ret = e_snprintf(buf, len, "%s_%d", base, i); 486 ret = e_snprintf(buf, len, "%s_%d", base, i);
448 if (ret < 0) 487 if (ret < 0)
449 die("snprintf() failed: %s", strerror(-ret)); 488 die("snprintf() failed: %s", strerror(-ret));
@@ -464,7 +503,7 @@ void add_trace_kprobe_events(struct probe_point *probes, int nr_probes)
464 503
465 fd = open_kprobe_events(O_RDWR, O_APPEND); 504 fd = open_kprobe_events(O_RDWR, O_APPEND);
466 /* Get current event names */ 505 /* Get current event names */
467 namelist = get_perf_event_names(fd); 506 namelist = get_perf_event_names(fd, false);
468 507
469 for (j = 0; j < nr_probes; j++) { 508 for (j = 0; j < nr_probes; j++) {
470 pp = probes + j; 509 pp = probes + j;
@@ -476,9 +515,73 @@ void add_trace_kprobe_events(struct probe_point *probes, int nr_probes)
476 PERFPROBE_GROUP, event, 515 PERFPROBE_GROUP, event,
477 pp->probes[i]); 516 pp->probes[i]);
478 write_trace_kprobe_event(fd, buf); 517 write_trace_kprobe_event(fd, buf);
518 printf("Added new event:\n");
519 /* Get the first parameter (probe-point) */
520 sscanf(pp->probes[i], "%s", buf);
521 show_perf_probe_event(PERFPROBE_GROUP, event,
522 buf, pp);
479 /* Add added event name to namelist */ 523 /* Add added event name to namelist */
480 strlist__add(namelist, event); 524 strlist__add(namelist, event);
481 } 525 }
482 } 526 }
527 /* Show how to use the event. */
528 printf("\nYou can now use it on all perf tools, such as:\n\n");
529 printf("\tperf record -e %s:%s -a sleep 1\n\n", PERFPROBE_GROUP, event);
530
531 strlist__delete(namelist);
532 close(fd);
533}
534
535static void del_trace_kprobe_event(int fd, const char *group,
536 const char *event, struct strlist *namelist)
537{
538 char buf[128];
539
540 if (e_snprintf(buf, 128, "%s:%s", group, event) < 0)
541 die("Failed to copy event.");
542 if (!strlist__has_entry(namelist, buf)) {
543 pr_warning("Warning: event \"%s\" is not found.\n", buf);
544 return;
545 }
546 /* Convert from perf-probe event to trace-kprobe event */
547 if (e_snprintf(buf, 128, "-:%s/%s", group, event) < 0)
548 die("Failed to copy event.");
549
550 write_trace_kprobe_event(fd, buf);
551 printf("Remove event: %s:%s\n", group, event);
552}
553
554void del_trace_kprobe_events(struct strlist *dellist)
555{
556 int fd;
557 unsigned int i;
558 const char *group, *event;
559 char *p, *str;
560 struct str_node *ent;
561 struct strlist *namelist;
562
563 fd = open_kprobe_events(O_RDWR, O_APPEND);
564 /* Get current event names */
565 namelist = get_perf_event_names(fd, true);
566
567 for (i = 0; i < strlist__nr_entries(dellist); i++) {
568 ent = strlist__entry(dellist, i);
569 str = strdup(ent->s);
570 if (!str)
571 die("Failed to copy event.");
572 p = strchr(str, ':');
573 if (p) {
574 group = str;
575 *p = '\0';
576 event = p + 1;
577 } else {
578 group = PERFPROBE_GROUP;
579 event = str;
580 }
581 del_trace_kprobe_event(fd, group, event, namelist);
582 free(str);
583 }
584 strlist__delete(namelist);
483 close(fd); 585 close(fd);
484} 586}
587
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 0c6fe56fe38a..f752159124ae 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -10,6 +10,7 @@ extern void parse_trace_kprobe_event(const char *str, char **group,
10 char **event, struct probe_point *pp); 10 char **event, struct probe_point *pp);
11extern int synthesize_trace_kprobe_event(struct probe_point *pp); 11extern int synthesize_trace_kprobe_event(struct probe_point *pp);
12extern void add_trace_kprobe_events(struct probe_point *probes, int nr_probes); 12extern void add_trace_kprobe_events(struct probe_point *probes, int nr_probes);
13extern void del_trace_kprobe_events(struct strlist *dellist);
13extern void show_perf_probe_events(void); 14extern void show_perf_probe_events(void);
14 15
15/* Maximum index number of event-name postfix */ 16/* Maximum index number of event-name postfix */
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 293cdfc1b8ca..4585f1d86792 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -106,7 +106,7 @@ static int strtailcmp(const char *s1, const char *s2)
106{ 106{
107 int i1 = strlen(s1); 107 int i1 = strlen(s1);
108 int i2 = strlen(s2); 108 int i2 = strlen(s2);
109 while (--i1 > 0 && --i2 > 0) { 109 while (--i1 >= 0 && --i2 >= 0) {
110 if (s1[i1] != s2[i2]) 110 if (s1[i1] != s2[i2])
111 return s1[i1] - s2[i2]; 111 return s1[i1] - s2[i2];
112 } 112 }
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index fffcb937cdcb..e7508ad3450f 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -938,8 +938,9 @@ static bool __dsos__read_build_ids(struct list_head *head)
938 938
939bool dsos__read_build_ids(void) 939bool dsos__read_build_ids(void)
940{ 940{
941 return __dsos__read_build_ids(&dsos__kernel) || 941 bool kbuildids = __dsos__read_build_ids(&dsos__kernel),
942 __dsos__read_build_ids(&dsos__user); 942 ubuildids = __dsos__read_build_ids(&dsos__user);
943 return kbuildids || ubuildids;
943} 944}
944 945
945/* 946/*
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 0302405aa2ca..c5c32be040bf 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -177,7 +177,7 @@ void parse_proc_kallsyms(char *file, unsigned int size __unused)
177 func_count++; 177 func_count++;
178 } 178 }
179 179
180 func_list = malloc_or_die(sizeof(*func_list) * func_count + 1); 180 func_list = malloc_or_die(sizeof(*func_list) * (func_count + 1));
181 181
182 i = 0; 182 i = 0;
183 while (list) { 183 while (list) {
@@ -1477,7 +1477,7 @@ process_fields(struct event *event, struct print_flag_sym **list, char **tok)
1477 goto out_free; 1477 goto out_free;
1478 1478
1479 field = malloc_or_die(sizeof(*field)); 1479 field = malloc_or_die(sizeof(*field));
1480 memset(field, 0, sizeof(field)); 1480 memset(field, 0, sizeof(*field));
1481 1481
1482 value = arg_eval(arg); 1482 value = arg_eval(arg);
1483 field->value = strdup(value); 1483 field->value = strdup(value);
diff --git a/tools/perf/util/trace-event-perl.c b/tools/perf/util/trace-event-perl.c
index 51e833fd58c3..a5ffe60db5d6 100644
--- a/tools/perf/util/trace-event-perl.c
+++ b/tools/perf/util/trace-event-perl.c
@@ -32,9 +32,6 @@
32 32
33void xs_init(pTHX); 33void xs_init(pTHX);
34 34
35void boot_Perf__Trace__Context(pTHX_ CV *cv);
36void boot_DynaLoader(pTHX_ CV *cv);
37
38void xs_init(pTHX) 35void xs_init(pTHX)
39{ 36{
40 const char *file = __FILE__; 37 const char *file = __FILE__;
@@ -573,26 +570,72 @@ struct scripting_ops perl_scripting_ops = {
573 .generate_script = perl_generate_script, 570 .generate_script = perl_generate_script,
574}; 571};
575 572
576#ifdef NO_LIBPERL 573static void print_unsupported_msg(void)
577void setup_perl_scripting(void)
578{ 574{
579 fprintf(stderr, "Perl scripting not supported." 575 fprintf(stderr, "Perl scripting not supported."
580 " Install libperl and rebuild perf to enable it. e.g. " 576 " Install libperl and rebuild perf to enable it.\n"
581 "apt-get install libperl-dev (ubuntu), yum install " 577 "For example:\n # apt-get install libperl-dev (ubuntu)"
582 "perl-ExtUtils-Embed (Fedora), etc.\n"); 578 "\n # yum install perl-ExtUtils-Embed (Fedora)"
579 "\n etc.\n");
583} 580}
584#else 581
585void setup_perl_scripting(void) 582static int perl_start_script_unsupported(const char *script __unused)
583{
584 print_unsupported_msg();
585
586 return -1;
587}
588
589static int perl_stop_script_unsupported(void)
590{
591 return 0;
592}
593
594static void perl_process_event_unsupported(int cpu __unused,
595 void *data __unused,
596 int size __unused,
597 unsigned long long nsecs __unused,
598 char *comm __unused)
599{
600}
601
602static int perl_generate_script_unsupported(const char *outfile __unused)
603{
604 print_unsupported_msg();
605
606 return -1;
607}
608
609struct scripting_ops perl_scripting_unsupported_ops = {
610 .name = "Perl",
611 .start_script = perl_start_script_unsupported,
612 .stop_script = perl_stop_script_unsupported,
613 .process_event = perl_process_event_unsupported,
614 .generate_script = perl_generate_script_unsupported,
615};
616
617static void register_perl_scripting(struct scripting_ops *scripting_ops)
586{ 618{
587 int err; 619 int err;
588 err = script_spec_register("Perl", &perl_scripting_ops); 620 err = script_spec_register("Perl", scripting_ops);
589 if (err) 621 if (err)
590 die("error registering Perl script extension"); 622 die("error registering Perl script extension");
591 623
592 err = script_spec_register("pl", &perl_scripting_ops); 624 err = script_spec_register("pl", scripting_ops);
593 if (err) 625 if (err)
594 die("error registering pl script extension"); 626 die("error registering pl script extension");
595 627
596 scripting_context = malloc(sizeof(struct scripting_context)); 628 scripting_context = malloc(sizeof(struct scripting_context));
597} 629}
630
631#ifdef NO_LIBPERL
632void setup_perl_scripting(void)
633{
634 register_perl_scripting(&perl_scripting_unsupported_ops);
635}
636#else
637void setup_perl_scripting(void)
638{
639 register_perl_scripting(&perl_scripting_ops);
640}
598#endif 641#endif
diff --git a/tools/perf/util/trace-event-perl.h b/tools/perf/util/trace-event-perl.h
index 8fe0d866fe1a..e88fb26137bb 100644
--- a/tools/perf/util/trace-event-perl.h
+++ b/tools/perf/util/trace-event-perl.h
@@ -34,9 +34,13 @@ typedef int INTERP;
34#define dXSUB_SYS 34#define dXSUB_SYS
35#define pTHX_ 35#define pTHX_
36static inline void newXS(const char *a, void *b, const char *c) {} 36static inline void newXS(const char *a, void *b, const char *c) {}
37static void boot_Perf__Trace__Context(pTHX_ CV *cv) {}
38static void boot_DynaLoader(pTHX_ CV *cv) {}
37#else 39#else
38#include <EXTERN.h> 40#include <EXTERN.h>
39#include <perl.h> 41#include <perl.h>
42void boot_Perf__Trace__Context(pTHX_ CV *cv);
43void boot_DynaLoader(pTHX_ CV *cv);
40typedef PerlInterpreter * INTERP; 44typedef PerlInterpreter * INTERP;
41#endif 45#endif
42 46
diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index 342dfdd43f87..1744422cafcb 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -145,8 +145,9 @@ static void read_proc_kallsyms(void)
145 if (!size) 145 if (!size)
146 return; 146 return;
147 147
148 buf = malloc_or_die(size); 148 buf = malloc_or_die(size + 1);
149 read_or_die(buf, size); 149 read_or_die(buf, size);
150 buf[size] = '\0';
150 151
151 parse_proc_kallsyms(buf, size); 152 parse_proc_kallsyms(buf, size);
152 153