aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-26 11:03:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-26 11:03:38 -0400
commit7115e3fcf45514db7525a05365b10454ff7f345e (patch)
tree17450e6337d559cc35dae6a7a73abab01ac63f00
parent1f6e05171bb5cc32a4d6437ab2269fc21d169ca7 (diff)
parentc752d04066a36ae30b29795f3fa3f536292c1f8c (diff)
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (121 commits) perf symbols: Increase symbol KSYM_NAME_LEN size perf hists browser: Refuse 'a' hotkey on non symbolic views perf ui browser: Use libslang to read keys perf tools: Fix tracing info recording perf hists browser: Elide DSO column when it is set to just one DSO, ditto for threads perf hists: Don't consider filtered entries when calculating column widths perf hists: Don't decay total_period for filtered entries perf hists browser: Honour symbol_conf.show_{nr_samples,total_period} perf hists browser: Do not exit on tab key with single event perf annotate browser: Don't change selection line when returning from callq perf tools: handle endianness of feature bitmap perf tools: Add prelink suggestion to dso update message perf script: Fix unknown feature comment perf hists browser: Apply the dso and thread filters when merging new batches perf hists: Move the dso and thread filters from hist_browser perf ui browser: Honour the xterm colors perf top tui: Give color hints just on the percentage, like on --stdio perf ui browser: Make the colors configurable and change the defaults perf tui: Remove unneeded call to newtCls on startup perf hists: Don't format the percentage on hist_entry__snprintf ... Fix up conflicts in arch/x86/kernel/kprobes.c manually. Ingo's tree did the insane "add volatile to const array", which just doesn't make sense ("volatile const"?). But we could remove the const *and* make the array volatile to make doubly sure that gcc doesn't optimize it away.. Also fix up kernel/trace/ring_buffer.c non-data-conflicts manually: the reader_lock has been turned into a raw lock by the core locking merge, and there was a new user of it introduced in this perf core merge. Make sure that new use also uses the raw accessor functions.
-rw-r--r--arch/m32r/Kconfig1
-rw-r--r--arch/x86/include/asm/nmi.h37
-rw-r--r--arch/x86/include/asm/perf_event.h55
-rw-r--r--arch/x86/include/asm/reboot.h2
-rw-r--r--arch/x86/kernel/Makefile2
-rw-r--r--arch/x86/kernel/apic/hw_nmi.c27
-rw-r--r--arch/x86/kernel/apic/x2apic_uv_x.c20
-rw-r--r--arch/x86/kernel/cpu/Makefile7
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce-inject.c20
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c23
-rw-r--r--arch/x86/kernel/cpu/perf_event.c442
-rw-r--r--arch/x86/kernel/cpu/perf_event.h505
-rw-r--r--arch/x86/kernel/cpu/perf_event_amd.c38
-rw-r--r--arch/x86/kernel/cpu/perf_event_amd_ibs.c294
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c146
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_ds.c79
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_lbr.c28
-rw-r--r--arch/x86/kernel/cpu/perf_event_p4.c10
-rw-r--r--arch/x86/kernel/cpu/perf_event_p6.c9
-rw-r--r--arch/x86/kernel/crash.c5
-rw-r--r--arch/x86/kernel/jump_label.c2
-rw-r--r--arch/x86/kernel/kgdb.c60
-rw-r--r--arch/x86/kernel/kprobes.c7
-rw-r--r--arch/x86/kernel/nmi.c433
-rw-r--r--arch/x86/kernel/process_32.c2
-rw-r--r--arch/x86/kernel/process_64.c2
-rw-r--r--arch/x86/kernel/reboot.c23
-rw-r--r--arch/x86/kernel/traps.c155
-rw-r--r--arch/x86/oprofile/nmi_int.c40
-rw-r--r--arch/x86/oprofile/nmi_timer_int.c28
-rw-r--r--arch/x86/oprofile/op_model_amd.c234
-rw-r--r--arch/x86/oprofile/op_model_ppro.c27
-rw-r--r--arch/x86/oprofile/op_x86_model.h1
-rw-r--r--drivers/acpi/apei/ghes.c22
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c33
-rw-r--r--drivers/watchdog/hpwdt.c25
-rw-r--r--include/linux/module.h12
-rw-r--r--include/linux/perf_event.h5
-rw-r--r--include/linux/ring_buffer.h2
-rw-r--r--include/linux/trace_clock.h1
-rw-r--r--include/linux/tracepoint.h25
-rw-r--r--include/trace/ftrace.h3
-rw-r--r--kernel/events/core.c101
-rw-r--r--kernel/module.c47
-rw-r--r--kernel/trace/Makefile2
-rw-r--r--kernel/trace/ftrace.c8
-rw-r--r--kernel/trace/ring_buffer.c70
-rw-r--r--kernel/trace/trace.c181
-rw-r--r--kernel/trace/trace.h16
-rw-r--r--kernel/trace/trace_clock.c12
-rw-r--r--kernel/trace/trace_events_filter.c795
-rw-r--r--kernel/trace/trace_events_filter_test.h50
-rw-r--r--kernel/trace/trace_irqsoff.c4
-rw-r--r--kernel/trace/trace_kprobe.c58
-rw-r--r--kernel/trace/trace_printk.c19
-rw-r--r--kernel/tracepoint.c169
-rw-r--r--kernel/watchdog.c7
-rw-r--r--tools/perf/Documentation/perf-annotate.txt13
-rw-r--r--tools/perf/Documentation/perf-buildid-list.txt6
-rw-r--r--tools/perf/Documentation/perf-report.txt20
-rw-r--r--tools/perf/Documentation/perf-sched.txt6
-rw-r--r--tools/perf/Documentation/perf-script.txt7
-rw-r--r--tools/perf/Documentation/perf-stat.txt16
-rw-r--r--tools/perf/Documentation/perf-top.txt48
-rw-r--r--tools/perf/Documentation/perfconfig.example20
-rw-r--r--tools/perf/Makefile5
-rw-r--r--tools/perf/arch/powerpc/Makefile1
-rw-r--r--tools/perf/arch/powerpc/util/header.c36
-rw-r--r--tools/perf/arch/x86/Makefile1
-rw-r--r--tools/perf/arch/x86/util/header.c59
-rw-r--r--tools/perf/builtin-annotate.c25
-rw-r--r--tools/perf/builtin-buildid-list.c52
-rw-r--r--tools/perf/builtin-diff.c2
-rw-r--r--tools/perf/builtin-record.c34
-rw-r--r--tools/perf/builtin-report.c28
-rw-r--r--tools/perf/builtin-script.c6
-rw-r--r--tools/perf/builtin-stat.c190
-rw-r--r--tools/perf/builtin-top.c495
-rw-r--r--tools/perf/builtin.h1
-rw-r--r--tools/perf/perf.c24
-rw-r--r--tools/perf/perf.h13
-rwxr-xr-xtools/perf/scripts/python/bin/net_dropmonitor-record2
-rwxr-xr-xtools/perf/scripts/python/bin/net_dropmonitor-report4
-rwxr-xr-xtools/perf/scripts/python/net_dropmonitor.py72
-rw-r--r--tools/perf/util/annotate.c11
-rw-r--r--tools/perf/util/annotate.h9
-rw-r--r--tools/perf/util/color.c2
-rw-r--r--tools/perf/util/evlist.c6
-rw-r--r--tools/perf/util/evlist.h4
-rw-r--r--tools/perf/util/evsel.c1
-rw-r--r--tools/perf/util/header.c1231
-rw-r--r--tools/perf/util/header.h29
-rw-r--r--tools/perf/util/hist.c447
-rw-r--r--tools/perf/util/hist.h61
-rw-r--r--tools/perf/util/map.c102
-rw-r--r--tools/perf/util/map.h42
-rw-r--r--tools/perf/util/probe-event.c4
-rw-r--r--tools/perf/util/session.c19
-rw-r--r--tools/perf/util/session.h1
-rw-r--r--tools/perf/util/sort.c4
-rw-r--r--tools/perf/util/sort.h2
-rw-r--r--tools/perf/util/symbol.c3
-rw-r--r--tools/perf/util/symbol.h5
-rw-r--r--tools/perf/util/top.c141
-rw-r--r--tools/perf/util/top.h39
-rw-r--r--tools/perf/util/trace-event-info.c112
-rw-r--r--tools/perf/util/trace-event.h13
-rw-r--r--tools/perf/util/ui/browser.c386
-rw-r--r--tools/perf/util/ui/browser.h12
-rw-r--r--tools/perf/util/ui/browsers/annotate.c201
-rw-r--r--tools/perf/util/ui/browsers/hists.c297
-rw-r--r--tools/perf/util/ui/browsers/map.c6
-rw-r--r--tools/perf/util/ui/browsers/top.c212
-rw-r--r--tools/perf/util/ui/helpline.h3
-rw-r--r--tools/perf/util/ui/keysyms.h25
-rw-r--r--tools/perf/util/ui/libslang.h2
-rw-r--r--tools/perf/util/ui/setup.c38
117 files changed, 6208 insertions, 2879 deletions
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index b92b9445255d..6c4e9aaa70c1 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -10,6 +10,7 @@ config M32R
10 select HAVE_GENERIC_HARDIRQS 10 select HAVE_GENERIC_HARDIRQS
11 select GENERIC_IRQ_PROBE 11 select GENERIC_IRQ_PROBE
12 select GENERIC_IRQ_SHOW 12 select GENERIC_IRQ_SHOW
13 select GENERIC_ATOMIC64
13 14
14config SBUS 15config SBUS
15 bool 16 bool
diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h
index 4886a68f267e..fd3f9f18cf3f 100644
--- a/arch/x86/include/asm/nmi.h
+++ b/arch/x86/include/asm/nmi.h
@@ -22,27 +22,26 @@ void arch_trigger_all_cpu_backtrace(void);
22#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace 22#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
23#endif 23#endif
24 24
25/* 25#define NMI_FLAG_FIRST 1
26 * Define some priorities for the nmi notifier call chain. 26
27 * 27enum {
28 * Create a local nmi bit that has a higher priority than 28 NMI_LOCAL=0,
29 * external nmis, because the local ones are more frequent. 29 NMI_UNKNOWN,
30 * 30 NMI_MAX
31 * Also setup some default high/normal/low settings for 31};
32 * subsystems to registers with. Using 4 bits to separate 32
33 * the priorities. This can go a lot higher if needed be. 33#define NMI_DONE 0
34 */ 34#define NMI_HANDLED 1
35 35
36#define NMI_LOCAL_SHIFT 16 /* randomly picked */ 36typedef int (*nmi_handler_t)(unsigned int, struct pt_regs *);
37#define NMI_LOCAL_BIT (1ULL << NMI_LOCAL_SHIFT) 37
38#define NMI_HIGH_PRIOR (1ULL << 8) 38int register_nmi_handler(unsigned int, nmi_handler_t, unsigned long,
39#define NMI_NORMAL_PRIOR (1ULL << 4) 39 const char *);
40#define NMI_LOW_PRIOR (1ULL << 0) 40
41#define NMI_LOCAL_HIGH_PRIOR (NMI_LOCAL_BIT | NMI_HIGH_PRIOR) 41void unregister_nmi_handler(unsigned int, const char *);
42#define NMI_LOCAL_NORMAL_PRIOR (NMI_LOCAL_BIT | NMI_NORMAL_PRIOR)
43#define NMI_LOCAL_LOW_PRIOR (NMI_LOCAL_BIT | NMI_LOW_PRIOR)
44 42
45void stop_nmi(void); 43void stop_nmi(void);
46void restart_nmi(void); 44void restart_nmi(void);
45void local_touch_nmi(void);
47 46
48#endif /* _ASM_X86_NMI_H */ 47#endif /* _ASM_X86_NMI_H */
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 094fb30817ab..f61c62f7d5d8 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -29,6 +29,9 @@
29#define ARCH_PERFMON_EVENTSEL_INV (1ULL << 23) 29#define ARCH_PERFMON_EVENTSEL_INV (1ULL << 23)
30#define ARCH_PERFMON_EVENTSEL_CMASK 0xFF000000ULL 30#define ARCH_PERFMON_EVENTSEL_CMASK 0xFF000000ULL
31 31
32#define AMD_PERFMON_EVENTSEL_GUESTONLY (1ULL << 40)
33#define AMD_PERFMON_EVENTSEL_HOSTONLY (1ULL << 41)
34
32#define AMD64_EVENTSEL_EVENT \ 35#define AMD64_EVENTSEL_EVENT \
33 (ARCH_PERFMON_EVENTSEL_EVENT | (0x0FULL << 32)) 36 (ARCH_PERFMON_EVENTSEL_EVENT | (0x0FULL << 32))
34#define INTEL_ARCH_EVENT_MASK \ 37#define INTEL_ARCH_EVENT_MASK \
@@ -43,14 +46,17 @@
43#define AMD64_RAW_EVENT_MASK \ 46#define AMD64_RAW_EVENT_MASK \
44 (X86_RAW_EVENT_MASK | \ 47 (X86_RAW_EVENT_MASK | \
45 AMD64_EVENTSEL_EVENT) 48 AMD64_EVENTSEL_EVENT)
49#define AMD64_NUM_COUNTERS 4
50#define AMD64_NUM_COUNTERS_F15H 6
51#define AMD64_NUM_COUNTERS_MAX AMD64_NUM_COUNTERS_F15H
46 52
47#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL 0x3c 53#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL 0x3c
48#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8) 54#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8)
49#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX 0 55#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX 0
50#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT \ 56#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT \
51 (1 << (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX)) 57 (1 << (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX))
52 58
53#define ARCH_PERFMON_BRANCH_MISSES_RETIRED 6 59#define ARCH_PERFMON_BRANCH_MISSES_RETIRED 6
54 60
55/* 61/*
56 * Intel "Architectural Performance Monitoring" CPUID 62 * Intel "Architectural Performance Monitoring" CPUID
@@ -110,6 +116,35 @@ union cpuid10_edx {
110 */ 116 */
111#define X86_PMC_IDX_FIXED_BTS (X86_PMC_IDX_FIXED + 16) 117#define X86_PMC_IDX_FIXED_BTS (X86_PMC_IDX_FIXED + 16)
112 118
119/*
120 * IBS cpuid feature detection
121 */
122
123#define IBS_CPUID_FEATURES 0x8000001b
124
125/*
126 * Same bit mask as for IBS cpuid feature flags (Fn8000_001B_EAX), but
127 * bit 0 is used to indicate the existence of IBS.
128 */
129#define IBS_CAPS_AVAIL (1U<<0)
130#define IBS_CAPS_FETCHSAM (1U<<1)
131#define IBS_CAPS_OPSAM (1U<<2)
132#define IBS_CAPS_RDWROPCNT (1U<<3)
133#define IBS_CAPS_OPCNT (1U<<4)
134#define IBS_CAPS_BRNTRGT (1U<<5)
135#define IBS_CAPS_OPCNTEXT (1U<<6)
136
137#define IBS_CAPS_DEFAULT (IBS_CAPS_AVAIL \
138 | IBS_CAPS_FETCHSAM \
139 | IBS_CAPS_OPSAM)
140
141/*
142 * IBS APIC setup
143 */
144#define IBSCTL 0x1cc
145#define IBSCTL_LVT_OFFSET_VALID (1ULL<<8)
146#define IBSCTL_LVT_OFFSET_MASK 0x0F
147
113/* IbsFetchCtl bits/masks */ 148/* IbsFetchCtl bits/masks */
114#define IBS_FETCH_RAND_EN (1ULL<<57) 149#define IBS_FETCH_RAND_EN (1ULL<<57)
115#define IBS_FETCH_VAL (1ULL<<49) 150#define IBS_FETCH_VAL (1ULL<<49)
@@ -124,6 +159,8 @@ union cpuid10_edx {
124#define IBS_OP_MAX_CNT 0x0000FFFFULL 159#define IBS_OP_MAX_CNT 0x0000FFFFULL
125#define IBS_OP_MAX_CNT_EXT 0x007FFFFFULL /* not a register bit mask */ 160#define IBS_OP_MAX_CNT_EXT 0x007FFFFFULL /* not a register bit mask */
126 161
162extern u32 get_ibs_caps(void);
163
127#ifdef CONFIG_PERF_EVENTS 164#ifdef CONFIG_PERF_EVENTS
128extern void perf_events_lapic_init(void); 165extern void perf_events_lapic_init(void);
129 166
@@ -159,7 +196,19 @@ extern unsigned long perf_misc_flags(struct pt_regs *regs);
159 ); \ 196 ); \
160} 197}
161 198
199struct perf_guest_switch_msr {
200 unsigned msr;
201 u64 host, guest;
202};
203
204extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr);
162#else 205#else
206static inline perf_guest_switch_msr *perf_guest_get_msrs(int *nr)
207{
208 *nr = 0;
209 return NULL;
210}
211
163static inline void perf_events_lapic_init(void) { } 212static inline void perf_events_lapic_init(void) { }
164#endif 213#endif
165 214
diff --git a/arch/x86/include/asm/reboot.h b/arch/x86/include/asm/reboot.h
index 3250e3d605d9..92f297069e87 100644
--- a/arch/x86/include/asm/reboot.h
+++ b/arch/x86/include/asm/reboot.h
@@ -23,7 +23,7 @@ void machine_real_restart(unsigned int type);
23#define MRR_BIOS 0 23#define MRR_BIOS 0
24#define MRR_APM 1 24#define MRR_APM 1
25 25
26typedef void (*nmi_shootdown_cb)(int, struct die_args*); 26typedef void (*nmi_shootdown_cb)(int, struct pt_regs*);
27void nmi_shootdown_cpus(nmi_shootdown_cb callback); 27void nmi_shootdown_cpus(nmi_shootdown_cb callback);
28 28
29#endif /* _ASM_X86_REBOOT_H */ 29#endif /* _ASM_X86_REBOOT_H */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 82f2912155a5..8baca3c4871c 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -19,7 +19,7 @@ endif
19 19
20obj-y := process_$(BITS).o signal.o entry_$(BITS).o 20obj-y := process_$(BITS).o signal.o entry_$(BITS).o
21obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o 21obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
22obj-y += time.o ioport.o ldt.o dumpstack.o 22obj-y += time.o ioport.o ldt.o dumpstack.o nmi.o
23obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o 23obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o
24obj-$(CONFIG_IRQ_WORK) += irq_work.o 24obj-$(CONFIG_IRQ_WORK) += irq_work.o
25obj-y += probe_roms.o 25obj-y += probe_roms.o
diff --git a/arch/x86/kernel/apic/hw_nmi.c b/arch/x86/kernel/apic/hw_nmi.c
index d5e57db0f7be..31cb9ae992b7 100644
--- a/arch/x86/kernel/apic/hw_nmi.c
+++ b/arch/x86/kernel/apic/hw_nmi.c
@@ -60,22 +60,10 @@ void arch_trigger_all_cpu_backtrace(void)
60} 60}
61 61
62static int __kprobes 62static int __kprobes
63arch_trigger_all_cpu_backtrace_handler(struct notifier_block *self, 63arch_trigger_all_cpu_backtrace_handler(unsigned int cmd, struct pt_regs *regs)
64 unsigned long cmd, void *__args)
65{ 64{
66 struct die_args *args = __args;
67 struct pt_regs *regs;
68 int cpu; 65 int cpu;
69 66
70 switch (cmd) {
71 case DIE_NMI:
72 break;
73
74 default:
75 return NOTIFY_DONE;
76 }
77
78 regs = args->regs;
79 cpu = smp_processor_id(); 67 cpu = smp_processor_id();
80 68
81 if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) { 69 if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) {
@@ -86,21 +74,16 @@ arch_trigger_all_cpu_backtrace_handler(struct notifier_block *self,
86 show_regs(regs); 74 show_regs(regs);
87 arch_spin_unlock(&lock); 75 arch_spin_unlock(&lock);
88 cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask)); 76 cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
89 return NOTIFY_STOP; 77 return NMI_HANDLED;
90 } 78 }
91 79
92 return NOTIFY_DONE; 80 return NMI_DONE;
93} 81}
94 82
95static __read_mostly struct notifier_block backtrace_notifier = {
96 .notifier_call = arch_trigger_all_cpu_backtrace_handler,
97 .next = NULL,
98 .priority = NMI_LOCAL_LOW_PRIOR,
99};
100
101static int __init register_trigger_all_cpu_backtrace(void) 83static int __init register_trigger_all_cpu_backtrace(void)
102{ 84{
103 register_die_notifier(&backtrace_notifier); 85 register_nmi_handler(NMI_LOCAL, arch_trigger_all_cpu_backtrace_handler,
86 0, "arch_bt");
104 return 0; 87 return 0;
105} 88}
106early_initcall(register_trigger_all_cpu_backtrace); 89early_initcall(register_trigger_all_cpu_backtrace);
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index 34b18594e724..75be00ecfff2 100644
--- a/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -672,18 +672,11 @@ void __cpuinit uv_cpu_init(void)
672/* 672/*
673 * When NMI is received, print a stack trace. 673 * When NMI is received, print a stack trace.
674 */ 674 */
675int uv_handle_nmi(struct notifier_block *self, unsigned long reason, void *data) 675int uv_handle_nmi(unsigned int reason, struct pt_regs *regs)
676{ 676{
677 unsigned long real_uv_nmi; 677 unsigned long real_uv_nmi;
678 int bid; 678 int bid;
679 679
680 if (reason != DIE_NMIUNKNOWN)
681 return NOTIFY_OK;
682
683 if (in_crash_kexec)
684 /* do nothing if entering the crash kernel */
685 return NOTIFY_OK;
686
687 /* 680 /*
688 * Each blade has an MMR that indicates when an NMI has been sent 681 * Each blade has an MMR that indicates when an NMI has been sent
689 * to cpus on the blade. If an NMI is detected, atomically 682 * to cpus on the blade. If an NMI is detected, atomically
@@ -704,7 +697,7 @@ int uv_handle_nmi(struct notifier_block *self, unsigned long reason, void *data)
704 } 697 }
705 698
706 if (likely(__get_cpu_var(cpu_last_nmi_count) == uv_blade_info[bid].nmi_count)) 699 if (likely(__get_cpu_var(cpu_last_nmi_count) == uv_blade_info[bid].nmi_count))
707 return NOTIFY_DONE; 700 return NMI_DONE;
708 701
709 __get_cpu_var(cpu_last_nmi_count) = uv_blade_info[bid].nmi_count; 702 __get_cpu_var(cpu_last_nmi_count) = uv_blade_info[bid].nmi_count;
710 703
@@ -717,17 +710,12 @@ int uv_handle_nmi(struct notifier_block *self, unsigned long reason, void *data)
717 dump_stack(); 710 dump_stack();
718 spin_unlock(&uv_nmi_lock); 711 spin_unlock(&uv_nmi_lock);
719 712
720 return NOTIFY_STOP; 713 return NMI_HANDLED;
721} 714}
722 715
723static struct notifier_block uv_dump_stack_nmi_nb = {
724 .notifier_call = uv_handle_nmi,
725 .priority = NMI_LOCAL_LOW_PRIOR - 1,
726};
727
728void uv_register_nmi_notifier(void) 716void uv_register_nmi_notifier(void)
729{ 717{
730 if (register_die_notifier(&uv_dump_stack_nmi_nb)) 718 if (register_nmi_handler(NMI_UNKNOWN, uv_handle_nmi, 0, "uv"))
731 printk(KERN_WARNING "UV NMI handler failed to register\n"); 719 printk(KERN_WARNING "UV NMI handler failed to register\n");
732} 720}
733 721
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index 6042981d0309..fe6eb197f848 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -28,10 +28,15 @@ obj-$(CONFIG_CPU_SUP_UMC_32) += umc.o
28 28
29obj-$(CONFIG_PERF_EVENTS) += perf_event.o 29obj-$(CONFIG_PERF_EVENTS) += perf_event.o
30 30
31ifdef CONFIG_PERF_EVENTS
32obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd.o
33obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_p4.o perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o
34endif
35
31obj-$(CONFIG_X86_MCE) += mcheck/ 36obj-$(CONFIG_X86_MCE) += mcheck/
32obj-$(CONFIG_MTRR) += mtrr/ 37obj-$(CONFIG_MTRR) += mtrr/
33 38
34obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o 39obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o perf_event_amd_ibs.o
35 40
36quiet_cmd_mkcapflags = MKCAP $@ 41quiet_cmd_mkcapflags = MKCAP $@
37 cmd_mkcapflags = $(PERL) $(srctree)/$(src)/mkcapflags.pl $< $@ 42 cmd_mkcapflags = $(PERL) $(srctree)/$(src)/mkcapflags.pl $< $@
diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c b/arch/x86/kernel/cpu/mcheck/mce-inject.c
index 0ed633c5048b..6199232161cf 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-inject.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c
@@ -78,27 +78,20 @@ static void raise_exception(struct mce *m, struct pt_regs *pregs)
78 78
79static cpumask_var_t mce_inject_cpumask; 79static cpumask_var_t mce_inject_cpumask;
80 80
81static int mce_raise_notify(struct notifier_block *self, 81static int mce_raise_notify(unsigned int cmd, struct pt_regs *regs)
82 unsigned long val, void *data)
83{ 82{
84 struct die_args *args = (struct die_args *)data;
85 int cpu = smp_processor_id(); 83 int cpu = smp_processor_id();
86 struct mce *m = &__get_cpu_var(injectm); 84 struct mce *m = &__get_cpu_var(injectm);
87 if (val != DIE_NMI || !cpumask_test_cpu(cpu, mce_inject_cpumask)) 85 if (!cpumask_test_cpu(cpu, mce_inject_cpumask))
88 return NOTIFY_DONE; 86 return NMI_DONE;
89 cpumask_clear_cpu(cpu, mce_inject_cpumask); 87 cpumask_clear_cpu(cpu, mce_inject_cpumask);
90 if (m->inject_flags & MCJ_EXCEPTION) 88 if (m->inject_flags & MCJ_EXCEPTION)
91 raise_exception(m, args->regs); 89 raise_exception(m, regs);
92 else if (m->status) 90 else if (m->status)
93 raise_poll(m); 91 raise_poll(m);
94 return NOTIFY_STOP; 92 return NMI_HANDLED;
95} 93}
96 94
97static struct notifier_block mce_raise_nb = {
98 .notifier_call = mce_raise_notify,
99 .priority = NMI_LOCAL_NORMAL_PRIOR,
100};
101
102/* Inject mce on current CPU */ 95/* Inject mce on current CPU */
103static int raise_local(void) 96static int raise_local(void)
104{ 97{
@@ -216,7 +209,8 @@ static int inject_init(void)
216 return -ENOMEM; 209 return -ENOMEM;
217 printk(KERN_INFO "Machine check injector initialized\n"); 210 printk(KERN_INFO "Machine check injector initialized\n");
218 mce_chrdev_ops.write = mce_write; 211 mce_chrdev_ops.write = mce_write;
219 register_die_notifier(&mce_raise_nb); 212 register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0,
213 "mce_notify");
220 return 0; 214 return 0;
221} 215}
222 216
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 08363b042122..fce51ad1f362 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -908,9 +908,6 @@ void do_machine_check(struct pt_regs *regs, long error_code)
908 908
909 percpu_inc(mce_exception_count); 909 percpu_inc(mce_exception_count);
910 910
911 if (notify_die(DIE_NMI, "machine check", regs, error_code,
912 18, SIGKILL) == NOTIFY_STOP)
913 goto out;
914 if (!banks) 911 if (!banks)
915 goto out; 912 goto out;
916 913
@@ -1140,6 +1137,15 @@ static void mce_start_timer(unsigned long data)
1140 add_timer_on(t, smp_processor_id()); 1137 add_timer_on(t, smp_processor_id());
1141} 1138}
1142 1139
1140/* Must not be called in IRQ context where del_timer_sync() can deadlock */
1141static void mce_timer_delete_all(void)
1142{
1143 int cpu;
1144
1145 for_each_online_cpu(cpu)
1146 del_timer_sync(&per_cpu(mce_timer, cpu));
1147}
1148
1143static void mce_do_trigger(struct work_struct *work) 1149static void mce_do_trigger(struct work_struct *work)
1144{ 1150{
1145 call_usermodehelper(mce_helper, mce_helper_argv, NULL, UMH_NO_WAIT); 1151 call_usermodehelper(mce_helper, mce_helper_argv, NULL, UMH_NO_WAIT);
@@ -1750,7 +1756,6 @@ static struct syscore_ops mce_syscore_ops = {
1750 1756
1751static void mce_cpu_restart(void *data) 1757static void mce_cpu_restart(void *data)
1752{ 1758{
1753 del_timer_sync(&__get_cpu_var(mce_timer));
1754 if (!mce_available(__this_cpu_ptr(&cpu_info))) 1759 if (!mce_available(__this_cpu_ptr(&cpu_info)))
1755 return; 1760 return;
1756 __mcheck_cpu_init_generic(); 1761 __mcheck_cpu_init_generic();
@@ -1760,16 +1765,15 @@ static void mce_cpu_restart(void *data)
1760/* Reinit MCEs after user configuration changes */ 1765/* Reinit MCEs after user configuration changes */
1761static void mce_restart(void) 1766static void mce_restart(void)
1762{ 1767{
1768 mce_timer_delete_all();
1763 on_each_cpu(mce_cpu_restart, NULL, 1); 1769 on_each_cpu(mce_cpu_restart, NULL, 1);
1764} 1770}
1765 1771
1766/* Toggle features for corrected errors */ 1772/* Toggle features for corrected errors */
1767static void mce_disable_ce(void *all) 1773static void mce_disable_cmci(void *data)
1768{ 1774{
1769 if (!mce_available(__this_cpu_ptr(&cpu_info))) 1775 if (!mce_available(__this_cpu_ptr(&cpu_info)))
1770 return; 1776 return;
1771 if (all)
1772 del_timer_sync(&__get_cpu_var(mce_timer));
1773 cmci_clear(); 1777 cmci_clear();
1774} 1778}
1775 1779
@@ -1852,7 +1856,8 @@ static ssize_t set_ignore_ce(struct sys_device *s,
1852 if (mce_ignore_ce ^ !!new) { 1856 if (mce_ignore_ce ^ !!new) {
1853 if (new) { 1857 if (new) {
1854 /* disable ce features */ 1858 /* disable ce features */
1855 on_each_cpu(mce_disable_ce, (void *)1, 1); 1859 mce_timer_delete_all();
1860 on_each_cpu(mce_disable_cmci, NULL, 1);
1856 mce_ignore_ce = 1; 1861 mce_ignore_ce = 1;
1857 } else { 1862 } else {
1858 /* enable ce features */ 1863 /* enable ce features */
@@ -1875,7 +1880,7 @@ static ssize_t set_cmci_disabled(struct sys_device *s,
1875 if (mce_cmci_disabled ^ !!new) { 1880 if (mce_cmci_disabled ^ !!new) {
1876 if (new) { 1881 if (new) {
1877 /* disable cmci */ 1882 /* disable cmci */
1878 on_each_cpu(mce_disable_ce, NULL, 1); 1883 on_each_cpu(mce_disable_cmci, NULL, 1);
1879 mce_cmci_disabled = 1; 1884 mce_cmci_disabled = 1;
1880 } else { 1885 } else {
1881 /* enable cmci */ 1886 /* enable cmci */
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index cfa62ec090ec..640891014b2a 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -32,6 +32,8 @@
32#include <asm/smp.h> 32#include <asm/smp.h>
33#include <asm/alternative.h> 33#include <asm/alternative.h>
34 34
35#include "perf_event.h"
36
35#if 0 37#if 0
36#undef wrmsrl 38#undef wrmsrl
37#define wrmsrl(msr, val) \ 39#define wrmsrl(msr, val) \
@@ -43,283 +45,17 @@ do { \
43} while (0) 45} while (0)
44#endif 46#endif
45 47
46/* 48struct x86_pmu x86_pmu __read_mostly;
47 * | NHM/WSM | SNB |
48 * register -------------------------------
49 * | HT | no HT | HT | no HT |
50 *-----------------------------------------
51 * offcore | core | core | cpu | core |
52 * lbr_sel | core | core | cpu | core |
53 * ld_lat | cpu | core | cpu | core |
54 *-----------------------------------------
55 *
56 * Given that there is a small number of shared regs,
57 * we can pre-allocate their slot in the per-cpu
58 * per-core reg tables.
59 */
60enum extra_reg_type {
61 EXTRA_REG_NONE = -1, /* not used */
62
63 EXTRA_REG_RSP_0 = 0, /* offcore_response_0 */
64 EXTRA_REG_RSP_1 = 1, /* offcore_response_1 */
65
66 EXTRA_REG_MAX /* number of entries needed */
67};
68
69struct event_constraint {
70 union {
71 unsigned long idxmsk[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
72 u64 idxmsk64;
73 };
74 u64 code;
75 u64 cmask;
76 int weight;
77};
78
79struct amd_nb {
80 int nb_id; /* NorthBridge id */
81 int refcnt; /* reference count */
82 struct perf_event *owners[X86_PMC_IDX_MAX];
83 struct event_constraint event_constraints[X86_PMC_IDX_MAX];
84};
85
86struct intel_percore;
87
88#define MAX_LBR_ENTRIES 16
89
90struct cpu_hw_events {
91 /*
92 * Generic x86 PMC bits
93 */
94 struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */
95 unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
96 unsigned long running[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
97 int enabled;
98
99 int n_events;
100 int n_added;
101 int n_txn;
102 int assign[X86_PMC_IDX_MAX]; /* event to counter assignment */
103 u64 tags[X86_PMC_IDX_MAX];
104 struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */
105
106 unsigned int group_flag;
107
108 /*
109 * Intel DebugStore bits
110 */
111 struct debug_store *ds;
112 u64 pebs_enabled;
113
114 /*
115 * Intel LBR bits
116 */
117 int lbr_users;
118 void *lbr_context;
119 struct perf_branch_stack lbr_stack;
120 struct perf_branch_entry lbr_entries[MAX_LBR_ENTRIES];
121
122 /*
123 * manage shared (per-core, per-cpu) registers
124 * used on Intel NHM/WSM/SNB
125 */
126 struct intel_shared_regs *shared_regs;
127
128 /*
129 * AMD specific bits
130 */
131 struct amd_nb *amd_nb;
132};
133
134#define __EVENT_CONSTRAINT(c, n, m, w) {\
135 { .idxmsk64 = (n) }, \
136 .code = (c), \
137 .cmask = (m), \
138 .weight = (w), \
139}
140
141#define EVENT_CONSTRAINT(c, n, m) \
142 __EVENT_CONSTRAINT(c, n, m, HWEIGHT(n))
143
144/*
145 * Constraint on the Event code.
146 */
147#define INTEL_EVENT_CONSTRAINT(c, n) \
148 EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)
149
150/*
151 * Constraint on the Event code + UMask + fixed-mask
152 *
153 * filter mask to validate fixed counter events.
154 * the following filters disqualify for fixed counters:
155 * - inv
156 * - edge
157 * - cnt-mask
158 * The other filters are supported by fixed counters.
159 * The any-thread option is supported starting with v3.
160 */
161#define FIXED_EVENT_CONSTRAINT(c, n) \
162 EVENT_CONSTRAINT(c, (1ULL << (32+n)), X86_RAW_EVENT_MASK)
163
164/*
165 * Constraint on the Event code + UMask
166 */
167#define INTEL_UEVENT_CONSTRAINT(c, n) \
168 EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)
169
170#define EVENT_CONSTRAINT_END \
171 EVENT_CONSTRAINT(0, 0, 0)
172
173#define for_each_event_constraint(e, c) \
174 for ((e) = (c); (e)->weight; (e)++)
175
176/*
177 * Per register state.
178 */
179struct er_account {
180 raw_spinlock_t lock; /* per-core: protect structure */
181 u64 config; /* extra MSR config */
182 u64 reg; /* extra MSR number */
183 atomic_t ref; /* reference count */
184};
185
186/*
187 * Extra registers for specific events.
188 *
189 * Some events need large masks and require external MSRs.
190 * Those extra MSRs end up being shared for all events on
191 * a PMU and sometimes between PMU of sibling HT threads.
192 * In either case, the kernel needs to handle conflicting
193 * accesses to those extra, shared, regs. The data structure
194 * to manage those registers is stored in cpu_hw_event.
195 */
196struct extra_reg {
197 unsigned int event;
198 unsigned int msr;
199 u64 config_mask;
200 u64 valid_mask;
201 int idx; /* per_xxx->regs[] reg index */
202};
203
204#define EVENT_EXTRA_REG(e, ms, m, vm, i) { \
205 .event = (e), \
206 .msr = (ms), \
207 .config_mask = (m), \
208 .valid_mask = (vm), \
209 .idx = EXTRA_REG_##i \
210 }
211
212#define INTEL_EVENT_EXTRA_REG(event, msr, vm, idx) \
213 EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT, vm, idx)
214
215#define EVENT_EXTRA_END EVENT_EXTRA_REG(0, 0, 0, 0, RSP_0)
216
217union perf_capabilities {
218 struct {
219 u64 lbr_format : 6;
220 u64 pebs_trap : 1;
221 u64 pebs_arch_reg : 1;
222 u64 pebs_format : 4;
223 u64 smm_freeze : 1;
224 };
225 u64 capabilities;
226};
227
228/*
229 * struct x86_pmu - generic x86 pmu
230 */
231struct x86_pmu {
232 /*
233 * Generic x86 PMC bits
234 */
235 const char *name;
236 int version;
237 int (*handle_irq)(struct pt_regs *);
238 void (*disable_all)(void);
239 void (*enable_all)(int added);
240 void (*enable)(struct perf_event *);
241 void (*disable)(struct perf_event *);
242 int (*hw_config)(struct perf_event *event);
243 int (*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign);
244 unsigned eventsel;
245 unsigned perfctr;
246 u64 (*event_map)(int);
247 int max_events;
248 int num_counters;
249 int num_counters_fixed;
250 int cntval_bits;
251 u64 cntval_mask;
252 int apic;
253 u64 max_period;
254 struct event_constraint *
255 (*get_event_constraints)(struct cpu_hw_events *cpuc,
256 struct perf_event *event);
257
258 void (*put_event_constraints)(struct cpu_hw_events *cpuc,
259 struct perf_event *event);
260 struct event_constraint *event_constraints;
261 void (*quirks)(void);
262 int perfctr_second_write;
263
264 int (*cpu_prepare)(int cpu);
265 void (*cpu_starting)(int cpu);
266 void (*cpu_dying)(int cpu);
267 void (*cpu_dead)(int cpu);
268
269 /*
270 * Intel Arch Perfmon v2+
271 */
272 u64 intel_ctrl;
273 union perf_capabilities intel_cap;
274 49
275 /* 50DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
276 * Intel DebugStore bits
277 */
278 int bts, pebs;
279 int bts_active, pebs_active;
280 int pebs_record_size;
281 void (*drain_pebs)(struct pt_regs *regs);
282 struct event_constraint *pebs_constraints;
283
284 /*
285 * Intel LBR
286 */
287 unsigned long lbr_tos, lbr_from, lbr_to; /* MSR base regs */
288 int lbr_nr; /* hardware stack size */
289
290 /*
291 * Extra registers for events
292 */
293 struct extra_reg *extra_regs;
294 unsigned int er_flags;
295};
296
297#define ERF_NO_HT_SHARING 1
298#define ERF_HAS_RSP_1 2
299
300static struct x86_pmu x86_pmu __read_mostly;
301
302static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
303 .enabled = 1, 51 .enabled = 1,
304}; 52};
305 53
306static int x86_perf_event_set_period(struct perf_event *event); 54u64 __read_mostly hw_cache_event_ids
307
308/*
309 * Generalized hw caching related hw_event table, filled
310 * in on a per model basis. A value of 0 means
311 * 'not supported', -1 means 'hw_event makes no sense on
312 * this CPU', any other value means the raw hw_event
313 * ID.
314 */
315
316#define C(x) PERF_COUNT_HW_CACHE_##x
317
318static u64 __read_mostly hw_cache_event_ids
319 [PERF_COUNT_HW_CACHE_MAX] 55 [PERF_COUNT_HW_CACHE_MAX]
320 [PERF_COUNT_HW_CACHE_OP_MAX] 56 [PERF_COUNT_HW_CACHE_OP_MAX]
321 [PERF_COUNT_HW_CACHE_RESULT_MAX]; 57 [PERF_COUNT_HW_CACHE_RESULT_MAX];
322static u64 __read_mostly hw_cache_extra_regs 58u64 __read_mostly hw_cache_extra_regs
323 [PERF_COUNT_HW_CACHE_MAX] 59 [PERF_COUNT_HW_CACHE_MAX]
324 [PERF_COUNT_HW_CACHE_OP_MAX] 60 [PERF_COUNT_HW_CACHE_OP_MAX]
325 [PERF_COUNT_HW_CACHE_RESULT_MAX]; 61 [PERF_COUNT_HW_CACHE_RESULT_MAX];
@@ -329,8 +65,7 @@ static u64 __read_mostly hw_cache_extra_regs
329 * Can only be executed on the CPU where the event is active. 65 * Can only be executed on the CPU where the event is active.
330 * Returns the delta events processed. 66 * Returns the delta events processed.
331 */ 67 */
332static u64 68u64 x86_perf_event_update(struct perf_event *event)
333x86_perf_event_update(struct perf_event *event)
334{ 69{
335 struct hw_perf_event *hwc = &event->hw; 70 struct hw_perf_event *hwc = &event->hw;
336 int shift = 64 - x86_pmu.cntval_bits; 71 int shift = 64 - x86_pmu.cntval_bits;
@@ -373,30 +108,6 @@ again:
373 return new_raw_count; 108 return new_raw_count;
374} 109}
375 110
376static inline int x86_pmu_addr_offset(int index)
377{
378 int offset;
379
380 /* offset = X86_FEATURE_PERFCTR_CORE ? index << 1 : index */
381 alternative_io(ASM_NOP2,
382 "shll $1, %%eax",
383 X86_FEATURE_PERFCTR_CORE,
384 "=a" (offset),
385 "a" (index));
386
387 return offset;
388}
389
390static inline unsigned int x86_pmu_config_addr(int index)
391{
392 return x86_pmu.eventsel + x86_pmu_addr_offset(index);
393}
394
395static inline unsigned int x86_pmu_event_addr(int index)
396{
397 return x86_pmu.perfctr + x86_pmu_addr_offset(index);
398}
399
400/* 111/*
401 * Find and validate any extra registers to set up. 112 * Find and validate any extra registers to set up.
402 */ 113 */
@@ -532,9 +243,6 @@ msr_fail:
532 return false; 243 return false;
533} 244}
534 245
535static void reserve_ds_buffers(void);
536static void release_ds_buffers(void);
537
538static void hw_perf_event_destroy(struct perf_event *event) 246static void hw_perf_event_destroy(struct perf_event *event)
539{ 247{
540 if (atomic_dec_and_mutex_lock(&active_events, &pmc_reserve_mutex)) { 248 if (atomic_dec_and_mutex_lock(&active_events, &pmc_reserve_mutex)) {
@@ -583,7 +291,7 @@ set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event *event)
583 return x86_pmu_extra_regs(val, event); 291 return x86_pmu_extra_regs(val, event);
584} 292}
585 293
586static int x86_setup_perfctr(struct perf_event *event) 294int x86_setup_perfctr(struct perf_event *event)
587{ 295{
588 struct perf_event_attr *attr = &event->attr; 296 struct perf_event_attr *attr = &event->attr;
589 struct hw_perf_event *hwc = &event->hw; 297 struct hw_perf_event *hwc = &event->hw;
@@ -647,7 +355,7 @@ static int x86_setup_perfctr(struct perf_event *event)
647 return 0; 355 return 0;
648} 356}
649 357
650static int x86_pmu_hw_config(struct perf_event *event) 358int x86_pmu_hw_config(struct perf_event *event)
651{ 359{
652 if (event->attr.precise_ip) { 360 if (event->attr.precise_ip) {
653 int precise = 0; 361 int precise = 0;
@@ -723,7 +431,7 @@ static int __x86_pmu_event_init(struct perf_event *event)
723 return x86_pmu.hw_config(event); 431 return x86_pmu.hw_config(event);
724} 432}
725 433
726static void x86_pmu_disable_all(void) 434void x86_pmu_disable_all(void)
727{ 435{
728 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 436 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
729 int idx; 437 int idx;
@@ -758,15 +466,7 @@ static void x86_pmu_disable(struct pmu *pmu)
758 x86_pmu.disable_all(); 466 x86_pmu.disable_all();
759} 467}
760 468
761static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, 469void x86_pmu_enable_all(int added)
762 u64 enable_mask)
763{
764 if (hwc->extra_reg.reg)
765 wrmsrl(hwc->extra_reg.reg, hwc->extra_reg.config);
766 wrmsrl(hwc->config_base, hwc->config | enable_mask);
767}
768
769static void x86_pmu_enable_all(int added)
770{ 470{
771 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 471 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
772 int idx; 472 int idx;
@@ -788,7 +488,7 @@ static inline int is_x86_event(struct perf_event *event)
788 return event->pmu == &pmu; 488 return event->pmu == &pmu;
789} 489}
790 490
791static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) 491int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
792{ 492{
793 struct event_constraint *c, *constraints[X86_PMC_IDX_MAX]; 493 struct event_constraint *c, *constraints[X86_PMC_IDX_MAX];
794 unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; 494 unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
@@ -959,7 +659,6 @@ static inline int match_prev_assignment(struct hw_perf_event *hwc,
959} 659}
960 660
961static void x86_pmu_start(struct perf_event *event, int flags); 661static void x86_pmu_start(struct perf_event *event, int flags);
962static void x86_pmu_stop(struct perf_event *event, int flags);
963 662
964static void x86_pmu_enable(struct pmu *pmu) 663static void x86_pmu_enable(struct pmu *pmu)
965{ 664{
@@ -1031,21 +730,13 @@ static void x86_pmu_enable(struct pmu *pmu)
1031 x86_pmu.enable_all(added); 730 x86_pmu.enable_all(added);
1032} 731}
1033 732
1034static inline void x86_pmu_disable_event(struct perf_event *event)
1035{
1036 struct hw_perf_event *hwc = &event->hw;
1037
1038 wrmsrl(hwc->config_base, hwc->config);
1039}
1040
1041static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left); 733static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left);
1042 734
1043/* 735/*
1044 * Set the next IRQ period, based on the hwc->period_left value. 736 * Set the next IRQ period, based on the hwc->period_left value.
1045 * To be called with the event disabled in hw: 737 * To be called with the event disabled in hw:
1046 */ 738 */
1047static int 739int x86_perf_event_set_period(struct perf_event *event)
1048x86_perf_event_set_period(struct perf_event *event)
1049{ 740{
1050 struct hw_perf_event *hwc = &event->hw; 741 struct hw_perf_event *hwc = &event->hw;
1051 s64 left = local64_read(&hwc->period_left); 742 s64 left = local64_read(&hwc->period_left);
@@ -1105,7 +796,7 @@ x86_perf_event_set_period(struct perf_event *event)
1105 return ret; 796 return ret;
1106} 797}
1107 798
1108static void x86_pmu_enable_event(struct perf_event *event) 799void x86_pmu_enable_event(struct perf_event *event)
1109{ 800{
1110 if (__this_cpu_read(cpu_hw_events.enabled)) 801 if (__this_cpu_read(cpu_hw_events.enabled))
1111 __x86_pmu_enable_event(&event->hw, 802 __x86_pmu_enable_event(&event->hw,
@@ -1244,7 +935,7 @@ void perf_event_print_debug(void)
1244 local_irq_restore(flags); 935 local_irq_restore(flags);
1245} 936}
1246 937
1247static void x86_pmu_stop(struct perf_event *event, int flags) 938void x86_pmu_stop(struct perf_event *event, int flags)
1248{ 939{
1249 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 940 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
1250 struct hw_perf_event *hwc = &event->hw; 941 struct hw_perf_event *hwc = &event->hw;
@@ -1297,7 +988,7 @@ static void x86_pmu_del(struct perf_event *event, int flags)
1297 perf_event_update_userpage(event); 988 perf_event_update_userpage(event);
1298} 989}
1299 990
1300static int x86_pmu_handle_irq(struct pt_regs *regs) 991int x86_pmu_handle_irq(struct pt_regs *regs)
1301{ 992{
1302 struct perf_sample_data data; 993 struct perf_sample_data data;
1303 struct cpu_hw_events *cpuc; 994 struct cpu_hw_events *cpuc;
@@ -1367,109 +1058,28 @@ void perf_events_lapic_init(void)
1367 apic_write(APIC_LVTPC, APIC_DM_NMI); 1058 apic_write(APIC_LVTPC, APIC_DM_NMI);
1368} 1059}
1369 1060
1370struct pmu_nmi_state {
1371 unsigned int marked;
1372 int handled;
1373};
1374
1375static DEFINE_PER_CPU(struct pmu_nmi_state, pmu_nmi);
1376
1377static int __kprobes 1061static int __kprobes
1378perf_event_nmi_handler(struct notifier_block *self, 1062perf_event_nmi_handler(unsigned int cmd, struct pt_regs *regs)
1379 unsigned long cmd, void *__args)
1380{ 1063{
1381 struct die_args *args = __args;
1382 unsigned int this_nmi;
1383 int handled;
1384
1385 if (!atomic_read(&active_events)) 1064 if (!atomic_read(&active_events))
1386 return NOTIFY_DONE; 1065 return NMI_DONE;
1387
1388 switch (cmd) {
1389 case DIE_NMI:
1390 break;
1391 case DIE_NMIUNKNOWN:
1392 this_nmi = percpu_read(irq_stat.__nmi_count);
1393 if (this_nmi != __this_cpu_read(pmu_nmi.marked))
1394 /* let the kernel handle the unknown nmi */
1395 return NOTIFY_DONE;
1396 /*
1397 * This one is a PMU back-to-back nmi. Two events
1398 * trigger 'simultaneously' raising two back-to-back
1399 * NMIs. If the first NMI handles both, the latter
1400 * will be empty and daze the CPU. So, we drop it to
1401 * avoid false-positive 'unknown nmi' messages.
1402 */
1403 return NOTIFY_STOP;
1404 default:
1405 return NOTIFY_DONE;
1406 }
1407
1408 handled = x86_pmu.handle_irq(args->regs);
1409 if (!handled)
1410 return NOTIFY_DONE;
1411
1412 this_nmi = percpu_read(irq_stat.__nmi_count);
1413 if ((handled > 1) ||
1414 /* the next nmi could be a back-to-back nmi */
1415 ((__this_cpu_read(pmu_nmi.marked) == this_nmi) &&
1416 (__this_cpu_read(pmu_nmi.handled) > 1))) {
1417 /*
1418 * We could have two subsequent back-to-back nmis: The
1419 * first handles more than one counter, the 2nd
1420 * handles only one counter and the 3rd handles no
1421 * counter.
1422 *
1423 * This is the 2nd nmi because the previous was
1424 * handling more than one counter. We will mark the
1425 * next (3rd) and then drop it if unhandled.
1426 */
1427 __this_cpu_write(pmu_nmi.marked, this_nmi + 1);
1428 __this_cpu_write(pmu_nmi.handled, handled);
1429 }
1430 1066
1431 return NOTIFY_STOP; 1067 return x86_pmu.handle_irq(regs);
1432} 1068}
1433 1069
1434static __read_mostly struct notifier_block perf_event_nmi_notifier = { 1070struct event_constraint emptyconstraint;
1435 .notifier_call = perf_event_nmi_handler, 1071struct event_constraint unconstrained;
1436 .next = NULL,
1437 .priority = NMI_LOCAL_LOW_PRIOR,
1438};
1439
1440static struct event_constraint unconstrained;
1441static struct event_constraint emptyconstraint;
1442
1443static struct event_constraint *
1444x86_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
1445{
1446 struct event_constraint *c;
1447
1448 if (x86_pmu.event_constraints) {
1449 for_each_event_constraint(c, x86_pmu.event_constraints) {
1450 if ((event->hw.config & c->cmask) == c->code)
1451 return c;
1452 }
1453 }
1454
1455 return &unconstrained;
1456}
1457
1458#include "perf_event_amd.c"
1459#include "perf_event_p6.c"
1460#include "perf_event_p4.c"
1461#include "perf_event_intel_lbr.c"
1462#include "perf_event_intel_ds.c"
1463#include "perf_event_intel.c"
1464 1072
1465static int __cpuinit 1073static int __cpuinit
1466x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) 1074x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
1467{ 1075{
1468 unsigned int cpu = (long)hcpu; 1076 unsigned int cpu = (long)hcpu;
1077 struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
1469 int ret = NOTIFY_OK; 1078 int ret = NOTIFY_OK;
1470 1079
1471 switch (action & ~CPU_TASKS_FROZEN) { 1080 switch (action & ~CPU_TASKS_FROZEN) {
1472 case CPU_UP_PREPARE: 1081 case CPU_UP_PREPARE:
1082 cpuc->kfree_on_online = NULL;
1473 if (x86_pmu.cpu_prepare) 1083 if (x86_pmu.cpu_prepare)
1474 ret = x86_pmu.cpu_prepare(cpu); 1084 ret = x86_pmu.cpu_prepare(cpu);
1475 break; 1085 break;
@@ -1479,6 +1089,10 @@ x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
1479 x86_pmu.cpu_starting(cpu); 1089 x86_pmu.cpu_starting(cpu);
1480 break; 1090 break;
1481 1091
1092 case CPU_ONLINE:
1093 kfree(cpuc->kfree_on_online);
1094 break;
1095
1482 case CPU_DYING: 1096 case CPU_DYING:
1483 if (x86_pmu.cpu_dying) 1097 if (x86_pmu.cpu_dying)
1484 x86_pmu.cpu_dying(cpu); 1098 x86_pmu.cpu_dying(cpu);
@@ -1557,7 +1171,7 @@ static int __init init_hw_perf_events(void)
1557 ((1LL << x86_pmu.num_counters_fixed)-1) << X86_PMC_IDX_FIXED; 1171 ((1LL << x86_pmu.num_counters_fixed)-1) << X86_PMC_IDX_FIXED;
1558 1172
1559 perf_events_lapic_init(); 1173 perf_events_lapic_init();
1560 register_die_notifier(&perf_event_nmi_notifier); 1174 register_nmi_handler(NMI_LOCAL, perf_event_nmi_handler, 0, "PMI");
1561 1175
1562 unconstrained = (struct event_constraint) 1176 unconstrained = (struct event_constraint)
1563 __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1, 1177 __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1,
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
new file mode 100644
index 000000000000..b9698d40ac4b
--- /dev/null
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -0,0 +1,505 @@
1/*
2 * Performance events x86 architecture header
3 *
4 * Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
5 * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
6 * Copyright (C) 2009 Jaswinder Singh Rajput
7 * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
8 * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
9 * Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
10 * Copyright (C) 2009 Google, Inc., Stephane Eranian
11 *
12 * For licencing details see kernel-base/COPYING
13 */
14
15#include <linux/perf_event.h>
16
17/*
18 * | NHM/WSM | SNB |
19 * register -------------------------------
20 * | HT | no HT | HT | no HT |
21 *-----------------------------------------
22 * offcore | core | core | cpu | core |
23 * lbr_sel | core | core | cpu | core |
24 * ld_lat | cpu | core | cpu | core |
25 *-----------------------------------------
26 *
27 * Given that there is a small number of shared regs,
28 * we can pre-allocate their slot in the per-cpu
29 * per-core reg tables.
30 */
31enum extra_reg_type {
32 EXTRA_REG_NONE = -1, /* not used */
33
34 EXTRA_REG_RSP_0 = 0, /* offcore_response_0 */
35 EXTRA_REG_RSP_1 = 1, /* offcore_response_1 */
36
37 EXTRA_REG_MAX /* number of entries needed */
38};
39
40struct event_constraint {
41 union {
42 unsigned long idxmsk[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
43 u64 idxmsk64;
44 };
45 u64 code;
46 u64 cmask;
47 int weight;
48};
49
50struct amd_nb {
51 int nb_id; /* NorthBridge id */
52 int refcnt; /* reference count */
53 struct perf_event *owners[X86_PMC_IDX_MAX];
54 struct event_constraint event_constraints[X86_PMC_IDX_MAX];
55};
56
57/* The maximal number of PEBS events: */
58#define MAX_PEBS_EVENTS 4
59
60/*
61 * A debug store configuration.
62 *
63 * We only support architectures that use 64bit fields.
64 */
65struct debug_store {
66 u64 bts_buffer_base;
67 u64 bts_index;
68 u64 bts_absolute_maximum;
69 u64 bts_interrupt_threshold;
70 u64 pebs_buffer_base;
71 u64 pebs_index;
72 u64 pebs_absolute_maximum;
73 u64 pebs_interrupt_threshold;
74 u64 pebs_event_reset[MAX_PEBS_EVENTS];
75};
76
77/*
78 * Per register state.
79 */
80struct er_account {
81 raw_spinlock_t lock; /* per-core: protect structure */
82 u64 config; /* extra MSR config */
83 u64 reg; /* extra MSR number */
84 atomic_t ref; /* reference count */
85};
86
87/*
88 * Per core/cpu state
89 *
90 * Used to coordinate shared registers between HT threads or
91 * among events on a single PMU.
92 */
93struct intel_shared_regs {
94 struct er_account regs[EXTRA_REG_MAX];
95 int refcnt; /* per-core: #HT threads */
96 unsigned core_id; /* per-core: core id */
97};
98
99#define MAX_LBR_ENTRIES 16
100
101struct cpu_hw_events {
102 /*
103 * Generic x86 PMC bits
104 */
105 struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */
106 unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
107 unsigned long running[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
108 int enabled;
109
110 int n_events;
111 int n_added;
112 int n_txn;
113 int assign[X86_PMC_IDX_MAX]; /* event to counter assignment */
114 u64 tags[X86_PMC_IDX_MAX];
115 struct perf_event *event_list[X86_PMC_IDX_MAX]; /* in enabled order */
116
117 unsigned int group_flag;
118
119 /*
120 * Intel DebugStore bits
121 */
122 struct debug_store *ds;
123 u64 pebs_enabled;
124
125 /*
126 * Intel LBR bits
127 */
128 int lbr_users;
129 void *lbr_context;
130 struct perf_branch_stack lbr_stack;
131 struct perf_branch_entry lbr_entries[MAX_LBR_ENTRIES];
132
133 /*
134 * Intel host/guest exclude bits
135 */
136 u64 intel_ctrl_guest_mask;
137 u64 intel_ctrl_host_mask;
138 struct perf_guest_switch_msr guest_switch_msrs[X86_PMC_IDX_MAX];
139
140 /*
141 * manage shared (per-core, per-cpu) registers
142 * used on Intel NHM/WSM/SNB
143 */
144 struct intel_shared_regs *shared_regs;
145
146 /*
147 * AMD specific bits
148 */
149 struct amd_nb *amd_nb;
150
151 void *kfree_on_online;
152};
153
154#define __EVENT_CONSTRAINT(c, n, m, w) {\
155 { .idxmsk64 = (n) }, \
156 .code = (c), \
157 .cmask = (m), \
158 .weight = (w), \
159}
160
161#define EVENT_CONSTRAINT(c, n, m) \
162 __EVENT_CONSTRAINT(c, n, m, HWEIGHT(n))
163
164/*
165 * Constraint on the Event code.
166 */
167#define INTEL_EVENT_CONSTRAINT(c, n) \
168 EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)
169
170/*
171 * Constraint on the Event code + UMask + fixed-mask
172 *
173 * filter mask to validate fixed counter events.
174 * the following filters disqualify for fixed counters:
175 * - inv
176 * - edge
177 * - cnt-mask
178 * The other filters are supported by fixed counters.
179 * The any-thread option is supported starting with v3.
180 */
181#define FIXED_EVENT_CONSTRAINT(c, n) \
182 EVENT_CONSTRAINT(c, (1ULL << (32+n)), X86_RAW_EVENT_MASK)
183
184/*
185 * Constraint on the Event code + UMask
186 */
187#define INTEL_UEVENT_CONSTRAINT(c, n) \
188 EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)
189
190#define EVENT_CONSTRAINT_END \
191 EVENT_CONSTRAINT(0, 0, 0)
192
193#define for_each_event_constraint(e, c) \
194 for ((e) = (c); (e)->weight; (e)++)
195
196/*
197 * Extra registers for specific events.
198 *
199 * Some events need large masks and require external MSRs.
200 * Those extra MSRs end up being shared for all events on
201 * a PMU and sometimes between PMU of sibling HT threads.
202 * In either case, the kernel needs to handle conflicting
203 * accesses to those extra, shared, regs. The data structure
204 * to manage those registers is stored in cpu_hw_event.
205 */
206struct extra_reg {
207 unsigned int event;
208 unsigned int msr;
209 u64 config_mask;
210 u64 valid_mask;
211 int idx; /* per_xxx->regs[] reg index */
212};
213
214#define EVENT_EXTRA_REG(e, ms, m, vm, i) { \
215 .event = (e), \
216 .msr = (ms), \
217 .config_mask = (m), \
218 .valid_mask = (vm), \
219 .idx = EXTRA_REG_##i \
220 }
221
222#define INTEL_EVENT_EXTRA_REG(event, msr, vm, idx) \
223 EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT, vm, idx)
224
225#define EVENT_EXTRA_END EVENT_EXTRA_REG(0, 0, 0, 0, RSP_0)
226
227union perf_capabilities {
228 struct {
229 u64 lbr_format:6;
230 u64 pebs_trap:1;
231 u64 pebs_arch_reg:1;
232 u64 pebs_format:4;
233 u64 smm_freeze:1;
234 };
235 u64 capabilities;
236};
237
238/*
239 * struct x86_pmu - generic x86 pmu
240 */
241struct x86_pmu {
242 /*
243 * Generic x86 PMC bits
244 */
245 const char *name;
246 int version;
247 int (*handle_irq)(struct pt_regs *);
248 void (*disable_all)(void);
249 void (*enable_all)(int added);
250 void (*enable)(struct perf_event *);
251 void (*disable)(struct perf_event *);
252 int (*hw_config)(struct perf_event *event);
253 int (*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign);
254 unsigned eventsel;
255 unsigned perfctr;
256 u64 (*event_map)(int);
257 int max_events;
258 int num_counters;
259 int num_counters_fixed;
260 int cntval_bits;
261 u64 cntval_mask;
262 int apic;
263 u64 max_period;
264 struct event_constraint *
265 (*get_event_constraints)(struct cpu_hw_events *cpuc,
266 struct perf_event *event);
267
268 void (*put_event_constraints)(struct cpu_hw_events *cpuc,
269 struct perf_event *event);
270 struct event_constraint *event_constraints;
271 void (*quirks)(void);
272 int perfctr_second_write;
273
274 int (*cpu_prepare)(int cpu);
275 void (*cpu_starting)(int cpu);
276 void (*cpu_dying)(int cpu);
277 void (*cpu_dead)(int cpu);
278
279 /*
280 * Intel Arch Perfmon v2+
281 */
282 u64 intel_ctrl;
283 union perf_capabilities intel_cap;
284
285 /*
286 * Intel DebugStore bits
287 */
288 int bts, pebs;
289 int bts_active, pebs_active;
290 int pebs_record_size;
291 void (*drain_pebs)(struct pt_regs *regs);
292 struct event_constraint *pebs_constraints;
293
294 /*
295 * Intel LBR
296 */
297 unsigned long lbr_tos, lbr_from, lbr_to; /* MSR base regs */
298 int lbr_nr; /* hardware stack size */
299
300 /*
301 * Extra registers for events
302 */
303 struct extra_reg *extra_regs;
304 unsigned int er_flags;
305
306 /*
307 * Intel host/guest support (KVM)
308 */
309 struct perf_guest_switch_msr *(*guest_get_msrs)(int *nr);
310};
311
312#define ERF_NO_HT_SHARING 1
313#define ERF_HAS_RSP_1 2
314
315extern struct x86_pmu x86_pmu __read_mostly;
316
317DECLARE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
318
319int x86_perf_event_set_period(struct perf_event *event);
320
321/*
322 * Generalized hw caching related hw_event table, filled
323 * in on a per model basis. A value of 0 means
324 * 'not supported', -1 means 'hw_event makes no sense on
325 * this CPU', any other value means the raw hw_event
326 * ID.
327 */
328
329#define C(x) PERF_COUNT_HW_CACHE_##x
330
331extern u64 __read_mostly hw_cache_event_ids
332 [PERF_COUNT_HW_CACHE_MAX]
333 [PERF_COUNT_HW_CACHE_OP_MAX]
334 [PERF_COUNT_HW_CACHE_RESULT_MAX];
335extern u64 __read_mostly hw_cache_extra_regs
336 [PERF_COUNT_HW_CACHE_MAX]
337 [PERF_COUNT_HW_CACHE_OP_MAX]
338 [PERF_COUNT_HW_CACHE_RESULT_MAX];
339
340u64 x86_perf_event_update(struct perf_event *event);
341
342static inline int x86_pmu_addr_offset(int index)
343{
344 int offset;
345
346 /* offset = X86_FEATURE_PERFCTR_CORE ? index << 1 : index */
347 alternative_io(ASM_NOP2,
348 "shll $1, %%eax",
349 X86_FEATURE_PERFCTR_CORE,
350 "=a" (offset),
351 "a" (index));
352
353 return offset;
354}
355
356static inline unsigned int x86_pmu_config_addr(int index)
357{
358 return x86_pmu.eventsel + x86_pmu_addr_offset(index);
359}
360
361static inline unsigned int x86_pmu_event_addr(int index)
362{
363 return x86_pmu.perfctr + x86_pmu_addr_offset(index);
364}
365
366int x86_setup_perfctr(struct perf_event *event);
367
368int x86_pmu_hw_config(struct perf_event *event);
369
370void x86_pmu_disable_all(void);
371
372static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc,
373 u64 enable_mask)
374{
375 if (hwc->extra_reg.reg)
376 wrmsrl(hwc->extra_reg.reg, hwc->extra_reg.config);
377 wrmsrl(hwc->config_base, hwc->config | enable_mask);
378}
379
380void x86_pmu_enable_all(int added);
381
382int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign);
383
384void x86_pmu_stop(struct perf_event *event, int flags);
385
386static inline void x86_pmu_disable_event(struct perf_event *event)
387{
388 struct hw_perf_event *hwc = &event->hw;
389
390 wrmsrl(hwc->config_base, hwc->config);
391}
392
393void x86_pmu_enable_event(struct perf_event *event);
394
395int x86_pmu_handle_irq(struct pt_regs *regs);
396
397extern struct event_constraint emptyconstraint;
398
399extern struct event_constraint unconstrained;
400
401#ifdef CONFIG_CPU_SUP_AMD
402
403int amd_pmu_init(void);
404
405#else /* CONFIG_CPU_SUP_AMD */
406
407static inline int amd_pmu_init(void)
408{
409 return 0;
410}
411
412#endif /* CONFIG_CPU_SUP_AMD */
413
414#ifdef CONFIG_CPU_SUP_INTEL
415
416int intel_pmu_save_and_restart(struct perf_event *event);
417
418struct event_constraint *
419x86_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event);
420
421struct intel_shared_regs *allocate_shared_regs(int cpu);
422
423int intel_pmu_init(void);
424
425void init_debug_store_on_cpu(int cpu);
426
427void fini_debug_store_on_cpu(int cpu);
428
429void release_ds_buffers(void);
430
431void reserve_ds_buffers(void);
432
433extern struct event_constraint bts_constraint;
434
435void intel_pmu_enable_bts(u64 config);
436
437void intel_pmu_disable_bts(void);
438
439int intel_pmu_drain_bts_buffer(void);
440
441extern struct event_constraint intel_core2_pebs_event_constraints[];
442
443extern struct event_constraint intel_atom_pebs_event_constraints[];
444
445extern struct event_constraint intel_nehalem_pebs_event_constraints[];
446
447extern struct event_constraint intel_westmere_pebs_event_constraints[];
448
449extern struct event_constraint intel_snb_pebs_event_constraints[];
450
451struct event_constraint *intel_pebs_constraints(struct perf_event *event);
452
453void intel_pmu_pebs_enable(struct perf_event *event);
454
455void intel_pmu_pebs_disable(struct perf_event *event);
456
457void intel_pmu_pebs_enable_all(void);
458
459void intel_pmu_pebs_disable_all(void);
460
461void intel_ds_init(void);
462
463void intel_pmu_lbr_reset(void);
464
465void intel_pmu_lbr_enable(struct perf_event *event);
466
467void intel_pmu_lbr_disable(struct perf_event *event);
468
469void intel_pmu_lbr_enable_all(void);
470
471void intel_pmu_lbr_disable_all(void);
472
473void intel_pmu_lbr_read(void);
474
475void intel_pmu_lbr_init_core(void);
476
477void intel_pmu_lbr_init_nhm(void);
478
479void intel_pmu_lbr_init_atom(void);
480
481int p4_pmu_init(void);
482
483int p6_pmu_init(void);
484
485#else /* CONFIG_CPU_SUP_INTEL */
486
487static inline void reserve_ds_buffers(void)
488{
489}
490
491static inline void release_ds_buffers(void)
492{
493}
494
495static inline int intel_pmu_init(void)
496{
497 return 0;
498}
499
500static inline struct intel_shared_regs *allocate_shared_regs(int cpu)
501{
502 return NULL;
503}
504
505#endif /* CONFIG_CPU_SUP_INTEL */
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c
index 941caa2e449b..aeefd45697a2 100644
--- a/arch/x86/kernel/cpu/perf_event_amd.c
+++ b/arch/x86/kernel/cpu/perf_event_amd.c
@@ -1,4 +1,10 @@
1#ifdef CONFIG_CPU_SUP_AMD 1#include <linux/perf_event.h>
2#include <linux/types.h>
3#include <linux/init.h>
4#include <linux/slab.h>
5#include <asm/apicdef.h>
6
7#include "perf_event.h"
2 8
3static __initconst const u64 amd_hw_cache_event_ids 9static __initconst const u64 amd_hw_cache_event_ids
4 [PERF_COUNT_HW_CACHE_MAX] 10 [PERF_COUNT_HW_CACHE_MAX]
@@ -132,6 +138,19 @@ static int amd_pmu_hw_config(struct perf_event *event)
132 if (ret) 138 if (ret)
133 return ret; 139 return ret;
134 140
141 if (event->attr.exclude_host && event->attr.exclude_guest)
142 /*
143 * When HO == GO == 1 the hardware treats that as GO == HO == 0
144 * and will count in both modes. We don't want to count in that
145 * case so we emulate no-counting by setting US = OS = 0.
146 */
147 event->hw.config &= ~(ARCH_PERFMON_EVENTSEL_USR |
148 ARCH_PERFMON_EVENTSEL_OS);
149 else if (event->attr.exclude_host)
150 event->hw.config |= AMD_PERFMON_EVENTSEL_GUESTONLY;
151 else if (event->attr.exclude_guest)
152 event->hw.config |= AMD_PERFMON_EVENTSEL_HOSTONLY;
153
135 if (event->attr.type != PERF_TYPE_RAW) 154 if (event->attr.type != PERF_TYPE_RAW)
136 return 0; 155 return 0;
137 156
@@ -350,7 +369,7 @@ static void amd_pmu_cpu_starting(int cpu)
350 continue; 369 continue;
351 370
352 if (nb->nb_id == nb_id) { 371 if (nb->nb_id == nb_id) {
353 kfree(cpuc->amd_nb); 372 cpuc->kfree_on_online = cpuc->amd_nb;
354 cpuc->amd_nb = nb; 373 cpuc->amd_nb = nb;
355 break; 374 break;
356 } 375 }
@@ -392,7 +411,7 @@ static __initconst const struct x86_pmu amd_pmu = {
392 .perfctr = MSR_K7_PERFCTR0, 411 .perfctr = MSR_K7_PERFCTR0,
393 .event_map = amd_pmu_event_map, 412 .event_map = amd_pmu_event_map,
394 .max_events = ARRAY_SIZE(amd_perfmon_event_map), 413 .max_events = ARRAY_SIZE(amd_perfmon_event_map),
395 .num_counters = 4, 414 .num_counters = AMD64_NUM_COUNTERS,
396 .cntval_bits = 48, 415 .cntval_bits = 48,
397 .cntval_mask = (1ULL << 48) - 1, 416 .cntval_mask = (1ULL << 48) - 1,
398 .apic = 1, 417 .apic = 1,
@@ -556,7 +575,7 @@ static __initconst const struct x86_pmu amd_pmu_f15h = {
556 .perfctr = MSR_F15H_PERF_CTR, 575 .perfctr = MSR_F15H_PERF_CTR,
557 .event_map = amd_pmu_event_map, 576 .event_map = amd_pmu_event_map,
558 .max_events = ARRAY_SIZE(amd_perfmon_event_map), 577 .max_events = ARRAY_SIZE(amd_perfmon_event_map),
559 .num_counters = 6, 578 .num_counters = AMD64_NUM_COUNTERS_F15H,
560 .cntval_bits = 48, 579 .cntval_bits = 48,
561 .cntval_mask = (1ULL << 48) - 1, 580 .cntval_mask = (1ULL << 48) - 1,
562 .apic = 1, 581 .apic = 1,
@@ -573,7 +592,7 @@ static __initconst const struct x86_pmu amd_pmu_f15h = {
573#endif 592#endif
574}; 593};
575 594
576static __init int amd_pmu_init(void) 595__init int amd_pmu_init(void)
577{ 596{
578 /* Performance-monitoring supported from K7 and later: */ 597 /* Performance-monitoring supported from K7 and later: */
579 if (boot_cpu_data.x86 < 6) 598 if (boot_cpu_data.x86 < 6)
@@ -602,12 +621,3 @@ static __init int amd_pmu_init(void)
602 621
603 return 0; 622 return 0;
604} 623}
605
606#else /* CONFIG_CPU_SUP_AMD */
607
608static int amd_pmu_init(void)
609{
610 return 0;
611}
612
613#endif
diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
new file mode 100644
index 000000000000..ab6343d21825
--- /dev/null
+++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
@@ -0,0 +1,294 @@
1/*
2 * Performance events - AMD IBS
3 *
4 * Copyright (C) 2011 Advanced Micro Devices, Inc., Robert Richter
5 *
6 * For licencing details see kernel-base/COPYING
7 */
8
9#include <linux/perf_event.h>
10#include <linux/module.h>
11#include <linux/pci.h>
12
13#include <asm/apic.h>
14
15static u32 ibs_caps;
16
17#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD)
18
19static struct pmu perf_ibs;
20
21static int perf_ibs_init(struct perf_event *event)
22{
23 if (perf_ibs.type != event->attr.type)
24 return -ENOENT;
25 return 0;
26}
27
28static int perf_ibs_add(struct perf_event *event, int flags)
29{
30 return 0;
31}
32
33static void perf_ibs_del(struct perf_event *event, int flags)
34{
35}
36
37static struct pmu perf_ibs = {
38 .event_init= perf_ibs_init,
39 .add= perf_ibs_add,
40 .del= perf_ibs_del,
41};
42
43static __init int perf_event_ibs_init(void)
44{
45 if (!ibs_caps)
46 return -ENODEV; /* ibs not supported by the cpu */
47
48 perf_pmu_register(&perf_ibs, "ibs", -1);
49 printk(KERN_INFO "perf: AMD IBS detected (0x%08x)\n", ibs_caps);
50
51 return 0;
52}
53
54#else /* defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) */
55
56static __init int perf_event_ibs_init(void) { return 0; }
57
58#endif
59
60/* IBS - apic initialization, for perf and oprofile */
61
62static __init u32 __get_ibs_caps(void)
63{
64 u32 caps;
65 unsigned int max_level;
66
67 if (!boot_cpu_has(X86_FEATURE_IBS))
68 return 0;
69
70 /* check IBS cpuid feature flags */
71 max_level = cpuid_eax(0x80000000);
72 if (max_level < IBS_CPUID_FEATURES)
73 return IBS_CAPS_DEFAULT;
74
75 caps = cpuid_eax(IBS_CPUID_FEATURES);
76 if (!(caps & IBS_CAPS_AVAIL))
77 /* cpuid flags not valid */
78 return IBS_CAPS_DEFAULT;
79
80 return caps;
81}
82
83u32 get_ibs_caps(void)
84{
85 return ibs_caps;
86}
87
88EXPORT_SYMBOL(get_ibs_caps);
89
90static inline int get_eilvt(int offset)
91{
92 return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1);
93}
94
95static inline int put_eilvt(int offset)
96{
97 return !setup_APIC_eilvt(offset, 0, 0, 1);
98}
99
100/*
101 * Check and reserve APIC extended interrupt LVT offset for IBS if available.
102 */
103static inline int ibs_eilvt_valid(void)
104{
105 int offset;
106 u64 val;
107 int valid = 0;
108
109 preempt_disable();
110
111 rdmsrl(MSR_AMD64_IBSCTL, val);
112 offset = val & IBSCTL_LVT_OFFSET_MASK;
113
114 if (!(val & IBSCTL_LVT_OFFSET_VALID)) {
115 pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n",
116 smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
117 goto out;
118 }
119
120 if (!get_eilvt(offset)) {
121 pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n",
122 smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
123 goto out;
124 }
125
126 valid = 1;
127out:
128 preempt_enable();
129
130 return valid;
131}
132
133static int setup_ibs_ctl(int ibs_eilvt_off)
134{
135 struct pci_dev *cpu_cfg;
136 int nodes;
137 u32 value = 0;
138
139 nodes = 0;
140 cpu_cfg = NULL;
141 do {
142 cpu_cfg = pci_get_device(PCI_VENDOR_ID_AMD,
143 PCI_DEVICE_ID_AMD_10H_NB_MISC,
144 cpu_cfg);
145 if (!cpu_cfg)
146 break;
147 ++nodes;
148 pci_write_config_dword(cpu_cfg, IBSCTL, ibs_eilvt_off
149 | IBSCTL_LVT_OFFSET_VALID);
150 pci_read_config_dword(cpu_cfg, IBSCTL, &value);
151 if (value != (ibs_eilvt_off | IBSCTL_LVT_OFFSET_VALID)) {
152 pci_dev_put(cpu_cfg);
153 printk(KERN_DEBUG "Failed to setup IBS LVT offset, "
154 "IBSCTL = 0x%08x\n", value);
155 return -EINVAL;
156 }
157 } while (1);
158
159 if (!nodes) {
160 printk(KERN_DEBUG "No CPU node configured for IBS\n");
161 return -ENODEV;
162 }
163
164 return 0;
165}
166
167/*
168 * This runs only on the current cpu. We try to find an LVT offset and
169 * setup the local APIC. For this we must disable preemption. On
170 * success we initialize all nodes with this offset. This updates then
171 * the offset in the IBS_CTL per-node msr. The per-core APIC setup of
172 * the IBS interrupt vector is handled by perf_ibs_cpu_notifier that
173 * is using the new offset.
174 */
175static int force_ibs_eilvt_setup(void)
176{
177 int offset;
178 int ret;
179
180 preempt_disable();
181 /* find the next free available EILVT entry, skip offset 0 */
182 for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) {
183 if (get_eilvt(offset))
184 break;
185 }
186 preempt_enable();
187
188 if (offset == APIC_EILVT_NR_MAX) {
189 printk(KERN_DEBUG "No EILVT entry available\n");
190 return -EBUSY;
191 }
192
193 ret = setup_ibs_ctl(offset);
194 if (ret)
195 goto out;
196
197 if (!ibs_eilvt_valid()) {
198 ret = -EFAULT;
199 goto out;
200 }
201
202 pr_err(FW_BUG "using offset %d for IBS interrupts\n", offset);
203 pr_err(FW_BUG "workaround enabled for IBS LVT offset\n");
204
205 return 0;
206out:
207 preempt_disable();
208 put_eilvt(offset);
209 preempt_enable();
210 return ret;
211}
212
213static inline int get_ibs_lvt_offset(void)
214{
215 u64 val;
216
217 rdmsrl(MSR_AMD64_IBSCTL, val);
218 if (!(val & IBSCTL_LVT_OFFSET_VALID))
219 return -EINVAL;
220
221 return val & IBSCTL_LVT_OFFSET_MASK;
222}
223
224static void setup_APIC_ibs(void *dummy)
225{
226 int offset;
227
228 offset = get_ibs_lvt_offset();
229 if (offset < 0)
230 goto failed;
231
232 if (!setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 0))
233 return;
234failed:
235 pr_warn("perf: IBS APIC setup failed on cpu #%d\n",
236 smp_processor_id());
237}
238
239static void clear_APIC_ibs(void *dummy)
240{
241 int offset;
242
243 offset = get_ibs_lvt_offset();
244 if (offset >= 0)
245 setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_FIX, 1);
246}
247
248static int __cpuinit
249perf_ibs_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
250{
251 switch (action & ~CPU_TASKS_FROZEN) {
252 case CPU_STARTING:
253 setup_APIC_ibs(NULL);
254 break;
255 case CPU_DYING:
256 clear_APIC_ibs(NULL);
257 break;
258 default:
259 break;
260 }
261
262 return NOTIFY_OK;
263}
264
265static __init int amd_ibs_init(void)
266{
267 u32 caps;
268 int ret;
269
270 caps = __get_ibs_caps();
271 if (!caps)
272 return -ENODEV; /* ibs not supported by the cpu */
273
274 if (!ibs_eilvt_valid()) {
275 ret = force_ibs_eilvt_setup();
276 if (ret) {
277 pr_err("Failed to setup IBS, %d\n", ret);
278 return ret;
279 }
280 }
281
282 get_online_cpus();
283 ibs_caps = caps;
284 /* make ibs_caps visible to other cpus: */
285 smp_mb();
286 perf_cpu_notifier(perf_ibs_cpu_notifier);
287 smp_call_function(setup_APIC_ibs, NULL, 1);
288 put_online_cpus();
289
290 return perf_event_ibs_init();
291}
292
293/* Since we need the pci subsystem to init ibs we can't do this earlier: */
294device_initcall(amd_ibs_init);
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index f88af2c2a561..e09ca20e86ee 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -1,16 +1,19 @@
1#ifdef CONFIG_CPU_SUP_INTEL
2
3/* 1/*
4 * Per core/cpu state 2 * Per core/cpu state
5 * 3 *
6 * Used to coordinate shared registers between HT threads or 4 * Used to coordinate shared registers between HT threads or
7 * among events on a single PMU. 5 * among events on a single PMU.
8 */ 6 */
9struct intel_shared_regs { 7
10 struct er_account regs[EXTRA_REG_MAX]; 8#include <linux/stddef.h>
11 int refcnt; /* per-core: #HT threads */ 9#include <linux/types.h>
12 unsigned core_id; /* per-core: core id */ 10#include <linux/init.h>
13}; 11#include <linux/slab.h>
12
13#include <asm/hardirq.h>
14#include <asm/apic.h>
15
16#include "perf_event.h"
14 17
15/* 18/*
16 * Intel PerfMon, used on Core and later. 19 * Intel PerfMon, used on Core and later.
@@ -746,7 +749,8 @@ static void intel_pmu_enable_all(int added)
746 749
747 intel_pmu_pebs_enable_all(); 750 intel_pmu_pebs_enable_all();
748 intel_pmu_lbr_enable_all(); 751 intel_pmu_lbr_enable_all();
749 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl); 752 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL,
753 x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask);
750 754
751 if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) { 755 if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
752 struct perf_event *event = 756 struct perf_event *event =
@@ -869,6 +873,7 @@ static void intel_pmu_disable_fixed(struct hw_perf_event *hwc)
869static void intel_pmu_disable_event(struct perf_event *event) 873static void intel_pmu_disable_event(struct perf_event *event)
870{ 874{
871 struct hw_perf_event *hwc = &event->hw; 875 struct hw_perf_event *hwc = &event->hw;
876 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
872 877
873 if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) { 878 if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) {
874 intel_pmu_disable_bts(); 879 intel_pmu_disable_bts();
@@ -876,6 +881,9 @@ static void intel_pmu_disable_event(struct perf_event *event)
876 return; 881 return;
877 } 882 }
878 883
884 cpuc->intel_ctrl_guest_mask &= ~(1ull << hwc->idx);
885 cpuc->intel_ctrl_host_mask &= ~(1ull << hwc->idx);
886
879 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { 887 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
880 intel_pmu_disable_fixed(hwc); 888 intel_pmu_disable_fixed(hwc);
881 return; 889 return;
@@ -921,6 +929,7 @@ static void intel_pmu_enable_fixed(struct hw_perf_event *hwc)
921static void intel_pmu_enable_event(struct perf_event *event) 929static void intel_pmu_enable_event(struct perf_event *event)
922{ 930{
923 struct hw_perf_event *hwc = &event->hw; 931 struct hw_perf_event *hwc = &event->hw;
932 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
924 933
925 if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) { 934 if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) {
926 if (!__this_cpu_read(cpu_hw_events.enabled)) 935 if (!__this_cpu_read(cpu_hw_events.enabled))
@@ -930,6 +939,11 @@ static void intel_pmu_enable_event(struct perf_event *event)
930 return; 939 return;
931 } 940 }
932 941
942 if (event->attr.exclude_host)
943 cpuc->intel_ctrl_guest_mask |= (1ull << hwc->idx);
944 if (event->attr.exclude_guest)
945 cpuc->intel_ctrl_host_mask |= (1ull << hwc->idx);
946
933 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { 947 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
934 intel_pmu_enable_fixed(hwc); 948 intel_pmu_enable_fixed(hwc);
935 return; 949 return;
@@ -945,7 +959,7 @@ static void intel_pmu_enable_event(struct perf_event *event)
945 * Save and restart an expired event. Called by NMI contexts, 959 * Save and restart an expired event. Called by NMI contexts,
946 * so it has to be careful about preempting normal event ops: 960 * so it has to be careful about preempting normal event ops:
947 */ 961 */
948static int intel_pmu_save_and_restart(struct perf_event *event) 962int intel_pmu_save_and_restart(struct perf_event *event)
949{ 963{
950 x86_perf_event_update(event); 964 x86_perf_event_update(event);
951 return x86_perf_event_set_period(event); 965 return x86_perf_event_set_period(event);
@@ -1197,6 +1211,21 @@ intel_shared_regs_constraints(struct cpu_hw_events *cpuc,
1197 return c; 1211 return c;
1198} 1212}
1199 1213
1214struct event_constraint *
1215x86_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
1216{
1217 struct event_constraint *c;
1218
1219 if (x86_pmu.event_constraints) {
1220 for_each_event_constraint(c, x86_pmu.event_constraints) {
1221 if ((event->hw.config & c->cmask) == c->code)
1222 return c;
1223 }
1224 }
1225
1226 return &unconstrained;
1227}
1228
1200static struct event_constraint * 1229static struct event_constraint *
1201intel_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event) 1230intel_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
1202{ 1231{
@@ -1284,12 +1313,84 @@ static int intel_pmu_hw_config(struct perf_event *event)
1284 return 0; 1313 return 0;
1285} 1314}
1286 1315
1316struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr)
1317{
1318 if (x86_pmu.guest_get_msrs)
1319 return x86_pmu.guest_get_msrs(nr);
1320 *nr = 0;
1321 return NULL;
1322}
1323EXPORT_SYMBOL_GPL(perf_guest_get_msrs);
1324
1325static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr)
1326{
1327 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
1328 struct perf_guest_switch_msr *arr = cpuc->guest_switch_msrs;
1329
1330 arr[0].msr = MSR_CORE_PERF_GLOBAL_CTRL;
1331 arr[0].host = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask;
1332 arr[0].guest = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_host_mask;
1333
1334 *nr = 1;
1335 return arr;
1336}
1337
1338static struct perf_guest_switch_msr *core_guest_get_msrs(int *nr)
1339{
1340 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
1341 struct perf_guest_switch_msr *arr = cpuc->guest_switch_msrs;
1342 int idx;
1343
1344 for (idx = 0; idx < x86_pmu.num_counters; idx++) {
1345 struct perf_event *event = cpuc->events[idx];
1346
1347 arr[idx].msr = x86_pmu_config_addr(idx);
1348 arr[idx].host = arr[idx].guest = 0;
1349
1350 if (!test_bit(idx, cpuc->active_mask))
1351 continue;
1352
1353 arr[idx].host = arr[idx].guest =
1354 event->hw.config | ARCH_PERFMON_EVENTSEL_ENABLE;
1355
1356 if (event->attr.exclude_host)
1357 arr[idx].host &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
1358 else if (event->attr.exclude_guest)
1359 arr[idx].guest &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
1360 }
1361
1362 *nr = x86_pmu.num_counters;
1363 return arr;
1364}
1365
1366static void core_pmu_enable_event(struct perf_event *event)
1367{
1368 if (!event->attr.exclude_host)
1369 x86_pmu_enable_event(event);
1370}
1371
1372static void core_pmu_enable_all(int added)
1373{
1374 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
1375 int idx;
1376
1377 for (idx = 0; idx < x86_pmu.num_counters; idx++) {
1378 struct hw_perf_event *hwc = &cpuc->events[idx]->hw;
1379
1380 if (!test_bit(idx, cpuc->active_mask) ||
1381 cpuc->events[idx]->attr.exclude_host)
1382 continue;
1383
1384 __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
1385 }
1386}
1387
1287static __initconst const struct x86_pmu core_pmu = { 1388static __initconst const struct x86_pmu core_pmu = {
1288 .name = "core", 1389 .name = "core",
1289 .handle_irq = x86_pmu_handle_irq, 1390 .handle_irq = x86_pmu_handle_irq,
1290 .disable_all = x86_pmu_disable_all, 1391 .disable_all = x86_pmu_disable_all,
1291 .enable_all = x86_pmu_enable_all, 1392 .enable_all = core_pmu_enable_all,
1292 .enable = x86_pmu_enable_event, 1393 .enable = core_pmu_enable_event,
1293 .disable = x86_pmu_disable_event, 1394 .disable = x86_pmu_disable_event,
1294 .hw_config = x86_pmu_hw_config, 1395 .hw_config = x86_pmu_hw_config,
1295 .schedule_events = x86_schedule_events, 1396 .schedule_events = x86_schedule_events,
@@ -1307,9 +1408,10 @@ static __initconst const struct x86_pmu core_pmu = {
1307 .get_event_constraints = intel_get_event_constraints, 1408 .get_event_constraints = intel_get_event_constraints,
1308 .put_event_constraints = intel_put_event_constraints, 1409 .put_event_constraints = intel_put_event_constraints,
1309 .event_constraints = intel_core_event_constraints, 1410 .event_constraints = intel_core_event_constraints,
1411 .guest_get_msrs = core_guest_get_msrs,
1310}; 1412};
1311 1413
1312static struct intel_shared_regs *allocate_shared_regs(int cpu) 1414struct intel_shared_regs *allocate_shared_regs(int cpu)
1313{ 1415{
1314 struct intel_shared_regs *regs; 1416 struct intel_shared_regs *regs;
1315 int i; 1417 int i;
@@ -1362,7 +1464,7 @@ static void intel_pmu_cpu_starting(int cpu)
1362 1464
1363 pc = per_cpu(cpu_hw_events, i).shared_regs; 1465 pc = per_cpu(cpu_hw_events, i).shared_regs;
1364 if (pc && pc->core_id == core_id) { 1466 if (pc && pc->core_id == core_id) {
1365 kfree(cpuc->shared_regs); 1467 cpuc->kfree_on_online = cpuc->shared_regs;
1366 cpuc->shared_regs = pc; 1468 cpuc->shared_regs = pc;
1367 break; 1469 break;
1368 } 1470 }
@@ -1413,6 +1515,7 @@ static __initconst const struct x86_pmu intel_pmu = {
1413 .cpu_prepare = intel_pmu_cpu_prepare, 1515 .cpu_prepare = intel_pmu_cpu_prepare,
1414 .cpu_starting = intel_pmu_cpu_starting, 1516 .cpu_starting = intel_pmu_cpu_starting,
1415 .cpu_dying = intel_pmu_cpu_dying, 1517 .cpu_dying = intel_pmu_cpu_dying,
1518 .guest_get_msrs = intel_guest_get_msrs,
1416}; 1519};
1417 1520
1418static void intel_clovertown_quirks(void) 1521static void intel_clovertown_quirks(void)
@@ -1441,7 +1544,7 @@ static void intel_clovertown_quirks(void)
1441 x86_pmu.pebs_constraints = NULL; 1544 x86_pmu.pebs_constraints = NULL;
1442} 1545}
1443 1546
1444static __init int intel_pmu_init(void) 1547__init int intel_pmu_init(void)
1445{ 1548{
1446 union cpuid10_edx edx; 1549 union cpuid10_edx edx;
1447 union cpuid10_eax eax; 1550 union cpuid10_eax eax;
@@ -1597,7 +1700,7 @@ static __init int intel_pmu_init(void)
1597 intel_pmu_lbr_init_nhm(); 1700 intel_pmu_lbr_init_nhm();
1598 1701
1599 x86_pmu.event_constraints = intel_snb_event_constraints; 1702 x86_pmu.event_constraints = intel_snb_event_constraints;
1600 x86_pmu.pebs_constraints = intel_snb_pebs_events; 1703 x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints;
1601 x86_pmu.extra_regs = intel_snb_extra_regs; 1704 x86_pmu.extra_regs = intel_snb_extra_regs;
1602 /* all extra regs are per-cpu when HT is on */ 1705 /* all extra regs are per-cpu when HT is on */
1603 x86_pmu.er_flags |= ERF_HAS_RSP_1; 1706 x86_pmu.er_flags |= ERF_HAS_RSP_1;
@@ -1628,16 +1731,3 @@ static __init int intel_pmu_init(void)
1628 } 1731 }
1629 return 0; 1732 return 0;
1630} 1733}
1631
1632#else /* CONFIG_CPU_SUP_INTEL */
1633
1634static int intel_pmu_init(void)
1635{
1636 return 0;
1637}
1638
1639static struct intel_shared_regs *allocate_shared_regs(int cpu)
1640{
1641 return NULL;
1642}
1643#endif /* CONFIG_CPU_SUP_INTEL */
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index 1b1ef3addcfd..c0d238f49db8 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -1,7 +1,10 @@
1#ifdef CONFIG_CPU_SUP_INTEL 1#include <linux/bitops.h>
2#include <linux/types.h>
3#include <linux/slab.h>
2 4
3/* The maximal number of PEBS events: */ 5#include <asm/perf_event.h>
4#define MAX_PEBS_EVENTS 4 6
7#include "perf_event.h"
5 8
6/* The size of a BTS record in bytes: */ 9/* The size of a BTS record in bytes: */
7#define BTS_RECORD_SIZE 24 10#define BTS_RECORD_SIZE 24
@@ -37,24 +40,7 @@ struct pebs_record_nhm {
37 u64 status, dla, dse, lat; 40 u64 status, dla, dse, lat;
38}; 41};
39 42
40/* 43void init_debug_store_on_cpu(int cpu)
41 * A debug store configuration.
42 *
43 * We only support architectures that use 64bit fields.
44 */
45struct debug_store {
46 u64 bts_buffer_base;
47 u64 bts_index;
48 u64 bts_absolute_maximum;
49 u64 bts_interrupt_threshold;
50 u64 pebs_buffer_base;
51 u64 pebs_index;
52 u64 pebs_absolute_maximum;
53 u64 pebs_interrupt_threshold;
54 u64 pebs_event_reset[MAX_PEBS_EVENTS];
55};
56
57static void init_debug_store_on_cpu(int cpu)
58{ 44{
59 struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds; 45 struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
60 46
@@ -66,7 +52,7 @@ static void init_debug_store_on_cpu(int cpu)
66 (u32)((u64)(unsigned long)ds >> 32)); 52 (u32)((u64)(unsigned long)ds >> 32));
67} 53}
68 54
69static void fini_debug_store_on_cpu(int cpu) 55void fini_debug_store_on_cpu(int cpu)
70{ 56{
71 if (!per_cpu(cpu_hw_events, cpu).ds) 57 if (!per_cpu(cpu_hw_events, cpu).ds)
72 return; 58 return;
@@ -175,7 +161,7 @@ static void release_ds_buffer(int cpu)
175 kfree(ds); 161 kfree(ds);
176} 162}
177 163
178static void release_ds_buffers(void) 164void release_ds_buffers(void)
179{ 165{
180 int cpu; 166 int cpu;
181 167
@@ -194,7 +180,7 @@ static void release_ds_buffers(void)
194 put_online_cpus(); 180 put_online_cpus();
195} 181}
196 182
197static void reserve_ds_buffers(void) 183void reserve_ds_buffers(void)
198{ 184{
199 int bts_err = 0, pebs_err = 0; 185 int bts_err = 0, pebs_err = 0;
200 int cpu; 186 int cpu;
@@ -260,10 +246,10 @@ static void reserve_ds_buffers(void)
260 * BTS 246 * BTS
261 */ 247 */
262 248
263static struct event_constraint bts_constraint = 249struct event_constraint bts_constraint =
264 EVENT_CONSTRAINT(0, 1ULL << X86_PMC_IDX_FIXED_BTS, 0); 250 EVENT_CONSTRAINT(0, 1ULL << X86_PMC_IDX_FIXED_BTS, 0);
265 251
266static void intel_pmu_enable_bts(u64 config) 252void intel_pmu_enable_bts(u64 config)
267{ 253{
268 unsigned long debugctlmsr; 254 unsigned long debugctlmsr;
269 255
@@ -282,7 +268,7 @@ static void intel_pmu_enable_bts(u64 config)
282 update_debugctlmsr(debugctlmsr); 268 update_debugctlmsr(debugctlmsr);
283} 269}
284 270
285static void intel_pmu_disable_bts(void) 271void intel_pmu_disable_bts(void)
286{ 272{
287 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 273 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
288 unsigned long debugctlmsr; 274 unsigned long debugctlmsr;
@@ -299,7 +285,7 @@ static void intel_pmu_disable_bts(void)
299 update_debugctlmsr(debugctlmsr); 285 update_debugctlmsr(debugctlmsr);
300} 286}
301 287
302static int intel_pmu_drain_bts_buffer(void) 288int intel_pmu_drain_bts_buffer(void)
303{ 289{
304 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 290 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
305 struct debug_store *ds = cpuc->ds; 291 struct debug_store *ds = cpuc->ds;
@@ -361,7 +347,7 @@ static int intel_pmu_drain_bts_buffer(void)
361/* 347/*
362 * PEBS 348 * PEBS
363 */ 349 */
364static struct event_constraint intel_core2_pebs_event_constraints[] = { 350struct event_constraint intel_core2_pebs_event_constraints[] = {
365 INTEL_UEVENT_CONSTRAINT(0x00c0, 0x1), /* INST_RETIRED.ANY */ 351 INTEL_UEVENT_CONSTRAINT(0x00c0, 0x1), /* INST_RETIRED.ANY */
366 INTEL_UEVENT_CONSTRAINT(0xfec1, 0x1), /* X87_OPS_RETIRED.ANY */ 352 INTEL_UEVENT_CONSTRAINT(0xfec1, 0x1), /* X87_OPS_RETIRED.ANY */
367 INTEL_UEVENT_CONSTRAINT(0x00c5, 0x1), /* BR_INST_RETIRED.MISPRED */ 353 INTEL_UEVENT_CONSTRAINT(0x00c5, 0x1), /* BR_INST_RETIRED.MISPRED */
@@ -370,14 +356,14 @@ static struct event_constraint intel_core2_pebs_event_constraints[] = {
370 EVENT_CONSTRAINT_END 356 EVENT_CONSTRAINT_END
371}; 357};
372 358
373static struct event_constraint intel_atom_pebs_event_constraints[] = { 359struct event_constraint intel_atom_pebs_event_constraints[] = {
374 INTEL_UEVENT_CONSTRAINT(0x00c0, 0x1), /* INST_RETIRED.ANY */ 360 INTEL_UEVENT_CONSTRAINT(0x00c0, 0x1), /* INST_RETIRED.ANY */
375 INTEL_UEVENT_CONSTRAINT(0x00c5, 0x1), /* MISPREDICTED_BRANCH_RETIRED */ 361 INTEL_UEVENT_CONSTRAINT(0x00c5, 0x1), /* MISPREDICTED_BRANCH_RETIRED */
376 INTEL_EVENT_CONSTRAINT(0xcb, 0x1), /* MEM_LOAD_RETIRED.* */ 362 INTEL_EVENT_CONSTRAINT(0xcb, 0x1), /* MEM_LOAD_RETIRED.* */
377 EVENT_CONSTRAINT_END 363 EVENT_CONSTRAINT_END
378}; 364};
379 365
380static struct event_constraint intel_nehalem_pebs_event_constraints[] = { 366struct event_constraint intel_nehalem_pebs_event_constraints[] = {
381 INTEL_EVENT_CONSTRAINT(0x0b, 0xf), /* MEM_INST_RETIRED.* */ 367 INTEL_EVENT_CONSTRAINT(0x0b, 0xf), /* MEM_INST_RETIRED.* */
382 INTEL_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */ 368 INTEL_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */
383 INTEL_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */ 369 INTEL_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */
@@ -392,7 +378,7 @@ static struct event_constraint intel_nehalem_pebs_event_constraints[] = {
392 EVENT_CONSTRAINT_END 378 EVENT_CONSTRAINT_END
393}; 379};
394 380
395static struct event_constraint intel_westmere_pebs_event_constraints[] = { 381struct event_constraint intel_westmere_pebs_event_constraints[] = {
396 INTEL_EVENT_CONSTRAINT(0x0b, 0xf), /* MEM_INST_RETIRED.* */ 382 INTEL_EVENT_CONSTRAINT(0x0b, 0xf), /* MEM_INST_RETIRED.* */
397 INTEL_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */ 383 INTEL_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */
398 INTEL_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */ 384 INTEL_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */
@@ -407,7 +393,7 @@ static struct event_constraint intel_westmere_pebs_event_constraints[] = {
407 EVENT_CONSTRAINT_END 393 EVENT_CONSTRAINT_END
408}; 394};
409 395
410static struct event_constraint intel_snb_pebs_events[] = { 396struct event_constraint intel_snb_pebs_event_constraints[] = {
411 INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */ 397 INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
412 INTEL_UEVENT_CONSTRAINT(0x01c2, 0xf), /* UOPS_RETIRED.ALL */ 398 INTEL_UEVENT_CONSTRAINT(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
413 INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */ 399 INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */
@@ -428,8 +414,7 @@ static struct event_constraint intel_snb_pebs_events[] = {
428 EVENT_CONSTRAINT_END 414 EVENT_CONSTRAINT_END
429}; 415};
430 416
431static struct event_constraint * 417struct event_constraint *intel_pebs_constraints(struct perf_event *event)
432intel_pebs_constraints(struct perf_event *event)
433{ 418{
434 struct event_constraint *c; 419 struct event_constraint *c;
435 420
@@ -446,7 +431,7 @@ intel_pebs_constraints(struct perf_event *event)
446 return &emptyconstraint; 431 return &emptyconstraint;
447} 432}
448 433
449static void intel_pmu_pebs_enable(struct perf_event *event) 434void intel_pmu_pebs_enable(struct perf_event *event)
450{ 435{
451 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 436 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
452 struct hw_perf_event *hwc = &event->hw; 437 struct hw_perf_event *hwc = &event->hw;
@@ -460,7 +445,7 @@ static void intel_pmu_pebs_enable(struct perf_event *event)
460 intel_pmu_lbr_enable(event); 445 intel_pmu_lbr_enable(event);
461} 446}
462 447
463static void intel_pmu_pebs_disable(struct perf_event *event) 448void intel_pmu_pebs_disable(struct perf_event *event)
464{ 449{
465 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 450 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
466 struct hw_perf_event *hwc = &event->hw; 451 struct hw_perf_event *hwc = &event->hw;
@@ -475,7 +460,7 @@ static void intel_pmu_pebs_disable(struct perf_event *event)
475 intel_pmu_lbr_disable(event); 460 intel_pmu_lbr_disable(event);
476} 461}
477 462
478static void intel_pmu_pebs_enable_all(void) 463void intel_pmu_pebs_enable_all(void)
479{ 464{
480 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 465 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
481 466
@@ -483,7 +468,7 @@ static void intel_pmu_pebs_enable_all(void)
483 wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled); 468 wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
484} 469}
485 470
486static void intel_pmu_pebs_disable_all(void) 471void intel_pmu_pebs_disable_all(void)
487{ 472{
488 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 473 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
489 474
@@ -576,8 +561,6 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
576 return 0; 561 return 0;
577} 562}
578 563
579static int intel_pmu_save_and_restart(struct perf_event *event);
580
581static void __intel_pmu_pebs_event(struct perf_event *event, 564static void __intel_pmu_pebs_event(struct perf_event *event,
582 struct pt_regs *iregs, void *__pebs) 565 struct pt_regs *iregs, void *__pebs)
583{ 566{
@@ -716,7 +699,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
716 * BTS, PEBS probe and setup 699 * BTS, PEBS probe and setup
717 */ 700 */
718 701
719static void intel_ds_init(void) 702void intel_ds_init(void)
720{ 703{
721 /* 704 /*
722 * No support for 32bit formats 705 * No support for 32bit formats
@@ -749,15 +732,3 @@ static void intel_ds_init(void)
749 } 732 }
750 } 733 }
751} 734}
752
753#else /* CONFIG_CPU_SUP_INTEL */
754
755static void reserve_ds_buffers(void)
756{
757}
758
759static void release_ds_buffers(void)
760{
761}
762
763#endif /* CONFIG_CPU_SUP_INTEL */
diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
index d202c1bece1a..3fab3de3ce96 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
@@ -1,4 +1,10 @@
1#ifdef CONFIG_CPU_SUP_INTEL 1#include <linux/perf_event.h>
2#include <linux/types.h>
3
4#include <asm/perf_event.h>
5#include <asm/msr.h>
6
7#include "perf_event.h"
2 8
3enum { 9enum {
4 LBR_FORMAT_32 = 0x00, 10 LBR_FORMAT_32 = 0x00,
@@ -48,7 +54,7 @@ static void intel_pmu_lbr_reset_64(void)
48 } 54 }
49} 55}
50 56
51static void intel_pmu_lbr_reset(void) 57void intel_pmu_lbr_reset(void)
52{ 58{
53 if (!x86_pmu.lbr_nr) 59 if (!x86_pmu.lbr_nr)
54 return; 60 return;
@@ -59,7 +65,7 @@ static void intel_pmu_lbr_reset(void)
59 intel_pmu_lbr_reset_64(); 65 intel_pmu_lbr_reset_64();
60} 66}
61 67
62static void intel_pmu_lbr_enable(struct perf_event *event) 68void intel_pmu_lbr_enable(struct perf_event *event)
63{ 69{
64 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 70 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
65 71
@@ -81,7 +87,7 @@ static void intel_pmu_lbr_enable(struct perf_event *event)
81 cpuc->lbr_users++; 87 cpuc->lbr_users++;
82} 88}
83 89
84static void intel_pmu_lbr_disable(struct perf_event *event) 90void intel_pmu_lbr_disable(struct perf_event *event)
85{ 91{
86 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 92 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
87 93
@@ -95,7 +101,7 @@ static void intel_pmu_lbr_disable(struct perf_event *event)
95 __intel_pmu_lbr_disable(); 101 __intel_pmu_lbr_disable();
96} 102}
97 103
98static void intel_pmu_lbr_enable_all(void) 104void intel_pmu_lbr_enable_all(void)
99{ 105{
100 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 106 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
101 107
@@ -103,7 +109,7 @@ static void intel_pmu_lbr_enable_all(void)
103 __intel_pmu_lbr_enable(); 109 __intel_pmu_lbr_enable();
104} 110}
105 111
106static void intel_pmu_lbr_disable_all(void) 112void intel_pmu_lbr_disable_all(void)
107{ 113{
108 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 114 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
109 115
@@ -178,7 +184,7 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
178 cpuc->lbr_stack.nr = i; 184 cpuc->lbr_stack.nr = i;
179} 185}
180 186
181static void intel_pmu_lbr_read(void) 187void intel_pmu_lbr_read(void)
182{ 188{
183 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 189 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
184 190
@@ -191,7 +197,7 @@ static void intel_pmu_lbr_read(void)
191 intel_pmu_lbr_read_64(cpuc); 197 intel_pmu_lbr_read_64(cpuc);
192} 198}
193 199
194static void intel_pmu_lbr_init_core(void) 200void intel_pmu_lbr_init_core(void)
195{ 201{
196 x86_pmu.lbr_nr = 4; 202 x86_pmu.lbr_nr = 4;
197 x86_pmu.lbr_tos = 0x01c9; 203 x86_pmu.lbr_tos = 0x01c9;
@@ -199,7 +205,7 @@ static void intel_pmu_lbr_init_core(void)
199 x86_pmu.lbr_to = 0x60; 205 x86_pmu.lbr_to = 0x60;
200} 206}
201 207
202static void intel_pmu_lbr_init_nhm(void) 208void intel_pmu_lbr_init_nhm(void)
203{ 209{
204 x86_pmu.lbr_nr = 16; 210 x86_pmu.lbr_nr = 16;
205 x86_pmu.lbr_tos = 0x01c9; 211 x86_pmu.lbr_tos = 0x01c9;
@@ -207,12 +213,10 @@ static void intel_pmu_lbr_init_nhm(void)
207 x86_pmu.lbr_to = 0x6c0; 213 x86_pmu.lbr_to = 0x6c0;
208} 214}
209 215
210static void intel_pmu_lbr_init_atom(void) 216void intel_pmu_lbr_init_atom(void)
211{ 217{
212 x86_pmu.lbr_nr = 8; 218 x86_pmu.lbr_nr = 8;
213 x86_pmu.lbr_tos = 0x01c9; 219 x86_pmu.lbr_tos = 0x01c9;
214 x86_pmu.lbr_from = 0x40; 220 x86_pmu.lbr_from = 0x40;
215 x86_pmu.lbr_to = 0x60; 221 x86_pmu.lbr_to = 0x60;
216} 222}
217
218#endif /* CONFIG_CPU_SUP_INTEL */
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c
index 7809d2bcb209..492bf1358a7c 100644
--- a/arch/x86/kernel/cpu/perf_event_p4.c
+++ b/arch/x86/kernel/cpu/perf_event_p4.c
@@ -7,9 +7,13 @@
7 * For licencing details see kernel-base/COPYING 7 * For licencing details see kernel-base/COPYING
8 */ 8 */
9 9
10#ifdef CONFIG_CPU_SUP_INTEL 10#include <linux/perf_event.h>
11 11
12#include <asm/perf_event_p4.h> 12#include <asm/perf_event_p4.h>
13#include <asm/hardirq.h>
14#include <asm/apic.h>
15
16#include "perf_event.h"
13 17
14#define P4_CNTR_LIMIT 3 18#define P4_CNTR_LIMIT 3
15/* 19/*
@@ -1303,7 +1307,7 @@ static __initconst const struct x86_pmu p4_pmu = {
1303 .perfctr_second_write = 1, 1307 .perfctr_second_write = 1,
1304}; 1308};
1305 1309
1306static __init int p4_pmu_init(void) 1310__init int p4_pmu_init(void)
1307{ 1311{
1308 unsigned int low, high; 1312 unsigned int low, high;
1309 1313
@@ -1326,5 +1330,3 @@ static __init int p4_pmu_init(void)
1326 1330
1327 return 0; 1331 return 0;
1328} 1332}
1329
1330#endif /* CONFIG_CPU_SUP_INTEL */
diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c
index 20c097e33860..c7181befecde 100644
--- a/arch/x86/kernel/cpu/perf_event_p6.c
+++ b/arch/x86/kernel/cpu/perf_event_p6.c
@@ -1,4 +1,7 @@
1#ifdef CONFIG_CPU_SUP_INTEL 1#include <linux/perf_event.h>
2#include <linux/types.h>
3
4#include "perf_event.h"
2 5
3/* 6/*
4 * Not sure about some of these 7 * Not sure about some of these
@@ -114,7 +117,7 @@ static __initconst const struct x86_pmu p6_pmu = {
114 .event_constraints = p6_event_constraints, 117 .event_constraints = p6_event_constraints,
115}; 118};
116 119
117static __init int p6_pmu_init(void) 120__init int p6_pmu_init(void)
118{ 121{
119 switch (boot_cpu_data.x86_model) { 122 switch (boot_cpu_data.x86_model) {
120 case 1: 123 case 1:
@@ -138,5 +141,3 @@ static __init int p6_pmu_init(void)
138 141
139 return 0; 142 return 0;
140} 143}
141
142#endif /* CONFIG_CPU_SUP_INTEL */
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index 764c7c2b1811..13ad89971d47 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -32,15 +32,12 @@ int in_crash_kexec;
32 32
33#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) 33#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
34 34
35static void kdump_nmi_callback(int cpu, struct die_args *args) 35static void kdump_nmi_callback(int cpu, struct pt_regs *regs)
36{ 36{
37 struct pt_regs *regs;
38#ifdef CONFIG_X86_32 37#ifdef CONFIG_X86_32
39 struct pt_regs fixed_regs; 38 struct pt_regs fixed_regs;
40#endif 39#endif
41 40
42 regs = args->regs;
43
44#ifdef CONFIG_X86_32 41#ifdef CONFIG_X86_32
45 if (!user_mode_vm(regs)) { 42 if (!user_mode_vm(regs)) {
46 crash_fixup_ss_esp(&fixed_regs, regs); 43 crash_fixup_ss_esp(&fixed_regs, regs);
diff --git a/arch/x86/kernel/jump_label.c b/arch/x86/kernel/jump_label.c
index 3fee346ef545..cacdd46d184d 100644
--- a/arch/x86/kernel/jump_label.c
+++ b/arch/x86/kernel/jump_label.c
@@ -42,7 +42,7 @@ void arch_jump_label_transform(struct jump_entry *entry,
42 put_online_cpus(); 42 put_online_cpus();
43} 43}
44 44
45void arch_jump_label_text_poke_early(jump_label_t addr) 45void __init_or_module arch_jump_label_text_poke_early(jump_label_t addr)
46{ 46{
47 text_poke_early((void *)addr, ideal_nops[NOP_ATOMIC5], 47 text_poke_early((void *)addr, ideal_nops[NOP_ATOMIC5],
48 JUMP_LABEL_NOP_SIZE); 48 JUMP_LABEL_NOP_SIZE);
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index 00354d4919a9..faba5771acad 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -511,28 +511,37 @@ single_step_cont(struct pt_regs *regs, struct die_args *args)
511 511
512static int was_in_debug_nmi[NR_CPUS]; 512static int was_in_debug_nmi[NR_CPUS];
513 513
514static int __kgdb_notify(struct die_args *args, unsigned long cmd) 514static int kgdb_nmi_handler(unsigned int cmd, struct pt_regs *regs)
515{ 515{
516 struct pt_regs *regs = args->regs;
517
518 switch (cmd) { 516 switch (cmd) {
519 case DIE_NMI: 517 case NMI_LOCAL:
520 if (atomic_read(&kgdb_active) != -1) { 518 if (atomic_read(&kgdb_active) != -1) {
521 /* KGDB CPU roundup */ 519 /* KGDB CPU roundup */
522 kgdb_nmicallback(raw_smp_processor_id(), regs); 520 kgdb_nmicallback(raw_smp_processor_id(), regs);
523 was_in_debug_nmi[raw_smp_processor_id()] = 1; 521 was_in_debug_nmi[raw_smp_processor_id()] = 1;
524 touch_nmi_watchdog(); 522 touch_nmi_watchdog();
525 return NOTIFY_STOP; 523 return NMI_HANDLED;
526 } 524 }
527 return NOTIFY_DONE; 525 break;
528 526
529 case DIE_NMIUNKNOWN: 527 case NMI_UNKNOWN:
530 if (was_in_debug_nmi[raw_smp_processor_id()]) { 528 if (was_in_debug_nmi[raw_smp_processor_id()]) {
531 was_in_debug_nmi[raw_smp_processor_id()] = 0; 529 was_in_debug_nmi[raw_smp_processor_id()] = 0;
532 return NOTIFY_STOP; 530 return NMI_HANDLED;
533 } 531 }
534 return NOTIFY_DONE; 532 break;
533 default:
534 /* do nothing */
535 break;
536 }
537 return NMI_DONE;
538}
539
540static int __kgdb_notify(struct die_args *args, unsigned long cmd)
541{
542 struct pt_regs *regs = args->regs;
535 543
544 switch (cmd) {
536 case DIE_DEBUG: 545 case DIE_DEBUG:
537 if (atomic_read(&kgdb_cpu_doing_single_step) != -1) { 546 if (atomic_read(&kgdb_cpu_doing_single_step) != -1) {
538 if (user_mode(regs)) 547 if (user_mode(regs))
@@ -590,11 +599,6 @@ kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
590 599
591static struct notifier_block kgdb_notifier = { 600static struct notifier_block kgdb_notifier = {
592 .notifier_call = kgdb_notify, 601 .notifier_call = kgdb_notify,
593
594 /*
595 * Lowest-prio notifier priority, we want to be notified last:
596 */
597 .priority = NMI_LOCAL_LOW_PRIOR,
598}; 602};
599 603
600/** 604/**
@@ -605,7 +609,31 @@ static struct notifier_block kgdb_notifier = {
605 */ 609 */
606int kgdb_arch_init(void) 610int kgdb_arch_init(void)
607{ 611{
608 return register_die_notifier(&kgdb_notifier); 612 int retval;
613
614 retval = register_die_notifier(&kgdb_notifier);
615 if (retval)
616 goto out;
617
618 retval = register_nmi_handler(NMI_LOCAL, kgdb_nmi_handler,
619 0, "kgdb");
620 if (retval)
621 goto out1;
622
623 retval = register_nmi_handler(NMI_UNKNOWN, kgdb_nmi_handler,
624 0, "kgdb");
625
626 if (retval)
627 goto out2;
628
629 return retval;
630
631out2:
632 unregister_nmi_handler(NMI_LOCAL, "kgdb");
633out1:
634 unregister_die_notifier(&kgdb_notifier);
635out:
636 return retval;
609} 637}
610 638
611static void kgdb_hw_overflow_handler(struct perf_event *event, 639static void kgdb_hw_overflow_handler(struct perf_event *event,
@@ -673,6 +701,8 @@ void kgdb_arch_exit(void)
673 breakinfo[i].pev = NULL; 701 breakinfo[i].pev = NULL;
674 } 702 }
675 } 703 }
704 unregister_nmi_handler(NMI_UNKNOWN, "kgdb");
705 unregister_nmi_handler(NMI_LOCAL, "kgdb");
676 unregister_die_notifier(&kgdb_notifier); 706 unregister_die_notifier(&kgdb_notifier);
677} 707}
678 708
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index 794bc95134cd..7da647d8b64c 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -75,10 +75,11 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
75 /* 75 /*
76 * Undefined/reserved opcodes, conditional jump, Opcode Extension 76 * Undefined/reserved opcodes, conditional jump, Opcode Extension
77 * Groups, and some special opcodes can not boost. 77 * Groups, and some special opcodes can not boost.
78 * This is non-const to keep gcc from statically optimizing it out, as 78 * This is non-const and volatile to keep gcc from statically
79 * variable_test_bit makes gcc think only *(unsigned long*) is used. 79 * optimizing it out, as variable_test_bit makes gcc think only
80 * *(unsigned long*) is used.
80 */ 81 */
81static u32 twobyte_is_boostable[256 / 32] = { 82static volatile u32 twobyte_is_boostable[256 / 32] = {
82 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 83 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
83 /* ---------------------------------------------- */ 84 /* ---------------------------------------------- */
84 W(0x00, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0) | /* 00 */ 85 W(0x00, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0) | /* 00 */
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c
new file mode 100644
index 000000000000..7ec5bd140b87
--- /dev/null
+++ b/arch/x86/kernel/nmi.c
@@ -0,0 +1,433 @@
1/*
2 * Copyright (C) 1991, 1992 Linus Torvalds
3 * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
4 * Copyright (C) 2011 Don Zickus Red Hat, Inc.
5 *
6 * Pentium III FXSR, SSE support
7 * Gareth Hughes <gareth@valinux.com>, May 2000
8 */
9
10/*
11 * Handle hardware traps and faults.
12 */
13#include <linux/spinlock.h>
14#include <linux/kprobes.h>
15#include <linux/kdebug.h>
16#include <linux/nmi.h>
17#include <linux/delay.h>
18#include <linux/hardirq.h>
19#include <linux/slab.h>
20
21#include <linux/mca.h>
22
23#if defined(CONFIG_EDAC)
24#include <linux/edac.h>
25#endif
26
27#include <linux/atomic.h>
28#include <asm/traps.h>
29#include <asm/mach_traps.h>
30#include <asm/nmi.h>
31
32#define NMI_MAX_NAMELEN 16
33struct nmiaction {
34 struct list_head list;
35 nmi_handler_t handler;
36 unsigned int flags;
37 char *name;
38};
39
40struct nmi_desc {
41 spinlock_t lock;
42 struct list_head head;
43};
44
45static struct nmi_desc nmi_desc[NMI_MAX] =
46{
47 {
48 .lock = __SPIN_LOCK_UNLOCKED(&nmi_desc[0].lock),
49 .head = LIST_HEAD_INIT(nmi_desc[0].head),
50 },
51 {
52 .lock = __SPIN_LOCK_UNLOCKED(&nmi_desc[1].lock),
53 .head = LIST_HEAD_INIT(nmi_desc[1].head),
54 },
55
56};
57
58struct nmi_stats {
59 unsigned int normal;
60 unsigned int unknown;
61 unsigned int external;
62 unsigned int swallow;
63};
64
65static DEFINE_PER_CPU(struct nmi_stats, nmi_stats);
66
67static int ignore_nmis;
68
69int unknown_nmi_panic;
70/*
71 * Prevent NMI reason port (0x61) being accessed simultaneously, can
72 * only be used in NMI handler.
73 */
74static DEFINE_RAW_SPINLOCK(nmi_reason_lock);
75
76static int __init setup_unknown_nmi_panic(char *str)
77{
78 unknown_nmi_panic = 1;
79 return 1;
80}
81__setup("unknown_nmi_panic", setup_unknown_nmi_panic);
82
83#define nmi_to_desc(type) (&nmi_desc[type])
84
85static int notrace __kprobes nmi_handle(unsigned int type, struct pt_regs *regs, bool b2b)
86{
87 struct nmi_desc *desc = nmi_to_desc(type);
88 struct nmiaction *a;
89 int handled=0;
90
91 rcu_read_lock();
92
93 /*
94 * NMIs are edge-triggered, which means if you have enough
95 * of them concurrently, you can lose some because only one
96 * can be latched at any given time. Walk the whole list
97 * to handle those situations.
98 */
99 list_for_each_entry_rcu(a, &desc->head, list)
100 handled += a->handler(type, regs);
101
102 rcu_read_unlock();
103
104 /* return total number of NMI events handled */
105 return handled;
106}
107
108static int __setup_nmi(unsigned int type, struct nmiaction *action)
109{
110 struct nmi_desc *desc = nmi_to_desc(type);
111 unsigned long flags;
112
113 spin_lock_irqsave(&desc->lock, flags);
114
115 /*
116 * most handlers of type NMI_UNKNOWN never return because
117 * they just assume the NMI is theirs. Just a sanity check
118 * to manage expectations
119 */
120 WARN_ON_ONCE(type == NMI_UNKNOWN && !list_empty(&desc->head));
121
122 /*
123 * some handlers need to be executed first otherwise a fake
124 * event confuses some handlers (kdump uses this flag)
125 */
126 if (action->flags & NMI_FLAG_FIRST)
127 list_add_rcu(&action->list, &desc->head);
128 else
129 list_add_tail_rcu(&action->list, &desc->head);
130
131 spin_unlock_irqrestore(&desc->lock, flags);
132 return 0;
133}
134
135static struct nmiaction *__free_nmi(unsigned int type, const char *name)
136{
137 struct nmi_desc *desc = nmi_to_desc(type);
138 struct nmiaction *n;
139 unsigned long flags;
140
141 spin_lock_irqsave(&desc->lock, flags);
142
143 list_for_each_entry_rcu(n, &desc->head, list) {
144 /*
145 * the name passed in to describe the nmi handler
146 * is used as the lookup key
147 */
148 if (!strcmp(n->name, name)) {
149 WARN(in_nmi(),
150 "Trying to free NMI (%s) from NMI context!\n", n->name);
151 list_del_rcu(&n->list);
152 break;
153 }
154 }
155
156 spin_unlock_irqrestore(&desc->lock, flags);
157 synchronize_rcu();
158 return (n);
159}
160
161int register_nmi_handler(unsigned int type, nmi_handler_t handler,
162 unsigned long nmiflags, const char *devname)
163{
164 struct nmiaction *action;
165 int retval = -ENOMEM;
166
167 if (!handler)
168 return -EINVAL;
169
170 action = kzalloc(sizeof(struct nmiaction), GFP_KERNEL);
171 if (!action)
172 goto fail_action;
173
174 action->handler = handler;
175 action->flags = nmiflags;
176 action->name = kstrndup(devname, NMI_MAX_NAMELEN, GFP_KERNEL);
177 if (!action->name)
178 goto fail_action_name;
179
180 retval = __setup_nmi(type, action);
181
182 if (retval)
183 goto fail_setup_nmi;
184
185 return retval;
186
187fail_setup_nmi:
188 kfree(action->name);
189fail_action_name:
190 kfree(action);
191fail_action:
192
193 return retval;
194}
195EXPORT_SYMBOL_GPL(register_nmi_handler);
196
197void unregister_nmi_handler(unsigned int type, const char *name)
198{
199 struct nmiaction *a;
200
201 a = __free_nmi(type, name);
202 if (a) {
203 kfree(a->name);
204 kfree(a);
205 }
206}
207
208EXPORT_SYMBOL_GPL(unregister_nmi_handler);
209
210static notrace __kprobes void
211pci_serr_error(unsigned char reason, struct pt_regs *regs)
212{
213 pr_emerg("NMI: PCI system error (SERR) for reason %02x on CPU %d.\n",
214 reason, smp_processor_id());
215
216 /*
217 * On some machines, PCI SERR line is used to report memory
218 * errors. EDAC makes use of it.
219 */
220#if defined(CONFIG_EDAC)
221 if (edac_handler_set()) {
222 edac_atomic_assert_error();
223 return;
224 }
225#endif
226
227 if (panic_on_unrecovered_nmi)
228 panic("NMI: Not continuing");
229
230 pr_emerg("Dazed and confused, but trying to continue\n");
231
232 /* Clear and disable the PCI SERR error line. */
233 reason = (reason & NMI_REASON_CLEAR_MASK) | NMI_REASON_CLEAR_SERR;
234 outb(reason, NMI_REASON_PORT);
235}
236
237static notrace __kprobes void
238io_check_error(unsigned char reason, struct pt_regs *regs)
239{
240 unsigned long i;
241
242 pr_emerg(
243 "NMI: IOCK error (debug interrupt?) for reason %02x on CPU %d.\n",
244 reason, smp_processor_id());
245 show_registers(regs);
246
247 if (panic_on_io_nmi)
248 panic("NMI IOCK error: Not continuing");
249
250 /* Re-enable the IOCK line, wait for a few seconds */
251 reason = (reason & NMI_REASON_CLEAR_MASK) | NMI_REASON_CLEAR_IOCHK;
252 outb(reason, NMI_REASON_PORT);
253
254 i = 20000;
255 while (--i) {
256 touch_nmi_watchdog();
257 udelay(100);
258 }
259
260 reason &= ~NMI_REASON_CLEAR_IOCHK;
261 outb(reason, NMI_REASON_PORT);
262}
263
264static notrace __kprobes void
265unknown_nmi_error(unsigned char reason, struct pt_regs *regs)
266{
267 int handled;
268
269 /*
270 * Use 'false' as back-to-back NMIs are dealt with one level up.
271 * Of course this makes having multiple 'unknown' handlers useless
272 * as only the first one is ever run (unless it can actually determine
273 * if it caused the NMI)
274 */
275 handled = nmi_handle(NMI_UNKNOWN, regs, false);
276 if (handled) {
277 __this_cpu_add(nmi_stats.unknown, handled);
278 return;
279 }
280
281 __this_cpu_add(nmi_stats.unknown, 1);
282
283#ifdef CONFIG_MCA
284 /*
285 * Might actually be able to figure out what the guilty party
286 * is:
287 */
288 if (MCA_bus) {
289 mca_handle_nmi();
290 return;
291 }
292#endif
293 pr_emerg("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n",
294 reason, smp_processor_id());
295
296 pr_emerg("Do you have a strange power saving mode enabled?\n");
297 if (unknown_nmi_panic || panic_on_unrecovered_nmi)
298 panic("NMI: Not continuing");
299
300 pr_emerg("Dazed and confused, but trying to continue\n");
301}
302
303static DEFINE_PER_CPU(bool, swallow_nmi);
304static DEFINE_PER_CPU(unsigned long, last_nmi_rip);
305
306static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
307{
308 unsigned char reason = 0;
309 int handled;
310 bool b2b = false;
311
312 /*
313 * CPU-specific NMI must be processed before non-CPU-specific
314 * NMI, otherwise we may lose it, because the CPU-specific
315 * NMI can not be detected/processed on other CPUs.
316 */
317
318 /*
319 * Back-to-back NMIs are interesting because they can either
320 * be two NMI or more than two NMIs (any thing over two is dropped
321 * due to NMI being edge-triggered). If this is the second half
322 * of the back-to-back NMI, assume we dropped things and process
323 * more handlers. Otherwise reset the 'swallow' NMI behaviour
324 */
325 if (regs->ip == __this_cpu_read(last_nmi_rip))
326 b2b = true;
327 else
328 __this_cpu_write(swallow_nmi, false);
329
330 __this_cpu_write(last_nmi_rip, regs->ip);
331
332 handled = nmi_handle(NMI_LOCAL, regs, b2b);
333 __this_cpu_add(nmi_stats.normal, handled);
334 if (handled) {
335 /*
336 * There are cases when a NMI handler handles multiple
337 * events in the current NMI. One of these events may
338 * be queued for in the next NMI. Because the event is
339 * already handled, the next NMI will result in an unknown
340 * NMI. Instead lets flag this for a potential NMI to
341 * swallow.
342 */
343 if (handled > 1)
344 __this_cpu_write(swallow_nmi, true);
345 return;
346 }
347
348 /* Non-CPU-specific NMI: NMI sources can be processed on any CPU */
349 raw_spin_lock(&nmi_reason_lock);
350 reason = get_nmi_reason();
351
352 if (reason & NMI_REASON_MASK) {
353 if (reason & NMI_REASON_SERR)
354 pci_serr_error(reason, regs);
355 else if (reason & NMI_REASON_IOCHK)
356 io_check_error(reason, regs);
357#ifdef CONFIG_X86_32
358 /*
359 * Reassert NMI in case it became active
360 * meanwhile as it's edge-triggered:
361 */
362 reassert_nmi();
363#endif
364 __this_cpu_add(nmi_stats.external, 1);
365 raw_spin_unlock(&nmi_reason_lock);
366 return;
367 }
368 raw_spin_unlock(&nmi_reason_lock);
369
370 /*
371 * Only one NMI can be latched at a time. To handle
372 * this we may process multiple nmi handlers at once to
373 * cover the case where an NMI is dropped. The downside
374 * to this approach is we may process an NMI prematurely,
375 * while its real NMI is sitting latched. This will cause
376 * an unknown NMI on the next run of the NMI processing.
377 *
378 * We tried to flag that condition above, by setting the
379 * swallow_nmi flag when we process more than one event.
380 * This condition is also only present on the second half
381 * of a back-to-back NMI, so we flag that condition too.
382 *
383 * If both are true, we assume we already processed this
384 * NMI previously and we swallow it. Otherwise we reset
385 * the logic.
386 *
387 * There are scenarios where we may accidentally swallow
388 * a 'real' unknown NMI. For example, while processing
389 * a perf NMI another perf NMI comes in along with a
390 * 'real' unknown NMI. These two NMIs get combined into
391 * one (as descibed above). When the next NMI gets
392 * processed, it will be flagged by perf as handled, but
393 * noone will know that there was a 'real' unknown NMI sent
394 * also. As a result it gets swallowed. Or if the first
395 * perf NMI returns two events handled then the second
396 * NMI will get eaten by the logic below, again losing a
397 * 'real' unknown NMI. But this is the best we can do
398 * for now.
399 */
400 if (b2b && __this_cpu_read(swallow_nmi))
401 __this_cpu_add(nmi_stats.swallow, 1);
402 else
403 unknown_nmi_error(reason, regs);
404}
405
406dotraplinkage notrace __kprobes void
407do_nmi(struct pt_regs *regs, long error_code)
408{
409 nmi_enter();
410
411 inc_irq_stat(__nmi_count);
412
413 if (!ignore_nmis)
414 default_do_nmi(regs);
415
416 nmi_exit();
417}
418
419void stop_nmi(void)
420{
421 ignore_nmis++;
422}
423
424void restart_nmi(void)
425{
426 ignore_nmis--;
427}
428
429/* reset the back-to-back NMI logic */
430void local_touch_nmi(void)
431{
432 __this_cpu_write(last_nmi_rip, 0);
433}
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 2196c703c5e2..795b79f984c2 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -57,6 +57,7 @@
57#include <asm/idle.h> 57#include <asm/idle.h>
58#include <asm/syscalls.h> 58#include <asm/syscalls.h>
59#include <asm/debugreg.h> 59#include <asm/debugreg.h>
60#include <asm/nmi.h>
60 61
61asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); 62asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
62 63
@@ -107,6 +108,7 @@ void cpu_idle(void)
107 if (cpu_is_offline(cpu)) 108 if (cpu_is_offline(cpu))
108 play_dead(); 109 play_dead();
109 110
111 local_touch_nmi();
110 local_irq_disable(); 112 local_irq_disable();
111 /* Don't trace irqs off for idle */ 113 /* Don't trace irqs off for idle */
112 stop_critical_timings(); 114 stop_critical_timings();
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index f693e44e1bf6..3bd7e6eebf31 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -51,6 +51,7 @@
51#include <asm/idle.h> 51#include <asm/idle.h>
52#include <asm/syscalls.h> 52#include <asm/syscalls.h>
53#include <asm/debugreg.h> 53#include <asm/debugreg.h>
54#include <asm/nmi.h>
54 55
55asmlinkage extern void ret_from_fork(void); 56asmlinkage extern void ret_from_fork(void);
56 57
@@ -133,6 +134,7 @@ void cpu_idle(void)
133 * from here on, until they go to idle. 134 * from here on, until they go to idle.
134 * Otherwise, idle callbacks can misfire. 135 * Otherwise, idle callbacks can misfire.
135 */ 136 */
137 local_touch_nmi();
136 local_irq_disable(); 138 local_irq_disable();
137 enter_idle(); 139 enter_idle();
138 /* Don't trace irqs off for idle */ 140 /* Don't trace irqs off for idle */
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 9242436e9937..e334be1182b9 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -464,7 +464,7 @@ static inline void kb_wait(void)
464 } 464 }
465} 465}
466 466
467static void vmxoff_nmi(int cpu, struct die_args *args) 467static void vmxoff_nmi(int cpu, struct pt_regs *regs)
468{ 468{
469 cpu_emergency_vmxoff(); 469 cpu_emergency_vmxoff();
470} 470}
@@ -736,14 +736,10 @@ static nmi_shootdown_cb shootdown_callback;
736 736
737static atomic_t waiting_for_crash_ipi; 737static atomic_t waiting_for_crash_ipi;
738 738
739static int crash_nmi_callback(struct notifier_block *self, 739static int crash_nmi_callback(unsigned int val, struct pt_regs *regs)
740 unsigned long val, void *data)
741{ 740{
742 int cpu; 741 int cpu;
743 742
744 if (val != DIE_NMI)
745 return NOTIFY_OK;
746
747 cpu = raw_smp_processor_id(); 743 cpu = raw_smp_processor_id();
748 744
749 /* Don't do anything if this handler is invoked on crashing cpu. 745 /* Don't do anything if this handler is invoked on crashing cpu.
@@ -751,10 +747,10 @@ static int crash_nmi_callback(struct notifier_block *self,
751 * an NMI if system was initially booted with nmi_watchdog parameter. 747 * an NMI if system was initially booted with nmi_watchdog parameter.
752 */ 748 */
753 if (cpu == crashing_cpu) 749 if (cpu == crashing_cpu)
754 return NOTIFY_STOP; 750 return NMI_HANDLED;
755 local_irq_disable(); 751 local_irq_disable();
756 752
757 shootdown_callback(cpu, (struct die_args *)data); 753 shootdown_callback(cpu, regs);
758 754
759 atomic_dec(&waiting_for_crash_ipi); 755 atomic_dec(&waiting_for_crash_ipi);
760 /* Assume hlt works */ 756 /* Assume hlt works */
@@ -762,7 +758,7 @@ static int crash_nmi_callback(struct notifier_block *self,
762 for (;;) 758 for (;;)
763 cpu_relax(); 759 cpu_relax();
764 760
765 return 1; 761 return NMI_HANDLED;
766} 762}
767 763
768static void smp_send_nmi_allbutself(void) 764static void smp_send_nmi_allbutself(void)
@@ -770,12 +766,6 @@ static void smp_send_nmi_allbutself(void)
770 apic->send_IPI_allbutself(NMI_VECTOR); 766 apic->send_IPI_allbutself(NMI_VECTOR);
771} 767}
772 768
773static struct notifier_block crash_nmi_nb = {
774 .notifier_call = crash_nmi_callback,
775 /* we want to be the first one called */
776 .priority = NMI_LOCAL_HIGH_PRIOR+1,
777};
778
779/* Halt all other CPUs, calling the specified function on each of them 769/* Halt all other CPUs, calling the specified function on each of them
780 * 770 *
781 * This function can be used to halt all other CPUs on crash 771 * This function can be used to halt all other CPUs on crash
@@ -794,7 +784,8 @@ void nmi_shootdown_cpus(nmi_shootdown_cb callback)
794 784
795 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); 785 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
796 /* Would it be better to replace the trap vector here? */ 786 /* Would it be better to replace the trap vector here? */
797 if (register_die_notifier(&crash_nmi_nb)) 787 if (register_nmi_handler(NMI_LOCAL, crash_nmi_callback,
788 NMI_FLAG_FIRST, "crash"))
798 return; /* return what? */ 789 return; /* return what? */
799 /* Ensure the new callback function is set before sending 790 /* Ensure the new callback function is set before sending
800 * out the NMI 791 * out the NMI
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 6913369c234c..a8e3eb83466c 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -81,15 +81,6 @@ gate_desc idt_table[NR_VECTORS] __page_aligned_data = { { { { 0, 0 } } }, };
81DECLARE_BITMAP(used_vectors, NR_VECTORS); 81DECLARE_BITMAP(used_vectors, NR_VECTORS);
82EXPORT_SYMBOL_GPL(used_vectors); 82EXPORT_SYMBOL_GPL(used_vectors);
83 83
84static int ignore_nmis;
85
86int unknown_nmi_panic;
87/*
88 * Prevent NMI reason port (0x61) being accessed simultaneously, can
89 * only be used in NMI handler.
90 */
91static DEFINE_RAW_SPINLOCK(nmi_reason_lock);
92
93static inline void conditional_sti(struct pt_regs *regs) 84static inline void conditional_sti(struct pt_regs *regs)
94{ 85{
95 if (regs->flags & X86_EFLAGS_IF) 86 if (regs->flags & X86_EFLAGS_IF)
@@ -307,152 +298,6 @@ gp_in_kernel:
307 die("general protection fault", regs, error_code); 298 die("general protection fault", regs, error_code);
308} 299}
309 300
310static int __init setup_unknown_nmi_panic(char *str)
311{
312 unknown_nmi_panic = 1;
313 return 1;
314}
315__setup("unknown_nmi_panic", setup_unknown_nmi_panic);
316
317static notrace __kprobes void
318pci_serr_error(unsigned char reason, struct pt_regs *regs)
319{
320 pr_emerg("NMI: PCI system error (SERR) for reason %02x on CPU %d.\n",
321 reason, smp_processor_id());
322
323 /*
324 * On some machines, PCI SERR line is used to report memory
325 * errors. EDAC makes use of it.
326 */
327#if defined(CONFIG_EDAC)
328 if (edac_handler_set()) {
329 edac_atomic_assert_error();
330 return;
331 }
332#endif
333
334 if (panic_on_unrecovered_nmi)
335 panic("NMI: Not continuing");
336
337 pr_emerg("Dazed and confused, but trying to continue\n");
338
339 /* Clear and disable the PCI SERR error line. */
340 reason = (reason & NMI_REASON_CLEAR_MASK) | NMI_REASON_CLEAR_SERR;
341 outb(reason, NMI_REASON_PORT);
342}
343
344static notrace __kprobes void
345io_check_error(unsigned char reason, struct pt_regs *regs)
346{
347 unsigned long i;
348
349 pr_emerg(
350 "NMI: IOCK error (debug interrupt?) for reason %02x on CPU %d.\n",
351 reason, smp_processor_id());
352 show_registers(regs);
353
354 if (panic_on_io_nmi)
355 panic("NMI IOCK error: Not continuing");
356
357 /* Re-enable the IOCK line, wait for a few seconds */
358 reason = (reason & NMI_REASON_CLEAR_MASK) | NMI_REASON_CLEAR_IOCHK;
359 outb(reason, NMI_REASON_PORT);
360
361 i = 20000;
362 while (--i) {
363 touch_nmi_watchdog();
364 udelay(100);
365 }
366
367 reason &= ~NMI_REASON_CLEAR_IOCHK;
368 outb(reason, NMI_REASON_PORT);
369}
370
371static notrace __kprobes void
372unknown_nmi_error(unsigned char reason, struct pt_regs *regs)
373{
374 if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) ==
375 NOTIFY_STOP)
376 return;
377#ifdef CONFIG_MCA
378 /*
379 * Might actually be able to figure out what the guilty party
380 * is:
381 */
382 if (MCA_bus) {
383 mca_handle_nmi();
384 return;
385 }
386#endif
387 pr_emerg("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n",
388 reason, smp_processor_id());
389
390 pr_emerg("Do you have a strange power saving mode enabled?\n");
391 if (unknown_nmi_panic || panic_on_unrecovered_nmi)
392 panic("NMI: Not continuing");
393
394 pr_emerg("Dazed and confused, but trying to continue\n");
395}
396
397static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
398{
399 unsigned char reason = 0;
400
401 /*
402 * CPU-specific NMI must be processed before non-CPU-specific
403 * NMI, otherwise we may lose it, because the CPU-specific
404 * NMI can not be detected/processed on other CPUs.
405 */
406 if (notify_die(DIE_NMI, "nmi", regs, 0, 2, SIGINT) == NOTIFY_STOP)
407 return;
408
409 /* Non-CPU-specific NMI: NMI sources can be processed on any CPU */
410 raw_spin_lock(&nmi_reason_lock);
411 reason = get_nmi_reason();
412
413 if (reason & NMI_REASON_MASK) {
414 if (reason & NMI_REASON_SERR)
415 pci_serr_error(reason, regs);
416 else if (reason & NMI_REASON_IOCHK)
417 io_check_error(reason, regs);
418#ifdef CONFIG_X86_32
419 /*
420 * Reassert NMI in case it became active
421 * meanwhile as it's edge-triggered:
422 */
423 reassert_nmi();
424#endif
425 raw_spin_unlock(&nmi_reason_lock);
426 return;
427 }
428 raw_spin_unlock(&nmi_reason_lock);
429
430 unknown_nmi_error(reason, regs);
431}
432
433dotraplinkage notrace __kprobes void
434do_nmi(struct pt_regs *regs, long error_code)
435{
436 nmi_enter();
437
438 inc_irq_stat(__nmi_count);
439
440 if (!ignore_nmis)
441 default_do_nmi(regs);
442
443 nmi_exit();
444}
445
446void stop_nmi(void)
447{
448 ignore_nmis++;
449}
450
451void restart_nmi(void)
452{
453 ignore_nmis--;
454}
455
456/* May run on IST stack. */ 301/* May run on IST stack. */
457dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) 302dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code)
458{ 303{
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 96646b3aeca8..75f9528e0372 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -61,26 +61,15 @@ u64 op_x86_get_ctrl(struct op_x86_model_spec const *model,
61} 61}
62 62
63 63
64static int profile_exceptions_notify(struct notifier_block *self, 64static int profile_exceptions_notify(unsigned int val, struct pt_regs *regs)
65 unsigned long val, void *data)
66{ 65{
67 struct die_args *args = (struct die_args *)data; 66 if (ctr_running)
68 int ret = NOTIFY_DONE; 67 model->check_ctrs(regs, &__get_cpu_var(cpu_msrs));
69 68 else if (!nmi_enabled)
70 switch (val) { 69 return NMI_DONE;
71 case DIE_NMI: 70 else
72 if (ctr_running) 71 model->stop(&__get_cpu_var(cpu_msrs));
73 model->check_ctrs(args->regs, &__get_cpu_var(cpu_msrs)); 72 return NMI_HANDLED;
74 else if (!nmi_enabled)
75 break;
76 else
77 model->stop(&__get_cpu_var(cpu_msrs));
78 ret = NOTIFY_STOP;
79 break;
80 default:
81 break;
82 }
83 return ret;
84} 73}
85 74
86static void nmi_cpu_save_registers(struct op_msrs *msrs) 75static void nmi_cpu_save_registers(struct op_msrs *msrs)
@@ -363,12 +352,6 @@ static void nmi_cpu_setup(void *dummy)
363 apic_write(APIC_LVTPC, APIC_DM_NMI); 352 apic_write(APIC_LVTPC, APIC_DM_NMI);
364} 353}
365 354
366static struct notifier_block profile_exceptions_nb = {
367 .notifier_call = profile_exceptions_notify,
368 .next = NULL,
369 .priority = NMI_LOCAL_LOW_PRIOR,
370};
371
372static void nmi_cpu_restore_registers(struct op_msrs *msrs) 355static void nmi_cpu_restore_registers(struct op_msrs *msrs)
373{ 356{
374 struct op_msr *counters = msrs->counters; 357 struct op_msr *counters = msrs->counters;
@@ -402,8 +385,6 @@ static void nmi_cpu_shutdown(void *dummy)
402 apic_write(APIC_LVTPC, per_cpu(saved_lvtpc, cpu)); 385 apic_write(APIC_LVTPC, per_cpu(saved_lvtpc, cpu));
403 apic_write(APIC_LVTERR, v); 386 apic_write(APIC_LVTERR, v);
404 nmi_cpu_restore_registers(msrs); 387 nmi_cpu_restore_registers(msrs);
405 if (model->cpu_down)
406 model->cpu_down();
407} 388}
408 389
409static void nmi_cpu_up(void *dummy) 390static void nmi_cpu_up(void *dummy)
@@ -508,7 +489,8 @@ static int nmi_setup(void)
508 ctr_running = 0; 489 ctr_running = 0;
509 /* make variables visible to the nmi handler: */ 490 /* make variables visible to the nmi handler: */
510 smp_mb(); 491 smp_mb();
511 err = register_die_notifier(&profile_exceptions_nb); 492 err = register_nmi_handler(NMI_LOCAL, profile_exceptions_notify,
493 0, "oprofile");
512 if (err) 494 if (err)
513 goto fail; 495 goto fail;
514 496
@@ -538,7 +520,7 @@ static void nmi_shutdown(void)
538 put_online_cpus(); 520 put_online_cpus();
539 /* make variables visible to the nmi handler: */ 521 /* make variables visible to the nmi handler: */
540 smp_mb(); 522 smp_mb();
541 unregister_die_notifier(&profile_exceptions_nb); 523 unregister_nmi_handler(NMI_LOCAL, "oprofile");
542 msrs = &get_cpu_var(cpu_msrs); 524 msrs = &get_cpu_var(cpu_msrs);
543 model->shutdown(msrs); 525 model->shutdown(msrs);
544 free_msrs(); 526 free_msrs();
diff --git a/arch/x86/oprofile/nmi_timer_int.c b/arch/x86/oprofile/nmi_timer_int.c
index 720bf5a53c51..7f8052cd6620 100644
--- a/arch/x86/oprofile/nmi_timer_int.c
+++ b/arch/x86/oprofile/nmi_timer_int.c
@@ -18,32 +18,16 @@
18#include <asm/apic.h> 18#include <asm/apic.h>
19#include <asm/ptrace.h> 19#include <asm/ptrace.h>
20 20
21static int profile_timer_exceptions_notify(struct notifier_block *self, 21static int profile_timer_exceptions_notify(unsigned int val, struct pt_regs *regs)
22 unsigned long val, void *data)
23{ 22{
24 struct die_args *args = (struct die_args *)data; 23 oprofile_add_sample(regs, 0);
25 int ret = NOTIFY_DONE; 24 return NMI_HANDLED;
26
27 switch (val) {
28 case DIE_NMI:
29 oprofile_add_sample(args->regs, 0);
30 ret = NOTIFY_STOP;
31 break;
32 default:
33 break;
34 }
35 return ret;
36} 25}
37 26
38static struct notifier_block profile_timer_exceptions_nb = {
39 .notifier_call = profile_timer_exceptions_notify,
40 .next = NULL,
41 .priority = NMI_LOW_PRIOR,
42};
43
44static int timer_start(void) 27static int timer_start(void)
45{ 28{
46 if (register_die_notifier(&profile_timer_exceptions_nb)) 29 if (register_nmi_handler(NMI_LOCAL, profile_timer_exceptions_notify,
30 0, "oprofile-timer"))
47 return 1; 31 return 1;
48 return 0; 32 return 0;
49} 33}
@@ -51,7 +35,7 @@ static int timer_start(void)
51 35
52static void timer_stop(void) 36static void timer_stop(void)
53{ 37{
54 unregister_die_notifier(&profile_timer_exceptions_nb); 38 unregister_nmi_handler(NMI_LOCAL, "oprofile-timer");
55 synchronize_sched(); /* Allow already-started NMIs to complete. */ 39 synchronize_sched(); /* Allow already-started NMIs to complete. */
56} 40}
57 41
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
index 9cbb710dc94b..303f08637826 100644
--- a/arch/x86/oprofile/op_model_amd.c
+++ b/arch/x86/oprofile/op_model_amd.c
@@ -29,8 +29,6 @@
29#include "op_x86_model.h" 29#include "op_x86_model.h"
30#include "op_counter.h" 30#include "op_counter.h"
31 31
32#define NUM_COUNTERS 4
33#define NUM_COUNTERS_F15H 6
34#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX 32#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
35#define NUM_VIRT_COUNTERS 32 33#define NUM_VIRT_COUNTERS 32
36#else 34#else
@@ -70,62 +68,12 @@ static struct ibs_config ibs_config;
70static struct ibs_state ibs_state; 68static struct ibs_state ibs_state;
71 69
72/* 70/*
73 * IBS cpuid feature detection
74 */
75
76#define IBS_CPUID_FEATURES 0x8000001b
77
78/*
79 * Same bit mask as for IBS cpuid feature flags (Fn8000_001B_EAX), but
80 * bit 0 is used to indicate the existence of IBS.
81 */
82#define IBS_CAPS_AVAIL (1U<<0)
83#define IBS_CAPS_FETCHSAM (1U<<1)
84#define IBS_CAPS_OPSAM (1U<<2)
85#define IBS_CAPS_RDWROPCNT (1U<<3)
86#define IBS_CAPS_OPCNT (1U<<4)
87#define IBS_CAPS_BRNTRGT (1U<<5)
88#define IBS_CAPS_OPCNTEXT (1U<<6)
89
90#define IBS_CAPS_DEFAULT (IBS_CAPS_AVAIL \
91 | IBS_CAPS_FETCHSAM \
92 | IBS_CAPS_OPSAM)
93
94/*
95 * IBS APIC setup
96 */
97#define IBSCTL 0x1cc
98#define IBSCTL_LVT_OFFSET_VALID (1ULL<<8)
99#define IBSCTL_LVT_OFFSET_MASK 0x0F
100
101/*
102 * IBS randomization macros 71 * IBS randomization macros
103 */ 72 */
104#define IBS_RANDOM_BITS 12 73#define IBS_RANDOM_BITS 12
105#define IBS_RANDOM_MASK ((1ULL << IBS_RANDOM_BITS) - 1) 74#define IBS_RANDOM_MASK ((1ULL << IBS_RANDOM_BITS) - 1)
106#define IBS_RANDOM_MAXCNT_OFFSET (1ULL << (IBS_RANDOM_BITS - 5)) 75#define IBS_RANDOM_MAXCNT_OFFSET (1ULL << (IBS_RANDOM_BITS - 5))
107 76
108static u32 get_ibs_caps(void)
109{
110 u32 ibs_caps;
111 unsigned int max_level;
112
113 if (!boot_cpu_has(X86_FEATURE_IBS))
114 return 0;
115
116 /* check IBS cpuid feature flags */
117 max_level = cpuid_eax(0x80000000);
118 if (max_level < IBS_CPUID_FEATURES)
119 return IBS_CAPS_DEFAULT;
120
121 ibs_caps = cpuid_eax(IBS_CPUID_FEATURES);
122 if (!(ibs_caps & IBS_CAPS_AVAIL))
123 /* cpuid flags not valid */
124 return IBS_CAPS_DEFAULT;
125
126 return ibs_caps;
127}
128
129/* 77/*
130 * 16-bit Linear Feedback Shift Register (LFSR) 78 * 16-bit Linear Feedback Shift Register (LFSR)
131 * 79 *
@@ -316,81 +264,6 @@ static void op_amd_stop_ibs(void)
316 wrmsrl(MSR_AMD64_IBSOPCTL, 0); 264 wrmsrl(MSR_AMD64_IBSOPCTL, 0);
317} 265}
318 266
319static inline int get_eilvt(int offset)
320{
321 return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1);
322}
323
324static inline int put_eilvt(int offset)
325{
326 return !setup_APIC_eilvt(offset, 0, 0, 1);
327}
328
329static inline int ibs_eilvt_valid(void)
330{
331 int offset;
332 u64 val;
333 int valid = 0;
334
335 preempt_disable();
336
337 rdmsrl(MSR_AMD64_IBSCTL, val);
338 offset = val & IBSCTL_LVT_OFFSET_MASK;
339
340 if (!(val & IBSCTL_LVT_OFFSET_VALID)) {
341 pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n",
342 smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
343 goto out;
344 }
345
346 if (!get_eilvt(offset)) {
347 pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n",
348 smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
349 goto out;
350 }
351
352 valid = 1;
353out:
354 preempt_enable();
355
356 return valid;
357}
358
359static inline int get_ibs_offset(void)
360{
361 u64 val;
362
363 rdmsrl(MSR_AMD64_IBSCTL, val);
364 if (!(val & IBSCTL_LVT_OFFSET_VALID))
365 return -EINVAL;
366
367 return val & IBSCTL_LVT_OFFSET_MASK;
368}
369
370static void setup_APIC_ibs(void)
371{
372 int offset;
373
374 offset = get_ibs_offset();
375 if (offset < 0)
376 goto failed;
377
378 if (!setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 0))
379 return;
380failed:
381 pr_warn("oprofile: IBS APIC setup failed on cpu #%d\n",
382 smp_processor_id());
383}
384
385static void clear_APIC_ibs(void)
386{
387 int offset;
388
389 offset = get_ibs_offset();
390 if (offset >= 0)
391 setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_FIX, 1);
392}
393
394#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX 267#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
395 268
396static void op_mux_switch_ctrl(struct op_x86_model_spec const *model, 269static void op_mux_switch_ctrl(struct op_x86_model_spec const *model,
@@ -439,7 +312,7 @@ static int op_amd_fill_in_addresses(struct op_msrs * const msrs)
439 goto fail; 312 goto fail;
440 } 313 }
441 /* both registers must be reserved */ 314 /* both registers must be reserved */
442 if (num_counters == NUM_COUNTERS_F15H) { 315 if (num_counters == AMD64_NUM_COUNTERS_F15H) {
443 msrs->counters[i].addr = MSR_F15H_PERF_CTR + (i << 1); 316 msrs->counters[i].addr = MSR_F15H_PERF_CTR + (i << 1);
444 msrs->controls[i].addr = MSR_F15H_PERF_CTL + (i << 1); 317 msrs->controls[i].addr = MSR_F15H_PERF_CTL + (i << 1);
445 } else { 318 } else {
@@ -504,15 +377,6 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model,
504 val |= op_x86_get_ctrl(model, &counter_config[virt]); 377 val |= op_x86_get_ctrl(model, &counter_config[virt]);
505 wrmsrl(msrs->controls[i].addr, val); 378 wrmsrl(msrs->controls[i].addr, val);
506 } 379 }
507
508 if (ibs_caps)
509 setup_APIC_ibs();
510}
511
512static void op_amd_cpu_shutdown(void)
513{
514 if (ibs_caps)
515 clear_APIC_ibs();
516} 380}
517 381
518static int op_amd_check_ctrs(struct pt_regs * const regs, 382static int op_amd_check_ctrs(struct pt_regs * const regs,
@@ -575,86 +439,6 @@ static void op_amd_stop(struct op_msrs const * const msrs)
575 op_amd_stop_ibs(); 439 op_amd_stop_ibs();
576} 440}
577 441
578static int setup_ibs_ctl(int ibs_eilvt_off)
579{
580 struct pci_dev *cpu_cfg;
581 int nodes;
582 u32 value = 0;
583
584 nodes = 0;
585 cpu_cfg = NULL;
586 do {
587 cpu_cfg = pci_get_device(PCI_VENDOR_ID_AMD,
588 PCI_DEVICE_ID_AMD_10H_NB_MISC,
589 cpu_cfg);
590 if (!cpu_cfg)
591 break;
592 ++nodes;
593 pci_write_config_dword(cpu_cfg, IBSCTL, ibs_eilvt_off
594 | IBSCTL_LVT_OFFSET_VALID);
595 pci_read_config_dword(cpu_cfg, IBSCTL, &value);
596 if (value != (ibs_eilvt_off | IBSCTL_LVT_OFFSET_VALID)) {
597 pci_dev_put(cpu_cfg);
598 printk(KERN_DEBUG "Failed to setup IBS LVT offset, "
599 "IBSCTL = 0x%08x\n", value);
600 return -EINVAL;
601 }
602 } while (1);
603
604 if (!nodes) {
605 printk(KERN_DEBUG "No CPU node configured for IBS\n");
606 return -ENODEV;
607 }
608
609 return 0;
610}
611
612/*
613 * This runs only on the current cpu. We try to find an LVT offset and
614 * setup the local APIC. For this we must disable preemption. On
615 * success we initialize all nodes with this offset. This updates then
616 * the offset in the IBS_CTL per-node msr. The per-core APIC setup of
617 * the IBS interrupt vector is called from op_amd_setup_ctrs()/op_-
618 * amd_cpu_shutdown() using the new offset.
619 */
620static int force_ibs_eilvt_setup(void)
621{
622 int offset;
623 int ret;
624
625 preempt_disable();
626 /* find the next free available EILVT entry, skip offset 0 */
627 for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) {
628 if (get_eilvt(offset))
629 break;
630 }
631 preempt_enable();
632
633 if (offset == APIC_EILVT_NR_MAX) {
634 printk(KERN_DEBUG "No EILVT entry available\n");
635 return -EBUSY;
636 }
637
638 ret = setup_ibs_ctl(offset);
639 if (ret)
640 goto out;
641
642 if (!ibs_eilvt_valid()) {
643 ret = -EFAULT;
644 goto out;
645 }
646
647 pr_err(FW_BUG "using offset %d for IBS interrupts\n", offset);
648 pr_err(FW_BUG "workaround enabled for IBS LVT offset\n");
649
650 return 0;
651out:
652 preempt_disable();
653 put_eilvt(offset);
654 preempt_enable();
655 return ret;
656}
657
658/* 442/*
659 * check and reserve APIC extended interrupt LVT offset for IBS if 443 * check and reserve APIC extended interrupt LVT offset for IBS if
660 * available 444 * available
@@ -667,17 +451,6 @@ static void init_ibs(void)
667 if (!ibs_caps) 451 if (!ibs_caps)
668 return; 452 return;
669 453
670 if (ibs_eilvt_valid())
671 goto out;
672
673 if (!force_ibs_eilvt_setup())
674 goto out;
675
676 /* Failed to setup ibs */
677 ibs_caps = 0;
678 return;
679
680out:
681 printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps); 454 printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps);
682} 455}
683 456
@@ -741,9 +514,9 @@ static int op_amd_init(struct oprofile_operations *ops)
741 ops->create_files = setup_ibs_files; 514 ops->create_files = setup_ibs_files;
742 515
743 if (boot_cpu_data.x86 == 0x15) { 516 if (boot_cpu_data.x86 == 0x15) {
744 num_counters = NUM_COUNTERS_F15H; 517 num_counters = AMD64_NUM_COUNTERS_F15H;
745 } else { 518 } else {
746 num_counters = NUM_COUNTERS; 519 num_counters = AMD64_NUM_COUNTERS;
747 } 520 }
748 521
749 op_amd_spec.num_counters = num_counters; 522 op_amd_spec.num_counters = num_counters;
@@ -760,7 +533,6 @@ struct op_x86_model_spec op_amd_spec = {
760 .init = op_amd_init, 533 .init = op_amd_init,
761 .fill_in_addresses = &op_amd_fill_in_addresses, 534 .fill_in_addresses = &op_amd_fill_in_addresses,
762 .setup_ctrs = &op_amd_setup_ctrs, 535 .setup_ctrs = &op_amd_setup_ctrs,
763 .cpu_down = &op_amd_cpu_shutdown,
764 .check_ctrs = &op_amd_check_ctrs, 536 .check_ctrs = &op_amd_check_ctrs,
765 .start = &op_amd_start, 537 .start = &op_amd_start,
766 .stop = &op_amd_stop, 538 .stop = &op_amd_stop,
diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c
index 94b745045e45..d90528ea5412 100644
--- a/arch/x86/oprofile/op_model_ppro.c
+++ b/arch/x86/oprofile/op_model_ppro.c
@@ -28,7 +28,7 @@ static int counter_width = 32;
28 28
29#define MSR_PPRO_EVENTSEL_RESERVED ((0xFFFFFFFFULL<<32)|(1ULL<<21)) 29#define MSR_PPRO_EVENTSEL_RESERVED ((0xFFFFFFFFULL<<32)|(1ULL<<21))
30 30
31static u64 *reset_value; 31static u64 reset_value[OP_MAX_COUNTER];
32 32
33static void ppro_shutdown(struct op_msrs const * const msrs) 33static void ppro_shutdown(struct op_msrs const * const msrs)
34{ 34{
@@ -40,10 +40,6 @@ static void ppro_shutdown(struct op_msrs const * const msrs)
40 release_perfctr_nmi(MSR_P6_PERFCTR0 + i); 40 release_perfctr_nmi(MSR_P6_PERFCTR0 + i);
41 release_evntsel_nmi(MSR_P6_EVNTSEL0 + i); 41 release_evntsel_nmi(MSR_P6_EVNTSEL0 + i);
42 } 42 }
43 if (reset_value) {
44 kfree(reset_value);
45 reset_value = NULL;
46 }
47} 43}
48 44
49static int ppro_fill_in_addresses(struct op_msrs * const msrs) 45static int ppro_fill_in_addresses(struct op_msrs * const msrs)
@@ -79,13 +75,6 @@ static void ppro_setup_ctrs(struct op_x86_model_spec const *model,
79 u64 val; 75 u64 val;
80 int i; 76 int i;
81 77
82 if (!reset_value) {
83 reset_value = kzalloc(sizeof(reset_value[0]) * num_counters,
84 GFP_ATOMIC);
85 if (!reset_value)
86 return;
87 }
88
89 if (cpu_has_arch_perfmon) { 78 if (cpu_has_arch_perfmon) {
90 union cpuid10_eax eax; 79 union cpuid10_eax eax;
91 eax.full = cpuid_eax(0xa); 80 eax.full = cpuid_eax(0xa);
@@ -141,13 +130,6 @@ static int ppro_check_ctrs(struct pt_regs * const regs,
141 u64 val; 130 u64 val;
142 int i; 131 int i;
143 132
144 /*
145 * This can happen if perf counters are in use when
146 * we steal the die notifier NMI.
147 */
148 if (unlikely(!reset_value))
149 goto out;
150
151 for (i = 0; i < num_counters; ++i) { 133 for (i = 0; i < num_counters; ++i) {
152 if (!reset_value[i]) 134 if (!reset_value[i])
153 continue; 135 continue;
@@ -158,7 +140,6 @@ static int ppro_check_ctrs(struct pt_regs * const regs,
158 wrmsrl(msrs->counters[i].addr, -reset_value[i]); 140 wrmsrl(msrs->counters[i].addr, -reset_value[i]);
159 } 141 }
160 142
161out:
162 /* Only P6 based Pentium M need to re-unmask the apic vector but it 143 /* Only P6 based Pentium M need to re-unmask the apic vector but it
163 * doesn't hurt other P6 variant */ 144 * doesn't hurt other P6 variant */
164 apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); 145 apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED);
@@ -179,8 +160,6 @@ static void ppro_start(struct op_msrs const * const msrs)
179 u64 val; 160 u64 val;
180 int i; 161 int i;
181 162
182 if (!reset_value)
183 return;
184 for (i = 0; i < num_counters; ++i) { 163 for (i = 0; i < num_counters; ++i) {
185 if (reset_value[i]) { 164 if (reset_value[i]) {
186 rdmsrl(msrs->controls[i].addr, val); 165 rdmsrl(msrs->controls[i].addr, val);
@@ -196,8 +175,6 @@ static void ppro_stop(struct op_msrs const * const msrs)
196 u64 val; 175 u64 val;
197 int i; 176 int i;
198 177
199 if (!reset_value)
200 return;
201 for (i = 0; i < num_counters; ++i) { 178 for (i = 0; i < num_counters; ++i) {
202 if (!reset_value[i]) 179 if (!reset_value[i])
203 continue; 180 continue;
@@ -242,7 +219,7 @@ static void arch_perfmon_setup_counters(void)
242 eax.split.bit_width = 40; 219 eax.split.bit_width = 40;
243 } 220 }
244 221
245 num_counters = eax.split.num_counters; 222 num_counters = min((int)eax.split.num_counters, OP_MAX_COUNTER);
246 223
247 op_arch_perfmon_spec.num_counters = num_counters; 224 op_arch_perfmon_spec.num_counters = num_counters;
248 op_arch_perfmon_spec.num_controls = num_counters; 225 op_arch_perfmon_spec.num_controls = num_counters;
diff --git a/arch/x86/oprofile/op_x86_model.h b/arch/x86/oprofile/op_x86_model.h
index 89017fa1fd63..71e8a67337e2 100644
--- a/arch/x86/oprofile/op_x86_model.h
+++ b/arch/x86/oprofile/op_x86_model.h
@@ -43,7 +43,6 @@ struct op_x86_model_spec {
43 int (*fill_in_addresses)(struct op_msrs * const msrs); 43 int (*fill_in_addresses)(struct op_msrs * const msrs);
44 void (*setup_ctrs)(struct op_x86_model_spec const *model, 44 void (*setup_ctrs)(struct op_x86_model_spec const *model,
45 struct op_msrs const * const msrs); 45 struct op_msrs const * const msrs);
46 void (*cpu_down)(void);
47 int (*check_ctrs)(struct pt_regs * const regs, 46 int (*check_ctrs)(struct pt_regs * const regs,
48 struct op_msrs const * const msrs); 47 struct op_msrs const * const msrs);
49 void (*start)(struct op_msrs const * const msrs); 48 void (*start)(struct op_msrs const * const msrs);
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 0784f99a4665..b8e08cb67a18 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -50,6 +50,7 @@
50#include <acpi/hed.h> 50#include <acpi/hed.h>
51#include <asm/mce.h> 51#include <asm/mce.h>
52#include <asm/tlbflush.h> 52#include <asm/tlbflush.h>
53#include <asm/nmi.h>
53 54
54#include "apei-internal.h" 55#include "apei-internal.h"
55 56
@@ -749,15 +750,11 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)
749 } 750 }
750} 751}
751 752
752static int ghes_notify_nmi(struct notifier_block *this, 753static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
753 unsigned long cmd, void *data)
754{ 754{
755 struct ghes *ghes, *ghes_global = NULL; 755 struct ghes *ghes, *ghes_global = NULL;
756 int sev, sev_global = -1; 756 int sev, sev_global = -1;
757 int ret = NOTIFY_DONE; 757 int ret = NMI_DONE;
758
759 if (cmd != DIE_NMI)
760 return ret;
761 758
762 raw_spin_lock(&ghes_nmi_lock); 759 raw_spin_lock(&ghes_nmi_lock);
763 list_for_each_entry_rcu(ghes, &ghes_nmi, list) { 760 list_for_each_entry_rcu(ghes, &ghes_nmi, list) {
@@ -770,10 +767,10 @@ static int ghes_notify_nmi(struct notifier_block *this,
770 sev_global = sev; 767 sev_global = sev;
771 ghes_global = ghes; 768 ghes_global = ghes;
772 } 769 }
773 ret = NOTIFY_STOP; 770 ret = NMI_HANDLED;
774 } 771 }
775 772
776 if (ret == NOTIFY_DONE) 773 if (ret == NMI_DONE)
777 goto out; 774 goto out;
778 775
779 if (sev_global >= GHES_SEV_PANIC) { 776 if (sev_global >= GHES_SEV_PANIC) {
@@ -825,10 +822,6 @@ static struct notifier_block ghes_notifier_sci = {
825 .notifier_call = ghes_notify_sci, 822 .notifier_call = ghes_notify_sci,
826}; 823};
827 824
828static struct notifier_block ghes_notifier_nmi = {
829 .notifier_call = ghes_notify_nmi,
830};
831
832static unsigned long ghes_esource_prealloc_size( 825static unsigned long ghes_esource_prealloc_size(
833 const struct acpi_hest_generic *generic) 826 const struct acpi_hest_generic *generic)
834{ 827{
@@ -918,7 +911,8 @@ static int __devinit ghes_probe(struct platform_device *ghes_dev)
918 ghes_estatus_pool_expand(len); 911 ghes_estatus_pool_expand(len);
919 mutex_lock(&ghes_list_mutex); 912 mutex_lock(&ghes_list_mutex);
920 if (list_empty(&ghes_nmi)) 913 if (list_empty(&ghes_nmi))
921 register_die_notifier(&ghes_notifier_nmi); 914 register_nmi_handler(NMI_LOCAL, ghes_notify_nmi, 0,
915 "ghes");
922 list_add_rcu(&ghes->list, &ghes_nmi); 916 list_add_rcu(&ghes->list, &ghes_nmi);
923 mutex_unlock(&ghes_list_mutex); 917 mutex_unlock(&ghes_list_mutex);
924 break; 918 break;
@@ -964,7 +958,7 @@ static int __devexit ghes_remove(struct platform_device *ghes_dev)
964 mutex_lock(&ghes_list_mutex); 958 mutex_lock(&ghes_list_mutex);
965 list_del_rcu(&ghes->list); 959 list_del_rcu(&ghes->list);
966 if (list_empty(&ghes_nmi)) 960 if (list_empty(&ghes_nmi))
967 unregister_die_notifier(&ghes_notifier_nmi); 961 unregister_nmi_handler(NMI_LOCAL, "ghes");
968 mutex_unlock(&ghes_list_mutex); 962 mutex_unlock(&ghes_list_mutex);
969 /* 963 /*
970 * To synchronize with NMI handler, ghes can only be 964 * To synchronize with NMI handler, ghes can only be
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 3302586655c4..c2917ffad2c2 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -65,6 +65,7 @@
65 * mechanism for it at that time. 65 * mechanism for it at that time.
66 */ 66 */
67#include <asm/kdebug.h> 67#include <asm/kdebug.h>
68#include <asm/nmi.h>
68#define HAVE_DIE_NMI 69#define HAVE_DIE_NMI
69#endif 70#endif
70 71
@@ -1077,17 +1078,8 @@ static void ipmi_unregister_watchdog(int ipmi_intf)
1077 1078
1078#ifdef HAVE_DIE_NMI 1079#ifdef HAVE_DIE_NMI
1079static int 1080static int
1080ipmi_nmi(struct notifier_block *self, unsigned long val, void *data) 1081ipmi_nmi(unsigned int val, struct pt_regs *regs)
1081{ 1082{
1082 struct die_args *args = data;
1083
1084 if (val != DIE_NMIUNKNOWN)
1085 return NOTIFY_OK;
1086
1087 /* Hack, if it's a memory or I/O error, ignore it. */
1088 if (args->err & 0xc0)
1089 return NOTIFY_OK;
1090
1091 /* 1083 /*
1092 * If we get here, it's an NMI that's not a memory or I/O 1084 * If we get here, it's an NMI that's not a memory or I/O
1093 * error. We can't truly tell if it's from IPMI or not 1085 * error. We can't truly tell if it's from IPMI or not
@@ -1097,15 +1089,15 @@ ipmi_nmi(struct notifier_block *self, unsigned long val, void *data)
1097 1089
1098 if (testing_nmi) { 1090 if (testing_nmi) {
1099 testing_nmi = 2; 1091 testing_nmi = 2;
1100 return NOTIFY_STOP; 1092 return NMI_HANDLED;
1101 } 1093 }
1102 1094
1103 /* If we are not expecting a timeout, ignore it. */ 1095 /* If we are not expecting a timeout, ignore it. */
1104 if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) 1096 if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
1105 return NOTIFY_OK; 1097 return NMI_DONE;
1106 1098
1107 if (preaction_val != WDOG_PRETIMEOUT_NMI) 1099 if (preaction_val != WDOG_PRETIMEOUT_NMI)
1108 return NOTIFY_OK; 1100 return NMI_DONE;
1109 1101
1110 /* 1102 /*
1111 * If no one else handled the NMI, we assume it was the IPMI 1103 * If no one else handled the NMI, we assume it was the IPMI
@@ -1120,12 +1112,8 @@ ipmi_nmi(struct notifier_block *self, unsigned long val, void *data)
1120 panic(PFX "pre-timeout"); 1112 panic(PFX "pre-timeout");
1121 } 1113 }
1122 1114
1123 return NOTIFY_STOP; 1115 return NMI_HANDLED;
1124} 1116}
1125
1126static struct notifier_block ipmi_nmi_handler = {
1127 .notifier_call = ipmi_nmi
1128};
1129#endif 1117#endif
1130 1118
1131static int wdog_reboot_handler(struct notifier_block *this, 1119static int wdog_reboot_handler(struct notifier_block *this,
@@ -1290,7 +1278,8 @@ static void check_parms(void)
1290 } 1278 }
1291 } 1279 }
1292 if (do_nmi && !nmi_handler_registered) { 1280 if (do_nmi && !nmi_handler_registered) {
1293 rv = register_die_notifier(&ipmi_nmi_handler); 1281 rv = register_nmi_handler(NMI_UNKNOWN, ipmi_nmi, 0,
1282 "ipmi");
1294 if (rv) { 1283 if (rv) {
1295 printk(KERN_WARNING PFX 1284 printk(KERN_WARNING PFX
1296 "Can't register nmi handler\n"); 1285 "Can't register nmi handler\n");
@@ -1298,7 +1287,7 @@ static void check_parms(void)
1298 } else 1287 } else
1299 nmi_handler_registered = 1; 1288 nmi_handler_registered = 1;
1300 } else if (!do_nmi && nmi_handler_registered) { 1289 } else if (!do_nmi && nmi_handler_registered) {
1301 unregister_die_notifier(&ipmi_nmi_handler); 1290 unregister_nmi_handler(NMI_UNKNOWN, "ipmi");
1302 nmi_handler_registered = 0; 1291 nmi_handler_registered = 0;
1303 } 1292 }
1304#endif 1293#endif
@@ -1336,7 +1325,7 @@ static int __init ipmi_wdog_init(void)
1336 if (rv) { 1325 if (rv) {
1337#ifdef HAVE_DIE_NMI 1326#ifdef HAVE_DIE_NMI
1338 if (nmi_handler_registered) 1327 if (nmi_handler_registered)
1339 unregister_die_notifier(&ipmi_nmi_handler); 1328 unregister_nmi_handler(NMI_UNKNOWN, "ipmi");
1340#endif 1329#endif
1341 atomic_notifier_chain_unregister(&panic_notifier_list, 1330 atomic_notifier_chain_unregister(&panic_notifier_list,
1342 &wdog_panic_notifier); 1331 &wdog_panic_notifier);
@@ -1357,7 +1346,7 @@ static void __exit ipmi_wdog_exit(void)
1357 1346
1358#ifdef HAVE_DIE_NMI 1347#ifdef HAVE_DIE_NMI
1359 if (nmi_handler_registered) 1348 if (nmi_handler_registered)
1360 unregister_die_notifier(&ipmi_nmi_handler); 1349 unregister_nmi_handler(NMI_UNKNOWN, "ipmi");
1361#endif 1350#endif
1362 1351
1363 atomic_notifier_chain_unregister(&panic_notifier_list, 1352 atomic_notifier_chain_unregister(&panic_notifier_list,
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 809cbda03d7a..3774c9b8dac9 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -35,6 +35,7 @@
35#include <linux/notifier.h> 35#include <linux/notifier.h>
36#include <asm/cacheflush.h> 36#include <asm/cacheflush.h>
37#endif /* CONFIG_HPWDT_NMI_DECODING */ 37#endif /* CONFIG_HPWDT_NMI_DECODING */
38#include <asm/nmi.h>
38 39
39#define HPWDT_VERSION "1.3.0" 40#define HPWDT_VERSION "1.3.0"
40#define SECS_TO_TICKS(secs) ((secs) * 1000 / 128) 41#define SECS_TO_TICKS(secs) ((secs) * 1000 / 128)
@@ -477,15 +478,11 @@ static int hpwdt_time_left(void)
477/* 478/*
478 * NMI Handler 479 * NMI Handler
479 */ 480 */
480static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason, 481static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs)
481 void *data)
482{ 482{
483 unsigned long rom_pl; 483 unsigned long rom_pl;
484 static int die_nmi_called; 484 static int die_nmi_called;
485 485
486 if (ulReason != DIE_NMIUNKNOWN)
487 goto out;
488
489 if (!hpwdt_nmi_decoding) 486 if (!hpwdt_nmi_decoding)
490 goto out; 487 goto out;
491 488
@@ -508,7 +505,7 @@ static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason,
508 "Management Log for details.\n"); 505 "Management Log for details.\n");
509 506
510out: 507out:
511 return NOTIFY_OK; 508 return NMI_DONE;
512} 509}
513#endif /* CONFIG_HPWDT_NMI_DECODING */ 510#endif /* CONFIG_HPWDT_NMI_DECODING */
514 511
@@ -648,13 +645,6 @@ static struct miscdevice hpwdt_miscdev = {
648 .fops = &hpwdt_fops, 645 .fops = &hpwdt_fops,
649}; 646};
650 647
651#ifdef CONFIG_HPWDT_NMI_DECODING
652static struct notifier_block die_notifier = {
653 .notifier_call = hpwdt_pretimeout,
654 .priority = 0,
655};
656#endif /* CONFIG_HPWDT_NMI_DECODING */
657
658/* 648/*
659 * Init & Exit 649 * Init & Exit
660 */ 650 */
@@ -740,10 +730,9 @@ static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev)
740 * die notify list to handle a critical NMI. The default is to 730 * die notify list to handle a critical NMI. The default is to
741 * be last so other users of the NMI signal can function. 731 * be last so other users of the NMI signal can function.
742 */ 732 */
743 if (priority) 733 retval = register_nmi_handler(NMI_UNKNOWN, hpwdt_pretimeout,
744 die_notifier.priority = 0x7FFFFFFF; 734 (priority) ? NMI_FLAG_FIRST : 0,
745 735 "hpwdt");
746 retval = register_die_notifier(&die_notifier);
747 if (retval != 0) { 736 if (retval != 0) {
748 dev_warn(&dev->dev, 737 dev_warn(&dev->dev,
749 "Unable to register a die notifier (err=%d).\n", 738 "Unable to register a die notifier (err=%d).\n",
@@ -763,7 +752,7 @@ static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev)
763 752
764static void hpwdt_exit_nmi_decoding(void) 753static void hpwdt_exit_nmi_decoding(void)
765{ 754{
766 unregister_die_notifier(&die_notifier); 755 unregister_nmi_handler(NMI_UNKNOWN, "hpwdt");
767 if (cru_rom_addr) 756 if (cru_rom_addr)
768 iounmap(cru_rom_addr); 757 iounmap(cru_rom_addr);
769} 758}
diff --git a/include/linux/module.h b/include/linux/module.h
index 1c30087a2d81..863921637d9f 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -580,9 +580,6 @@ int unregister_module_notifier(struct notifier_block * nb);
580 580
581extern void print_modules(void); 581extern void print_modules(void);
582 582
583extern void module_update_tracepoints(void);
584extern int module_get_iter_tracepoints(struct tracepoint_iter *iter);
585
586#else /* !CONFIG_MODULES... */ 583#else /* !CONFIG_MODULES... */
587#define EXPORT_SYMBOL(sym) 584#define EXPORT_SYMBOL(sym)
588#define EXPORT_SYMBOL_GPL(sym) 585#define EXPORT_SYMBOL_GPL(sym)
@@ -698,15 +695,6 @@ static inline int unregister_module_notifier(struct notifier_block * nb)
698static inline void print_modules(void) 695static inline void print_modules(void)
699{ 696{
700} 697}
701
702static inline void module_update_tracepoints(void)
703{
704}
705
706static inline int module_get_iter_tracepoints(struct tracepoint_iter *iter)
707{
708 return 0;
709}
710#endif /* CONFIG_MODULES */ 698#endif /* CONFIG_MODULES */
711 699
712#ifdef CONFIG_SYSFS 700#ifdef CONFIG_SYSFS
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index c816075c01ce..1e9ebe5e0091 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -220,7 +220,10 @@ struct perf_event_attr {
220 mmap_data : 1, /* non-exec mmap data */ 220 mmap_data : 1, /* non-exec mmap data */
221 sample_id_all : 1, /* sample_type all events */ 221 sample_id_all : 1, /* sample_type all events */
222 222
223 __reserved_1 : 45; 223 exclude_host : 1, /* don't count in host */
224 exclude_guest : 1, /* don't count in guest */
225
226 __reserved_1 : 43;
224 227
225 union { 228 union {
226 __u32 wakeup_events; /* wakeup every n events */ 229 __u32 wakeup_events; /* wakeup every n events */
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
index b891de96000f..67be0376d8e3 100644
--- a/include/linux/ring_buffer.h
+++ b/include/linux/ring_buffer.h
@@ -154,6 +154,8 @@ void ring_buffer_record_enable(struct ring_buffer *buffer);
154void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu); 154void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu);
155void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu); 155void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu);
156 156
157unsigned long ring_buffer_oldest_event_ts(struct ring_buffer *buffer, int cpu);
158unsigned long ring_buffer_bytes_cpu(struct ring_buffer *buffer, int cpu);
157unsigned long ring_buffer_entries(struct ring_buffer *buffer); 159unsigned long ring_buffer_entries(struct ring_buffer *buffer);
158unsigned long ring_buffer_overruns(struct ring_buffer *buffer); 160unsigned long ring_buffer_overruns(struct ring_buffer *buffer);
159unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu); 161unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu);
diff --git a/include/linux/trace_clock.h b/include/linux/trace_clock.h
index 7a8130384087..4eb490237d4c 100644
--- a/include/linux/trace_clock.h
+++ b/include/linux/trace_clock.h
@@ -15,5 +15,6 @@
15extern u64 notrace trace_clock_local(void); 15extern u64 notrace trace_clock_local(void);
16extern u64 notrace trace_clock(void); 16extern u64 notrace trace_clock(void);
17extern u64 notrace trace_clock_global(void); 17extern u64 notrace trace_clock_global(void);
18extern u64 notrace trace_clock_counter(void);
18 19
19#endif /* _LINUX_TRACE_CLOCK_H */ 20#endif /* _LINUX_TRACE_CLOCK_H */
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index d530a4460a0b..df0a779c1bbd 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -54,8 +54,18 @@ extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe,
54 void *data); 54 void *data);
55extern void tracepoint_probe_update_all(void); 55extern void tracepoint_probe_update_all(void);
56 56
57#ifdef CONFIG_MODULES
58struct tp_module {
59 struct list_head list;
60 unsigned int num_tracepoints;
61 struct tracepoint * const *tracepoints_ptrs;
62};
63#endif /* CONFIG_MODULES */
64
57struct tracepoint_iter { 65struct tracepoint_iter {
58 struct module *module; 66#ifdef CONFIG_MODULES
67 struct tp_module *module;
68#endif /* CONFIG_MODULES */
59 struct tracepoint * const *tracepoint; 69 struct tracepoint * const *tracepoint;
60}; 70};
61 71
@@ -63,8 +73,6 @@ extern void tracepoint_iter_start(struct tracepoint_iter *iter);
63extern void tracepoint_iter_next(struct tracepoint_iter *iter); 73extern void tracepoint_iter_next(struct tracepoint_iter *iter);
64extern void tracepoint_iter_stop(struct tracepoint_iter *iter); 74extern void tracepoint_iter_stop(struct tracepoint_iter *iter);
65extern void tracepoint_iter_reset(struct tracepoint_iter *iter); 75extern void tracepoint_iter_reset(struct tracepoint_iter *iter);
66extern int tracepoint_get_iter_range(struct tracepoint * const **tracepoint,
67 struct tracepoint * const *begin, struct tracepoint * const *end);
68 76
69/* 77/*
70 * tracepoint_synchronize_unregister must be called between the last tracepoint 78 * tracepoint_synchronize_unregister must be called between the last tracepoint
@@ -78,17 +86,6 @@ static inline void tracepoint_synchronize_unregister(void)
78 86
79#define PARAMS(args...) args 87#define PARAMS(args...) args
80 88
81#ifdef CONFIG_TRACEPOINTS
82extern
83void tracepoint_update_probe_range(struct tracepoint * const *begin,
84 struct tracepoint * const *end);
85#else
86static inline
87void tracepoint_update_probe_range(struct tracepoint * const *begin,
88 struct tracepoint * const *end)
89{ }
90#endif /* CONFIG_TRACEPOINTS */
91
92#endif /* _LINUX_TRACEPOINT_H */ 89#endif /* _LINUX_TRACEPOINT_H */
93 90
94/* 91/*
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index 533c49f48047..769724944fc6 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -711,6 +711,9 @@ __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call
711#undef __perf_count 711#undef __perf_count
712#define __perf_count(c) __count = (c) 712#define __perf_count(c) __count = (c)
713 713
714#undef TP_perf_assign
715#define TP_perf_assign(args...) args
716
714#undef DECLARE_EVENT_CLASS 717#undef DECLARE_EVENT_CLASS
715#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ 718#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
716static notrace void \ 719static notrace void \
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 0f857782d06f..d1a1bee35228 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -29,6 +29,7 @@
29#include <linux/hardirq.h> 29#include <linux/hardirq.h>
30#include <linux/rculist.h> 30#include <linux/rculist.h>
31#include <linux/uaccess.h> 31#include <linux/uaccess.h>
32#include <linux/suspend.h>
32#include <linux/syscalls.h> 33#include <linux/syscalls.h>
33#include <linux/anon_inodes.h> 34#include <linux/anon_inodes.h>
34#include <linux/kernel_stat.h> 35#include <linux/kernel_stat.h>
@@ -5758,6 +5759,7 @@ struct pmu *perf_init_event(struct perf_event *event)
5758 pmu = idr_find(&pmu_idr, event->attr.type); 5759 pmu = idr_find(&pmu_idr, event->attr.type);
5759 rcu_read_unlock(); 5760 rcu_read_unlock();
5760 if (pmu) { 5761 if (pmu) {
5762 event->pmu = pmu;
5761 ret = pmu->event_init(event); 5763 ret = pmu->event_init(event);
5762 if (ret) 5764 if (ret)
5763 pmu = ERR_PTR(ret); 5765 pmu = ERR_PTR(ret);
@@ -5765,6 +5767,7 @@ struct pmu *perf_init_event(struct perf_event *event)
5765 } 5767 }
5766 5768
5767 list_for_each_entry_rcu(pmu, &pmus, entry) { 5769 list_for_each_entry_rcu(pmu, &pmus, entry) {
5770 event->pmu = pmu;
5768 ret = pmu->event_init(event); 5771 ret = pmu->event_init(event);
5769 if (!ret) 5772 if (!ret)
5770 goto unlock; 5773 goto unlock;
@@ -5891,8 +5894,6 @@ done:
5891 return ERR_PTR(err); 5894 return ERR_PTR(err);
5892 } 5895 }
5893 5896
5894 event->pmu = pmu;
5895
5896 if (!event->parent) { 5897 if (!event->parent) {
5897 if (event->attach_state & PERF_ATTACH_TASK) 5898 if (event->attach_state & PERF_ATTACH_TASK)
5898 jump_label_inc(&perf_sched_events); 5899 jump_label_inc(&perf_sched_events);
@@ -6852,7 +6853,7 @@ static void __cpuinit perf_event_init_cpu(int cpu)
6852 struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu); 6853 struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu);
6853 6854
6854 mutex_lock(&swhash->hlist_mutex); 6855 mutex_lock(&swhash->hlist_mutex);
6855 if (swhash->hlist_refcount > 0) { 6856 if (swhash->hlist_refcount > 0 && !swhash->swevent_hlist) {
6856 struct swevent_hlist *hlist; 6857 struct swevent_hlist *hlist;
6857 6858
6858 hlist = kzalloc_node(sizeof(*hlist), GFP_KERNEL, cpu_to_node(cpu)); 6859 hlist = kzalloc_node(sizeof(*hlist), GFP_KERNEL, cpu_to_node(cpu));
@@ -6941,7 +6942,14 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu)
6941{ 6942{
6942 unsigned int cpu = (long)hcpu; 6943 unsigned int cpu = (long)hcpu;
6943 6944
6944 switch (action & ~CPU_TASKS_FROZEN) { 6945 /*
6946 * Ignore suspend/resume action, the perf_pm_notifier will
6947 * take care of that.
6948 */
6949 if (action & CPU_TASKS_FROZEN)
6950 return NOTIFY_OK;
6951
6952 switch (action) {
6945 6953
6946 case CPU_UP_PREPARE: 6954 case CPU_UP_PREPARE:
6947 case CPU_DOWN_FAILED: 6955 case CPU_DOWN_FAILED:
@@ -6960,6 +6968,90 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu)
6960 return NOTIFY_OK; 6968 return NOTIFY_OK;
6961} 6969}
6962 6970
6971static void perf_pm_resume_cpu(void *unused)
6972{
6973 struct perf_cpu_context *cpuctx;
6974 struct perf_event_context *ctx;
6975 struct pmu *pmu;
6976 int idx;
6977
6978 idx = srcu_read_lock(&pmus_srcu);
6979 list_for_each_entry_rcu(pmu, &pmus, entry) {
6980 cpuctx = this_cpu_ptr(pmu->pmu_cpu_context);
6981 ctx = cpuctx->task_ctx;
6982
6983 perf_ctx_lock(cpuctx, ctx);
6984 perf_pmu_disable(cpuctx->ctx.pmu);
6985
6986 cpu_ctx_sched_out(cpuctx, EVENT_ALL);
6987 if (ctx)
6988 ctx_sched_out(ctx, cpuctx, EVENT_ALL);
6989
6990 perf_pmu_enable(cpuctx->ctx.pmu);
6991 perf_ctx_unlock(cpuctx, ctx);
6992 }
6993 srcu_read_unlock(&pmus_srcu, idx);
6994}
6995
6996static void perf_pm_suspend_cpu(void *unused)
6997{
6998 struct perf_cpu_context *cpuctx;
6999 struct perf_event_context *ctx;
7000 struct pmu *pmu;
7001 int idx;
7002
7003 idx = srcu_read_lock(&pmus_srcu);
7004 list_for_each_entry_rcu(pmu, &pmus, entry) {
7005 cpuctx = this_cpu_ptr(pmu->pmu_cpu_context);
7006 ctx = cpuctx->task_ctx;
7007
7008 perf_ctx_lock(cpuctx, ctx);
7009 perf_pmu_disable(cpuctx->ctx.pmu);
7010
7011 perf_event_sched_in(cpuctx, ctx, current);
7012
7013 perf_pmu_enable(cpuctx->ctx.pmu);
7014 perf_ctx_unlock(cpuctx, ctx);
7015 }
7016 srcu_read_unlock(&pmus_srcu, idx);
7017}
7018
7019static int perf_resume(void)
7020{
7021 get_online_cpus();
7022 smp_call_function(perf_pm_resume_cpu, NULL, 1);
7023 put_online_cpus();
7024
7025 return NOTIFY_OK;
7026}
7027
7028static int perf_suspend(void)
7029{
7030 get_online_cpus();
7031 smp_call_function(perf_pm_suspend_cpu, NULL, 1);
7032 put_online_cpus();
7033
7034 return NOTIFY_OK;
7035}
7036
7037static int perf_pm(struct notifier_block *self, unsigned long action, void *ptr)
7038{
7039 switch (action) {
7040 case PM_POST_HIBERNATION:
7041 case PM_POST_SUSPEND:
7042 return perf_resume();
7043 case PM_HIBERNATION_PREPARE:
7044 case PM_SUSPEND_PREPARE:
7045 return perf_suspend();
7046 default:
7047 return NOTIFY_DONE;
7048 }
7049}
7050
7051static struct notifier_block perf_pm_notifier = {
7052 .notifier_call = perf_pm,
7053};
7054
6963void __init perf_event_init(void) 7055void __init perf_event_init(void)
6964{ 7056{
6965 int ret; 7057 int ret;
@@ -6974,6 +7066,7 @@ void __init perf_event_init(void)
6974 perf_tp_register(); 7066 perf_tp_register();
6975 perf_cpu_notifier(perf_cpu_notify); 7067 perf_cpu_notifier(perf_cpu_notify);
6976 register_reboot_notifier(&perf_reboot_notifier); 7068 register_reboot_notifier(&perf_reboot_notifier);
7069 register_pm_notifier(&perf_pm_notifier);
6977 7070
6978 ret = init_hw_breakpoint(); 7071 ret = init_hw_breakpoint();
6979 WARN(ret, "hw_breakpoint initialization failed with: %d", ret); 7072 WARN(ret, "hw_breakpoint initialization failed with: %d", ret);
diff --git a/kernel/module.c b/kernel/module.c
index 04379f92f843..93342d992f34 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3487,50 +3487,3 @@ void module_layout(struct module *mod,
3487} 3487}
3488EXPORT_SYMBOL(module_layout); 3488EXPORT_SYMBOL(module_layout);
3489#endif 3489#endif
3490
3491#ifdef CONFIG_TRACEPOINTS
3492void module_update_tracepoints(void)
3493{
3494 struct module *mod;
3495
3496 mutex_lock(&module_mutex);
3497 list_for_each_entry(mod, &modules, list)
3498 if (!mod->taints)
3499 tracepoint_update_probe_range(mod->tracepoints_ptrs,
3500 mod->tracepoints_ptrs + mod->num_tracepoints);
3501 mutex_unlock(&module_mutex);
3502}
3503
3504/*
3505 * Returns 0 if current not found.
3506 * Returns 1 if current found.
3507 */
3508int module_get_iter_tracepoints(struct tracepoint_iter *iter)
3509{
3510 struct module *iter_mod;
3511 int found = 0;
3512
3513 mutex_lock(&module_mutex);
3514 list_for_each_entry(iter_mod, &modules, list) {
3515 if (!iter_mod->taints) {
3516 /*
3517 * Sorted module list
3518 */
3519 if (iter_mod < iter->module)
3520 continue;
3521 else if (iter_mod > iter->module)
3522 iter->tracepoint = NULL;
3523 found = tracepoint_get_iter_range(&iter->tracepoint,
3524 iter_mod->tracepoints_ptrs,
3525 iter_mod->tracepoints_ptrs
3526 + iter_mod->num_tracepoints);
3527 if (found) {
3528 iter->module = iter_mod;
3529 break;
3530 }
3531 }
3532 }
3533 mutex_unlock(&module_mutex);
3534 return found;
3535}
3536#endif
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index f49405f842f4..5f39a07fe5ea 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -15,6 +15,8 @@ ifdef CONFIG_TRACING_BRANCHES
15KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING 15KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
16endif 16endif
17 17
18CFLAGS_trace_events_filter.o := -I$(src)
19
18# 20#
19# Make the trace clocks available generally: it's infrastructure 21# Make the trace clocks available generally: it's infrastructure
20# relied on by ptrace for example: 22# relied on by ptrace for example:
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index c3e4575e7829..077d85387908 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -3863,6 +3863,14 @@ void ftrace_kill(void)
3863} 3863}
3864 3864
3865/** 3865/**
3866 * Test if ftrace is dead or not.
3867 */
3868int ftrace_is_dead(void)
3869{
3870 return ftrace_disabled;
3871}
3872
3873/**
3866 * register_ftrace_function - register a function for profiling 3874 * register_ftrace_function - register a function for profiling
3867 * @ops - ops structure that holds the function for profiling. 3875 * @ops - ops structure that holds the function for profiling.
3868 * 3876 *
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index f2f821acc597..f5b7b5c1195b 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -488,12 +488,14 @@ struct ring_buffer_per_cpu {
488 struct buffer_page *reader_page; 488 struct buffer_page *reader_page;
489 unsigned long lost_events; 489 unsigned long lost_events;
490 unsigned long last_overrun; 490 unsigned long last_overrun;
491 local_t entries_bytes;
491 local_t commit_overrun; 492 local_t commit_overrun;
492 local_t overrun; 493 local_t overrun;
493 local_t entries; 494 local_t entries;
494 local_t committing; 495 local_t committing;
495 local_t commits; 496 local_t commits;
496 unsigned long read; 497 unsigned long read;
498 unsigned long read_bytes;
497 u64 write_stamp; 499 u64 write_stamp;
498 u64 read_stamp; 500 u64 read_stamp;
499}; 501};
@@ -1708,6 +1710,7 @@ rb_handle_head_page(struct ring_buffer_per_cpu *cpu_buffer,
1708 * the counters. 1710 * the counters.
1709 */ 1711 */
1710 local_add(entries, &cpu_buffer->overrun); 1712 local_add(entries, &cpu_buffer->overrun);
1713 local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes);
1711 1714
1712 /* 1715 /*
1713 * The entries will be zeroed out when we move the 1716 * The entries will be zeroed out when we move the
@@ -1863,6 +1866,9 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer,
1863 event = __rb_page_index(tail_page, tail); 1866 event = __rb_page_index(tail_page, tail);
1864 kmemcheck_annotate_bitfield(event, bitfield); 1867 kmemcheck_annotate_bitfield(event, bitfield);
1865 1868
1869 /* account for padding bytes */
1870 local_add(BUF_PAGE_SIZE - tail, &cpu_buffer->entries_bytes);
1871
1866 /* 1872 /*
1867 * Save the original length to the meta data. 1873 * Save the original length to the meta data.
1868 * This will be used by the reader to add lost event 1874 * This will be used by the reader to add lost event
@@ -2054,6 +2060,9 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
2054 if (!tail) 2060 if (!tail)
2055 tail_page->page->time_stamp = ts; 2061 tail_page->page->time_stamp = ts;
2056 2062
2063 /* account for these added bytes */
2064 local_add(length, &cpu_buffer->entries_bytes);
2065
2057 return event; 2066 return event;
2058} 2067}
2059 2068
@@ -2076,6 +2085,7 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer,
2076 if (bpage->page == (void *)addr && rb_page_write(bpage) == old_index) { 2085 if (bpage->page == (void *)addr && rb_page_write(bpage) == old_index) {
2077 unsigned long write_mask = 2086 unsigned long write_mask =
2078 local_read(&bpage->write) & ~RB_WRITE_MASK; 2087 local_read(&bpage->write) & ~RB_WRITE_MASK;
2088 unsigned long event_length = rb_event_length(event);
2079 /* 2089 /*
2080 * This is on the tail page. It is possible that 2090 * This is on the tail page. It is possible that
2081 * a write could come in and move the tail page 2091 * a write could come in and move the tail page
@@ -2085,8 +2095,11 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer,
2085 old_index += write_mask; 2095 old_index += write_mask;
2086 new_index += write_mask; 2096 new_index += write_mask;
2087 index = local_cmpxchg(&bpage->write, old_index, new_index); 2097 index = local_cmpxchg(&bpage->write, old_index, new_index);
2088 if (index == old_index) 2098 if (index == old_index) {
2099 /* update counters */
2100 local_sub(event_length, &cpu_buffer->entries_bytes);
2089 return 1; 2101 return 1;
2102 }
2090 } 2103 }
2091 2104
2092 /* could not discard */ 2105 /* could not discard */
@@ -2661,6 +2674,58 @@ rb_num_of_entries(struct ring_buffer_per_cpu *cpu_buffer)
2661} 2674}
2662 2675
2663/** 2676/**
2677 * ring_buffer_oldest_event_ts - get the oldest event timestamp from the buffer
2678 * @buffer: The ring buffer
2679 * @cpu: The per CPU buffer to read from.
2680 */
2681unsigned long ring_buffer_oldest_event_ts(struct ring_buffer *buffer, int cpu)
2682{
2683 unsigned long flags;
2684 struct ring_buffer_per_cpu *cpu_buffer;
2685 struct buffer_page *bpage;
2686 unsigned long ret;
2687
2688 if (!cpumask_test_cpu(cpu, buffer->cpumask))
2689 return 0;
2690
2691 cpu_buffer = buffer->buffers[cpu];
2692 raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
2693 /*
2694 * if the tail is on reader_page, oldest time stamp is on the reader
2695 * page
2696 */
2697 if (cpu_buffer->tail_page == cpu_buffer->reader_page)
2698 bpage = cpu_buffer->reader_page;
2699 else
2700 bpage = rb_set_head_page(cpu_buffer);
2701 ret = bpage->page->time_stamp;
2702 raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
2703
2704 return ret;
2705}
2706EXPORT_SYMBOL_GPL(ring_buffer_oldest_event_ts);
2707
2708/**
2709 * ring_buffer_bytes_cpu - get the number of bytes consumed in a cpu buffer
2710 * @buffer: The ring buffer
2711 * @cpu: The per CPU buffer to read from.
2712 */
2713unsigned long ring_buffer_bytes_cpu(struct ring_buffer *buffer, int cpu)
2714{
2715 struct ring_buffer_per_cpu *cpu_buffer;
2716 unsigned long ret;
2717
2718 if (!cpumask_test_cpu(cpu, buffer->cpumask))
2719 return 0;
2720
2721 cpu_buffer = buffer->buffers[cpu];
2722 ret = local_read(&cpu_buffer->entries_bytes) - cpu_buffer->read_bytes;
2723
2724 return ret;
2725}
2726EXPORT_SYMBOL_GPL(ring_buffer_bytes_cpu);
2727
2728/**
2664 * ring_buffer_entries_cpu - get the number of entries in a cpu buffer 2729 * ring_buffer_entries_cpu - get the number of entries in a cpu buffer
2665 * @buffer: The ring buffer 2730 * @buffer: The ring buffer
2666 * @cpu: The per CPU buffer to get the entries from. 2731 * @cpu: The per CPU buffer to get the entries from.
@@ -3527,11 +3592,13 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
3527 cpu_buffer->reader_page->read = 0; 3592 cpu_buffer->reader_page->read = 0;
3528 3593
3529 local_set(&cpu_buffer->commit_overrun, 0); 3594 local_set(&cpu_buffer->commit_overrun, 0);
3595 local_set(&cpu_buffer->entries_bytes, 0);
3530 local_set(&cpu_buffer->overrun, 0); 3596 local_set(&cpu_buffer->overrun, 0);
3531 local_set(&cpu_buffer->entries, 0); 3597 local_set(&cpu_buffer->entries, 0);
3532 local_set(&cpu_buffer->committing, 0); 3598 local_set(&cpu_buffer->committing, 0);
3533 local_set(&cpu_buffer->commits, 0); 3599 local_set(&cpu_buffer->commits, 0);
3534 cpu_buffer->read = 0; 3600 cpu_buffer->read = 0;
3601 cpu_buffer->read_bytes = 0;
3535 3602
3536 cpu_buffer->write_stamp = 0; 3603 cpu_buffer->write_stamp = 0;
3537 cpu_buffer->read_stamp = 0; 3604 cpu_buffer->read_stamp = 0;
@@ -3918,6 +3985,7 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
3918 } else { 3985 } else {
3919 /* update the entry counter */ 3986 /* update the entry counter */
3920 cpu_buffer->read += rb_page_entries(reader); 3987 cpu_buffer->read += rb_page_entries(reader);
3988 cpu_buffer->read_bytes += BUF_PAGE_SIZE;
3921 3989
3922 /* swap the pages */ 3990 /* swap the pages */
3923 rb_init_page(bpage); 3991 rb_init_page(bpage);
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 0c8bdeeb358b..f2bd275bb60f 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -435,6 +435,7 @@ static struct {
435} trace_clocks[] = { 435} trace_clocks[] = {
436 { trace_clock_local, "local" }, 436 { trace_clock_local, "local" },
437 { trace_clock_global, "global" }, 437 { trace_clock_global, "global" },
438 { trace_clock_counter, "counter" },
438}; 439};
439 440
440int trace_clock_id; 441int trace_clock_id;
@@ -2159,6 +2160,14 @@ void trace_default_header(struct seq_file *m)
2159 } 2160 }
2160} 2161}
2161 2162
2163static void test_ftrace_alive(struct seq_file *m)
2164{
2165 if (!ftrace_is_dead())
2166 return;
2167 seq_printf(m, "# WARNING: FUNCTION TRACING IS CORRUPTED\n");
2168 seq_printf(m, "# MAY BE MISSING FUNCTION EVENTS\n");
2169}
2170
2162static int s_show(struct seq_file *m, void *v) 2171static int s_show(struct seq_file *m, void *v)
2163{ 2172{
2164 struct trace_iterator *iter = v; 2173 struct trace_iterator *iter = v;
@@ -2168,6 +2177,7 @@ static int s_show(struct seq_file *m, void *v)
2168 if (iter->tr) { 2177 if (iter->tr) {
2169 seq_printf(m, "# tracer: %s\n", iter->trace->name); 2178 seq_printf(m, "# tracer: %s\n", iter->trace->name);
2170 seq_puts(m, "#\n"); 2179 seq_puts(m, "#\n");
2180 test_ftrace_alive(m);
2171 } 2181 }
2172 if (iter->trace && iter->trace->print_header) 2182 if (iter->trace && iter->trace->print_header)
2173 iter->trace->print_header(m); 2183 iter->trace->print_header(m);
@@ -2710,9 +2720,9 @@ static const char readme_msg[] =
2710 "# cat /sys/kernel/debug/tracing/trace_options\n" 2720 "# cat /sys/kernel/debug/tracing/trace_options\n"
2711 "noprint-parent nosym-offset nosym-addr noverbose\n" 2721 "noprint-parent nosym-offset nosym-addr noverbose\n"
2712 "# echo print-parent > /sys/kernel/debug/tracing/trace_options\n" 2722 "# echo print-parent > /sys/kernel/debug/tracing/trace_options\n"
2713 "# echo 1 > /sys/kernel/debug/tracing/tracing_enabled\n" 2723 "# echo 1 > /sys/kernel/debug/tracing/tracing_on\n"
2714 "# cat /sys/kernel/debug/tracing/trace > /tmp/trace.txt\n" 2724 "# cat /sys/kernel/debug/tracing/trace > /tmp/trace.txt\n"
2715 "# echo 0 > /sys/kernel/debug/tracing/tracing_enabled\n" 2725 "# echo 0 > /sys/kernel/debug/tracing/tracing_on\n"
2716; 2726;
2717 2727
2718static ssize_t 2728static ssize_t
@@ -3569,6 +3579,30 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
3569} 3579}
3570 3580
3571static ssize_t 3581static ssize_t
3582tracing_total_entries_read(struct file *filp, char __user *ubuf,
3583 size_t cnt, loff_t *ppos)
3584{
3585 struct trace_array *tr = filp->private_data;
3586 char buf[64];
3587 int r, cpu;
3588 unsigned long size = 0, expanded_size = 0;
3589
3590 mutex_lock(&trace_types_lock);
3591 for_each_tracing_cpu(cpu) {
3592 size += tr->entries >> 10;
3593 if (!ring_buffer_expanded)
3594 expanded_size += trace_buf_size >> 10;
3595 }
3596 if (ring_buffer_expanded)
3597 r = sprintf(buf, "%lu\n", size);
3598 else
3599 r = sprintf(buf, "%lu (expanded: %lu)\n", size, expanded_size);
3600 mutex_unlock(&trace_types_lock);
3601
3602 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
3603}
3604
3605static ssize_t
3572tracing_free_buffer_write(struct file *filp, const char __user *ubuf, 3606tracing_free_buffer_write(struct file *filp, const char __user *ubuf,
3573 size_t cnt, loff_t *ppos) 3607 size_t cnt, loff_t *ppos)
3574{ 3608{
@@ -3594,22 +3628,24 @@ tracing_free_buffer_release(struct inode *inode, struct file *filp)
3594 return 0; 3628 return 0;
3595} 3629}
3596 3630
3597static int mark_printk(const char *fmt, ...)
3598{
3599 int ret;
3600 va_list args;
3601 va_start(args, fmt);
3602 ret = trace_vprintk(0, fmt, args);
3603 va_end(args);
3604 return ret;
3605}
3606
3607static ssize_t 3631static ssize_t
3608tracing_mark_write(struct file *filp, const char __user *ubuf, 3632tracing_mark_write(struct file *filp, const char __user *ubuf,
3609 size_t cnt, loff_t *fpos) 3633 size_t cnt, loff_t *fpos)
3610{ 3634{
3611 char *buf; 3635 unsigned long addr = (unsigned long)ubuf;
3612 size_t written; 3636 struct ring_buffer_event *event;
3637 struct ring_buffer *buffer;
3638 struct print_entry *entry;
3639 unsigned long irq_flags;
3640 struct page *pages[2];
3641 int nr_pages = 1;
3642 ssize_t written;
3643 void *page1;
3644 void *page2;
3645 int offset;
3646 int size;
3647 int len;
3648 int ret;
3613 3649
3614 if (tracing_disabled) 3650 if (tracing_disabled)
3615 return -EINVAL; 3651 return -EINVAL;
@@ -3617,28 +3653,81 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
3617 if (cnt > TRACE_BUF_SIZE) 3653 if (cnt > TRACE_BUF_SIZE)
3618 cnt = TRACE_BUF_SIZE; 3654 cnt = TRACE_BUF_SIZE;
3619 3655
3620 buf = kmalloc(cnt + 2, GFP_KERNEL); 3656 /*
3621 if (buf == NULL) 3657 * Userspace is injecting traces into the kernel trace buffer.
3622 return -ENOMEM; 3658 * We want to be as non intrusive as possible.
3659 * To do so, we do not want to allocate any special buffers
3660 * or take any locks, but instead write the userspace data
3661 * straight into the ring buffer.
3662 *
3663 * First we need to pin the userspace buffer into memory,
3664 * which, most likely it is, because it just referenced it.
3665 * But there's no guarantee that it is. By using get_user_pages_fast()
3666 * and kmap_atomic/kunmap_atomic() we can get access to the
3667 * pages directly. We then write the data directly into the
3668 * ring buffer.
3669 */
3670 BUILD_BUG_ON(TRACE_BUF_SIZE >= PAGE_SIZE);
3623 3671
3624 if (copy_from_user(buf, ubuf, cnt)) { 3672 /* check if we cross pages */
3625 kfree(buf); 3673 if ((addr & PAGE_MASK) != ((addr + cnt) & PAGE_MASK))
3626 return -EFAULT; 3674 nr_pages = 2;
3675
3676 offset = addr & (PAGE_SIZE - 1);
3677 addr &= PAGE_MASK;
3678
3679 ret = get_user_pages_fast(addr, nr_pages, 0, pages);
3680 if (ret < nr_pages) {
3681 while (--ret >= 0)
3682 put_page(pages[ret]);
3683 written = -EFAULT;
3684 goto out;
3685 }
3686
3687 page1 = kmap_atomic(pages[0]);
3688 if (nr_pages == 2)
3689 page2 = kmap_atomic(pages[1]);
3690
3691 local_save_flags(irq_flags);
3692 size = sizeof(*entry) + cnt + 2; /* possible \n added */
3693 buffer = global_trace.buffer;
3694 event = trace_buffer_lock_reserve(buffer, TRACE_PRINT, size,
3695 irq_flags, preempt_count());
3696 if (!event) {
3697 /* Ring buffer disabled, return as if not open for write */
3698 written = -EBADF;
3699 goto out_unlock;
3627 } 3700 }
3628 if (buf[cnt-1] != '\n') { 3701
3629 buf[cnt] = '\n'; 3702 entry = ring_buffer_event_data(event);
3630 buf[cnt+1] = '\0'; 3703 entry->ip = _THIS_IP_;
3704
3705 if (nr_pages == 2) {
3706 len = PAGE_SIZE - offset;
3707 memcpy(&entry->buf, page1 + offset, len);
3708 memcpy(&entry->buf[len], page2, cnt - len);
3631 } else 3709 } else
3632 buf[cnt] = '\0'; 3710 memcpy(&entry->buf, page1 + offset, cnt);
3633 3711
3634 written = mark_printk("%s", buf); 3712 if (entry->buf[cnt - 1] != '\n') {
3635 kfree(buf); 3713 entry->buf[cnt] = '\n';
3636 *fpos += written; 3714 entry->buf[cnt + 1] = '\0';
3715 } else
3716 entry->buf[cnt] = '\0';
3717
3718 ring_buffer_unlock_commit(buffer, event);
3637 3719
3638 /* don't tell userspace we wrote more - it might confuse them */ 3720 written = cnt;
3639 if (written > cnt)
3640 written = cnt;
3641 3721
3722 *fpos += written;
3723
3724 out_unlock:
3725 if (nr_pages == 2)
3726 kunmap_atomic(page2);
3727 kunmap_atomic(page1);
3728 while (nr_pages > 0)
3729 put_page(pages[--nr_pages]);
3730 out:
3642 return written; 3731 return written;
3643} 3732}
3644 3733
@@ -3739,6 +3828,12 @@ static const struct file_operations tracing_entries_fops = {
3739 .llseek = generic_file_llseek, 3828 .llseek = generic_file_llseek,
3740}; 3829};
3741 3830
3831static const struct file_operations tracing_total_entries_fops = {
3832 .open = tracing_open_generic,
3833 .read = tracing_total_entries_read,
3834 .llseek = generic_file_llseek,
3835};
3836
3742static const struct file_operations tracing_free_buffer_fops = { 3837static const struct file_operations tracing_free_buffer_fops = {
3743 .write = tracing_free_buffer_write, 3838 .write = tracing_free_buffer_write,
3744 .release = tracing_free_buffer_release, 3839 .release = tracing_free_buffer_release,
@@ -3808,8 +3903,6 @@ tracing_buffers_read(struct file *filp, char __user *ubuf,
3808 if (info->read < PAGE_SIZE) 3903 if (info->read < PAGE_SIZE)
3809 goto read; 3904 goto read;
3810 3905
3811 info->read = 0;
3812
3813 trace_access_lock(info->cpu); 3906 trace_access_lock(info->cpu);
3814 ret = ring_buffer_read_page(info->tr->buffer, 3907 ret = ring_buffer_read_page(info->tr->buffer,
3815 &info->spare, 3908 &info->spare,
@@ -3819,6 +3912,8 @@ tracing_buffers_read(struct file *filp, char __user *ubuf,
3819 if (ret < 0) 3912 if (ret < 0)
3820 return 0; 3913 return 0;
3821 3914
3915 info->read = 0;
3916
3822read: 3917read:
3823 size = PAGE_SIZE - info->read; 3918 size = PAGE_SIZE - info->read;
3824 if (size > count) 3919 if (size > count)
@@ -4026,6 +4121,8 @@ tracing_stats_read(struct file *filp, char __user *ubuf,
4026 struct trace_array *tr = &global_trace; 4121 struct trace_array *tr = &global_trace;
4027 struct trace_seq *s; 4122 struct trace_seq *s;
4028 unsigned long cnt; 4123 unsigned long cnt;
4124 unsigned long long t;
4125 unsigned long usec_rem;
4029 4126
4030 s = kmalloc(sizeof(*s), GFP_KERNEL); 4127 s = kmalloc(sizeof(*s), GFP_KERNEL);
4031 if (!s) 4128 if (!s)
@@ -4042,6 +4139,17 @@ tracing_stats_read(struct file *filp, char __user *ubuf,
4042 cnt = ring_buffer_commit_overrun_cpu(tr->buffer, cpu); 4139 cnt = ring_buffer_commit_overrun_cpu(tr->buffer, cpu);
4043 trace_seq_printf(s, "commit overrun: %ld\n", cnt); 4140 trace_seq_printf(s, "commit overrun: %ld\n", cnt);
4044 4141
4142 cnt = ring_buffer_bytes_cpu(tr->buffer, cpu);
4143 trace_seq_printf(s, "bytes: %ld\n", cnt);
4144
4145 t = ns2usecs(ring_buffer_oldest_event_ts(tr->buffer, cpu));
4146 usec_rem = do_div(t, USEC_PER_SEC);
4147 trace_seq_printf(s, "oldest event ts: %5llu.%06lu\n", t, usec_rem);
4148
4149 t = ns2usecs(ring_buffer_time_stamp(tr->buffer, cpu));
4150 usec_rem = do_div(t, USEC_PER_SEC);
4151 trace_seq_printf(s, "now ts: %5llu.%06lu\n", t, usec_rem);
4152
4045 count = simple_read_from_buffer(ubuf, count, ppos, s->buffer, s->len); 4153 count = simple_read_from_buffer(ubuf, count, ppos, s->buffer, s->len);
4046 4154
4047 kfree(s); 4155 kfree(s);
@@ -4450,6 +4558,9 @@ static __init int tracer_init_debugfs(void)
4450 trace_create_file("buffer_size_kb", 0644, d_tracer, 4558 trace_create_file("buffer_size_kb", 0644, d_tracer,
4451 &global_trace, &tracing_entries_fops); 4559 &global_trace, &tracing_entries_fops);
4452 4560
4561 trace_create_file("buffer_total_size_kb", 0444, d_tracer,
4562 &global_trace, &tracing_total_entries_fops);
4563
4453 trace_create_file("free_buffer", 0644, d_tracer, 4564 trace_create_file("free_buffer", 0644, d_tracer,
4454 &global_trace, &tracing_free_buffer_fops); 4565 &global_trace, &tracing_free_buffer_fops);
4455 4566
@@ -4566,6 +4677,12 @@ __ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode)
4566 4677
4567 tracing_off(); 4678 tracing_off();
4568 4679
4680 /* Did function tracer already get disabled? */
4681 if (ftrace_is_dead()) {
4682 printk("# WARNING: FUNCTION TRACING IS CORRUPTED\n");
4683 printk("# MAY BE MISSING FUNCTION EVENTS\n");
4684 }
4685
4569 if (disable_tracing) 4686 if (disable_tracing)
4570 ftrace_kill(); 4687 ftrace_kill();
4571 4688
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 616846bcfee5..092e1f8d18dc 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -579,11 +579,13 @@ static inline int ftrace_trace_task(struct task_struct *task)
579 579
580 return test_tsk_trace_trace(task); 580 return test_tsk_trace_trace(task);
581} 581}
582extern int ftrace_is_dead(void);
582#else 583#else
583static inline int ftrace_trace_task(struct task_struct *task) 584static inline int ftrace_trace_task(struct task_struct *task)
584{ 585{
585 return 1; 586 return 1;
586} 587}
588static inline int ftrace_is_dead(void) { return 0; }
587#endif 589#endif
588 590
589/* 591/*
@@ -761,16 +763,10 @@ struct filter_pred {
761 filter_pred_fn_t fn; 763 filter_pred_fn_t fn;
762 u64 val; 764 u64 val;
763 struct regex regex; 765 struct regex regex;
764 /* 766 unsigned short *ops;
765 * Leaf nodes use field_name, ops is used by AND and OR 767#ifdef CONFIG_FTRACE_STARTUP_TEST
766 * nodes. The field_name is always freed when freeing a pred. 768 struct ftrace_event_field *field;
767 * We can overload field_name for ops and have it freed 769#endif
768 * as well.
769 */
770 union {
771 char *field_name;
772 unsigned short *ops;
773 };
774 int offset; 770 int offset;
775 int not; 771 int not;
776 int op; 772 int op;
diff --git a/kernel/trace/trace_clock.c b/kernel/trace/trace_clock.c
index 6302747a1398..394783531cbb 100644
--- a/kernel/trace/trace_clock.c
+++ b/kernel/trace/trace_clock.c
@@ -113,3 +113,15 @@ u64 notrace trace_clock_global(void)
113 113
114 return now; 114 return now;
115} 115}
116
117static atomic64_t trace_counter;
118
119/*
120 * trace_clock_counter(): simply an atomic counter.
121 * Use the trace_counter "counter" for cases where you do not care
122 * about timings, but are interested in strict ordering.
123 */
124u64 notrace trace_clock_counter(void)
125{
126 return atomic64_add_return(1, &trace_counter);
127}
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 256764ecccd6..816d3d074979 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -381,6 +381,63 @@ get_pred_parent(struct filter_pred *pred, struct filter_pred *preds,
381 return pred; 381 return pred;
382} 382}
383 383
384enum walk_return {
385 WALK_PRED_ABORT,
386 WALK_PRED_PARENT,
387 WALK_PRED_DEFAULT,
388};
389
390typedef int (*filter_pred_walkcb_t) (enum move_type move,
391 struct filter_pred *pred,
392 int *err, void *data);
393
394static int walk_pred_tree(struct filter_pred *preds,
395 struct filter_pred *root,
396 filter_pred_walkcb_t cb, void *data)
397{
398 struct filter_pred *pred = root;
399 enum move_type move = MOVE_DOWN;
400 int done = 0;
401
402 if (!preds)
403 return -EINVAL;
404
405 do {
406 int err = 0, ret;
407
408 ret = cb(move, pred, &err, data);
409 if (ret == WALK_PRED_ABORT)
410 return err;
411 if (ret == WALK_PRED_PARENT)
412 goto get_parent;
413
414 switch (move) {
415 case MOVE_DOWN:
416 if (pred->left != FILTER_PRED_INVALID) {
417 pred = &preds[pred->left];
418 continue;
419 }
420 goto get_parent;
421 case MOVE_UP_FROM_LEFT:
422 pred = &preds[pred->right];
423 move = MOVE_DOWN;
424 continue;
425 case MOVE_UP_FROM_RIGHT:
426 get_parent:
427 if (pred == root)
428 break;
429 pred = get_pred_parent(pred, preds,
430 pred->parent,
431 &move);
432 continue;
433 }
434 done = 1;
435 } while (!done);
436
437 /* We are fine. */
438 return 0;
439}
440
384/* 441/*
385 * A series of AND or ORs where found together. Instead of 442 * A series of AND or ORs where found together. Instead of
386 * climbing up and down the tree branches, an array of the 443 * climbing up and down the tree branches, an array of the
@@ -410,99 +467,91 @@ static int process_ops(struct filter_pred *preds,
410 467
411 for (i = 0; i < op->val; i++) { 468 for (i = 0; i < op->val; i++) {
412 pred = &preds[op->ops[i]]; 469 pred = &preds[op->ops[i]];
413 match = pred->fn(pred, rec); 470 if (!WARN_ON_ONCE(!pred->fn))
471 match = pred->fn(pred, rec);
414 if (!!match == type) 472 if (!!match == type)
415 return match; 473 return match;
416 } 474 }
417 return match; 475 return match;
418} 476}
419 477
478struct filter_match_preds_data {
479 struct filter_pred *preds;
480 int match;
481 void *rec;
482};
483
484static int filter_match_preds_cb(enum move_type move, struct filter_pred *pred,
485 int *err, void *data)
486{
487 struct filter_match_preds_data *d = data;
488
489 *err = 0;
490 switch (move) {
491 case MOVE_DOWN:
492 /* only AND and OR have children */
493 if (pred->left != FILTER_PRED_INVALID) {
494 /* If ops is set, then it was folded. */
495 if (!pred->ops)
496 return WALK_PRED_DEFAULT;
497 /* We can treat folded ops as a leaf node */
498 d->match = process_ops(d->preds, pred, d->rec);
499 } else {
500 if (!WARN_ON_ONCE(!pred->fn))
501 d->match = pred->fn(pred, d->rec);
502 }
503
504 return WALK_PRED_PARENT;
505 case MOVE_UP_FROM_LEFT:
506 /*
507 * Check for short circuits.
508 *
509 * Optimization: !!match == (pred->op == OP_OR)
510 * is the same as:
511 * if ((match && pred->op == OP_OR) ||
512 * (!match && pred->op == OP_AND))
513 */
514 if (!!d->match == (pred->op == OP_OR))
515 return WALK_PRED_PARENT;
516 break;
517 case MOVE_UP_FROM_RIGHT:
518 break;
519 }
520
521 return WALK_PRED_DEFAULT;
522}
523
420/* return 1 if event matches, 0 otherwise (discard) */ 524/* return 1 if event matches, 0 otherwise (discard) */
421int filter_match_preds(struct event_filter *filter, void *rec) 525int filter_match_preds(struct event_filter *filter, void *rec)
422{ 526{
423 int match = -1;
424 enum move_type move = MOVE_DOWN;
425 struct filter_pred *preds; 527 struct filter_pred *preds;
426 struct filter_pred *pred;
427 struct filter_pred *root; 528 struct filter_pred *root;
428 int n_preds; 529 struct filter_match_preds_data data = {
429 int done = 0; 530 /* match is currently meaningless */
531 .match = -1,
532 .rec = rec,
533 };
534 int n_preds, ret;
430 535
431 /* no filter is considered a match */ 536 /* no filter is considered a match */
432 if (!filter) 537 if (!filter)
433 return 1; 538 return 1;
434 539
435 n_preds = filter->n_preds; 540 n_preds = filter->n_preds;
436
437 if (!n_preds) 541 if (!n_preds)
438 return 1; 542 return 1;
439 543
440 /* 544 /*
441 * n_preds, root and filter->preds are protect with preemption disabled. 545 * n_preds, root and filter->preds are protect with preemption disabled.
442 */ 546 */
443 preds = rcu_dereference_sched(filter->preds);
444 root = rcu_dereference_sched(filter->root); 547 root = rcu_dereference_sched(filter->root);
445 if (!root) 548 if (!root)
446 return 1; 549 return 1;
447 550
448 pred = root; 551 data.preds = preds = rcu_dereference_sched(filter->preds);
449 552 ret = walk_pred_tree(preds, root, filter_match_preds_cb, &data);
450 /* match is currently meaningless */ 553 WARN_ON(ret);
451 match = -1; 554 return data.match;
452
453 do {
454 switch (move) {
455 case MOVE_DOWN:
456 /* only AND and OR have children */
457 if (pred->left != FILTER_PRED_INVALID) {
458 /* If ops is set, then it was folded. */
459 if (!pred->ops) {
460 /* keep going to down the left side */
461 pred = &preds[pred->left];
462 continue;
463 }
464 /* We can treat folded ops as a leaf node */
465 match = process_ops(preds, pred, rec);
466 } else
467 match = pred->fn(pred, rec);
468 /* If this pred is the only pred */
469 if (pred == root)
470 break;
471 pred = get_pred_parent(pred, preds,
472 pred->parent, &move);
473 continue;
474 case MOVE_UP_FROM_LEFT:
475 /*
476 * Check for short circuits.
477 *
478 * Optimization: !!match == (pred->op == OP_OR)
479 * is the same as:
480 * if ((match && pred->op == OP_OR) ||
481 * (!match && pred->op == OP_AND))
482 */
483 if (!!match == (pred->op == OP_OR)) {
484 if (pred == root)
485 break;
486 pred = get_pred_parent(pred, preds,
487 pred->parent, &move);
488 continue;
489 }
490 /* now go down the right side of the tree. */
491 pred = &preds[pred->right];
492 move = MOVE_DOWN;
493 continue;
494 case MOVE_UP_FROM_RIGHT:
495 /* We finished this equation. */
496 if (pred == root)
497 break;
498 pred = get_pred_parent(pred, preds,
499 pred->parent, &move);
500 continue;
501 }
502 done = 1;
503 } while (!done);
504
505 return match;
506} 555}
507EXPORT_SYMBOL_GPL(filter_match_preds); 556EXPORT_SYMBOL_GPL(filter_match_preds);
508 557
@@ -628,22 +677,6 @@ find_event_field(struct ftrace_event_call *call, char *name)
628 return __find_event_field(head, name); 677 return __find_event_field(head, name);
629} 678}
630 679
631static void filter_free_pred(struct filter_pred *pred)
632{
633 if (!pred)
634 return;
635
636 kfree(pred->field_name);
637 kfree(pred);
638}
639
640static void filter_clear_pred(struct filter_pred *pred)
641{
642 kfree(pred->field_name);
643 pred->field_name = NULL;
644 pred->regex.len = 0;
645}
646
647static int __alloc_pred_stack(struct pred_stack *stack, int n_preds) 680static int __alloc_pred_stack(struct pred_stack *stack, int n_preds)
648{ 681{
649 stack->preds = kzalloc(sizeof(*stack->preds)*(n_preds + 1), GFP_KERNEL); 682 stack->preds = kzalloc(sizeof(*stack->preds)*(n_preds + 1), GFP_KERNEL);
@@ -689,20 +722,13 @@ __pop_pred_stack(struct pred_stack *stack)
689static int filter_set_pred(struct event_filter *filter, 722static int filter_set_pred(struct event_filter *filter,
690 int idx, 723 int idx,
691 struct pred_stack *stack, 724 struct pred_stack *stack,
692 struct filter_pred *src, 725 struct filter_pred *src)
693 filter_pred_fn_t fn)
694{ 726{
695 struct filter_pred *dest = &filter->preds[idx]; 727 struct filter_pred *dest = &filter->preds[idx];
696 struct filter_pred *left; 728 struct filter_pred *left;
697 struct filter_pred *right; 729 struct filter_pred *right;
698 730
699 *dest = *src; 731 *dest = *src;
700 if (src->field_name) {
701 dest->field_name = kstrdup(src->field_name, GFP_KERNEL);
702 if (!dest->field_name)
703 return -ENOMEM;
704 }
705 dest->fn = fn;
706 dest->index = idx; 732 dest->index = idx;
707 733
708 if (dest->op == OP_OR || dest->op == OP_AND) { 734 if (dest->op == OP_OR || dest->op == OP_AND) {
@@ -743,11 +769,7 @@ static int filter_set_pred(struct event_filter *filter,
743 769
744static void __free_preds(struct event_filter *filter) 770static void __free_preds(struct event_filter *filter)
745{ 771{
746 int i;
747
748 if (filter->preds) { 772 if (filter->preds) {
749 for (i = 0; i < filter->a_preds; i++)
750 kfree(filter->preds[i].field_name);
751 kfree(filter->preds); 773 kfree(filter->preds);
752 filter->preds = NULL; 774 filter->preds = NULL;
753 } 775 }
@@ -840,23 +862,19 @@ static void filter_free_subsystem_filters(struct event_subsystem *system)
840 } 862 }
841} 863}
842 864
843static int filter_add_pred_fn(struct filter_parse_state *ps, 865static int filter_add_pred(struct filter_parse_state *ps,
844 struct ftrace_event_call *call, 866 struct event_filter *filter,
845 struct event_filter *filter, 867 struct filter_pred *pred,
846 struct filter_pred *pred, 868 struct pred_stack *stack)
847 struct pred_stack *stack,
848 filter_pred_fn_t fn)
849{ 869{
850 int idx, err; 870 int err;
851 871
852 if (WARN_ON(filter->n_preds == filter->a_preds)) { 872 if (WARN_ON(filter->n_preds == filter->a_preds)) {
853 parse_error(ps, FILT_ERR_TOO_MANY_PREDS, 0); 873 parse_error(ps, FILT_ERR_TOO_MANY_PREDS, 0);
854 return -ENOSPC; 874 return -ENOSPC;
855 } 875 }
856 876
857 idx = filter->n_preds; 877 err = filter_set_pred(filter, filter->n_preds, stack, pred);
858 filter_clear_pred(&filter->preds[idx]);
859 err = filter_set_pred(filter, idx, stack, pred, fn);
860 if (err) 878 if (err)
861 return err; 879 return err;
862 880
@@ -937,31 +955,15 @@ static filter_pred_fn_t select_comparison_fn(int op, int field_size,
937 return fn; 955 return fn;
938} 956}
939 957
940static int filter_add_pred(struct filter_parse_state *ps, 958static int init_pred(struct filter_parse_state *ps,
941 struct ftrace_event_call *call, 959 struct ftrace_event_field *field,
942 struct event_filter *filter, 960 struct filter_pred *pred)
943 struct filter_pred *pred, 961
944 struct pred_stack *stack,
945 bool dry_run)
946{ 962{
947 struct ftrace_event_field *field; 963 filter_pred_fn_t fn = filter_pred_none;
948 filter_pred_fn_t fn;
949 unsigned long long val; 964 unsigned long long val;
950 int ret; 965 int ret;
951 966
952 fn = pred->fn = filter_pred_none;
953
954 if (pred->op == OP_AND)
955 goto add_pred_fn;
956 else if (pred->op == OP_OR)
957 goto add_pred_fn;
958
959 field = find_event_field(call, pred->field_name);
960 if (!field) {
961 parse_error(ps, FILT_ERR_FIELD_NOT_FOUND, 0);
962 return -EINVAL;
963 }
964
965 pred->offset = field->offset; 967 pred->offset = field->offset;
966 968
967 if (!is_legal_op(field, pred->op)) { 969 if (!is_legal_op(field, pred->op)) {
@@ -1001,9 +1003,7 @@ static int filter_add_pred(struct filter_parse_state *ps,
1001 if (pred->op == OP_NE) 1003 if (pred->op == OP_NE)
1002 pred->not = 1; 1004 pred->not = 1;
1003 1005
1004add_pred_fn: 1006 pred->fn = fn;
1005 if (!dry_run)
1006 return filter_add_pred_fn(ps, call, filter, pred, stack, fn);
1007 return 0; 1007 return 0;
1008} 1008}
1009 1009
@@ -1302,39 +1302,37 @@ parse_operand:
1302 return 0; 1302 return 0;
1303} 1303}
1304 1304
1305static struct filter_pred *create_pred(int op, char *operand1, char *operand2) 1305static struct filter_pred *create_pred(struct filter_parse_state *ps,
1306 struct ftrace_event_call *call,
1307 int op, char *operand1, char *operand2)
1306{ 1308{
1307 struct filter_pred *pred; 1309 struct ftrace_event_field *field;
1310 static struct filter_pred pred;
1308 1311
1309 pred = kzalloc(sizeof(*pred), GFP_KERNEL); 1312 memset(&pred, 0, sizeof(pred));
1310 if (!pred) 1313 pred.op = op;
1311 return NULL;
1312 1314
1313 pred->field_name = kstrdup(operand1, GFP_KERNEL); 1315 if (op == OP_AND || op == OP_OR)
1314 if (!pred->field_name) { 1316 return &pred;
1315 kfree(pred); 1317
1318 if (!operand1 || !operand2) {
1319 parse_error(ps, FILT_ERR_MISSING_FIELD, 0);
1316 return NULL; 1320 return NULL;
1317 } 1321 }
1318 1322
1319 strcpy(pred->regex.pattern, operand2); 1323 field = find_event_field(call, operand1);
1320 pred->regex.len = strlen(pred->regex.pattern); 1324 if (!field) {
1321 1325 parse_error(ps, FILT_ERR_FIELD_NOT_FOUND, 0);
1322 pred->op = op;
1323
1324 return pred;
1325}
1326
1327static struct filter_pred *create_logical_pred(int op)
1328{
1329 struct filter_pred *pred;
1330
1331 pred = kzalloc(sizeof(*pred), GFP_KERNEL);
1332 if (!pred)
1333 return NULL; 1326 return NULL;
1327 }
1334 1328
1335 pred->op = op; 1329 strcpy(pred.regex.pattern, operand2);
1330 pred.regex.len = strlen(pred.regex.pattern);
1336 1331
1337 return pred; 1332#ifdef CONFIG_FTRACE_STARTUP_TEST
1333 pred.field = field;
1334#endif
1335 return init_pred(ps, field, &pred) ? NULL : &pred;
1338} 1336}
1339 1337
1340static int check_preds(struct filter_parse_state *ps) 1338static int check_preds(struct filter_parse_state *ps)
@@ -1375,6 +1373,23 @@ static int count_preds(struct filter_parse_state *ps)
1375 return n_preds; 1373 return n_preds;
1376} 1374}
1377 1375
1376struct check_pred_data {
1377 int count;
1378 int max;
1379};
1380
1381static int check_pred_tree_cb(enum move_type move, struct filter_pred *pred,
1382 int *err, void *data)
1383{
1384 struct check_pred_data *d = data;
1385
1386 if (WARN_ON(d->count++ > d->max)) {
1387 *err = -EINVAL;
1388 return WALK_PRED_ABORT;
1389 }
1390 return WALK_PRED_DEFAULT;
1391}
1392
1378/* 1393/*
1379 * The tree is walked at filtering of an event. If the tree is not correctly 1394 * The tree is walked at filtering of an event. If the tree is not correctly
1380 * built, it may cause an infinite loop. Check here that the tree does 1395 * built, it may cause an infinite loop. Check here that the tree does
@@ -1383,107 +1398,76 @@ static int count_preds(struct filter_parse_state *ps)
1383static int check_pred_tree(struct event_filter *filter, 1398static int check_pred_tree(struct event_filter *filter,
1384 struct filter_pred *root) 1399 struct filter_pred *root)
1385{ 1400{
1386 struct filter_pred *preds; 1401 struct check_pred_data data = {
1387 struct filter_pred *pred; 1402 /*
1388 enum move_type move = MOVE_DOWN; 1403 * The max that we can hit a node is three times.
1389 int count = 0; 1404 * Once going down, once coming up from left, and
1390 int done = 0; 1405 * once coming up from right. This is more than enough
1391 int max; 1406 * since leafs are only hit a single time.
1392 1407 */
1393 /* 1408 .max = 3 * filter->n_preds,
1394 * The max that we can hit a node is three times. 1409 .count = 0,
1395 * Once going down, once coming up from left, and 1410 };
1396 * once coming up from right. This is more than enough
1397 * since leafs are only hit a single time.
1398 */
1399 max = 3 * filter->n_preds;
1400 1411
1401 preds = filter->preds; 1412 return walk_pred_tree(filter->preds, root,
1402 if (!preds) 1413 check_pred_tree_cb, &data);
1403 return -EINVAL; 1414}
1404 pred = root;
1405 1415
1406 do { 1416static int count_leafs_cb(enum move_type move, struct filter_pred *pred,
1407 if (WARN_ON(count++ > max)) 1417 int *err, void *data)
1408 return -EINVAL; 1418{
1419 int *count = data;
1409 1420
1410 switch (move) { 1421 if ((move == MOVE_DOWN) &&
1411 case MOVE_DOWN: 1422 (pred->left == FILTER_PRED_INVALID))
1412 if (pred->left != FILTER_PRED_INVALID) { 1423 (*count)++;
1413 pred = &preds[pred->left];
1414 continue;
1415 }
1416 /* A leaf at the root is just a leaf in the tree */
1417 if (pred == root)
1418 break;
1419 pred = get_pred_parent(pred, preds,
1420 pred->parent, &move);
1421 continue;
1422 case MOVE_UP_FROM_LEFT:
1423 pred = &preds[pred->right];
1424 move = MOVE_DOWN;
1425 continue;
1426 case MOVE_UP_FROM_RIGHT:
1427 if (pred == root)
1428 break;
1429 pred = get_pred_parent(pred, preds,
1430 pred->parent, &move);
1431 continue;
1432 }
1433 done = 1;
1434 } while (!done);
1435 1424
1436 /* We are fine. */ 1425 return WALK_PRED_DEFAULT;
1437 return 0;
1438} 1426}
1439 1427
1440static int count_leafs(struct filter_pred *preds, struct filter_pred *root) 1428static int count_leafs(struct filter_pred *preds, struct filter_pred *root)
1441{ 1429{
1442 struct filter_pred *pred; 1430 int count = 0, ret;
1443 enum move_type move = MOVE_DOWN;
1444 int count = 0;
1445 int done = 0;
1446 1431
1447 pred = root; 1432 ret = walk_pred_tree(preds, root, count_leafs_cb, &count);
1433 WARN_ON(ret);
1434 return count;
1435}
1448 1436
1449 do { 1437struct fold_pred_data {
1450 switch (move) { 1438 struct filter_pred *root;
1451 case MOVE_DOWN: 1439 int count;
1452 if (pred->left != FILTER_PRED_INVALID) { 1440 int children;
1453 pred = &preds[pred->left]; 1441};
1454 continue;
1455 }
1456 /* A leaf at the root is just a leaf in the tree */
1457 if (pred == root)
1458 return 1;
1459 count++;
1460 pred = get_pred_parent(pred, preds,
1461 pred->parent, &move);
1462 continue;
1463 case MOVE_UP_FROM_LEFT:
1464 pred = &preds[pred->right];
1465 move = MOVE_DOWN;
1466 continue;
1467 case MOVE_UP_FROM_RIGHT:
1468 if (pred == root)
1469 break;
1470 pred = get_pred_parent(pred, preds,
1471 pred->parent, &move);
1472 continue;
1473 }
1474 done = 1;
1475 } while (!done);
1476 1442
1477 return count; 1443static int fold_pred_cb(enum move_type move, struct filter_pred *pred,
1444 int *err, void *data)
1445{
1446 struct fold_pred_data *d = data;
1447 struct filter_pred *root = d->root;
1448
1449 if (move != MOVE_DOWN)
1450 return WALK_PRED_DEFAULT;
1451 if (pred->left != FILTER_PRED_INVALID)
1452 return WALK_PRED_DEFAULT;
1453
1454 if (WARN_ON(d->count == d->children)) {
1455 *err = -EINVAL;
1456 return WALK_PRED_ABORT;
1457 }
1458
1459 pred->index &= ~FILTER_PRED_FOLD;
1460 root->ops[d->count++] = pred->index;
1461 return WALK_PRED_DEFAULT;
1478} 1462}
1479 1463
1480static int fold_pred(struct filter_pred *preds, struct filter_pred *root) 1464static int fold_pred(struct filter_pred *preds, struct filter_pred *root)
1481{ 1465{
1482 struct filter_pred *pred; 1466 struct fold_pred_data data = {
1483 enum move_type move = MOVE_DOWN; 1467 .root = root,
1484 int count = 0; 1468 .count = 0,
1469 };
1485 int children; 1470 int children;
1486 int done = 0;
1487 1471
1488 /* No need to keep the fold flag */ 1472 /* No need to keep the fold flag */
1489 root->index &= ~FILTER_PRED_FOLD; 1473 root->index &= ~FILTER_PRED_FOLD;
@@ -1501,37 +1485,26 @@ static int fold_pred(struct filter_pred *preds, struct filter_pred *root)
1501 return -ENOMEM; 1485 return -ENOMEM;
1502 1486
1503 root->val = children; 1487 root->val = children;
1488 data.children = children;
1489 return walk_pred_tree(preds, root, fold_pred_cb, &data);
1490}
1504 1491
1505 pred = root; 1492static int fold_pred_tree_cb(enum move_type move, struct filter_pred *pred,
1506 do { 1493 int *err, void *data)
1507 switch (move) { 1494{
1508 case MOVE_DOWN: 1495 struct filter_pred *preds = data;
1509 if (pred->left != FILTER_PRED_INVALID) {
1510 pred = &preds[pred->left];
1511 continue;
1512 }
1513 if (WARN_ON(count == children))
1514 return -EINVAL;
1515 pred->index &= ~FILTER_PRED_FOLD;
1516 root->ops[count++] = pred->index;
1517 pred = get_pred_parent(pred, preds,
1518 pred->parent, &move);
1519 continue;
1520 case MOVE_UP_FROM_LEFT:
1521 pred = &preds[pred->right];
1522 move = MOVE_DOWN;
1523 continue;
1524 case MOVE_UP_FROM_RIGHT:
1525 if (pred == root)
1526 break;
1527 pred = get_pred_parent(pred, preds,
1528 pred->parent, &move);
1529 continue;
1530 }
1531 done = 1;
1532 } while (!done);
1533 1496
1534 return 0; 1497 if (move != MOVE_DOWN)
1498 return WALK_PRED_DEFAULT;
1499 if (!(pred->index & FILTER_PRED_FOLD))
1500 return WALK_PRED_DEFAULT;
1501
1502 *err = fold_pred(preds, pred);
1503 if (*err)
1504 return WALK_PRED_ABORT;
1505
1506 /* eveyrhing below is folded, continue with parent */
1507 return WALK_PRED_PARENT;
1535} 1508}
1536 1509
1537/* 1510/*
@@ -1542,51 +1515,8 @@ static int fold_pred(struct filter_pred *preds, struct filter_pred *root)
1542static int fold_pred_tree(struct event_filter *filter, 1515static int fold_pred_tree(struct event_filter *filter,
1543 struct filter_pred *root) 1516 struct filter_pred *root)
1544{ 1517{
1545 struct filter_pred *preds; 1518 return walk_pred_tree(filter->preds, root, fold_pred_tree_cb,
1546 struct filter_pred *pred; 1519 filter->preds);
1547 enum move_type move = MOVE_DOWN;
1548 int done = 0;
1549 int err;
1550
1551 preds = filter->preds;
1552 if (!preds)
1553 return -EINVAL;
1554 pred = root;
1555
1556 do {
1557 switch (move) {
1558 case MOVE_DOWN:
1559 if (pred->index & FILTER_PRED_FOLD) {
1560 err = fold_pred(preds, pred);
1561 if (err)
1562 return err;
1563 /* Folded nodes are like leafs */
1564 } else if (pred->left != FILTER_PRED_INVALID) {
1565 pred = &preds[pred->left];
1566 continue;
1567 }
1568
1569 /* A leaf at the root is just a leaf in the tree */
1570 if (pred == root)
1571 break;
1572 pred = get_pred_parent(pred, preds,
1573 pred->parent, &move);
1574 continue;
1575 case MOVE_UP_FROM_LEFT:
1576 pred = &preds[pred->right];
1577 move = MOVE_DOWN;
1578 continue;
1579 case MOVE_UP_FROM_RIGHT:
1580 if (pred == root)
1581 break;
1582 pred = get_pred_parent(pred, preds,
1583 pred->parent, &move);
1584 continue;
1585 }
1586 done = 1;
1587 } while (!done);
1588
1589 return 0;
1590} 1520}
1591 1521
1592static int replace_preds(struct ftrace_event_call *call, 1522static int replace_preds(struct ftrace_event_call *call,
@@ -1643,27 +1573,17 @@ static int replace_preds(struct ftrace_event_call *call,
1643 goto fail; 1573 goto fail;
1644 } 1574 }
1645 1575
1646 if (elt->op == OP_AND || elt->op == OP_OR) { 1576 pred = create_pred(ps, call, elt->op, operand1, operand2);
1647 pred = create_logical_pred(elt->op); 1577 if (!pred) {
1648 goto add_pred;
1649 }
1650
1651 if (!operand1 || !operand2) {
1652 parse_error(ps, FILT_ERR_MISSING_FIELD, 0);
1653 err = -EINVAL; 1578 err = -EINVAL;
1654 goto fail; 1579 goto fail;
1655 } 1580 }
1656 1581
1657 pred = create_pred(elt->op, operand1, operand2); 1582 if (!dry_run) {
1658add_pred: 1583 err = filter_add_pred(ps, filter, pred, &stack);
1659 if (!pred) { 1584 if (err)
1660 err = -ENOMEM; 1585 goto fail;
1661 goto fail;
1662 } 1586 }
1663 err = filter_add_pred(ps, call, filter, pred, &stack, dry_run);
1664 filter_free_pred(pred);
1665 if (err)
1666 goto fail;
1667 1587
1668 operand1 = operand2 = NULL; 1588 operand1 = operand2 = NULL;
1669 } 1589 }
@@ -1958,17 +1878,14 @@ int ftrace_profile_set_filter(struct perf_event *event, int event_id,
1958 int err; 1878 int err;
1959 struct event_filter *filter; 1879 struct event_filter *filter;
1960 struct filter_parse_state *ps; 1880 struct filter_parse_state *ps;
1961 struct ftrace_event_call *call = NULL; 1881 struct ftrace_event_call *call;
1962 1882
1963 mutex_lock(&event_mutex); 1883 mutex_lock(&event_mutex);
1964 1884
1965 list_for_each_entry(call, &ftrace_events, list) { 1885 call = event->tp_event;
1966 if (call->event.type == event_id)
1967 break;
1968 }
1969 1886
1970 err = -EINVAL; 1887 err = -EINVAL;
1971 if (&call->list == &ftrace_events) 1888 if (!call)
1972 goto out_unlock; 1889 goto out_unlock;
1973 1890
1974 err = -EEXIST; 1891 err = -EEXIST;
@@ -2012,3 +1929,215 @@ out_unlock:
2012 1929
2013#endif /* CONFIG_PERF_EVENTS */ 1930#endif /* CONFIG_PERF_EVENTS */
2014 1931
1932#ifdef CONFIG_FTRACE_STARTUP_TEST
1933
1934#include <linux/types.h>
1935#include <linux/tracepoint.h>
1936
1937#define CREATE_TRACE_POINTS
1938#include "trace_events_filter_test.h"
1939
1940static int test_get_filter(char *filter_str, struct ftrace_event_call *call,
1941 struct event_filter **pfilter)
1942{
1943 struct event_filter *filter;
1944 struct filter_parse_state *ps;
1945 int err = -ENOMEM;
1946
1947 filter = __alloc_filter();
1948 if (!filter)
1949 goto out;
1950
1951 ps = kzalloc(sizeof(*ps), GFP_KERNEL);
1952 if (!ps)
1953 goto free_filter;
1954
1955 parse_init(ps, filter_ops, filter_str);
1956 err = filter_parse(ps);
1957 if (err)
1958 goto free_ps;
1959
1960 err = replace_preds(call, filter, ps, filter_str, false);
1961 if (!err)
1962 *pfilter = filter;
1963
1964 free_ps:
1965 filter_opstack_clear(ps);
1966 postfix_clear(ps);
1967 kfree(ps);
1968
1969 free_filter:
1970 if (err)
1971 __free_filter(filter);
1972
1973 out:
1974 return err;
1975}
1976
1977#define DATA_REC(m, va, vb, vc, vd, ve, vf, vg, vh, nvisit) \
1978{ \
1979 .filter = FILTER, \
1980 .rec = { .a = va, .b = vb, .c = vc, .d = vd, \
1981 .e = ve, .f = vf, .g = vg, .h = vh }, \
1982 .match = m, \
1983 .not_visited = nvisit, \
1984}
1985#define YES 1
1986#define NO 0
1987
1988static struct test_filter_data_t {
1989 char *filter;
1990 struct ftrace_raw_ftrace_test_filter rec;
1991 int match;
1992 char *not_visited;
1993} test_filter_data[] = {
1994#define FILTER "a == 1 && b == 1 && c == 1 && d == 1 && " \
1995 "e == 1 && f == 1 && g == 1 && h == 1"
1996 DATA_REC(YES, 1, 1, 1, 1, 1, 1, 1, 1, ""),
1997 DATA_REC(NO, 0, 1, 1, 1, 1, 1, 1, 1, "bcdefgh"),
1998 DATA_REC(NO, 1, 1, 1, 1, 1, 1, 1, 0, ""),
1999#undef FILTER
2000#define FILTER "a == 1 || b == 1 || c == 1 || d == 1 || " \
2001 "e == 1 || f == 1 || g == 1 || h == 1"
2002 DATA_REC(NO, 0, 0, 0, 0, 0, 0, 0, 0, ""),
2003 DATA_REC(YES, 0, 0, 0, 0, 0, 0, 0, 1, ""),
2004 DATA_REC(YES, 1, 0, 0, 0, 0, 0, 0, 0, "bcdefgh"),
2005#undef FILTER
2006#define FILTER "(a == 1 || b == 1) && (c == 1 || d == 1) && " \
2007 "(e == 1 || f == 1) && (g == 1 || h == 1)"
2008 DATA_REC(NO, 0, 0, 1, 1, 1, 1, 1, 1, "dfh"),
2009 DATA_REC(YES, 0, 1, 0, 1, 0, 1, 0, 1, ""),
2010 DATA_REC(YES, 1, 0, 1, 0, 0, 1, 0, 1, "bd"),
2011 DATA_REC(NO, 1, 0, 1, 0, 0, 1, 0, 0, "bd"),
2012#undef FILTER
2013#define FILTER "(a == 1 && b == 1) || (c == 1 && d == 1) || " \
2014 "(e == 1 && f == 1) || (g == 1 && h == 1)"
2015 DATA_REC(YES, 1, 0, 1, 1, 1, 1, 1, 1, "efgh"),
2016 DATA_REC(YES, 0, 0, 0, 0, 0, 0, 1, 1, ""),
2017 DATA_REC(NO, 0, 0, 0, 0, 0, 0, 0, 1, ""),
2018#undef FILTER
2019#define FILTER "(a == 1 && b == 1) && (c == 1 && d == 1) && " \
2020 "(e == 1 && f == 1) || (g == 1 && h == 1)"
2021 DATA_REC(YES, 1, 1, 1, 1, 1, 1, 0, 0, "gh"),
2022 DATA_REC(NO, 0, 0, 0, 0, 0, 0, 0, 1, ""),
2023 DATA_REC(YES, 1, 1, 1, 1, 1, 0, 1, 1, ""),
2024#undef FILTER
2025#define FILTER "((a == 1 || b == 1) || (c == 1 || d == 1) || " \
2026 "(e == 1 || f == 1)) && (g == 1 || h == 1)"
2027 DATA_REC(YES, 1, 1, 1, 1, 1, 1, 0, 1, "bcdef"),
2028 DATA_REC(NO, 0, 0, 0, 0, 0, 0, 0, 0, ""),
2029 DATA_REC(YES, 1, 1, 1, 1, 1, 0, 1, 1, "h"),
2030#undef FILTER
2031#define FILTER "((((((((a == 1) && (b == 1)) || (c == 1)) && (d == 1)) || " \
2032 "(e == 1)) && (f == 1)) || (g == 1)) && (h == 1))"
2033 DATA_REC(YES, 1, 1, 1, 1, 1, 1, 1, 1, "ceg"),
2034 DATA_REC(NO, 0, 1, 0, 1, 0, 1, 0, 1, ""),
2035 DATA_REC(NO, 1, 0, 1, 0, 1, 0, 1, 0, ""),
2036#undef FILTER
2037#define FILTER "((((((((a == 1) || (b == 1)) && (c == 1)) || (d == 1)) && " \
2038 "(e == 1)) || (f == 1)) && (g == 1)) || (h == 1))"
2039 DATA_REC(YES, 1, 1, 1, 1, 1, 1, 1, 1, "bdfh"),
2040 DATA_REC(YES, 0, 1, 0, 1, 0, 1, 0, 1, ""),
2041 DATA_REC(YES, 1, 0, 1, 0, 1, 0, 1, 0, "bdfh"),
2042};
2043
2044#undef DATA_REC
2045#undef FILTER
2046#undef YES
2047#undef NO
2048
2049#define DATA_CNT (sizeof(test_filter_data)/sizeof(struct test_filter_data_t))
2050
2051static int test_pred_visited;
2052
2053static int test_pred_visited_fn(struct filter_pred *pred, void *event)
2054{
2055 struct ftrace_event_field *field = pred->field;
2056
2057 test_pred_visited = 1;
2058 printk(KERN_INFO "\npred visited %s\n", field->name);
2059 return 1;
2060}
2061
2062static int test_walk_pred_cb(enum move_type move, struct filter_pred *pred,
2063 int *err, void *data)
2064{
2065 char *fields = data;
2066
2067 if ((move == MOVE_DOWN) &&
2068 (pred->left == FILTER_PRED_INVALID)) {
2069 struct ftrace_event_field *field = pred->field;
2070
2071 if (!field) {
2072 WARN(1, "all leafs should have field defined");
2073 return WALK_PRED_DEFAULT;
2074 }
2075 if (!strchr(fields, *field->name))
2076 return WALK_PRED_DEFAULT;
2077
2078 WARN_ON(!pred->fn);
2079 pred->fn = test_pred_visited_fn;
2080 }
2081 return WALK_PRED_DEFAULT;
2082}
2083
2084static __init int ftrace_test_event_filter(void)
2085{
2086 int i;
2087
2088 printk(KERN_INFO "Testing ftrace filter: ");
2089
2090 for (i = 0; i < DATA_CNT; i++) {
2091 struct event_filter *filter = NULL;
2092 struct test_filter_data_t *d = &test_filter_data[i];
2093 int err;
2094
2095 err = test_get_filter(d->filter, &event_ftrace_test_filter,
2096 &filter);
2097 if (err) {
2098 printk(KERN_INFO
2099 "Failed to get filter for '%s', err %d\n",
2100 d->filter, err);
2101 break;
2102 }
2103
2104 /*
2105 * The preemption disabling is not really needed for self
2106 * tests, but the rcu dereference will complain without it.
2107 */
2108 preempt_disable();
2109 if (*d->not_visited)
2110 walk_pred_tree(filter->preds, filter->root,
2111 test_walk_pred_cb,
2112 d->not_visited);
2113
2114 test_pred_visited = 0;
2115 err = filter_match_preds(filter, &d->rec);
2116 preempt_enable();
2117
2118 __free_filter(filter);
2119
2120 if (test_pred_visited) {
2121 printk(KERN_INFO
2122 "Failed, unwanted pred visited for filter %s\n",
2123 d->filter);
2124 break;
2125 }
2126
2127 if (err != d->match) {
2128 printk(KERN_INFO
2129 "Failed to match filter '%s', expected %d\n",
2130 d->filter, d->match);
2131 break;
2132 }
2133 }
2134
2135 if (i == DATA_CNT)
2136 printk(KERN_CONT "OK\n");
2137
2138 return 0;
2139}
2140
2141late_initcall(ftrace_test_event_filter);
2142
2143#endif /* CONFIG_FTRACE_STARTUP_TEST */
diff --git a/kernel/trace/trace_events_filter_test.h b/kernel/trace/trace_events_filter_test.h
new file mode 100644
index 000000000000..bfd4dba0d603
--- /dev/null
+++ b/kernel/trace/trace_events_filter_test.h
@@ -0,0 +1,50 @@
1#undef TRACE_SYSTEM
2#define TRACE_SYSTEM test
3
4#if !defined(_TRACE_TEST_H) || defined(TRACE_HEADER_MULTI_READ)
5#define _TRACE_TEST_H
6
7#include <linux/tracepoint.h>
8
9TRACE_EVENT(ftrace_test_filter,
10
11 TP_PROTO(int a, int b, int c, int d, int e, int f, int g, int h),
12
13 TP_ARGS(a, b, c, d, e, f, g, h),
14
15 TP_STRUCT__entry(
16 __field(int, a)
17 __field(int, b)
18 __field(int, c)
19 __field(int, d)
20 __field(int, e)
21 __field(int, f)
22 __field(int, g)
23 __field(int, h)
24 ),
25
26 TP_fast_assign(
27 __entry->a = a;
28 __entry->b = b;
29 __entry->c = c;
30 __entry->d = d;
31 __entry->e = e;
32 __entry->f = f;
33 __entry->g = g;
34 __entry->h = h;
35 ),
36
37 TP_printk("a %d, b %d, c %d, d %d, e %d, f %d, g %d, h %d",
38 __entry->a, __entry->b, __entry->c, __entry->d,
39 __entry->e, __entry->f, __entry->g, __entry->h)
40);
41
42#endif /* _TRACE_TEST_H || TRACE_HEADER_MULTI_READ */
43
44#undef TRACE_INCLUDE_PATH
45#undef TRACE_INCLUDE_FILE
46#define TRACE_INCLUDE_PATH .
47#define TRACE_INCLUDE_FILE trace_events_filter_test
48
49/* This part must be outside protection */
50#include <trace/define_trace.h>
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index 11186212068c..20dad0d7a163 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -505,13 +505,13 @@ EXPORT_SYMBOL(trace_hardirqs_off_caller);
505#ifdef CONFIG_PREEMPT_TRACER 505#ifdef CONFIG_PREEMPT_TRACER
506void trace_preempt_on(unsigned long a0, unsigned long a1) 506void trace_preempt_on(unsigned long a0, unsigned long a1)
507{ 507{
508 if (preempt_trace()) 508 if (preempt_trace() && !irq_trace())
509 stop_critical_timing(a0, a1); 509 stop_critical_timing(a0, a1);
510} 510}
511 511
512void trace_preempt_off(unsigned long a0, unsigned long a1) 512void trace_preempt_off(unsigned long a0, unsigned long a1)
513{ 513{
514 if (preempt_trace()) 514 if (preempt_trace() && !irq_trace())
515 start_critical_timing(a0, a1); 515 start_critical_timing(a0, a1);
516} 516}
517#endif /* CONFIG_PREEMPT_TRACER */ 517#endif /* CONFIG_PREEMPT_TRACER */
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 5fb3697bf0e5..00d527c945a4 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -836,11 +836,17 @@ static void __unregister_trace_probe(struct trace_probe *tp)
836} 836}
837 837
838/* Unregister a trace_probe and probe_event: call with locking probe_lock */ 838/* Unregister a trace_probe and probe_event: call with locking probe_lock */
839static void unregister_trace_probe(struct trace_probe *tp) 839static int unregister_trace_probe(struct trace_probe *tp)
840{ 840{
841 /* Enabled event can not be unregistered */
842 if (trace_probe_is_enabled(tp))
843 return -EBUSY;
844
841 __unregister_trace_probe(tp); 845 __unregister_trace_probe(tp);
842 list_del(&tp->list); 846 list_del(&tp->list);
843 unregister_probe_event(tp); 847 unregister_probe_event(tp);
848
849 return 0;
844} 850}
845 851
846/* Register a trace_probe and probe_event */ 852/* Register a trace_probe and probe_event */
@@ -854,7 +860,9 @@ static int register_trace_probe(struct trace_probe *tp)
854 /* Delete old (same name) event if exist */ 860 /* Delete old (same name) event if exist */
855 old_tp = find_trace_probe(tp->call.name, tp->call.class->system); 861 old_tp = find_trace_probe(tp->call.name, tp->call.class->system);
856 if (old_tp) { 862 if (old_tp) {
857 unregister_trace_probe(old_tp); 863 ret = unregister_trace_probe(old_tp);
864 if (ret < 0)
865 goto end;
858 free_trace_probe(old_tp); 866 free_trace_probe(old_tp);
859 } 867 }
860 868
@@ -892,6 +900,7 @@ static int trace_probe_module_callback(struct notifier_block *nb,
892 mutex_lock(&probe_lock); 900 mutex_lock(&probe_lock);
893 list_for_each_entry(tp, &probe_list, list) { 901 list_for_each_entry(tp, &probe_list, list) {
894 if (trace_probe_within_module(tp, mod)) { 902 if (trace_probe_within_module(tp, mod)) {
903 /* Don't need to check busy - this should have gone. */
895 __unregister_trace_probe(tp); 904 __unregister_trace_probe(tp);
896 ret = __register_trace_probe(tp); 905 ret = __register_trace_probe(tp);
897 if (ret) 906 if (ret)
@@ -1205,10 +1214,11 @@ static int create_trace_probe(int argc, char **argv)
1205 return -ENOENT; 1214 return -ENOENT;
1206 } 1215 }
1207 /* delete an event */ 1216 /* delete an event */
1208 unregister_trace_probe(tp); 1217 ret = unregister_trace_probe(tp);
1209 free_trace_probe(tp); 1218 if (ret == 0)
1219 free_trace_probe(tp);
1210 mutex_unlock(&probe_lock); 1220 mutex_unlock(&probe_lock);
1211 return 0; 1221 return ret;
1212 } 1222 }
1213 1223
1214 if (argc < 2) { 1224 if (argc < 2) {
@@ -1317,18 +1327,29 @@ error:
1317 return ret; 1327 return ret;
1318} 1328}
1319 1329
1320static void release_all_trace_probes(void) 1330static int release_all_trace_probes(void)
1321{ 1331{
1322 struct trace_probe *tp; 1332 struct trace_probe *tp;
1333 int ret = 0;
1323 1334
1324 mutex_lock(&probe_lock); 1335 mutex_lock(&probe_lock);
1336 /* Ensure no probe is in use. */
1337 list_for_each_entry(tp, &probe_list, list)
1338 if (trace_probe_is_enabled(tp)) {
1339 ret = -EBUSY;
1340 goto end;
1341 }
1325 /* TODO: Use batch unregistration */ 1342 /* TODO: Use batch unregistration */
1326 while (!list_empty(&probe_list)) { 1343 while (!list_empty(&probe_list)) {
1327 tp = list_entry(probe_list.next, struct trace_probe, list); 1344 tp = list_entry(probe_list.next, struct trace_probe, list);
1328 unregister_trace_probe(tp); 1345 unregister_trace_probe(tp);
1329 free_trace_probe(tp); 1346 free_trace_probe(tp);
1330 } 1347 }
1348
1349end:
1331 mutex_unlock(&probe_lock); 1350 mutex_unlock(&probe_lock);
1351
1352 return ret;
1332} 1353}
1333 1354
1334/* Probes listing interfaces */ 1355/* Probes listing interfaces */
@@ -1380,9 +1401,13 @@ static const struct seq_operations probes_seq_op = {
1380 1401
1381static int probes_open(struct inode *inode, struct file *file) 1402static int probes_open(struct inode *inode, struct file *file)
1382{ 1403{
1383 if ((file->f_mode & FMODE_WRITE) && 1404 int ret;
1384 (file->f_flags & O_TRUNC)) 1405
1385 release_all_trace_probes(); 1406 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
1407 ret = release_all_trace_probes();
1408 if (ret < 0)
1409 return ret;
1410 }
1386 1411
1387 return seq_open(file, &probes_seq_op); 1412 return seq_open(file, &probes_seq_op);
1388} 1413}
@@ -2055,6 +2080,21 @@ static __init int kprobe_trace_self_tests_init(void)
2055 2080
2056 ret = target(1, 2, 3, 4, 5, 6); 2081 ret = target(1, 2, 3, 4, 5, 6);
2057 2082
2083 /* Disable trace points before removing it */
2084 tp = find_trace_probe("testprobe", KPROBE_EVENT_SYSTEM);
2085 if (WARN_ON_ONCE(tp == NULL)) {
2086 pr_warning("error on getting test probe.\n");
2087 warn++;
2088 } else
2089 disable_trace_probe(tp, TP_FLAG_TRACE);
2090
2091 tp = find_trace_probe("testprobe2", KPROBE_EVENT_SYSTEM);
2092 if (WARN_ON_ONCE(tp == NULL)) {
2093 pr_warning("error on getting 2nd test probe.\n");
2094 warn++;
2095 } else
2096 disable_trace_probe(tp, TP_FLAG_TRACE);
2097
2058 ret = command_trace_probe("-:testprobe"); 2098 ret = command_trace_probe("-:testprobe");
2059 if (WARN_ON_ONCE(ret)) { 2099 if (WARN_ON_ONCE(ret)) {
2060 pr_warning("error on deleting a probe.\n"); 2100 pr_warning("error on deleting a probe.\n");
diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
index 1f06468a10d7..6fd4ffd042f9 100644
--- a/kernel/trace/trace_printk.c
+++ b/kernel/trace/trace_printk.c
@@ -59,18 +59,19 @@ void hold_module_trace_bprintk_format(const char **start, const char **end)
59 continue; 59 continue;
60 } 60 }
61 61
62 fmt = NULL;
62 tb_fmt = kmalloc(sizeof(*tb_fmt), GFP_KERNEL); 63 tb_fmt = kmalloc(sizeof(*tb_fmt), GFP_KERNEL);
63 if (tb_fmt) 64 if (tb_fmt) {
64 fmt = kmalloc(strlen(*iter) + 1, GFP_KERNEL); 65 fmt = kmalloc(strlen(*iter) + 1, GFP_KERNEL);
65 if (tb_fmt && fmt) { 66 if (fmt) {
66 list_add_tail(&tb_fmt->list, &trace_bprintk_fmt_list); 67 list_add_tail(&tb_fmt->list, &trace_bprintk_fmt_list);
67 strcpy(fmt, *iter); 68 strcpy(fmt, *iter);
68 tb_fmt->fmt = fmt; 69 tb_fmt->fmt = fmt;
69 *iter = tb_fmt->fmt; 70 } else
70 } else { 71 kfree(tb_fmt);
71 kfree(tb_fmt);
72 *iter = NULL;
73 } 72 }
73 *iter = fmt;
74
74 } 75 }
75 mutex_unlock(&btrace_mutex); 76 mutex_unlock(&btrace_mutex);
76} 77}
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index b219f1449c54..db110b8ae030 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -34,11 +34,16 @@ extern struct tracepoint * const __stop___tracepoints_ptrs[];
34static const int tracepoint_debug; 34static const int tracepoint_debug;
35 35
36/* 36/*
37 * tracepoints_mutex nests inside module_mutex. Tracepoints mutex protects the 37 * Tracepoints mutex protects the builtin and module tracepoints and the hash
38 * builtin and module tracepoints and the hash table. 38 * table, as well as the local module list.
39 */ 39 */
40static DEFINE_MUTEX(tracepoints_mutex); 40static DEFINE_MUTEX(tracepoints_mutex);
41 41
42#ifdef CONFIG_MODULES
43/* Local list of struct module */
44static LIST_HEAD(tracepoint_module_list);
45#endif /* CONFIG_MODULES */
46
42/* 47/*
43 * Tracepoint hash table, containing the active tracepoints. 48 * Tracepoint hash table, containing the active tracepoints.
44 * Protected by tracepoints_mutex. 49 * Protected by tracepoints_mutex.
@@ -292,9 +297,10 @@ static void disable_tracepoint(struct tracepoint *elem)
292 * @end: end of the range 297 * @end: end of the range
293 * 298 *
294 * Updates the probe callback corresponding to a range of tracepoints. 299 * Updates the probe callback corresponding to a range of tracepoints.
300 * Called with tracepoints_mutex held.
295 */ 301 */
296void tracepoint_update_probe_range(struct tracepoint * const *begin, 302static void tracepoint_update_probe_range(struct tracepoint * const *begin,
297 struct tracepoint * const *end) 303 struct tracepoint * const *end)
298{ 304{
299 struct tracepoint * const *iter; 305 struct tracepoint * const *iter;
300 struct tracepoint_entry *mark_entry; 306 struct tracepoint_entry *mark_entry;
@@ -302,7 +308,6 @@ void tracepoint_update_probe_range(struct tracepoint * const *begin,
302 if (!begin) 308 if (!begin)
303 return; 309 return;
304 310
305 mutex_lock(&tracepoints_mutex);
306 for (iter = begin; iter < end; iter++) { 311 for (iter = begin; iter < end; iter++) {
307 mark_entry = get_tracepoint((*iter)->name); 312 mark_entry = get_tracepoint((*iter)->name);
308 if (mark_entry) { 313 if (mark_entry) {
@@ -312,11 +317,27 @@ void tracepoint_update_probe_range(struct tracepoint * const *begin,
312 disable_tracepoint(*iter); 317 disable_tracepoint(*iter);
313 } 318 }
314 } 319 }
315 mutex_unlock(&tracepoints_mutex);
316} 320}
317 321
322#ifdef CONFIG_MODULES
323void module_update_tracepoints(void)
324{
325 struct tp_module *tp_mod;
326
327 list_for_each_entry(tp_mod, &tracepoint_module_list, list)
328 tracepoint_update_probe_range(tp_mod->tracepoints_ptrs,
329 tp_mod->tracepoints_ptrs + tp_mod->num_tracepoints);
330}
331#else /* CONFIG_MODULES */
332void module_update_tracepoints(void)
333{
334}
335#endif /* CONFIG_MODULES */
336
337
318/* 338/*
319 * Update probes, removing the faulty probes. 339 * Update probes, removing the faulty probes.
340 * Called with tracepoints_mutex held.
320 */ 341 */
321static void tracepoint_update_probes(void) 342static void tracepoint_update_probes(void)
322{ 343{
@@ -359,11 +380,12 @@ int tracepoint_probe_register(const char *name, void *probe, void *data)
359 380
360 mutex_lock(&tracepoints_mutex); 381 mutex_lock(&tracepoints_mutex);
361 old = tracepoint_add_probe(name, probe, data); 382 old = tracepoint_add_probe(name, probe, data);
362 mutex_unlock(&tracepoints_mutex); 383 if (IS_ERR(old)) {
363 if (IS_ERR(old)) 384 mutex_unlock(&tracepoints_mutex);
364 return PTR_ERR(old); 385 return PTR_ERR(old);
365 386 }
366 tracepoint_update_probes(); /* may update entry */ 387 tracepoint_update_probes(); /* may update entry */
388 mutex_unlock(&tracepoints_mutex);
367 release_probes(old); 389 release_probes(old);
368 return 0; 390 return 0;
369} 391}
@@ -402,11 +424,12 @@ int tracepoint_probe_unregister(const char *name, void *probe, void *data)
402 424
403 mutex_lock(&tracepoints_mutex); 425 mutex_lock(&tracepoints_mutex);
404 old = tracepoint_remove_probe(name, probe, data); 426 old = tracepoint_remove_probe(name, probe, data);
405 mutex_unlock(&tracepoints_mutex); 427 if (IS_ERR(old)) {
406 if (IS_ERR(old)) 428 mutex_unlock(&tracepoints_mutex);
407 return PTR_ERR(old); 429 return PTR_ERR(old);
408 430 }
409 tracepoint_update_probes(); /* may update entry */ 431 tracepoint_update_probes(); /* may update entry */
432 mutex_unlock(&tracepoints_mutex);
410 release_probes(old); 433 release_probes(old);
411 return 0; 434 return 0;
412} 435}
@@ -489,9 +512,8 @@ void tracepoint_probe_update_all(void)
489 if (!list_empty(&old_probes)) 512 if (!list_empty(&old_probes))
490 list_replace_init(&old_probes, &release_probes); 513 list_replace_init(&old_probes, &release_probes);
491 need_update = 0; 514 need_update = 0;
492 mutex_unlock(&tracepoints_mutex);
493
494 tracepoint_update_probes(); 515 tracepoint_update_probes();
516 mutex_unlock(&tracepoints_mutex);
495 list_for_each_entry_safe(pos, next, &release_probes, u.list) { 517 list_for_each_entry_safe(pos, next, &release_probes, u.list) {
496 list_del(&pos->u.list); 518 list_del(&pos->u.list);
497 call_rcu_sched(&pos->u.rcu, rcu_free_old_probes); 519 call_rcu_sched(&pos->u.rcu, rcu_free_old_probes);
@@ -509,7 +531,7 @@ EXPORT_SYMBOL_GPL(tracepoint_probe_update_all);
509 * Will return the first tracepoint in the range if the input tracepoint is 531 * Will return the first tracepoint in the range if the input tracepoint is
510 * NULL. 532 * NULL.
511 */ 533 */
512int tracepoint_get_iter_range(struct tracepoint * const **tracepoint, 534static int tracepoint_get_iter_range(struct tracepoint * const **tracepoint,
513 struct tracepoint * const *begin, struct tracepoint * const *end) 535 struct tracepoint * const *begin, struct tracepoint * const *end)
514{ 536{
515 if (!*tracepoint && begin != end) { 537 if (!*tracepoint && begin != end) {
@@ -520,11 +542,12 @@ int tracepoint_get_iter_range(struct tracepoint * const **tracepoint,
520 return 1; 542 return 1;
521 return 0; 543 return 0;
522} 544}
523EXPORT_SYMBOL_GPL(tracepoint_get_iter_range);
524 545
546#ifdef CONFIG_MODULES
525static void tracepoint_get_iter(struct tracepoint_iter *iter) 547static void tracepoint_get_iter(struct tracepoint_iter *iter)
526{ 548{
527 int found = 0; 549 int found = 0;
550 struct tp_module *iter_mod;
528 551
529 /* Core kernel tracepoints */ 552 /* Core kernel tracepoints */
530 if (!iter->module) { 553 if (!iter->module) {
@@ -534,12 +557,43 @@ static void tracepoint_get_iter(struct tracepoint_iter *iter)
534 if (found) 557 if (found)
535 goto end; 558 goto end;
536 } 559 }
537 /* tracepoints in modules. */ 560 /* Tracepoints in modules */
538 found = module_get_iter_tracepoints(iter); 561 mutex_lock(&tracepoints_mutex);
562 list_for_each_entry(iter_mod, &tracepoint_module_list, list) {
563 /*
564 * Sorted module list
565 */
566 if (iter_mod < iter->module)
567 continue;
568 else if (iter_mod > iter->module)
569 iter->tracepoint = NULL;
570 found = tracepoint_get_iter_range(&iter->tracepoint,
571 iter_mod->tracepoints_ptrs,
572 iter_mod->tracepoints_ptrs
573 + iter_mod->num_tracepoints);
574 if (found) {
575 iter->module = iter_mod;
576 break;
577 }
578 }
579 mutex_unlock(&tracepoints_mutex);
539end: 580end:
540 if (!found) 581 if (!found)
541 tracepoint_iter_reset(iter); 582 tracepoint_iter_reset(iter);
542} 583}
584#else /* CONFIG_MODULES */
585static void tracepoint_get_iter(struct tracepoint_iter *iter)
586{
587 int found = 0;
588
589 /* Core kernel tracepoints */
590 found = tracepoint_get_iter_range(&iter->tracepoint,
591 __start___tracepoints_ptrs,
592 __stop___tracepoints_ptrs);
593 if (!found)
594 tracepoint_iter_reset(iter);
595}
596#endif /* CONFIG_MODULES */
543 597
544void tracepoint_iter_start(struct tracepoint_iter *iter) 598void tracepoint_iter_start(struct tracepoint_iter *iter)
545{ 599{
@@ -566,26 +620,98 @@ EXPORT_SYMBOL_GPL(tracepoint_iter_stop);
566 620
567void tracepoint_iter_reset(struct tracepoint_iter *iter) 621void tracepoint_iter_reset(struct tracepoint_iter *iter)
568{ 622{
623#ifdef CONFIG_MODULES
569 iter->module = NULL; 624 iter->module = NULL;
625#endif /* CONFIG_MODULES */
570 iter->tracepoint = NULL; 626 iter->tracepoint = NULL;
571} 627}
572EXPORT_SYMBOL_GPL(tracepoint_iter_reset); 628EXPORT_SYMBOL_GPL(tracepoint_iter_reset);
573 629
574#ifdef CONFIG_MODULES 630#ifdef CONFIG_MODULES
631static int tracepoint_module_coming(struct module *mod)
632{
633 struct tp_module *tp_mod, *iter;
634 int ret = 0;
635
636 /*
637 * We skip modules that tain the kernel, especially those with different
638 * module header (for forced load), to make sure we don't cause a crash.
639 */
640 if (mod->taints)
641 return 0;
642 mutex_lock(&tracepoints_mutex);
643 tp_mod = kmalloc(sizeof(struct tp_module), GFP_KERNEL);
644 if (!tp_mod) {
645 ret = -ENOMEM;
646 goto end;
647 }
648 tp_mod->num_tracepoints = mod->num_tracepoints;
649 tp_mod->tracepoints_ptrs = mod->tracepoints_ptrs;
650
651 /*
652 * tracepoint_module_list is kept sorted by struct module pointer
653 * address for iteration on tracepoints from a seq_file that can release
654 * the mutex between calls.
655 */
656 list_for_each_entry_reverse(iter, &tracepoint_module_list, list) {
657 BUG_ON(iter == tp_mod); /* Should never be in the list twice */
658 if (iter < tp_mod) {
659 /* We belong to the location right after iter. */
660 list_add(&tp_mod->list, &iter->list);
661 goto module_added;
662 }
663 }
664 /* We belong to the beginning of the list */
665 list_add(&tp_mod->list, &tracepoint_module_list);
666module_added:
667 tracepoint_update_probe_range(mod->tracepoints_ptrs,
668 mod->tracepoints_ptrs + mod->num_tracepoints);
669end:
670 mutex_unlock(&tracepoints_mutex);
671 return ret;
672}
673
674static int tracepoint_module_going(struct module *mod)
675{
676 struct tp_module *pos;
677
678 mutex_lock(&tracepoints_mutex);
679 tracepoint_update_probe_range(mod->tracepoints_ptrs,
680 mod->tracepoints_ptrs + mod->num_tracepoints);
681 list_for_each_entry(pos, &tracepoint_module_list, list) {
682 if (pos->tracepoints_ptrs == mod->tracepoints_ptrs) {
683 list_del(&pos->list);
684 kfree(pos);
685 break;
686 }
687 }
688 /*
689 * In the case of modules that were tainted at "coming", we'll simply
690 * walk through the list without finding it. We cannot use the "tainted"
691 * flag on "going", in case a module taints the kernel only after being
692 * loaded.
693 */
694 mutex_unlock(&tracepoints_mutex);
695 return 0;
696}
575 697
576int tracepoint_module_notify(struct notifier_block *self, 698int tracepoint_module_notify(struct notifier_block *self,
577 unsigned long val, void *data) 699 unsigned long val, void *data)
578{ 700{
579 struct module *mod = data; 701 struct module *mod = data;
702 int ret = 0;
580 703
581 switch (val) { 704 switch (val) {
582 case MODULE_STATE_COMING: 705 case MODULE_STATE_COMING:
706 ret = tracepoint_module_coming(mod);
707 break;
708 case MODULE_STATE_LIVE:
709 break;
583 case MODULE_STATE_GOING: 710 case MODULE_STATE_GOING:
584 tracepoint_update_probe_range(mod->tracepoints_ptrs, 711 ret = tracepoint_module_going(mod);
585 mod->tracepoints_ptrs + mod->num_tracepoints);
586 break; 712 break;
587 } 713 }
588 return 0; 714 return ret;
589} 715}
590 716
591struct notifier_block tracepoint_module_nb = { 717struct notifier_block tracepoint_module_nb = {
@@ -598,7 +724,6 @@ static int init_tracepoints(void)
598 return register_module_notifier(&tracepoint_module_nb); 724 return register_module_notifier(&tracepoint_module_nb);
599} 725}
600__initcall(init_tracepoints); 726__initcall(init_tracepoints);
601
602#endif /* CONFIG_MODULES */ 727#endif /* CONFIG_MODULES */
603 728
604#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS 729#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 36491cd5b7d4..d680381b0e9c 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -321,7 +321,7 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
321 */ 321 */
322static int watchdog(void *unused) 322static int watchdog(void *unused)
323{ 323{
324 static struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; 324 struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
325 struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer); 325 struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer);
326 326
327 sched_setscheduler(current, SCHED_FIFO, &param); 327 sched_setscheduler(current, SCHED_FIFO, &param);
@@ -350,7 +350,8 @@ static int watchdog(void *unused)
350 set_current_state(TASK_INTERRUPTIBLE); 350 set_current_state(TASK_INTERRUPTIBLE);
351 } 351 }
352 __set_current_state(TASK_RUNNING); 352 __set_current_state(TASK_RUNNING);
353 353 param.sched_priority = 0;
354 sched_setscheduler(current, SCHED_NORMAL, &param);
354 return 0; 355 return 0;
355} 356}
356 357
@@ -438,7 +439,7 @@ static int watchdog_enable(int cpu)
438 439
439 /* create the watchdog thread */ 440 /* create the watchdog thread */
440 if (!p) { 441 if (!p) {
441 p = kthread_create(watchdog, (void *)(unsigned long)cpu, "watchdog/%d", cpu); 442 p = kthread_create_on_node(watchdog, NULL, cpu_to_node(cpu), "watchdog/%d", cpu);
442 if (IS_ERR(p)) { 443 if (IS_ERR(p)) {
443 printk(KERN_ERR "softlockup watchdog for %i failed\n", cpu); 444 printk(KERN_ERR "softlockup watchdog for %i failed\n", cpu);
444 if (!err) { 445 if (!err) {
diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt
index 85c5f026930d..fe6762ed56bd 100644
--- a/tools/perf/Documentation/perf-annotate.txt
+++ b/tools/perf/Documentation/perf-annotate.txt
@@ -72,6 +72,19 @@ OPTIONS
72 CPUs are specified with -: 0-2. Default is to report samples on all 72 CPUs are specified with -: 0-2. Default is to report samples on all
73 CPUs. 73 CPUs.
74 74
75--asm-raw::
76 Show raw instruction encoding of assembly instructions.
77
78--source::
79 Interleave source code with assembly code. Enabled by default,
80 disable with --no-source.
81
82--symfs=<directory>::
83 Look for files with symbols relative to this directory.
84
85-M::
86--disassembler-style=:: Set disassembler style for objdump.
87
75SEE ALSO 88SEE ALSO
76-------- 89--------
77linkperf:perf-record[1], linkperf:perf-report[1] 90linkperf:perf-record[1], linkperf:perf-report[1]
diff --git a/tools/perf/Documentation/perf-buildid-list.txt b/tools/perf/Documentation/perf-buildid-list.txt
index 5eaac6f26d51..cc22325ffd1b 100644
--- a/tools/perf/Documentation/perf-buildid-list.txt
+++ b/tools/perf/Documentation/perf-buildid-list.txt
@@ -16,6 +16,9 @@ This command displays the buildids found in a perf.data file, so that other
16tools can be used to fetch packages with matching symbol tables for use by 16tools can be used to fetch packages with matching symbol tables for use by
17perf report. 17perf report.
18 18
19It can also be used to show the build id of the running kernel or in an ELF
20file using -i/--input.
21
19OPTIONS 22OPTIONS
20------- 23-------
21-H:: 24-H::
@@ -27,6 +30,9 @@ OPTIONS
27-f:: 30-f::
28--force:: 31--force::
29 Don't do ownership validation. 32 Don't do ownership validation.
33-k::
34--kernel::
35 Show running kernel build id.
30-v:: 36-v::
31--verbose:: 37--verbose::
32 Be more verbose. 38 Be more verbose.
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 04253c07d19a..212f24d672e1 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -134,6 +134,24 @@ OPTIONS
134 CPUs are specified with -: 0-2. Default is to report samples on all 134 CPUs are specified with -: 0-2. Default is to report samples on all
135 CPUs. 135 CPUs.
136 136
137-M::
138--disassembler-style=:: Set disassembler style for objdump.
139
140--source::
141 Interleave source code with assembly code. Enabled by default,
142 disable with --no-source.
143
144--asm-raw::
145 Show raw instruction encoding of assembly instructions.
146
147--show-total-period:: Show a column with the sum of periods.
148
149-I::
150--show-info::
151 Display extended information about the perf.data file. This adds
152 information which may be very large and thus may clutter the display.
153 It currently includes: cpu and numa topology of the host system.
154
137SEE ALSO 155SEE ALSO
138-------- 156--------
139linkperf:perf-stat[1] 157linkperf:perf-stat[1], linkperf:perf-annotate[1]
diff --git a/tools/perf/Documentation/perf-sched.txt b/tools/perf/Documentation/perf-sched.txt
index 46822d5fde1c..5b212b57f70b 100644
--- a/tools/perf/Documentation/perf-sched.txt
+++ b/tools/perf/Documentation/perf-sched.txt
@@ -8,7 +8,7 @@ perf-sched - Tool to trace/measure scheduler properties (latencies)
8SYNOPSIS 8SYNOPSIS
9-------- 9--------
10[verse] 10[verse]
11'perf sched' {record|latency|map|replay|trace} 11'perf sched' {record|latency|map|replay|script}
12 12
13DESCRIPTION 13DESCRIPTION
14----------- 14-----------
@@ -20,8 +20,8 @@ There are five variants of perf sched:
20 'perf sched latency' to report the per task scheduling latencies 20 'perf sched latency' to report the per task scheduling latencies
21 and other scheduling properties of the workload. 21 and other scheduling properties of the workload.
22 22
23 'perf sched trace' to see a detailed trace of the workload that 23 'perf sched script' to see a detailed trace of the workload that
24 was recorded. 24 was recorded (aliased to 'perf script' for now).
25 25
26 'perf sched replay' to simulate the workload that was recorded 26 'perf sched replay' to simulate the workload that was recorded
27 via perf sched record. (this is done by starting up mockup threads 27 via perf sched record. (this is done by starting up mockup threads
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index db017867d9e8..dec87ecb530e 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -188,6 +188,13 @@ OPTIONS
188 CPUs are specified with -: 0-2. Default is to report samples on all 188 CPUs are specified with -: 0-2. Default is to report samples on all
189 CPUs. 189 CPUs.
190 190
191-I::
192--show-info::
193 Display extended information about the perf.data file. This adds
194 information which may be very large and thus may clutter the display.
195 It currently includes: cpu and numa topology of the host system.
196 It can only be used with the perf script report mode.
197
191SEE ALSO 198SEE ALSO
192-------- 199--------
193linkperf:perf-record[1], linkperf:perf-script-perl[1], 200linkperf:perf-record[1], linkperf:perf-script-perl[1],
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 918cc38ee6d1..8966b9ab2014 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -94,6 +94,22 @@ an empty cgroup (monitor all the time) using, e.g., -G foo,,bar. Cgroups must ha
94corresponding events, i.e., they always refer to events defined earlier on the command 94corresponding events, i.e., they always refer to events defined earlier on the command
95line. 95line.
96 96
97-o file::
98--output file::
99Print the output into the designated file.
100
101--append::
102Append to the output file designated with the -o option. Ignored if -o is not specified.
103
104--log-fd::
105
106Log output to fd, instead of stderr. Complementary to --output, and mutually exclusive
107with it. --append may be used here. Examples:
108 3>results perf stat --log-fd 3 -- $cmd
109 3>>results perf stat --log-fd 3 --append -- $cmd
110
111
112
97EXAMPLES 113EXAMPLES
98-------- 114--------
99 115
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index f6eb1cdafb77..b1a5bbbfebef 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -106,6 +106,51 @@ Default is to monitor all CPUS.
106--zero:: 106--zero::
107 Zero history across display updates. 107 Zero history across display updates.
108 108
109-s::
110--sort::
111 Sort by key(s): pid, comm, dso, symbol, parent
112
113-n::
114--show-nr-samples::
115 Show a column with the number of samples.
116
117--show-total-period::
118 Show a column with the sum of periods.
119
120--dsos::
121 Only consider symbols in these dsos.
122
123--comms::
124 Only consider symbols in these comms.
125
126--symbols::
127 Only consider these symbols.
128
129-M::
130--disassembler-style=:: Set disassembler style for objdump.
131
132--source::
133 Interleave source code with assembly code. Enabled by default,
134 disable with --no-source.
135
136--asm-raw::
137 Show raw instruction encoding of assembly instructions.
138
139-G [type,min,order]::
140--call-graph::
141 Display call chains using type, min percent threshold and order.
142 type can be either:
143 - flat: single column, linear exposure of call chains.
144 - graph: use a graph tree, displaying absolute overhead rates.
145 - fractal: like graph, but displays relative rates. Each branch of
146 the tree is considered as a new profiled object.
147
148 order can be either:
149 - callee: callee based call graph.
150 - caller: inverted caller based call graph.
151
152 Default: fractal,0.5,callee.
153
109INTERACTIVE PROMPTING KEYS 154INTERACTIVE PROMPTING KEYS
110-------------------------- 155--------------------------
111 156
@@ -130,9 +175,6 @@ INTERACTIVE PROMPTING KEYS
130[S]:: 175[S]::
131 Stop annotation, return to full profile display. 176 Stop annotation, return to full profile display.
132 177
133[w]::
134 Toggle between weighted sum and individual count[E]r profile.
135
136[z]:: 178[z]::
137 Toggle event count zeroing across display updates. 179 Toggle event count zeroing across display updates.
138 180
diff --git a/tools/perf/Documentation/perfconfig.example b/tools/perf/Documentation/perfconfig.example
new file mode 100644
index 000000000000..d1448668f4d4
--- /dev/null
+++ b/tools/perf/Documentation/perfconfig.example
@@ -0,0 +1,20 @@
1[colors]
2
3 # These were the old defaults
4 top = red, lightgray
5 medium = green, lightgray
6 normal = black, lightgray
7 selected = lightgray, magenta
8 code = blue, lightgray
9
10[tui]
11
12 # Defaults if linked with libslang
13 report = on
14 annotate = on
15 top = on
16
17[buildid]
18
19 # Default, disable using /dev/null
20 dir = /root/.debug
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index e9d5c271db69..b98e3075646b 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -466,13 +466,13 @@ else
466 LIB_OBJS += $(OUTPUT)util/ui/browsers/annotate.o 466 LIB_OBJS += $(OUTPUT)util/ui/browsers/annotate.o
467 LIB_OBJS += $(OUTPUT)util/ui/browsers/hists.o 467 LIB_OBJS += $(OUTPUT)util/ui/browsers/hists.o
468 LIB_OBJS += $(OUTPUT)util/ui/browsers/map.o 468 LIB_OBJS += $(OUTPUT)util/ui/browsers/map.o
469 LIB_OBJS += $(OUTPUT)util/ui/browsers/top.o
470 LIB_OBJS += $(OUTPUT)util/ui/helpline.o 469 LIB_OBJS += $(OUTPUT)util/ui/helpline.o
471 LIB_OBJS += $(OUTPUT)util/ui/progress.o 470 LIB_OBJS += $(OUTPUT)util/ui/progress.o
472 LIB_OBJS += $(OUTPUT)util/ui/util.o 471 LIB_OBJS += $(OUTPUT)util/ui/util.o
473 LIB_H += util/ui/browser.h 472 LIB_H += util/ui/browser.h
474 LIB_H += util/ui/browsers/map.h 473 LIB_H += util/ui/browsers/map.h
475 LIB_H += util/ui/helpline.h 474 LIB_H += util/ui/helpline.h
475 LIB_H += util/ui/keysyms.h
476 LIB_H += util/ui/libslang.h 476 LIB_H += util/ui/libslang.h
477 LIB_H += util/ui/progress.h 477 LIB_H += util/ui/progress.h
478 LIB_H += util/ui/util.h 478 LIB_H += util/ui/util.h
@@ -729,9 +729,6 @@ $(OUTPUT)util/ui/browser.o: util/ui/browser.c $(OUTPUT)PERF-CFLAGS
729$(OUTPUT)util/ui/browsers/annotate.o: util/ui/browsers/annotate.c $(OUTPUT)PERF-CFLAGS 729$(OUTPUT)util/ui/browsers/annotate.o: util/ui/browsers/annotate.c $(OUTPUT)PERF-CFLAGS
730 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< 730 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
731 731
732$(OUTPUT)util/ui/browsers/top.o: util/ui/browsers/top.c $(OUTPUT)PERF-CFLAGS
733 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
734
735$(OUTPUT)util/ui/browsers/hists.o: util/ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS 732$(OUTPUT)util/ui/browsers/hists.o: util/ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS
736 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< 733 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
737 734
diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile
index 15130b50dfe3..744e629797be 100644
--- a/tools/perf/arch/powerpc/Makefile
+++ b/tools/perf/arch/powerpc/Makefile
@@ -2,3 +2,4 @@ ifndef NO_DWARF
2PERF_HAVE_DWARF_REGS := 1 2PERF_HAVE_DWARF_REGS := 1
3LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o 3LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
4endif 4endif
5LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o
diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c
new file mode 100644
index 000000000000..eba80c292945
--- /dev/null
+++ b/tools/perf/arch/powerpc/util/header.c
@@ -0,0 +1,36 @@
1#include <sys/types.h>
2#include <unistd.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6
7#include "../../util/header.h"
8
9#define __stringify_1(x) #x
10#define __stringify(x) __stringify_1(x)
11
12#define mfspr(rn) ({unsigned long rval; \
13 asm volatile("mfspr %0," __stringify(rn) \
14 : "=r" (rval)); rval; })
15
16#define SPRN_PVR 0x11F /* Processor Version Register */
17#define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */
18#define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */
19
20int
21get_cpuid(char *buffer, size_t sz)
22{
23 unsigned long pvr;
24 int nb;
25
26 pvr = mfspr(SPRN_PVR);
27
28 nb = snprintf(buffer, sz, "%lu,%lu$", PVR_VER(pvr), PVR_REV(pvr));
29
30 /* look for end marker to ensure the entire data fit */
31 if (strchr(buffer, '$')) {
32 buffer[nb-1] = '\0';
33 return 0;
34 }
35 return -1;
36}
diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
index 15130b50dfe3..744e629797be 100644
--- a/tools/perf/arch/x86/Makefile
+++ b/tools/perf/arch/x86/Makefile
@@ -2,3 +2,4 @@ ifndef NO_DWARF
2PERF_HAVE_DWARF_REGS := 1 2PERF_HAVE_DWARF_REGS := 1
3LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o 3LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
4endif 4endif
5LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o
diff --git a/tools/perf/arch/x86/util/header.c b/tools/perf/arch/x86/util/header.c
new file mode 100644
index 000000000000..f94006068d2b
--- /dev/null
+++ b/tools/perf/arch/x86/util/header.c
@@ -0,0 +1,59 @@
1#include <sys/types.h>
2#include <unistd.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6
7#include "../../util/header.h"
8
9static inline void
10cpuid(unsigned int op, unsigned int *a, unsigned int *b, unsigned int *c,
11 unsigned int *d)
12{
13 __asm__ __volatile__ (".byte 0x53\n\tcpuid\n\t"
14 "movl %%ebx, %%esi\n\t.byte 0x5b"
15 : "=a" (*a),
16 "=S" (*b),
17 "=c" (*c),
18 "=d" (*d)
19 : "a" (op));
20}
21
22int
23get_cpuid(char *buffer, size_t sz)
24{
25 unsigned int a, b, c, d, lvl;
26 int family = -1, model = -1, step = -1;
27 int nb;
28 char vendor[16];
29
30 cpuid(0, &lvl, &b, &c, &d);
31 strncpy(&vendor[0], (char *)(&b), 4);
32 strncpy(&vendor[4], (char *)(&d), 4);
33 strncpy(&vendor[8], (char *)(&c), 4);
34 vendor[12] = '\0';
35
36 if (lvl >= 1) {
37 cpuid(1, &a, &b, &c, &d);
38
39 family = (a >> 8) & 0xf; /* bits 11 - 8 */
40 model = (a >> 4) & 0xf; /* Bits 7 - 4 */
41 step = a & 0xf;
42
43 /* extended family */
44 if (family == 0xf)
45 family += (a >> 20) & 0xff;
46
47 /* extended model */
48 if (family >= 0x6)
49 model += ((a >> 16) & 0xf) << 4;
50 }
51 nb = snprintf(buffer, sz, "%s,%u,%u,%u$", vendor, family, model, step);
52
53 /* look for end marker to ensure the entire data fit */
54 if (strchr(buffer, '$')) {
55 buffer[nb-1] = '\0';
56 return 0;
57 }
58 return -1;
59}
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 555aefd7fe01..46b4c24f338e 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -114,10 +114,11 @@ static int hist_entry__tty_annotate(struct hist_entry *he, int evidx)
114 print_line, full_paths, 0, 0); 114 print_line, full_paths, 0, 0);
115} 115}
116 116
117static void hists__find_annotations(struct hists *self, int evidx) 117static void hists__find_annotations(struct hists *self, int evidx,
118 int nr_events)
118{ 119{
119 struct rb_node *nd = rb_first(&self->entries), *next; 120 struct rb_node *nd = rb_first(&self->entries), *next;
120 int key = KEY_RIGHT; 121 int key = K_RIGHT;
121 122
122 while (nd) { 123 while (nd) {
123 struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); 124 struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
@@ -129,7 +130,7 @@ static void hists__find_annotations(struct hists *self, int evidx)
129 notes = symbol__annotation(he->ms.sym); 130 notes = symbol__annotation(he->ms.sym);
130 if (notes->src == NULL) { 131 if (notes->src == NULL) {
131find_next: 132find_next:
132 if (key == KEY_LEFT) 133 if (key == K_LEFT)
133 nd = rb_prev(nd); 134 nd = rb_prev(nd);
134 else 135 else
135 nd = rb_next(nd); 136 nd = rb_next(nd);
@@ -137,12 +138,13 @@ find_next:
137 } 138 }
138 139
139 if (use_browser > 0) { 140 if (use_browser > 0) {
140 key = hist_entry__tui_annotate(he, evidx); 141 key = hist_entry__tui_annotate(he, evidx, nr_events,
142 NULL, NULL, 0);
141 switch (key) { 143 switch (key) {
142 case KEY_RIGHT: 144 case K_RIGHT:
143 next = rb_next(nd); 145 next = rb_next(nd);
144 break; 146 break;
145 case KEY_LEFT: 147 case K_LEFT:
146 next = rb_prev(nd); 148 next = rb_prev(nd);
147 break; 149 break;
148 default: 150 default:
@@ -215,7 +217,8 @@ static int __cmd_annotate(void)
215 total_nr_samples += nr_samples; 217 total_nr_samples += nr_samples;
216 hists__collapse_resort(hists); 218 hists__collapse_resort(hists);
217 hists__output_resort(hists); 219 hists__output_resort(hists);
218 hists__find_annotations(hists, pos->idx); 220 hists__find_annotations(hists, pos->idx,
221 session->evlist->nr_entries);
219 } 222 }
220 } 223 }
221 224
@@ -267,6 +270,14 @@ static const struct option options[] = {
267 OPT_BOOLEAN('P', "full-paths", &full_paths, 270 OPT_BOOLEAN('P', "full-paths", &full_paths,
268 "Don't shorten the displayed pathnames"), 271 "Don't shorten the displayed pathnames"),
269 OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"), 272 OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
273 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
274 "Look for files with symbols relative to this directory"),
275 OPT_BOOLEAN(0, "source", &symbol_conf.annotate_src,
276 "Interleave source code with assembly code (default)"),
277 OPT_BOOLEAN(0, "asm-raw", &symbol_conf.annotate_asm_raw,
278 "Display raw encoding of assembly instructions (default)"),
279 OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
280 "Specify disassembler style (e.g. -M intel for intel syntax)"),
270 OPT_END() 281 OPT_END()
271}; 282};
272 283
diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c
index 5af32ae9031e..cb690a65bf02 100644
--- a/tools/perf/builtin-buildid-list.c
+++ b/tools/perf/builtin-buildid-list.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * builtin-buildid-list.c 2 * builtin-buildid-list.c
3 * 3 *
4 * Builtin buildid-list command: list buildids in perf.data 4 * Builtin buildid-list command: list buildids in perf.data, in the running
5 * kernel and in ELF files.
5 * 6 *
6 * Copyright (C) 2009, Red Hat Inc. 7 * Copyright (C) 2009, Red Hat Inc.
7 * Copyright (C) 2009, Arnaldo Carvalho de Melo <acme@redhat.com> 8 * Copyright (C) 2009, Arnaldo Carvalho de Melo <acme@redhat.com>
@@ -15,8 +16,11 @@
15#include "util/session.h" 16#include "util/session.h"
16#include "util/symbol.h" 17#include "util/symbol.h"
17 18
19#include <libelf.h>
20
18static char const *input_name = "perf.data"; 21static char const *input_name = "perf.data";
19static bool force; 22static bool force;
23static bool show_kernel;
20static bool with_hits; 24static bool with_hits;
21 25
22static const char * const buildid_list_usage[] = { 26static const char * const buildid_list_usage[] = {
@@ -29,12 +33,13 @@ static const struct option options[] = {
29 OPT_STRING('i', "input", &input_name, "file", 33 OPT_STRING('i', "input", &input_name, "file",
30 "input file name"), 34 "input file name"),
31 OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), 35 OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
36 OPT_BOOLEAN('k', "kernel", &show_kernel, "Show current kernel build id"),
32 OPT_INCR('v', "verbose", &verbose, 37 OPT_INCR('v', "verbose", &verbose,
33 "be more verbose"), 38 "be more verbose"),
34 OPT_END() 39 OPT_END()
35}; 40};
36 41
37static int __cmd_buildid_list(void) 42static int perf_session__list_build_ids(void)
38{ 43{
39 struct perf_session *session; 44 struct perf_session *session;
40 45
@@ -52,6 +57,49 @@ static int __cmd_buildid_list(void)
52 return 0; 57 return 0;
53} 58}
54 59
60static int sysfs__fprintf_build_id(FILE *fp)
61{
62 u8 kallsyms_build_id[BUILD_ID_SIZE];
63 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
64
65 if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
66 sizeof(kallsyms_build_id)) != 0)
67 return -1;
68
69 build_id__sprintf(kallsyms_build_id, sizeof(kallsyms_build_id),
70 sbuild_id);
71 fprintf(fp, "%s\n", sbuild_id);
72 return 0;
73}
74
75static int filename__fprintf_build_id(const char *name, FILE *fp)
76{
77 u8 build_id[BUILD_ID_SIZE];
78 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
79
80 if (filename__read_build_id(name, build_id,
81 sizeof(build_id)) != sizeof(build_id))
82 return 0;
83
84 build_id__sprintf(build_id, sizeof(build_id), sbuild_id);
85 return fprintf(fp, "%s\n", sbuild_id);
86}
87
88static int __cmd_buildid_list(void)
89{
90 if (show_kernel)
91 return sysfs__fprintf_build_id(stdout);
92
93 elf_version(EV_CURRENT);
94 /*
95 * See if this is an ELF file first:
96 */
97 if (filename__fprintf_build_id(input_name, stdout))
98 return 0;
99
100 return perf_session__list_build_ids();
101}
102
55int cmd_buildid_list(int argc, const char **argv, const char *prefix __used) 103int cmd_buildid_list(int argc, const char **argv, const char *prefix __used)
56{ 104{
57 argc = parse_options(argc, argv, options, buildid_list_usage, 0); 105 argc = parse_options(argc, argv, options, buildid_list_usage, 0);
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index e8219990f8b8..b39f3a1ee7dc 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -162,7 +162,7 @@ static int __cmd_diff(void)
162 162
163 hists__match(&session[0]->hists, &session[1]->hists); 163 hists__match(&session[0]->hists, &session[1]->hists);
164 hists__fprintf(&session[1]->hists, &session[0]->hists, 164 hists__fprintf(&session[1]->hists, &session[0]->hists,
165 show_displacement, stdout); 165 show_displacement, true, 0, 0, stdout);
166out_delete: 166out_delete:
167 for (i = 0; i < 2; ++i) 167 for (i = 0; i < 2; ++i)
168 perf_session__delete(session[i]); 168 perf_session__delete(session[i]);
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index f4c3fbee4bad..f82480fa7f27 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -73,6 +73,7 @@ static off_t post_processing_offset;
73 73
74static struct perf_session *session; 74static struct perf_session *session;
75static const char *cpu_list; 75static const char *cpu_list;
76static const char *progname;
76 77
77static void advance_output(size_t size) 78static void advance_output(size_t size)
78{ 79{
@@ -137,17 +138,29 @@ static void mmap_read(struct perf_mmap *md)
137 138
138static volatile int done = 0; 139static volatile int done = 0;
139static volatile int signr = -1; 140static volatile int signr = -1;
141static volatile int child_finished = 0;
140 142
141static void sig_handler(int sig) 143static void sig_handler(int sig)
142{ 144{
145 if (sig == SIGCHLD)
146 child_finished = 1;
147
143 done = 1; 148 done = 1;
144 signr = sig; 149 signr = sig;
145} 150}
146 151
147static void sig_atexit(void) 152static void sig_atexit(void)
148{ 153{
149 if (child_pid > 0) 154 int status;
150 kill(child_pid, SIGTERM); 155
156 if (child_pid > 0) {
157 if (!child_finished)
158 kill(child_pid, SIGTERM);
159
160 wait(&status);
161 if (WIFSIGNALED(status))
162 psignal(WTERMSIG(status), progname);
163 }
151 164
152 if (signr == -1 || signr == SIGUSR1) 165 if (signr == -1 || signr == SIGUSR1)
153 return; 166 return;
@@ -446,6 +459,8 @@ static int __cmd_record(int argc, const char **argv)
446 char buf; 459 char buf;
447 struct machine *machine; 460 struct machine *machine;
448 461
462 progname = argv[0];
463
449 page_size = sysconf(_SC_PAGE_SIZE); 464 page_size = sysconf(_SC_PAGE_SIZE);
450 465
451 atexit(sig_atexit); 466 atexit(sig_atexit);
@@ -514,6 +529,19 @@ static int __cmd_record(int argc, const char **argv)
514 if (have_tracepoints(&evsel_list->entries)) 529 if (have_tracepoints(&evsel_list->entries))
515 perf_header__set_feat(&session->header, HEADER_TRACE_INFO); 530 perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
516 531
532 perf_header__set_feat(&session->header, HEADER_HOSTNAME);
533 perf_header__set_feat(&session->header, HEADER_OSRELEASE);
534 perf_header__set_feat(&session->header, HEADER_ARCH);
535 perf_header__set_feat(&session->header, HEADER_CPUDESC);
536 perf_header__set_feat(&session->header, HEADER_NRCPUS);
537 perf_header__set_feat(&session->header, HEADER_EVENT_DESC);
538 perf_header__set_feat(&session->header, HEADER_CMDLINE);
539 perf_header__set_feat(&session->header, HEADER_VERSION);
540 perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY);
541 perf_header__set_feat(&session->header, HEADER_TOTAL_MEM);
542 perf_header__set_feat(&session->header, HEADER_NUMA_TOPOLOGY);
543 perf_header__set_feat(&session->header, HEADER_CPUID);
544
517 /* 512 kiB: default amount of unprivileged mlocked memory */ 545 /* 512 kiB: default amount of unprivileged mlocked memory */
518 if (mmap_pages == UINT_MAX) 546 if (mmap_pages == UINT_MAX)
519 mmap_pages = (512 * 1024) / page_size; 547 mmap_pages = (512 * 1024) / page_size;
@@ -785,6 +813,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
785 int err = -ENOMEM; 813 int err = -ENOMEM;
786 struct perf_evsel *pos; 814 struct perf_evsel *pos;
787 815
816 perf_header__set_cmdline(argc, argv);
817
788 evsel_list = perf_evlist__new(NULL, NULL); 818 evsel_list = perf_evlist__new(NULL, NULL);
789 if (evsel_list == NULL) 819 if (evsel_list == NULL)
790 return -ENOMEM; 820 return -ENOMEM;
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index d7ff277bdb78..4d7c8340c326 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -40,6 +40,7 @@ static char const *input_name = "perf.data";
40static bool force, use_tui, use_stdio; 40static bool force, use_tui, use_stdio;
41static bool hide_unresolved; 41static bool hide_unresolved;
42static bool dont_use_callchains; 42static bool dont_use_callchains;
43static bool show_full_info;
43 44
44static bool show_threads; 45static bool show_threads;
45static struct perf_read_values show_threads_values; 46static struct perf_read_values show_threads_values;
@@ -229,13 +230,10 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
229 230
230 list_for_each_entry(pos, &evlist->entries, node) { 231 list_for_each_entry(pos, &evlist->entries, node) {
231 struct hists *hists = &pos->hists; 232 struct hists *hists = &pos->hists;
232 const char *evname = NULL; 233 const char *evname = event_name(pos);
233
234 if (rb_first(&hists->entries) != rb_last(&hists->entries))
235 evname = event_name(pos);
236 234
237 hists__fprintf_nr_sample_events(hists, evname, stdout); 235 hists__fprintf_nr_sample_events(hists, evname, stdout);
238 hists__fprintf(hists, NULL, false, stdout); 236 hists__fprintf(hists, NULL, false, true, 0, 0, stdout);
239 fprintf(stdout, "\n\n"); 237 fprintf(stdout, "\n\n");
240 } 238 }
241 239
@@ -276,6 +274,9 @@ static int __cmd_report(void)
276 goto out_delete; 274 goto out_delete;
277 } 275 }
278 276
277 if (use_browser <= 0)
278 perf_session__fprintf_info(session, stdout, show_full_info);
279
279 if (show_threads) 280 if (show_threads)
280 perf_read_values_init(&show_threads_values); 281 perf_read_values_init(&show_threads_values);
281 282
@@ -330,9 +331,10 @@ static int __cmd_report(void)
330 goto out_delete; 331 goto out_delete;
331 } 332 }
332 333
333 if (use_browser > 0) 334 if (use_browser > 0) {
334 perf_evlist__tui_browse_hists(session->evlist, help); 335 perf_evlist__tui_browse_hists(session->evlist, help,
335 else 336 NULL, NULL, 0);
337 } else
336 perf_evlist__tty_browse_hists(session->evlist, help); 338 perf_evlist__tty_browse_hists(session->evlist, help);
337 339
338out_delete: 340out_delete:
@@ -487,6 +489,16 @@ static const struct option options[] = {
487 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", 489 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
488 "Look for files with symbols relative to this directory"), 490 "Look for files with symbols relative to this directory"),
489 OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"), 491 OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
492 OPT_BOOLEAN('I', "show-info", &show_full_info,
493 "Display extended information about perf.data file"),
494 OPT_BOOLEAN(0, "source", &symbol_conf.annotate_src,
495 "Interleave source code with assembly code (default)"),
496 OPT_BOOLEAN(0, "asm-raw", &symbol_conf.annotate_asm_raw,
497 "Display raw encoding of assembly instructions (default)"),
498 OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
499 "Specify disassembler style (e.g. -M intel for intel syntax)"),
500 OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
501 "Show a column with the sum of periods"),
490 OPT_END() 502 OPT_END()
491}; 503};
492 504
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 09024ec2ab2e..2f62a2952269 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -22,6 +22,7 @@ static u64 last_timestamp;
22static u64 nr_unordered; 22static u64 nr_unordered;
23extern const struct option record_options[]; 23extern const struct option record_options[];
24static bool no_callchain; 24static bool no_callchain;
25static bool show_full_info;
25static const char *cpu_list; 26static const char *cpu_list;
26static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 27static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
27 28
@@ -1083,7 +1084,8 @@ static const struct option options[] = {
1083 "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,addr", 1084 "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,addr",
1084 parse_output_fields), 1085 parse_output_fields),
1085 OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"), 1086 OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
1086 1087 OPT_BOOLEAN('I', "show-info", &show_full_info,
1088 "display extended information from perf.data file"),
1087 OPT_END() 1089 OPT_END()
1088}; 1090};
1089 1091
@@ -1268,6 +1270,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1268 return -1; 1270 return -1;
1269 } 1271 }
1270 1272
1273 perf_session__fprintf_info(session, stdout, show_full_info);
1274
1271 if (!no_callchain) 1275 if (!no_callchain)
1272 symbol_conf.use_callchain = true; 1276 symbol_conf.use_callchain = true;
1273 else 1277 else
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 5deb17d9e795..7ce65f52415e 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -194,6 +194,9 @@ static const char *cpu_list;
194static const char *csv_sep = NULL; 194static const char *csv_sep = NULL;
195static bool csv_output = false; 195static bool csv_output = false;
196static bool group = false; 196static bool group = false;
197static const char *output_name = NULL;
198static FILE *output = NULL;
199static int output_fd;
197 200
198static volatile int done = 0; 201static volatile int done = 0;
199 202
@@ -251,8 +254,13 @@ static double avg_stats(struct stats *stats)
251 */ 254 */
252static double stddev_stats(struct stats *stats) 255static double stddev_stats(struct stats *stats)
253{ 256{
254 double variance = stats->M2 / (stats->n - 1); 257 double variance, variance_mean;
255 double variance_mean = variance / stats->n; 258
259 if (!stats->n)
260 return 0.0;
261
262 variance = stats->M2 / (stats->n - 1);
263 variance_mean = variance / stats->n;
256 264
257 return sqrt(variance_mean); 265 return sqrt(variance_mean);
258} 266}
@@ -352,7 +360,7 @@ static int read_counter_aggr(struct perf_evsel *counter)
352 update_stats(&ps->res_stats[i], count[i]); 360 update_stats(&ps->res_stats[i], count[i]);
353 361
354 if (verbose) { 362 if (verbose) {
355 fprintf(stderr, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", 363 fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
356 event_name(counter), count[0], count[1], count[2]); 364 event_name(counter), count[0], count[1], count[2]);
357 } 365 }
358 366
@@ -487,6 +495,8 @@ static int run_perf_stat(int argc __used, const char **argv)
487 if (forks) { 495 if (forks) {
488 close(go_pipe[1]); 496 close(go_pipe[1]);
489 wait(&status); 497 wait(&status);
498 if (WIFSIGNALED(status))
499 psignal(WTERMSIG(status), argv[0]);
490 } else { 500 } else {
491 while(!done) sleep(1); 501 while(!done) sleep(1);
492 } 502 }
@@ -519,9 +529,9 @@ static void print_noise_pct(double total, double avg)
519 pct = 100.0*total/avg; 529 pct = 100.0*total/avg;
520 530
521 if (csv_output) 531 if (csv_output)
522 fprintf(stderr, "%s%.2f%%", csv_sep, pct); 532 fprintf(output, "%s%.2f%%", csv_sep, pct);
523 else 533 else if (pct)
524 fprintf(stderr, " ( +-%6.2f%% )", pct); 534 fprintf(output, " ( +-%6.2f%% )", pct);
525} 535}
526 536
527static void print_noise(struct perf_evsel *evsel, double avg) 537static void print_noise(struct perf_evsel *evsel, double avg)
@@ -546,16 +556,17 @@ static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg)
546 csv_output ? 0 : -4, 556 csv_output ? 0 : -4,
547 evsel_list->cpus->map[cpu], csv_sep); 557 evsel_list->cpus->map[cpu], csv_sep);
548 558
549 fprintf(stderr, fmt, cpustr, msecs, csv_sep, event_name(evsel)); 559 fprintf(output, fmt, cpustr, msecs, csv_sep, event_name(evsel));
550 560
551 if (evsel->cgrp) 561 if (evsel->cgrp)
552 fprintf(stderr, "%s%s", csv_sep, evsel->cgrp->name); 562 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
553 563
554 if (csv_output) 564 if (csv_output)
555 return; 565 return;
556 566
557 if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) 567 if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
558 fprintf(stderr, " # %8.3f CPUs utilized ", avg / avg_stats(&walltime_nsecs_stats)); 568 fprintf(output, " # %8.3f CPUs utilized ",
569 avg / avg_stats(&walltime_nsecs_stats));
559} 570}
560 571
561static void print_stalled_cycles_frontend(int cpu, struct perf_evsel *evsel __used, double avg) 572static void print_stalled_cycles_frontend(int cpu, struct perf_evsel *evsel __used, double avg)
@@ -576,9 +587,9 @@ static void print_stalled_cycles_frontend(int cpu, struct perf_evsel *evsel __us
576 else if (ratio > 10.0) 587 else if (ratio > 10.0)
577 color = PERF_COLOR_YELLOW; 588 color = PERF_COLOR_YELLOW;
578 589
579 fprintf(stderr, " # "); 590 fprintf(output, " # ");
580 color_fprintf(stderr, color, "%6.2f%%", ratio); 591 color_fprintf(output, color, "%6.2f%%", ratio);
581 fprintf(stderr, " frontend cycles idle "); 592 fprintf(output, " frontend cycles idle ");
582} 593}
583 594
584static void print_stalled_cycles_backend(int cpu, struct perf_evsel *evsel __used, double avg) 595static void print_stalled_cycles_backend(int cpu, struct perf_evsel *evsel __used, double avg)
@@ -599,9 +610,9 @@ static void print_stalled_cycles_backend(int cpu, struct perf_evsel *evsel __use
599 else if (ratio > 20.0) 610 else if (ratio > 20.0)
600 color = PERF_COLOR_YELLOW; 611 color = PERF_COLOR_YELLOW;
601 612
602 fprintf(stderr, " # "); 613 fprintf(output, " # ");
603 color_fprintf(stderr, color, "%6.2f%%", ratio); 614 color_fprintf(output, color, "%6.2f%%", ratio);
604 fprintf(stderr, " backend cycles idle "); 615 fprintf(output, " backend cycles idle ");
605} 616}
606 617
607static void print_branch_misses(int cpu, struct perf_evsel *evsel __used, double avg) 618static void print_branch_misses(int cpu, struct perf_evsel *evsel __used, double avg)
@@ -622,9 +633,9 @@ static void print_branch_misses(int cpu, struct perf_evsel *evsel __used, double
622 else if (ratio > 5.0) 633 else if (ratio > 5.0)
623 color = PERF_COLOR_YELLOW; 634 color = PERF_COLOR_YELLOW;
624 635
625 fprintf(stderr, " # "); 636 fprintf(output, " # ");
626 color_fprintf(stderr, color, "%6.2f%%", ratio); 637 color_fprintf(output, color, "%6.2f%%", ratio);
627 fprintf(stderr, " of all branches "); 638 fprintf(output, " of all branches ");
628} 639}
629 640
630static void print_l1_dcache_misses(int cpu, struct perf_evsel *evsel __used, double avg) 641static void print_l1_dcache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
@@ -645,9 +656,9 @@ static void print_l1_dcache_misses(int cpu, struct perf_evsel *evsel __used, dou
645 else if (ratio > 5.0) 656 else if (ratio > 5.0)
646 color = PERF_COLOR_YELLOW; 657 color = PERF_COLOR_YELLOW;
647 658
648 fprintf(stderr, " # "); 659 fprintf(output, " # ");
649 color_fprintf(stderr, color, "%6.2f%%", ratio); 660 color_fprintf(output, color, "%6.2f%%", ratio);
650 fprintf(stderr, " of all L1-dcache hits "); 661 fprintf(output, " of all L1-dcache hits ");
651} 662}
652 663
653static void print_l1_icache_misses(int cpu, struct perf_evsel *evsel __used, double avg) 664static void print_l1_icache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
@@ -668,9 +679,9 @@ static void print_l1_icache_misses(int cpu, struct perf_evsel *evsel __used, dou
668 else if (ratio > 5.0) 679 else if (ratio > 5.0)
669 color = PERF_COLOR_YELLOW; 680 color = PERF_COLOR_YELLOW;
670 681
671 fprintf(stderr, " # "); 682 fprintf(output, " # ");
672 color_fprintf(stderr, color, "%6.2f%%", ratio); 683 color_fprintf(output, color, "%6.2f%%", ratio);
673 fprintf(stderr, " of all L1-icache hits "); 684 fprintf(output, " of all L1-icache hits ");
674} 685}
675 686
676static void print_dtlb_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg) 687static void print_dtlb_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
@@ -691,9 +702,9 @@ static void print_dtlb_cache_misses(int cpu, struct perf_evsel *evsel __used, do
691 else if (ratio > 5.0) 702 else if (ratio > 5.0)
692 color = PERF_COLOR_YELLOW; 703 color = PERF_COLOR_YELLOW;
693 704
694 fprintf(stderr, " # "); 705 fprintf(output, " # ");
695 color_fprintf(stderr, color, "%6.2f%%", ratio); 706 color_fprintf(output, color, "%6.2f%%", ratio);
696 fprintf(stderr, " of all dTLB cache hits "); 707 fprintf(output, " of all dTLB cache hits ");
697} 708}
698 709
699static void print_itlb_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg) 710static void print_itlb_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
@@ -714,9 +725,9 @@ static void print_itlb_cache_misses(int cpu, struct perf_evsel *evsel __used, do
714 else if (ratio > 5.0) 725 else if (ratio > 5.0)
715 color = PERF_COLOR_YELLOW; 726 color = PERF_COLOR_YELLOW;
716 727
717 fprintf(stderr, " # "); 728 fprintf(output, " # ");
718 color_fprintf(stderr, color, "%6.2f%%", ratio); 729 color_fprintf(output, color, "%6.2f%%", ratio);
719 fprintf(stderr, " of all iTLB cache hits "); 730 fprintf(output, " of all iTLB cache hits ");
720} 731}
721 732
722static void print_ll_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg) 733static void print_ll_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
@@ -737,9 +748,9 @@ static void print_ll_cache_misses(int cpu, struct perf_evsel *evsel __used, doub
737 else if (ratio > 5.0) 748 else if (ratio > 5.0)
738 color = PERF_COLOR_YELLOW; 749 color = PERF_COLOR_YELLOW;
739 750
740 fprintf(stderr, " # "); 751 fprintf(output, " # ");
741 color_fprintf(stderr, color, "%6.2f%%", ratio); 752 color_fprintf(output, color, "%6.2f%%", ratio);
742 fprintf(stderr, " of all LL-cache hits "); 753 fprintf(output, " of all LL-cache hits ");
743} 754}
744 755
745static void abs_printout(int cpu, struct perf_evsel *evsel, double avg) 756static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
@@ -762,10 +773,10 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
762 else 773 else
763 cpu = 0; 774 cpu = 0;
764 775
765 fprintf(stderr, fmt, cpustr, avg, csv_sep, event_name(evsel)); 776 fprintf(output, fmt, cpustr, avg, csv_sep, event_name(evsel));
766 777
767 if (evsel->cgrp) 778 if (evsel->cgrp)
768 fprintf(stderr, "%s%s", csv_sep, evsel->cgrp->name); 779 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
769 780
770 if (csv_output) 781 if (csv_output)
771 return; 782 return;
@@ -776,14 +787,14 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
776 if (total) 787 if (total)
777 ratio = avg / total; 788 ratio = avg / total;
778 789
779 fprintf(stderr, " # %5.2f insns per cycle ", ratio); 790 fprintf(output, " # %5.2f insns per cycle ", ratio);
780 791
781 total = avg_stats(&runtime_stalled_cycles_front_stats[cpu]); 792 total = avg_stats(&runtime_stalled_cycles_front_stats[cpu]);
782 total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[cpu])); 793 total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[cpu]));
783 794
784 if (total && avg) { 795 if (total && avg) {
785 ratio = total / avg; 796 ratio = total / avg;
786 fprintf(stderr, "\n # %5.2f stalled cycles per insn", ratio); 797 fprintf(output, "\n # %5.2f stalled cycles per insn", ratio);
787 } 798 }
788 799
789 } else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) && 800 } else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) &&
@@ -831,7 +842,7 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
831 if (total) 842 if (total)
832 ratio = avg * 100 / total; 843 ratio = avg * 100 / total;
833 844
834 fprintf(stderr, " # %8.3f %% of all cache refs ", ratio); 845 fprintf(output, " # %8.3f %% of all cache refs ", ratio);
835 846
836 } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) { 847 } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) {
837 print_stalled_cycles_frontend(cpu, evsel, avg); 848 print_stalled_cycles_frontend(cpu, evsel, avg);
@@ -843,16 +854,16 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
843 if (total) 854 if (total)
844 ratio = 1.0 * avg / total; 855 ratio = 1.0 * avg / total;
845 856
846 fprintf(stderr, " # %8.3f GHz ", ratio); 857 fprintf(output, " # %8.3f GHz ", ratio);
847 } else if (runtime_nsecs_stats[cpu].n != 0) { 858 } else if (runtime_nsecs_stats[cpu].n != 0) {
848 total = avg_stats(&runtime_nsecs_stats[cpu]); 859 total = avg_stats(&runtime_nsecs_stats[cpu]);
849 860
850 if (total) 861 if (total)
851 ratio = 1000.0 * avg / total; 862 ratio = 1000.0 * avg / total;
852 863
853 fprintf(stderr, " # %8.3f M/sec ", ratio); 864 fprintf(output, " # %8.3f M/sec ", ratio);
854 } else { 865 } else {
855 fprintf(stderr, " "); 866 fprintf(output, " ");
856 } 867 }
857} 868}
858 869
@@ -867,7 +878,7 @@ static void print_counter_aggr(struct perf_evsel *counter)
867 int scaled = counter->counts->scaled; 878 int scaled = counter->counts->scaled;
868 879
869 if (scaled == -1) { 880 if (scaled == -1) {
870 fprintf(stderr, "%*s%s%*s", 881 fprintf(output, "%*s%s%*s",
871 csv_output ? 0 : 18, 882 csv_output ? 0 : 18,
872 counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 883 counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
873 csv_sep, 884 csv_sep,
@@ -875,9 +886,9 @@ static void print_counter_aggr(struct perf_evsel *counter)
875 event_name(counter)); 886 event_name(counter));
876 887
877 if (counter->cgrp) 888 if (counter->cgrp)
878 fprintf(stderr, "%s%s", csv_sep, counter->cgrp->name); 889 fprintf(output, "%s%s", csv_sep, counter->cgrp->name);
879 890
880 fputc('\n', stderr); 891 fputc('\n', output);
881 return; 892 return;
882 } 893 }
883 894
@@ -889,7 +900,7 @@ static void print_counter_aggr(struct perf_evsel *counter)
889 print_noise(counter, avg); 900 print_noise(counter, avg);
890 901
891 if (csv_output) { 902 if (csv_output) {
892 fputc('\n', stderr); 903 fputc('\n', output);
893 return; 904 return;
894 } 905 }
895 906
@@ -899,9 +910,9 @@ static void print_counter_aggr(struct perf_evsel *counter)
899 avg_enabled = avg_stats(&ps->res_stats[1]); 910 avg_enabled = avg_stats(&ps->res_stats[1]);
900 avg_running = avg_stats(&ps->res_stats[2]); 911 avg_running = avg_stats(&ps->res_stats[2]);
901 912
902 fprintf(stderr, " [%5.2f%%]", 100 * avg_running / avg_enabled); 913 fprintf(output, " [%5.2f%%]", 100 * avg_running / avg_enabled);
903 } 914 }
904 fprintf(stderr, "\n"); 915 fprintf(output, "\n");
905} 916}
906 917
907/* 918/*
@@ -918,7 +929,7 @@ static void print_counter(struct perf_evsel *counter)
918 ena = counter->counts->cpu[cpu].ena; 929 ena = counter->counts->cpu[cpu].ena;
919 run = counter->counts->cpu[cpu].run; 930 run = counter->counts->cpu[cpu].run;
920 if (run == 0 || ena == 0) { 931 if (run == 0 || ena == 0) {
921 fprintf(stderr, "CPU%*d%s%*s%s%*s", 932 fprintf(output, "CPU%*d%s%*s%s%*s",
922 csv_output ? 0 : -4, 933 csv_output ? 0 : -4,
923 evsel_list->cpus->map[cpu], csv_sep, 934 evsel_list->cpus->map[cpu], csv_sep,
924 csv_output ? 0 : 18, 935 csv_output ? 0 : 18,
@@ -928,9 +939,10 @@ static void print_counter(struct perf_evsel *counter)
928 event_name(counter)); 939 event_name(counter));
929 940
930 if (counter->cgrp) 941 if (counter->cgrp)
931 fprintf(stderr, "%s%s", csv_sep, counter->cgrp->name); 942 fprintf(output, "%s%s",
943 csv_sep, counter->cgrp->name);
932 944
933 fputc('\n', stderr); 945 fputc('\n', output);
934 continue; 946 continue;
935 } 947 }
936 948
@@ -943,9 +955,10 @@ static void print_counter(struct perf_evsel *counter)
943 print_noise(counter, 1.0); 955 print_noise(counter, 1.0);
944 956
945 if (run != ena) 957 if (run != ena)
946 fprintf(stderr, " (%.2f%%)", 100.0 * run / ena); 958 fprintf(output, " (%.2f%%)",
959 100.0 * run / ena);
947 } 960 }
948 fputc('\n', stderr); 961 fputc('\n', output);
949 } 962 }
950} 963}
951 964
@@ -957,21 +970,21 @@ static void print_stat(int argc, const char **argv)
957 fflush(stdout); 970 fflush(stdout);
958 971
959 if (!csv_output) { 972 if (!csv_output) {
960 fprintf(stderr, "\n"); 973 fprintf(output, "\n");
961 fprintf(stderr, " Performance counter stats for "); 974 fprintf(output, " Performance counter stats for ");
962 if(target_pid == -1 && target_tid == -1) { 975 if(target_pid == -1 && target_tid == -1) {
963 fprintf(stderr, "\'%s", argv[0]); 976 fprintf(output, "\'%s", argv[0]);
964 for (i = 1; i < argc; i++) 977 for (i = 1; i < argc; i++)
965 fprintf(stderr, " %s", argv[i]); 978 fprintf(output, " %s", argv[i]);
966 } else if (target_pid != -1) 979 } else if (target_pid != -1)
967 fprintf(stderr, "process id \'%d", target_pid); 980 fprintf(output, "process id \'%d", target_pid);
968 else 981 else
969 fprintf(stderr, "thread id \'%d", target_tid); 982 fprintf(output, "thread id \'%d", target_tid);
970 983
971 fprintf(stderr, "\'"); 984 fprintf(output, "\'");
972 if (run_count > 1) 985 if (run_count > 1)
973 fprintf(stderr, " (%d runs)", run_count); 986 fprintf(output, " (%d runs)", run_count);
974 fprintf(stderr, ":\n\n"); 987 fprintf(output, ":\n\n");
975 } 988 }
976 989
977 if (no_aggr) { 990 if (no_aggr) {
@@ -984,15 +997,15 @@ static void print_stat(int argc, const char **argv)
984 997
985 if (!csv_output) { 998 if (!csv_output) {
986 if (!null_run) 999 if (!null_run)
987 fprintf(stderr, "\n"); 1000 fprintf(output, "\n");
988 fprintf(stderr, " %17.9f seconds time elapsed", 1001 fprintf(output, " %17.9f seconds time elapsed",
989 avg_stats(&walltime_nsecs_stats)/1e9); 1002 avg_stats(&walltime_nsecs_stats)/1e9);
990 if (run_count > 1) { 1003 if (run_count > 1) {
991 fprintf(stderr, " "); 1004 fprintf(output, " ");
992 print_noise_pct(stddev_stats(&walltime_nsecs_stats), 1005 print_noise_pct(stddev_stats(&walltime_nsecs_stats),
993 avg_stats(&walltime_nsecs_stats)); 1006 avg_stats(&walltime_nsecs_stats));
994 } 1007 }
995 fprintf(stderr, "\n\n"); 1008 fprintf(output, "\n\n");
996 } 1009 }
997} 1010}
998 1011
@@ -1030,6 +1043,8 @@ static int stat__set_big_num(const struct option *opt __used,
1030 return 0; 1043 return 0;
1031} 1044}
1032 1045
1046static bool append_file;
1047
1033static const struct option options[] = { 1048static const struct option options[] = {
1034 OPT_CALLBACK('e', "event", &evsel_list, "event", 1049 OPT_CALLBACK('e', "event", &evsel_list, "event",
1035 "event selector. use 'perf list' to list available events", 1050 "event selector. use 'perf list' to list available events",
@@ -1070,6 +1085,11 @@ static const struct option options[] = {
1070 OPT_CALLBACK('G', "cgroup", &evsel_list, "name", 1085 OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
1071 "monitor event in cgroup name only", 1086 "monitor event in cgroup name only",
1072 parse_cgroups), 1087 parse_cgroups),
1088 OPT_STRING('o', "output", &output_name, "file",
1089 "output file name"),
1090 OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
1091 OPT_INTEGER(0, "log-fd", &output_fd,
1092 "log output to fd, instead of stderr"),
1073 OPT_END() 1093 OPT_END()
1074}; 1094};
1075 1095
@@ -1141,6 +1161,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
1141{ 1161{
1142 struct perf_evsel *pos; 1162 struct perf_evsel *pos;
1143 int status = -ENOMEM; 1163 int status = -ENOMEM;
1164 const char *mode;
1144 1165
1145 setlocale(LC_ALL, ""); 1166 setlocale(LC_ALL, "");
1146 1167
@@ -1151,16 +1172,46 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
1151 argc = parse_options(argc, argv, options, stat_usage, 1172 argc = parse_options(argc, argv, options, stat_usage,
1152 PARSE_OPT_STOP_AT_NON_OPTION); 1173 PARSE_OPT_STOP_AT_NON_OPTION);
1153 1174
1154 if (csv_sep) 1175 output = stderr;
1176 if (output_name && strcmp(output_name, "-"))
1177 output = NULL;
1178
1179 if (output_name && output_fd) {
1180 fprintf(stderr, "cannot use both --output and --log-fd\n");
1181 usage_with_options(stat_usage, options);
1182 }
1183 if (!output) {
1184 struct timespec tm;
1185 mode = append_file ? "a" : "w";
1186
1187 output = fopen(output_name, mode);
1188 if (!output) {
1189 perror("failed to create output file");
1190 exit(-1);
1191 }
1192 clock_gettime(CLOCK_REALTIME, &tm);
1193 fprintf(output, "# started on %s\n", ctime(&tm.tv_sec));
1194 } else if (output_fd != 2) {
1195 mode = append_file ? "a" : "w";
1196 output = fdopen(output_fd, mode);
1197 if (!output) {
1198 perror("Failed opening logfd");
1199 return -errno;
1200 }
1201 }
1202
1203 if (csv_sep) {
1155 csv_output = true; 1204 csv_output = true;
1156 else 1205 if (!strcmp(csv_sep, "\\t"))
1206 csv_sep = "\t";
1207 } else
1157 csv_sep = DEFAULT_SEPARATOR; 1208 csv_sep = DEFAULT_SEPARATOR;
1158 1209
1159 /* 1210 /*
1160 * let the spreadsheet do the pretty-printing 1211 * let the spreadsheet do the pretty-printing
1161 */ 1212 */
1162 if (csv_output) { 1213 if (csv_output) {
1163 /* User explicitely passed -B? */ 1214 /* User explicitly passed -B? */
1164 if (big_num_opt == 1) { 1215 if (big_num_opt == 1) {
1165 fprintf(stderr, "-B option not supported with -x\n"); 1216 fprintf(stderr, "-B option not supported with -x\n");
1166 usage_with_options(stat_usage, options); 1217 usage_with_options(stat_usage, options);
@@ -1226,7 +1277,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
1226 status = 0; 1277 status = 0;
1227 for (run_idx = 0; run_idx < run_count; run_idx++) { 1278 for (run_idx = 0; run_idx < run_count; run_idx++) {
1228 if (run_count != 1 && verbose) 1279 if (run_count != 1 && verbose)
1229 fprintf(stderr, "[ perf stat: executing run #%d ... ]\n", run_idx + 1); 1280 fprintf(output, "[ perf stat: executing run #%d ... ]\n",
1281 run_idx + 1);
1230 1282
1231 if (sync_run) 1283 if (sync_run)
1232 sync(); 1284 sync();
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index d28013b7d61c..7a871714d44e 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -5,6 +5,7 @@
5 * any workload, CPU or specific PID. 5 * any workload, CPU or specific PID.
6 * 6 *
7 * Copyright (C) 2008, Red Hat Inc, Ingo Molnar <mingo@redhat.com> 7 * Copyright (C) 2008, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
8 * 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
8 * 9 *
9 * Improvements and fixes by: 10 * Improvements and fixes by:
10 * 11 *
@@ -36,6 +37,7 @@
36#include "util/parse-events.h" 37#include "util/parse-events.h"
37#include "util/cpumap.h" 38#include "util/cpumap.h"
38#include "util/xyarray.h" 39#include "util/xyarray.h"
40#include "util/sort.h"
39 41
40#include "util/debug.h" 42#include "util/debug.h"
41 43
@@ -65,12 +67,8 @@
65static struct perf_top top = { 67static struct perf_top top = {
66 .count_filter = 5, 68 .count_filter = 5,
67 .delay_secs = 2, 69 .delay_secs = 2,
68 .display_weighted = -1,
69 .target_pid = -1, 70 .target_pid = -1,
70 .target_tid = -1, 71 .target_tid = -1,
71 .active_symbols = LIST_HEAD_INIT(top.active_symbols),
72 .active_symbols_lock = PTHREAD_MUTEX_INITIALIZER,
73 .active_symbols_cond = PTHREAD_COND_INITIALIZER,
74 .freq = 1000, /* 1 KHz */ 72 .freq = 1000, /* 1 KHz */
75}; 73};
76 74
@@ -78,6 +76,12 @@ static bool system_wide = false;
78 76
79static bool use_tui, use_stdio; 77static bool use_tui, use_stdio;
80 78
79static bool sort_has_symbols;
80
81static bool dont_use_callchains;
82static char callchain_default_opt[] = "fractal,0.5,callee";
83
84
81static int default_interval = 0; 85static int default_interval = 0;
82 86
83static bool kptr_restrict_warned; 87static bool kptr_restrict_warned;
@@ -85,7 +89,6 @@ static bool vmlinux_warned;
85static bool inherit = false; 89static bool inherit = false;
86static int realtime_prio = 0; 90static int realtime_prio = 0;
87static bool group = false; 91static bool group = false;
88static unsigned int page_size;
89static unsigned int mmap_pages = 128; 92static unsigned int mmap_pages = 128;
90 93
91static bool dump_symtab = false; 94static bool dump_symtab = false;
@@ -93,7 +96,6 @@ static bool dump_symtab = false;
93static struct winsize winsize; 96static struct winsize winsize;
94 97
95static const char *sym_filter = NULL; 98static const char *sym_filter = NULL;
96struct sym_entry *sym_filter_entry_sched = NULL;
97static int sym_pcnt_filter = 5; 99static int sym_pcnt_filter = 5;
98 100
99/* 101/*
@@ -136,18 +138,18 @@ static void sig_winch_handler(int sig __used)
136 update_print_entries(&winsize); 138 update_print_entries(&winsize);
137} 139}
138 140
139static int parse_source(struct sym_entry *syme) 141static int parse_source(struct hist_entry *he)
140{ 142{
141 struct symbol *sym; 143 struct symbol *sym;
142 struct annotation *notes; 144 struct annotation *notes;
143 struct map *map; 145 struct map *map;
144 int err = -1; 146 int err = -1;
145 147
146 if (!syme) 148 if (!he || !he->ms.sym)
147 return -1; 149 return -1;
148 150
149 sym = sym_entry__symbol(syme); 151 sym = he->ms.sym;
150 map = syme->map; 152 map = he->ms.map;
151 153
152 /* 154 /*
153 * We can't annotate with just /proc/kallsyms 155 * We can't annotate with just /proc/kallsyms
@@ -175,53 +177,62 @@ static int parse_source(struct sym_entry *syme)
175 return err; 177 return err;
176 } 178 }
177 179
178 err = symbol__annotate(sym, syme->map, 0); 180 err = symbol__annotate(sym, map, 0);
179 if (err == 0) { 181 if (err == 0) {
180out_assign: 182out_assign:
181 top.sym_filter_entry = syme; 183 top.sym_filter_entry = he;
182 } 184 }
183 185
184 pthread_mutex_unlock(&notes->lock); 186 pthread_mutex_unlock(&notes->lock);
185 return err; 187 return err;
186} 188}
187 189
188static void __zero_source_counters(struct sym_entry *syme) 190static void __zero_source_counters(struct hist_entry *he)
189{ 191{
190 struct symbol *sym = sym_entry__symbol(syme); 192 struct symbol *sym = he->ms.sym;
191 symbol__annotate_zero_histograms(sym); 193 symbol__annotate_zero_histograms(sym);
192} 194}
193 195
194static void record_precise_ip(struct sym_entry *syme, struct map *map, 196static void record_precise_ip(struct hist_entry *he, int counter, u64 ip)
195 int counter, u64 ip)
196{ 197{
197 struct annotation *notes; 198 struct annotation *notes;
198 struct symbol *sym; 199 struct symbol *sym;
199 200
200 if (syme != top.sym_filter_entry) 201 if (he == NULL || he->ms.sym == NULL ||
202 (he != top.sym_filter_entry && use_browser != 1))
201 return; 203 return;
202 204
203 sym = sym_entry__symbol(syme); 205 sym = he->ms.sym;
204 notes = symbol__annotation(sym); 206 notes = symbol__annotation(sym);
205 207
206 if (pthread_mutex_trylock(&notes->lock)) 208 if (pthread_mutex_trylock(&notes->lock))
207 return; 209 return;
208 210
209 ip = map->map_ip(map, ip); 211 if (notes->src == NULL &&
210 symbol__inc_addr_samples(sym, map, counter, ip); 212 symbol__alloc_hist(sym, top.evlist->nr_entries) < 0) {
213 pthread_mutex_unlock(&notes->lock);
214 pr_err("Not enough memory for annotating '%s' symbol!\n",
215 sym->name);
216 sleep(1);
217 return;
218 }
219
220 ip = he->ms.map->map_ip(he->ms.map, ip);
221 symbol__inc_addr_samples(sym, he->ms.map, counter, ip);
211 222
212 pthread_mutex_unlock(&notes->lock); 223 pthread_mutex_unlock(&notes->lock);
213} 224}
214 225
215static void show_details(struct sym_entry *syme) 226static void show_details(struct hist_entry *he)
216{ 227{
217 struct annotation *notes; 228 struct annotation *notes;
218 struct symbol *symbol; 229 struct symbol *symbol;
219 int more; 230 int more;
220 231
221 if (!syme) 232 if (!he)
222 return; 233 return;
223 234
224 symbol = sym_entry__symbol(syme); 235 symbol = he->ms.sym;
225 notes = symbol__annotation(symbol); 236 notes = symbol__annotation(symbol);
226 237
227 pthread_mutex_lock(&notes->lock); 238 pthread_mutex_lock(&notes->lock);
@@ -232,7 +243,7 @@ static void show_details(struct sym_entry *syme)
232 printf("Showing %s for %s\n", event_name(top.sym_evsel), symbol->name); 243 printf("Showing %s for %s\n", event_name(top.sym_evsel), symbol->name);
233 printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter); 244 printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter);
234 245
235 more = symbol__annotate_printf(symbol, syme->map, top.sym_evsel->idx, 246 more = symbol__annotate_printf(symbol, he->ms.map, top.sym_evsel->idx,
236 0, sym_pcnt_filter, top.print_entries, 4); 247 0, sym_pcnt_filter, top.print_entries, 4);
237 if (top.zero) 248 if (top.zero)
238 symbol__annotate_zero_histogram(symbol, top.sym_evsel->idx); 249 symbol__annotate_zero_histogram(symbol, top.sym_evsel->idx);
@@ -246,21 +257,28 @@ out_unlock:
246 257
247static const char CONSOLE_CLEAR[] = ""; 258static const char CONSOLE_CLEAR[] = "";
248 259
249static void __list_insert_active_sym(struct sym_entry *syme) 260static struct hist_entry *
261 perf_session__add_hist_entry(struct perf_session *session,
262 struct addr_location *al,
263 struct perf_sample *sample,
264 struct perf_evsel *evsel)
250{ 265{
251 list_add(&syme->node, &top.active_symbols); 266 struct hist_entry *he;
267
268 he = __hists__add_entry(&evsel->hists, al, NULL, sample->period);
269 if (he == NULL)
270 return NULL;
271
272 session->hists.stats.total_period += sample->period;
273 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
274 return he;
252} 275}
253 276
254static void print_sym_table(struct perf_session *session) 277static void print_sym_table(void)
255{ 278{
256 char bf[160]; 279 char bf[160];
257 int printed = 0; 280 int printed = 0;
258 struct rb_node *nd;
259 struct sym_entry *syme;
260 struct rb_root tmp = RB_ROOT;
261 const int win_width = winsize.ws_col - 1; 281 const int win_width = winsize.ws_col - 1;
262 int sym_width, dso_width, dso_short_width;
263 float sum_ksamples = perf_top__decay_samples(&top, &tmp);
264 282
265 puts(CONSOLE_CLEAR); 283 puts(CONSOLE_CLEAR);
266 284
@@ -271,10 +289,12 @@ static void print_sym_table(struct perf_session *session)
271 289
272 printf("%-*.*s\n", win_width, win_width, graph_dotted_line); 290 printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
273 291
274 if (session->hists.stats.total_lost != 0) { 292 if (top.total_lost_warned != top.session->hists.stats.total_lost) {
293 top.total_lost_warned = top.session->hists.stats.total_lost;
275 color_fprintf(stdout, PERF_COLOR_RED, "WARNING:"); 294 color_fprintf(stdout, PERF_COLOR_RED, "WARNING:");
276 printf(" LOST %" PRIu64 " events, Check IO/CPU overload\n", 295 printf(" LOST %" PRIu64 " events, Check IO/CPU overload\n",
277 session->hists.stats.total_lost); 296 top.total_lost_warned);
297 ++printed;
278 } 298 }
279 299
280 if (top.sym_filter_entry) { 300 if (top.sym_filter_entry) {
@@ -282,58 +302,15 @@ static void print_sym_table(struct perf_session *session)
282 return; 302 return;
283 } 303 }
284 304
285 perf_top__find_widths(&top, &tmp, &dso_width, &dso_short_width, 305 hists__collapse_resort_threaded(&top.sym_evsel->hists);
286 &sym_width); 306 hists__output_resort_threaded(&top.sym_evsel->hists);
287 307 hists__decay_entries_threaded(&top.sym_evsel->hists,
288 if (sym_width + dso_width > winsize.ws_col - 29) { 308 top.hide_user_symbols,
289 dso_width = dso_short_width; 309 top.hide_kernel_symbols);
290 if (sym_width + dso_width > winsize.ws_col - 29) 310 hists__output_recalc_col_len(&top.sym_evsel->hists, winsize.ws_row - 3);
291 sym_width = winsize.ws_col - dso_width - 29;
292 }
293 putchar('\n'); 311 putchar('\n');
294 if (top.evlist->nr_entries == 1) 312 hists__fprintf(&top.sym_evsel->hists, NULL, false, false,
295 printf(" samples pcnt"); 313 winsize.ws_row - 4 - printed, win_width, stdout);
296 else
297 printf(" weight samples pcnt");
298
299 if (verbose)
300 printf(" RIP ");
301 printf(" %-*.*s DSO\n", sym_width, sym_width, "function");
302 printf(" %s _______ _____",
303 top.evlist->nr_entries == 1 ? " " : "______");
304 if (verbose)
305 printf(" ________________");
306 printf(" %-*.*s", sym_width, sym_width, graph_line);
307 printf(" %-*.*s", dso_width, dso_width, graph_line);
308 puts("\n");
309
310 for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) {
311 struct symbol *sym;
312 double pcnt;
313
314 syme = rb_entry(nd, struct sym_entry, rb_node);
315 sym = sym_entry__symbol(syme);
316 if (++printed > top.print_entries ||
317 (int)syme->snap_count < top.count_filter)
318 continue;
319
320 pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) /
321 sum_ksamples));
322
323 if (top.evlist->nr_entries == 1 || !top.display_weighted)
324 printf("%20.2f ", syme->weight);
325 else
326 printf("%9.1f %10ld ", syme->weight, syme->snap_count);
327
328 percent_color_fprintf(stdout, "%4.1f%%", pcnt);
329 if (verbose)
330 printf(" %016" PRIx64, sym->start);
331 printf(" %-*.*s", sym_width, sym_width, sym->name);
332 printf(" %-*.*s\n", dso_width, dso_width,
333 dso_width >= syme->map->dso->long_name_len ?
334 syme->map->dso->long_name :
335 syme->map->dso->short_name);
336 }
337} 314}
338 315
339static void prompt_integer(int *target, const char *msg) 316static void prompt_integer(int *target, const char *msg)
@@ -371,10 +348,11 @@ static void prompt_percent(int *target, const char *msg)
371 *target = tmp; 348 *target = tmp;
372} 349}
373 350
374static void prompt_symbol(struct sym_entry **target, const char *msg) 351static void prompt_symbol(struct hist_entry **target, const char *msg)
375{ 352{
376 char *buf = malloc(0), *p; 353 char *buf = malloc(0), *p;
377 struct sym_entry *syme = *target, *n, *found = NULL; 354 struct hist_entry *syme = *target, *n, *found = NULL;
355 struct rb_node *next;
378 size_t dummy = 0; 356 size_t dummy = 0;
379 357
380 /* zero counters of active symbol */ 358 /* zero counters of active symbol */
@@ -391,17 +369,14 @@ static void prompt_symbol(struct sym_entry **target, const char *msg)
391 if (p) 369 if (p)
392 *p = 0; 370 *p = 0;
393 371
394 pthread_mutex_lock(&top.active_symbols_lock); 372 next = rb_first(&top.sym_evsel->hists.entries);
395 syme = list_entry(top.active_symbols.next, struct sym_entry, node); 373 while (next) {
396 pthread_mutex_unlock(&top.active_symbols_lock); 374 n = rb_entry(next, struct hist_entry, rb_node);
397 375 if (n->ms.sym && !strcmp(buf, n->ms.sym->name)) {
398 list_for_each_entry_safe_from(syme, n, &top.active_symbols, node) { 376 found = n;
399 struct symbol *sym = sym_entry__symbol(syme);
400
401 if (!strcmp(buf, sym->name)) {
402 found = syme;
403 break; 377 break;
404 } 378 }
379 next = rb_next(&n->rb_node);
405 } 380 }
406 381
407 if (!found) { 382 if (!found) {
@@ -420,7 +395,7 @@ static void print_mapped_keys(void)
420 char *name = NULL; 395 char *name = NULL;
421 396
422 if (top.sym_filter_entry) { 397 if (top.sym_filter_entry) {
423 struct symbol *sym = sym_entry__symbol(top.sym_filter_entry); 398 struct symbol *sym = top.sym_filter_entry->ms.sym;
424 name = sym->name; 399 name = sym->name;
425 } 400 }
426 401
@@ -437,9 +412,6 @@ static void print_mapped_keys(void)
437 fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL"); 412 fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL");
438 fprintf(stdout, "\t[S] stop annotation.\n"); 413 fprintf(stdout, "\t[S] stop annotation.\n");
439 414
440 if (top.evlist->nr_entries > 1)
441 fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", top.display_weighted ? 1 : 0);
442
443 fprintf(stdout, 415 fprintf(stdout,
444 "\t[K] hide kernel_symbols symbols. \t(%s)\n", 416 "\t[K] hide kernel_symbols symbols. \t(%s)\n",
445 top.hide_kernel_symbols ? "yes" : "no"); 417 top.hide_kernel_symbols ? "yes" : "no");
@@ -466,7 +438,6 @@ static int key_mapped(int c)
466 case 'S': 438 case 'S':
467 return 1; 439 return 1;
468 case 'E': 440 case 'E':
469 case 'w':
470 return top.evlist->nr_entries > 1 ? 1 : 0; 441 return top.evlist->nr_entries > 1 ? 1 : 0;
471 default: 442 default:
472 break; 443 break;
@@ -475,7 +446,7 @@ static int key_mapped(int c)
475 return 0; 446 return 0;
476} 447}
477 448
478static void handle_keypress(struct perf_session *session, int c) 449static void handle_keypress(int c)
479{ 450{
480 if (!key_mapped(c)) { 451 if (!key_mapped(c)) {
481 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; 452 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
@@ -551,7 +522,7 @@ static void handle_keypress(struct perf_session *session, int c)
551 case 'Q': 522 case 'Q':
552 printf("exiting.\n"); 523 printf("exiting.\n");
553 if (dump_symtab) 524 if (dump_symtab)
554 perf_session__fprintf_dsos(session, stderr); 525 perf_session__fprintf_dsos(top.session, stderr);
555 exit(0); 526 exit(0);
556 case 's': 527 case 's':
557 prompt_symbol(&top.sym_filter_entry, "Enter details symbol"); 528 prompt_symbol(&top.sym_filter_entry, "Enter details symbol");
@@ -560,7 +531,7 @@ static void handle_keypress(struct perf_session *session, int c)
560 if (!top.sym_filter_entry) 531 if (!top.sym_filter_entry)
561 break; 532 break;
562 else { 533 else {
563 struct sym_entry *syme = top.sym_filter_entry; 534 struct hist_entry *syme = top.sym_filter_entry;
564 535
565 top.sym_filter_entry = NULL; 536 top.sym_filter_entry = NULL;
566 __zero_source_counters(syme); 537 __zero_source_counters(syme);
@@ -569,9 +540,6 @@ static void handle_keypress(struct perf_session *session, int c)
569 case 'U': 540 case 'U':
570 top.hide_user_symbols = !top.hide_user_symbols; 541 top.hide_user_symbols = !top.hide_user_symbols;
571 break; 542 break;
572 case 'w':
573 top.display_weighted = ~top.display_weighted;
574 break;
575 case 'z': 543 case 'z':
576 top.zero = !top.zero; 544 top.zero = !top.zero;
577 break; 545 break;
@@ -580,19 +548,31 @@ static void handle_keypress(struct perf_session *session, int c)
580 } 548 }
581} 549}
582 550
551static void perf_top__sort_new_samples(void *arg)
552{
553 struct perf_top *t = arg;
554 perf_top__reset_sample_counters(t);
555
556 if (t->evlist->selected != NULL)
557 t->sym_evsel = t->evlist->selected;
558
559 hists__collapse_resort_threaded(&t->sym_evsel->hists);
560 hists__output_resort_threaded(&t->sym_evsel->hists);
561 hists__decay_entries_threaded(&t->sym_evsel->hists,
562 top.hide_user_symbols,
563 top.hide_kernel_symbols);
564 hists__output_recalc_col_len(&t->sym_evsel->hists, winsize.ws_row - 3);
565}
566
583static void *display_thread_tui(void *arg __used) 567static void *display_thread_tui(void *arg __used)
584{ 568{
585 int err = 0; 569 const char *help = "For a higher level overview, try: perf top --sort comm,dso";
586 pthread_mutex_lock(&top.active_symbols_lock); 570
587 while (list_empty(&top.active_symbols)) { 571 perf_top__sort_new_samples(&top);
588 err = pthread_cond_wait(&top.active_symbols_cond, 572 perf_evlist__tui_browse_hists(top.evlist, help,
589 &top.active_symbols_lock); 573 perf_top__sort_new_samples,
590 if (err) 574 &top, top.delay_secs);
591 break; 575
592 }
593 pthread_mutex_unlock(&top.active_symbols_lock);
594 if (!err)
595 perf_top__tui_browser(&top);
596 exit_browser(0); 576 exit_browser(0);
597 exit(0); 577 exit(0);
598 return NULL; 578 return NULL;
@@ -603,7 +583,6 @@ static void *display_thread(void *arg __used)
603 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; 583 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
604 struct termios tc, save; 584 struct termios tc, save;
605 int delay_msecs, c; 585 int delay_msecs, c;
606 struct perf_session *session = (struct perf_session *) arg;
607 586
608 tcgetattr(0, &save); 587 tcgetattr(0, &save);
609 tc = save; 588 tc = save;
@@ -611,20 +590,35 @@ static void *display_thread(void *arg __used)
611 tc.c_cc[VMIN] = 0; 590 tc.c_cc[VMIN] = 0;
612 tc.c_cc[VTIME] = 0; 591 tc.c_cc[VTIME] = 0;
613 592
593 pthread__unblock_sigwinch();
614repeat: 594repeat:
615 delay_msecs = top.delay_secs * 1000; 595 delay_msecs = top.delay_secs * 1000;
616 tcsetattr(0, TCSANOW, &tc); 596 tcsetattr(0, TCSANOW, &tc);
617 /* trash return*/ 597 /* trash return*/
618 getc(stdin); 598 getc(stdin);
619 599
620 do { 600 while (1) {
621 print_sym_table(session); 601 print_sym_table();
622 } while (!poll(&stdin_poll, 1, delay_msecs) == 1); 602 /*
623 603 * Either timeout expired or we got an EINTR due to SIGWINCH,
604 * refresh screen in both cases.
605 */
606 switch (poll(&stdin_poll, 1, delay_msecs)) {
607 case 0:
608 continue;
609 case -1:
610 if (errno == EINTR)
611 continue;
612 /* Fall trhu */
613 default:
614 goto process_hotkey;
615 }
616 }
617process_hotkey:
624 c = getc(stdin); 618 c = getc(stdin);
625 tcsetattr(0, TCSAFLUSH, &save); 619 tcsetattr(0, TCSAFLUSH, &save);
626 620
627 handle_keypress(session, c); 621 handle_keypress(c);
628 goto repeat; 622 goto repeat;
629 623
630 return NULL; 624 return NULL;
@@ -645,9 +639,8 @@ static const char *skip_symbols[] = {
645 NULL 639 NULL
646}; 640};
647 641
648static int symbol_filter(struct map *map, struct symbol *sym) 642static int symbol_filter(struct map *map __used, struct symbol *sym)
649{ 643{
650 struct sym_entry *syme;
651 const char *name = sym->name; 644 const char *name = sym->name;
652 int i; 645 int i;
653 646
@@ -667,16 +660,6 @@ static int symbol_filter(struct map *map, struct symbol *sym)
667 strstr(name, "_text_end")) 660 strstr(name, "_text_end"))
668 return 1; 661 return 1;
669 662
670 syme = symbol__priv(sym);
671 syme->map = map;
672 symbol__annotate_init(map, sym);
673
674 if (!top.sym_filter_entry && sym_filter && !strcmp(name, sym_filter)) {
675 /* schedule initial sym_filter_entry setup */
676 sym_filter_entry_sched = syme;
677 sym_filter = NULL;
678 }
679
680 for (i = 0; skip_symbols[i]; i++) { 663 for (i = 0; skip_symbols[i]; i++) {
681 if (!strcmp(skip_symbols[i], name)) { 664 if (!strcmp(skip_symbols[i], name)) {
682 sym->ignore = true; 665 sym->ignore = true;
@@ -691,10 +674,11 @@ static void perf_event__process_sample(const union perf_event *event,
691 struct perf_sample *sample, 674 struct perf_sample *sample,
692 struct perf_session *session) 675 struct perf_session *session)
693{ 676{
677 struct symbol *parent = NULL;
694 u64 ip = event->ip.ip; 678 u64 ip = event->ip.ip;
695 struct sym_entry *syme;
696 struct addr_location al; 679 struct addr_location al;
697 struct machine *machine; 680 struct machine *machine;
681 int err;
698 u8 origin = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 682 u8 origin = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
699 683
700 ++top.samples; 684 ++top.samples;
@@ -783,46 +767,41 @@ static void perf_event__process_sample(const union perf_event *event,
783 sleep(5); 767 sleep(5);
784 vmlinux_warned = true; 768 vmlinux_warned = true;
785 } 769 }
786
787 return;
788 }
789
790 /* let's see, whether we need to install initial sym_filter_entry */
791 if (sym_filter_entry_sched) {
792 top.sym_filter_entry = sym_filter_entry_sched;
793 sym_filter_entry_sched = NULL;
794 if (parse_source(top.sym_filter_entry) < 0) {
795 struct symbol *sym = sym_entry__symbol(top.sym_filter_entry);
796
797 pr_err("Can't annotate %s", sym->name);
798 if (top.sym_filter_entry->map->dso->symtab_type == SYMTAB__KALLSYMS) {
799 pr_err(": No vmlinux file was found in the path:\n");
800 machine__fprintf_vmlinux_path(machine, stderr);
801 } else
802 pr_err(".\n");
803 exit(1);
804 }
805 } 770 }
806 771
807 syme = symbol__priv(al.sym); 772 if (al.sym == NULL || !al.sym->ignore) {
808 if (!al.sym->ignore) {
809 struct perf_evsel *evsel; 773 struct perf_evsel *evsel;
774 struct hist_entry *he;
810 775
811 evsel = perf_evlist__id2evsel(top.evlist, sample->id); 776 evsel = perf_evlist__id2evsel(top.evlist, sample->id);
812 assert(evsel != NULL); 777 assert(evsel != NULL);
813 syme->count[evsel->idx]++; 778
814 record_precise_ip(syme, al.map, evsel->idx, ip); 779 if ((sort__has_parent || symbol_conf.use_callchain) &&
815 pthread_mutex_lock(&top.active_symbols_lock); 780 sample->callchain) {
816 if (list_empty(&syme->node) || !syme->node.next) { 781 err = perf_session__resolve_callchain(session, al.thread,
817 static bool first = true; 782 sample->callchain, &parent);
818 __list_insert_active_sym(syme); 783 if (err)
819 if (first) { 784 return;
820 pthread_cond_broadcast(&top.active_symbols_cond);
821 first = false;
822 }
823 } 785 }
824 pthread_mutex_unlock(&top.active_symbols_lock); 786
787 he = perf_session__add_hist_entry(session, &al, sample, evsel);
788 if (he == NULL) {
789 pr_err("Problem incrementing symbol period, skipping event\n");
790 return;
791 }
792
793 if (symbol_conf.use_callchain) {
794 err = callchain_append(he->callchain, &session->callchain_cursor,
795 sample->period);
796 if (err)
797 return;
798 }
799
800 if (sort_has_symbols)
801 record_precise_ip(he, evsel->idx, ip);
825 } 802 }
803
804 return;
826} 805}
827 806
828static void perf_session__mmap_read_idx(struct perf_session *self, int idx) 807static void perf_session__mmap_read_idx(struct perf_session *self, int idx)
@@ -873,7 +852,11 @@ static void start_counters(struct perf_evlist *evlist)
873 attr->read_format |= PERF_FORMAT_ID; 852 attr->read_format |= PERF_FORMAT_ID;
874 } 853 }
875 854
855 if (symbol_conf.use_callchain)
856 attr->sample_type |= PERF_SAMPLE_CALLCHAIN;
857
876 attr->mmap = 1; 858 attr->mmap = 1;
859 attr->comm = 1;
877 attr->inherit = inherit; 860 attr->inherit = inherit;
878try_again: 861try_again:
879 if (perf_evsel__open(counter, top.evlist->cpus, 862 if (perf_evsel__open(counter, top.evlist->cpus,
@@ -928,35 +911,56 @@ out_err:
928 exit(0); 911 exit(0);
929} 912}
930 913
914static int setup_sample_type(void)
915{
916 if (!sort_has_symbols) {
917 if (symbol_conf.use_callchain) {
918 ui__warning("Selected -g but \"sym\" not present in --sort/-s.");
919 return -EINVAL;
920 }
921 } else if (!dont_use_callchains && callchain_param.mode != CHAIN_NONE) {
922 if (callchain_register_param(&callchain_param) < 0) {
923 ui__warning("Can't register callchain params.\n");
924 return -EINVAL;
925 }
926 }
927
928 return 0;
929}
930
931static int __cmd_top(void) 931static int __cmd_top(void)
932{ 932{
933 pthread_t thread; 933 pthread_t thread;
934 int ret __used; 934 int ret;
935 /* 935 /*
936 * FIXME: perf_session__new should allow passing a O_MMAP, so that all this 936 * FIXME: perf_session__new should allow passing a O_MMAP, so that all this
937 * mmap reading, etc is encapsulated in it. Use O_WRONLY for now. 937 * mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
938 */ 938 */
939 struct perf_session *session = perf_session__new(NULL, O_WRONLY, false, false, NULL); 939 top.session = perf_session__new(NULL, O_WRONLY, false, false, NULL);
940 if (session == NULL) 940 if (top.session == NULL)
941 return -ENOMEM; 941 return -ENOMEM;
942 942
943 ret = setup_sample_type();
944 if (ret)
945 goto out_delete;
946
943 if (top.target_tid != -1) 947 if (top.target_tid != -1)
944 perf_event__synthesize_thread_map(top.evlist->threads, 948 perf_event__synthesize_thread_map(top.evlist->threads,
945 perf_event__process, session); 949 perf_event__process, top.session);
946 else 950 else
947 perf_event__synthesize_threads(perf_event__process, session); 951 perf_event__synthesize_threads(perf_event__process, top.session);
948 952
949 start_counters(top.evlist); 953 start_counters(top.evlist);
950 session->evlist = top.evlist; 954 top.session->evlist = top.evlist;
951 perf_session__update_sample_type(session); 955 perf_session__update_sample_type(top.session);
952 956
953 /* Wait for a minimal set of events before starting the snapshot */ 957 /* Wait for a minimal set of events before starting the snapshot */
954 poll(top.evlist->pollfd, top.evlist->nr_fds, 100); 958 poll(top.evlist->pollfd, top.evlist->nr_fds, 100);
955 959
956 perf_session__mmap_read(session); 960 perf_session__mmap_read(top.session);
957 961
958 if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui : 962 if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui :
959 display_thread), session)) { 963 display_thread), NULL)) {
960 printf("Could not create display thread.\n"); 964 printf("Could not create display thread.\n");
961 exit(-1); 965 exit(-1);
962 } 966 }
@@ -974,12 +978,96 @@ static int __cmd_top(void)
974 while (1) { 978 while (1) {
975 u64 hits = top.samples; 979 u64 hits = top.samples;
976 980
977 perf_session__mmap_read(session); 981 perf_session__mmap_read(top.session);
978 982
979 if (hits == top.samples) 983 if (hits == top.samples)
980 ret = poll(top.evlist->pollfd, top.evlist->nr_fds, 100); 984 ret = poll(top.evlist->pollfd, top.evlist->nr_fds, 100);
981 } 985 }
982 986
987out_delete:
988 perf_session__delete(top.session);
989 top.session = NULL;
990
991 return 0;
992}
993
994static int
995parse_callchain_opt(const struct option *opt __used, const char *arg,
996 int unset)
997{
998 char *tok, *tok2;
999 char *endptr;
1000
1001 /*
1002 * --no-call-graph
1003 */
1004 if (unset) {
1005 dont_use_callchains = true;
1006 return 0;
1007 }
1008
1009 symbol_conf.use_callchain = true;
1010
1011 if (!arg)
1012 return 0;
1013
1014 tok = strtok((char *)arg, ",");
1015 if (!tok)
1016 return -1;
1017
1018 /* get the output mode */
1019 if (!strncmp(tok, "graph", strlen(arg)))
1020 callchain_param.mode = CHAIN_GRAPH_ABS;
1021
1022 else if (!strncmp(tok, "flat", strlen(arg)))
1023 callchain_param.mode = CHAIN_FLAT;
1024
1025 else if (!strncmp(tok, "fractal", strlen(arg)))
1026 callchain_param.mode = CHAIN_GRAPH_REL;
1027
1028 else if (!strncmp(tok, "none", strlen(arg))) {
1029 callchain_param.mode = CHAIN_NONE;
1030 symbol_conf.use_callchain = false;
1031
1032 return 0;
1033 }
1034
1035 else
1036 return -1;
1037
1038 /* get the min percentage */
1039 tok = strtok(NULL, ",");
1040 if (!tok)
1041 goto setup;
1042
1043 callchain_param.min_percent = strtod(tok, &endptr);
1044 if (tok == endptr)
1045 return -1;
1046
1047 /* get the print limit */
1048 tok2 = strtok(NULL, ",");
1049 if (!tok2)
1050 goto setup;
1051
1052 if (tok2[0] != 'c') {
1053 callchain_param.print_limit = strtod(tok2, &endptr);
1054 tok2 = strtok(NULL, ",");
1055 if (!tok2)
1056 goto setup;
1057 }
1058
1059 /* get the call chain order */
1060 if (!strcmp(tok2, "caller"))
1061 callchain_param.order = ORDER_CALLER;
1062 else if (!strcmp(tok2, "callee"))
1063 callchain_param.order = ORDER_CALLEE;
1064 else
1065 return -1;
1066setup:
1067 if (callchain_register_param(&callchain_param) < 0) {
1068 fprintf(stderr, "Can't register callchain params\n");
1069 return -1;
1070 }
983 return 0; 1071 return 0;
984} 1072}
985 1073
@@ -1019,7 +1107,7 @@ static const struct option options[] = {
1019 "put the counters into a counter group"), 1107 "put the counters into a counter group"),
1020 OPT_BOOLEAN('i', "inherit", &inherit, 1108 OPT_BOOLEAN('i', "inherit", &inherit,
1021 "child tasks inherit counters"), 1109 "child tasks inherit counters"),
1022 OPT_STRING('s', "sym-annotate", &sym_filter, "symbol name", 1110 OPT_STRING(0, "sym-annotate", &sym_filter, "symbol name",
1023 "symbol to annotate"), 1111 "symbol to annotate"),
1024 OPT_BOOLEAN('z', "zero", &top.zero, 1112 OPT_BOOLEAN('z', "zero", &top.zero,
1025 "zero history across updates"), 1113 "zero history across updates"),
@@ -1033,6 +1121,28 @@ static const struct option options[] = {
1033 OPT_BOOLEAN(0, "stdio", &use_stdio, "Use the stdio interface"), 1121 OPT_BOOLEAN(0, "stdio", &use_stdio, "Use the stdio interface"),
1034 OPT_INCR('v', "verbose", &verbose, 1122 OPT_INCR('v', "verbose", &verbose,
1035 "be more verbose (show counter open errors, etc)"), 1123 "be more verbose (show counter open errors, etc)"),
1124 OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
1125 "sort by key(s): pid, comm, dso, symbol, parent"),
1126 OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
1127 "Show a column with the number of samples"),
1128 OPT_CALLBACK_DEFAULT('G', "call-graph", NULL, "output_type,min_percent, call_order",
1129 "Display callchains using output_type (graph, flat, fractal, or none), min percent threshold and callchain order. "
1130 "Default: fractal,0.5,callee", &parse_callchain_opt,
1131 callchain_default_opt),
1132 OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
1133 "Show a column with the sum of periods"),
1134 OPT_STRING(0, "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
1135 "only consider symbols in these dsos"),
1136 OPT_STRING(0, "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
1137 "only consider symbols in these comms"),
1138 OPT_STRING(0, "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
1139 "only consider these symbols"),
1140 OPT_BOOLEAN(0, "source", &symbol_conf.annotate_src,
1141 "Interleave source code with assembly code (default)"),
1142 OPT_BOOLEAN(0, "asm-raw", &symbol_conf.annotate_asm_raw,
1143 "Display raw encoding of assembly instructions (default)"),
1144 OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
1145 "Specify disassembler style (e.g. -M intel for intel syntax)"),
1036 OPT_END() 1146 OPT_END()
1037}; 1147};
1038 1148
@@ -1045,18 +1155,16 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1045 if (top.evlist == NULL) 1155 if (top.evlist == NULL)
1046 return -ENOMEM; 1156 return -ENOMEM;
1047 1157
1048 page_size = sysconf(_SC_PAGE_SIZE); 1158 symbol_conf.exclude_other = false;
1049 1159
1050 argc = parse_options(argc, argv, options, top_usage, 0); 1160 argc = parse_options(argc, argv, options, top_usage, 0);
1051 if (argc) 1161 if (argc)
1052 usage_with_options(top_usage, options); 1162 usage_with_options(top_usage, options);
1053 1163
1054 /* 1164 if (sort_order == default_sort_order)
1055 * XXX For now start disabled, only using TUI if explicitely asked for. 1165 sort_order = "dso,symbol";
1056 * Change that when handle_keys equivalent gets written, live annotation 1166
1057 * done, etc. 1167 setup_sorting(top_usage, options);
1058 */
1059 use_browser = 0;
1060 1168
1061 if (use_stdio) 1169 if (use_stdio)
1062 use_browser = 0; 1170 use_browser = 0;
@@ -1119,13 +1227,22 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1119 1227
1120 top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node); 1228 top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node);
1121 1229
1122 symbol_conf.priv_size = (sizeof(struct sym_entry) + sizeof(struct annotation) + 1230 symbol_conf.priv_size = sizeof(struct annotation);
1123 (top.evlist->nr_entries + 1) * sizeof(unsigned long));
1124 1231
1125 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); 1232 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
1126 if (symbol__init() < 0) 1233 if (symbol__init() < 0)
1127 return -1; 1234 return -1;
1128 1235
1236 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", stdout);
1237 sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout);
1238 sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout);
1239
1240 /*
1241 * Avoid annotation data structures overhead when symbols aren't on the
1242 * sort list.
1243 */
1244 sort_has_symbols = sort_sym.list.next != NULL;
1245
1129 get_term_dimensions(&winsize); 1246 get_term_dimensions(&winsize);
1130 if (top.print_entries == 0) { 1247 if (top.print_entries == 0) {
1131 update_print_entries(&winsize); 1248 update_print_entries(&winsize);
diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index 4702e2443a8e..b382bd551aac 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -4,7 +4,6 @@
4#include "util/util.h" 4#include "util/util.h"
5#include "util/strbuf.h" 5#include "util/strbuf.h"
6 6
7extern const char perf_version_string[];
8extern const char perf_usage_string[]; 7extern const char perf_usage_string[];
9extern const char perf_more_info_string[]; 8extern const char perf_more_info_string[];
10 9
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index ec635b7cc8ea..73d0cac8b67e 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -427,6 +427,24 @@ static void get_debugfs_mntpt(void)
427 debugfs_mntpt[0] = '\0'; 427 debugfs_mntpt[0] = '\0';
428} 428}
429 429
430static void pthread__block_sigwinch(void)
431{
432 sigset_t set;
433
434 sigemptyset(&set);
435 sigaddset(&set, SIGWINCH);
436 pthread_sigmask(SIG_BLOCK, &set, NULL);
437}
438
439void pthread__unblock_sigwinch(void)
440{
441 sigset_t set;
442
443 sigemptyset(&set);
444 sigaddset(&set, SIGWINCH);
445 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
446}
447
430int main(int argc, const char **argv) 448int main(int argc, const char **argv)
431{ 449{
432 const char *cmd; 450 const char *cmd;
@@ -480,6 +498,12 @@ int main(int argc, const char **argv)
480 * time. 498 * time.
481 */ 499 */
482 setup_path(); 500 setup_path();
501 /*
502 * Block SIGWINCH notifications so that the thread that wants it can
503 * unblock and get syscalls like select interrupted instead of waiting
504 * forever while the signal goes to some other non interested thread.
505 */
506 pthread__block_sigwinch();
483 507
484 while (1) { 508 while (1) {
485 static int done_help; 509 static int done_help;
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index a5fc660c1f12..914c895510f7 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -9,18 +9,21 @@ void get_term_dimensions(struct winsize *ws);
9#include "../../arch/x86/include/asm/unistd.h" 9#include "../../arch/x86/include/asm/unistd.h"
10#define rmb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory") 10#define rmb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory")
11#define cpu_relax() asm volatile("rep; nop" ::: "memory"); 11#define cpu_relax() asm volatile("rep; nop" ::: "memory");
12#define CPUINFO_PROC "model name"
12#endif 13#endif
13 14
14#if defined(__x86_64__) 15#if defined(__x86_64__)
15#include "../../arch/x86/include/asm/unistd.h" 16#include "../../arch/x86/include/asm/unistd.h"
16#define rmb() asm volatile("lfence" ::: "memory") 17#define rmb() asm volatile("lfence" ::: "memory")
17#define cpu_relax() asm volatile("rep; nop" ::: "memory"); 18#define cpu_relax() asm volatile("rep; nop" ::: "memory");
19#define CPUINFO_PROC "model name"
18#endif 20#endif
19 21
20#ifdef __powerpc__ 22#ifdef __powerpc__
21#include "../../arch/powerpc/include/asm/unistd.h" 23#include "../../arch/powerpc/include/asm/unistd.h"
22#define rmb() asm volatile ("sync" ::: "memory") 24#define rmb() asm volatile ("sync" ::: "memory")
23#define cpu_relax() asm volatile ("" ::: "memory"); 25#define cpu_relax() asm volatile ("" ::: "memory");
26#define CPUINFO_PROC "cpu"
24#endif 27#endif
25 28
26#ifdef __s390__ 29#ifdef __s390__
@@ -37,30 +40,35 @@ void get_term_dimensions(struct winsize *ws);
37# define rmb() asm volatile("" ::: "memory") 40# define rmb() asm volatile("" ::: "memory")
38#endif 41#endif
39#define cpu_relax() asm volatile("" ::: "memory") 42#define cpu_relax() asm volatile("" ::: "memory")
43#define CPUINFO_PROC "cpu type"
40#endif 44#endif
41 45
42#ifdef __hppa__ 46#ifdef __hppa__
43#include "../../arch/parisc/include/asm/unistd.h" 47#include "../../arch/parisc/include/asm/unistd.h"
44#define rmb() asm volatile("" ::: "memory") 48#define rmb() asm volatile("" ::: "memory")
45#define cpu_relax() asm volatile("" ::: "memory"); 49#define cpu_relax() asm volatile("" ::: "memory");
50#define CPUINFO_PROC "cpu"
46#endif 51#endif
47 52
48#ifdef __sparc__ 53#ifdef __sparc__
49#include "../../arch/sparc/include/asm/unistd.h" 54#include "../../arch/sparc/include/asm/unistd.h"
50#define rmb() asm volatile("":::"memory") 55#define rmb() asm volatile("":::"memory")
51#define cpu_relax() asm volatile("":::"memory") 56#define cpu_relax() asm volatile("":::"memory")
57#define CPUINFO_PROC "cpu"
52#endif 58#endif
53 59
54#ifdef __alpha__ 60#ifdef __alpha__
55#include "../../arch/alpha/include/asm/unistd.h" 61#include "../../arch/alpha/include/asm/unistd.h"
56#define rmb() asm volatile("mb" ::: "memory") 62#define rmb() asm volatile("mb" ::: "memory")
57#define cpu_relax() asm volatile("" ::: "memory") 63#define cpu_relax() asm volatile("" ::: "memory")
64#define CPUINFO_PROC "cpu model"
58#endif 65#endif
59 66
60#ifdef __ia64__ 67#ifdef __ia64__
61#include "../../arch/ia64/include/asm/unistd.h" 68#include "../../arch/ia64/include/asm/unistd.h"
62#define rmb() asm volatile ("mf" ::: "memory") 69#define rmb() asm volatile ("mf" ::: "memory")
63#define cpu_relax() asm volatile ("hint @pause" ::: "memory") 70#define cpu_relax() asm volatile ("hint @pause" ::: "memory")
71#define CPUINFO_PROC "model name"
64#endif 72#endif
65 73
66#ifdef __arm__ 74#ifdef __arm__
@@ -71,6 +79,7 @@ void get_term_dimensions(struct winsize *ws);
71 */ 79 */
72#define rmb() ((void(*)(void))0xffff0fa0)() 80#define rmb() ((void(*)(void))0xffff0fa0)()
73#define cpu_relax() asm volatile("":::"memory") 81#define cpu_relax() asm volatile("":::"memory")
82#define CPUINFO_PROC "Processor"
74#endif 83#endif
75 84
76#ifdef __mips__ 85#ifdef __mips__
@@ -83,6 +92,7 @@ void get_term_dimensions(struct winsize *ws);
83 : /* no input */ \ 92 : /* no input */ \
84 : "memory") 93 : "memory")
85#define cpu_relax() asm volatile("" ::: "memory") 94#define cpu_relax() asm volatile("" ::: "memory")
95#define CPUINFO_PROC "cpu model"
86#endif 96#endif
87 97
88#include <time.h> 98#include <time.h>
@@ -171,5 +181,8 @@ struct ip_callchain {
171}; 181};
172 182
173extern bool perf_host, perf_guest; 183extern bool perf_host, perf_guest;
184extern const char perf_version_string[];
185
186void pthread__unblock_sigwinch(void);
174 187
175#endif 188#endif
diff --git a/tools/perf/scripts/python/bin/net_dropmonitor-record b/tools/perf/scripts/python/bin/net_dropmonitor-record
new file mode 100755
index 000000000000..423fb81dadae
--- /dev/null
+++ b/tools/perf/scripts/python/bin/net_dropmonitor-record
@@ -0,0 +1,2 @@
1#!/bin/bash
2perf record -e skb:kfree_skb $@
diff --git a/tools/perf/scripts/python/bin/net_dropmonitor-report b/tools/perf/scripts/python/bin/net_dropmonitor-report
new file mode 100755
index 000000000000..8d698f5a06aa
--- /dev/null
+++ b/tools/perf/scripts/python/bin/net_dropmonitor-report
@@ -0,0 +1,4 @@
1#!/bin/bash
2# description: display a table of dropped frames
3
4perf script -s "$PERF_EXEC_PATH"/scripts/python/net_dropmonitor.py $@
diff --git a/tools/perf/scripts/python/net_dropmonitor.py b/tools/perf/scripts/python/net_dropmonitor.py
new file mode 100755
index 000000000000..a4ffc9500023
--- /dev/null
+++ b/tools/perf/scripts/python/net_dropmonitor.py
@@ -0,0 +1,72 @@
1# Monitor the system for dropped packets and proudce a report of drop locations and counts
2
3import os
4import sys
5
6sys.path.append(os.environ['PERF_EXEC_PATH'] + \
7 '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
8
9from perf_trace_context import *
10from Core import *
11from Util import *
12
13drop_log = {}
14kallsyms = []
15
16def get_kallsyms_table():
17 global kallsyms
18 try:
19 f = open("/proc/kallsyms", "r")
20 linecount = 0
21 for line in f:
22 linecount = linecount+1
23 f.seek(0)
24 except:
25 return
26
27
28 j = 0
29 for line in f:
30 loc = int(line.split()[0], 16)
31 name = line.split()[2]
32 j = j +1
33 if ((j % 100) == 0):
34 print "\r" + str(j) + "/" + str(linecount),
35 kallsyms.append({ 'loc': loc, 'name' : name})
36
37 print "\r" + str(j) + "/" + str(linecount)
38 kallsyms.sort()
39 return
40
41def get_sym(sloc):
42 loc = int(sloc)
43 for i in kallsyms:
44 if (i['loc'] >= loc):
45 return (i['name'], i['loc']-loc)
46 return (None, 0)
47
48def print_drop_table():
49 print "%25s %25s %25s" % ("LOCATION", "OFFSET", "COUNT")
50 for i in drop_log.keys():
51 (sym, off) = get_sym(i)
52 if sym == None:
53 sym = i
54 print "%25s %25s %25s" % (sym, off, drop_log[i])
55
56
57def trace_begin():
58 print "Starting trace (Ctrl-C to dump results)"
59
60def trace_end():
61 print "Gathering kallsyms data"
62 get_kallsyms_table()
63 print_drop_table()
64
65# called from perf, when it finds a correspoinding event
66def skb__kfree_skb(name, context, cpu, sec, nsec, pid, comm,
67 skbaddr, protocol, location):
68 slocation = str(location)
69 try:
70 drop_log[slocation] = drop_log[slocation] + 1
71 except:
72 drop_log[slocation] = 1
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index e01af2b1a469..bc8f4773d4d8 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -16,6 +16,8 @@
16#include "annotate.h" 16#include "annotate.h"
17#include <pthread.h> 17#include <pthread.h>
18 18
19const char *disassembler_style;
20
19int symbol__annotate_init(struct map *map __used, struct symbol *sym) 21int symbol__annotate_init(struct map *map __used, struct symbol *sym)
20{ 22{
21 struct annotation *notes = symbol__annotation(sym); 23 struct annotation *notes = symbol__annotation(sym);
@@ -323,10 +325,15 @@ fallback:
323 dso, dso->long_name, sym, sym->name); 325 dso, dso->long_name, sym, sym->name);
324 326
325 snprintf(command, sizeof(command), 327 snprintf(command, sizeof(command),
326 "objdump --start-address=0x%016" PRIx64 328 "objdump %s%s --start-address=0x%016" PRIx64
327 " --stop-address=0x%016" PRIx64 " -dS -C %s|grep -v %s|expand", 329 " --stop-address=0x%016" PRIx64
330 " -d %s %s -C %s|grep -v %s|expand",
331 disassembler_style ? "-M " : "",
332 disassembler_style ? disassembler_style : "",
328 map__rip_2objdump(map, sym->start), 333 map__rip_2objdump(map, sym->start),
329 map__rip_2objdump(map, sym->end), 334 map__rip_2objdump(map, sym->end),
335 symbol_conf.annotate_asm_raw ? "" : "--no-show-raw",
336 symbol_conf.annotate_src ? "-S" : "",
330 symfs_filename, filename); 337 symfs_filename, filename);
331 338
332 pr_debug("Executing: %s\n", command); 339 pr_debug("Executing: %s\n", command);
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index c2c286896801..d9072523d342 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -91,13 +91,18 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx,
91#ifdef NO_NEWT_SUPPORT 91#ifdef NO_NEWT_SUPPORT
92static inline int symbol__tui_annotate(struct symbol *sym __used, 92static inline int symbol__tui_annotate(struct symbol *sym __used,
93 struct map *map __used, 93 struct map *map __used,
94 int evidx __used, int refresh __used) 94 int evidx __used,
95 void(*timer)(void *arg) __used,
96 void *arg __used, int delay_secs __used)
95{ 97{
96 return 0; 98 return 0;
97} 99}
98#else 100#else
99int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, 101int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
100 int refresh); 102 int nr_events, void(*timer)(void *arg), void *arg,
103 int delay_secs);
101#endif 104#endif
102 105
106extern const char *disassembler_style;
107
103#endif /* __PERF_ANNOTATE_H */ 108#endif /* __PERF_ANNOTATE_H */
diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c
index e191eb9a667f..521c38a79190 100644
--- a/tools/perf/util/color.c
+++ b/tools/perf/util/color.c
@@ -200,7 +200,7 @@ static int __color_vfprintf(FILE *fp, const char *color, const char *fmt,
200 * Auto-detect: 200 * Auto-detect:
201 */ 201 */
202 if (perf_use_color_default < 0) { 202 if (perf_use_color_default < 0) {
203 if (isatty(1) || pager_in_use()) 203 if (isatty(fileno(fp)) || pager_in_use())
204 perf_use_color_default = 1; 204 perf_use_color_default = 1;
205 else 205 else
206 perf_use_color_default = 0; 206 perf_use_color_default = 0;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 72e9f4886b6d..2f6bc89027da 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -533,3 +533,9 @@ bool perf_evlist__sample_id_all(const struct perf_evlist *evlist)
533 first = list_entry(evlist->entries.next, struct perf_evsel, node); 533 first = list_entry(evlist->entries.next, struct perf_evsel, node);
534 return first->attr.sample_id_all; 534 return first->attr.sample_id_all;
535} 535}
536
537void perf_evlist__set_selected(struct perf_evlist *evlist,
538 struct perf_evsel *evsel)
539{
540 evlist->selected = evsel;
541}
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index f34915002745..6be71fc57794 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -25,6 +25,7 @@ struct perf_evlist {
25 struct pollfd *pollfd; 25 struct pollfd *pollfd;
26 struct thread_map *threads; 26 struct thread_map *threads;
27 struct cpu_map *cpus; 27 struct cpu_map *cpus;
28 struct perf_evsel *selected;
28}; 29};
29 30
30struct perf_evsel; 31struct perf_evsel;
@@ -56,6 +57,9 @@ void perf_evlist__munmap(struct perf_evlist *evlist);
56void perf_evlist__disable(struct perf_evlist *evlist); 57void perf_evlist__disable(struct perf_evlist *evlist);
57void perf_evlist__enable(struct perf_evlist *evlist); 58void perf_evlist__enable(struct perf_evlist *evlist);
58 59
60void perf_evlist__set_selected(struct perf_evlist *evlist,
61 struct perf_evsel *evsel);
62
59static inline void perf_evlist__set_maps(struct perf_evlist *evlist, 63static inline void perf_evlist__set_maps(struct perf_evlist *evlist,
60 struct cpu_map *cpus, 64 struct cpu_map *cpus,
61 struct thread_map *threads) 65 struct thread_map *threads)
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index e389815078d3..b46f6e4bff3c 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -39,6 +39,7 @@ void perf_evsel__init(struct perf_evsel *evsel,
39 evsel->idx = idx; 39 evsel->idx = idx;
40 evsel->attr = *attr; 40 evsel->attr = *attr;
41 INIT_LIST_HEAD(&evsel->node); 41 INIT_LIST_HEAD(&evsel->node);
42 hists__init(&evsel->hists);
42} 43}
43 44
44struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx) 45struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx)
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index b6c1ad123ca9..76c0b2c49eb8 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -7,6 +7,7 @@
7#include <stdlib.h> 7#include <stdlib.h>
8#include <linux/list.h> 8#include <linux/list.h>
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <sys/utsname.h>
10 11
11#include "evlist.h" 12#include "evlist.h"
12#include "evsel.h" 13#include "evsel.h"
@@ -17,12 +18,19 @@
17#include "session.h" 18#include "session.h"
18#include "symbol.h" 19#include "symbol.h"
19#include "debug.h" 20#include "debug.h"
21#include "cpumap.h"
20 22
21static bool no_buildid_cache = false; 23static bool no_buildid_cache = false;
22 24
23static int event_count; 25static int event_count;
24static struct perf_trace_event_type *events; 26static struct perf_trace_event_type *events;
25 27
28static u32 header_argc;
29static const char **header_argv;
30
31static int dsos__write_buildid_table(struct perf_header *header, int fd);
32static int perf_session__cache_build_ids(struct perf_session *session);
33
26int perf_header__push_event(u64 id, const char *name) 34int perf_header__push_event(u64 id, const char *name)
27{ 35{
28 if (strlen(name) > MAX_EVENT_NAME) 36 if (strlen(name) > MAX_EVENT_NAME)
@@ -110,6 +118,1020 @@ static int write_padded(int fd, const void *bf, size_t count,
110 return err; 118 return err;
111} 119}
112 120
121static int do_write_string(int fd, const char *str)
122{
123 u32 len, olen;
124 int ret;
125
126 olen = strlen(str) + 1;
127 len = ALIGN(olen, NAME_ALIGN);
128
129 /* write len, incl. \0 */
130 ret = do_write(fd, &len, sizeof(len));
131 if (ret < 0)
132 return ret;
133
134 return write_padded(fd, str, olen, len);
135}
136
137static char *do_read_string(int fd, struct perf_header *ph)
138{
139 ssize_t sz, ret;
140 u32 len;
141 char *buf;
142
143 sz = read(fd, &len, sizeof(len));
144 if (sz < (ssize_t)sizeof(len))
145 return NULL;
146
147 if (ph->needs_swap)
148 len = bswap_32(len);
149
150 buf = malloc(len);
151 if (!buf)
152 return NULL;
153
154 ret = read(fd, buf, len);
155 if (ret == (ssize_t)len) {
156 /*
157 * strings are padded by zeroes
158 * thus the actual strlen of buf
159 * may be less than len
160 */
161 return buf;
162 }
163
164 free(buf);
165 return NULL;
166}
167
168int
169perf_header__set_cmdline(int argc, const char **argv)
170{
171 int i;
172
173 header_argc = (u32)argc;
174
175 /* do not include NULL termination */
176 header_argv = calloc(argc, sizeof(char *));
177 if (!header_argv)
178 return -ENOMEM;
179
180 /*
181 * must copy argv contents because it gets moved
182 * around during option parsing
183 */
184 for (i = 0; i < argc ; i++)
185 header_argv[i] = argv[i];
186
187 return 0;
188}
189
190static int write_trace_info(int fd, struct perf_header *h __used,
191 struct perf_evlist *evlist)
192{
193 return read_tracing_data(fd, &evlist->entries);
194}
195
196
197static int write_build_id(int fd, struct perf_header *h,
198 struct perf_evlist *evlist __used)
199{
200 struct perf_session *session;
201 int err;
202
203 session = container_of(h, struct perf_session, header);
204
205 err = dsos__write_buildid_table(h, fd);
206 if (err < 0) {
207 pr_debug("failed to write buildid table\n");
208 return err;
209 }
210 if (!no_buildid_cache)
211 perf_session__cache_build_ids(session);
212
213 return 0;
214}
215
216static int write_hostname(int fd, struct perf_header *h __used,
217 struct perf_evlist *evlist __used)
218{
219 struct utsname uts;
220 int ret;
221
222 ret = uname(&uts);
223 if (ret < 0)
224 return -1;
225
226 return do_write_string(fd, uts.nodename);
227}
228
229static int write_osrelease(int fd, struct perf_header *h __used,
230 struct perf_evlist *evlist __used)
231{
232 struct utsname uts;
233 int ret;
234
235 ret = uname(&uts);
236 if (ret < 0)
237 return -1;
238
239 return do_write_string(fd, uts.release);
240}
241
242static int write_arch(int fd, struct perf_header *h __used,
243 struct perf_evlist *evlist __used)
244{
245 struct utsname uts;
246 int ret;
247
248 ret = uname(&uts);
249 if (ret < 0)
250 return -1;
251
252 return do_write_string(fd, uts.machine);
253}
254
255static int write_version(int fd, struct perf_header *h __used,
256 struct perf_evlist *evlist __used)
257{
258 return do_write_string(fd, perf_version_string);
259}
260
261static int write_cpudesc(int fd, struct perf_header *h __used,
262 struct perf_evlist *evlist __used)
263{
264#ifndef CPUINFO_PROC
265#define CPUINFO_PROC NULL
266#endif
267 FILE *file;
268 char *buf = NULL;
269 char *s, *p;
270 const char *search = CPUINFO_PROC;
271 size_t len = 0;
272 int ret = -1;
273
274 if (!search)
275 return -1;
276
277 file = fopen("/proc/cpuinfo", "r");
278 if (!file)
279 return -1;
280
281 while (getline(&buf, &len, file) > 0) {
282 ret = strncmp(buf, search, strlen(search));
283 if (!ret)
284 break;
285 }
286
287 if (ret)
288 goto done;
289
290 s = buf;
291
292 p = strchr(buf, ':');
293 if (p && *(p+1) == ' ' && *(p+2))
294 s = p + 2;
295 p = strchr(s, '\n');
296 if (p)
297 *p = '\0';
298
299 /* squash extra space characters (branding string) */
300 p = s;
301 while (*p) {
302 if (isspace(*p)) {
303 char *r = p + 1;
304 char *q = r;
305 *p = ' ';
306 while (*q && isspace(*q))
307 q++;
308 if (q != (p+1))
309 while ((*r++ = *q++));
310 }
311 p++;
312 }
313 ret = do_write_string(fd, s);
314done:
315 free(buf);
316 fclose(file);
317 return ret;
318}
319
320static int write_nrcpus(int fd, struct perf_header *h __used,
321 struct perf_evlist *evlist __used)
322{
323 long nr;
324 u32 nrc, nra;
325 int ret;
326
327 nr = sysconf(_SC_NPROCESSORS_CONF);
328 if (nr < 0)
329 return -1;
330
331 nrc = (u32)(nr & UINT_MAX);
332
333 nr = sysconf(_SC_NPROCESSORS_ONLN);
334 if (nr < 0)
335 return -1;
336
337 nra = (u32)(nr & UINT_MAX);
338
339 ret = do_write(fd, &nrc, sizeof(nrc));
340 if (ret < 0)
341 return ret;
342
343 return do_write(fd, &nra, sizeof(nra));
344}
345
346static int write_event_desc(int fd, struct perf_header *h __used,
347 struct perf_evlist *evlist)
348{
349 struct perf_evsel *attr;
350 u32 nre = 0, nri, sz;
351 int ret;
352
353 list_for_each_entry(attr, &evlist->entries, node)
354 nre++;
355
356 /*
357 * write number of events
358 */
359 ret = do_write(fd, &nre, sizeof(nre));
360 if (ret < 0)
361 return ret;
362
363 /*
364 * size of perf_event_attr struct
365 */
366 sz = (u32)sizeof(attr->attr);
367 ret = do_write(fd, &sz, sizeof(sz));
368 if (ret < 0)
369 return ret;
370
371 list_for_each_entry(attr, &evlist->entries, node) {
372
373 ret = do_write(fd, &attr->attr, sz);
374 if (ret < 0)
375 return ret;
376 /*
377 * write number of unique id per event
378 * there is one id per instance of an event
379 *
380 * copy into an nri to be independent of the
381 * type of ids,
382 */
383 nri = attr->ids;
384 ret = do_write(fd, &nri, sizeof(nri));
385 if (ret < 0)
386 return ret;
387
388 /*
389 * write event string as passed on cmdline
390 */
391 ret = do_write_string(fd, attr->name);
392 if (ret < 0)
393 return ret;
394 /*
395 * write unique ids for this event
396 */
397 ret = do_write(fd, attr->id, attr->ids * sizeof(u64));
398 if (ret < 0)
399 return ret;
400 }
401 return 0;
402}
403
404static int write_cmdline(int fd, struct perf_header *h __used,
405 struct perf_evlist *evlist __used)
406{
407 char buf[MAXPATHLEN];
408 char proc[32];
409 u32 i, n;
410 int ret;
411
412 /*
413 * actual atual path to perf binary
414 */
415 sprintf(proc, "/proc/%d/exe", getpid());
416 ret = readlink(proc, buf, sizeof(buf));
417 if (ret <= 0)
418 return -1;
419
420 /* readlink() does not add null termination */
421 buf[ret] = '\0';
422
423 /* account for binary path */
424 n = header_argc + 1;
425
426 ret = do_write(fd, &n, sizeof(n));
427 if (ret < 0)
428 return ret;
429
430 ret = do_write_string(fd, buf);
431 if (ret < 0)
432 return ret;
433
434 for (i = 0 ; i < header_argc; i++) {
435 ret = do_write_string(fd, header_argv[i]);
436 if (ret < 0)
437 return ret;
438 }
439 return 0;
440}
441
442#define CORE_SIB_FMT \
443 "/sys/devices/system/cpu/cpu%d/topology/core_siblings_list"
444#define THRD_SIB_FMT \
445 "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list"
446
447struct cpu_topo {
448 u32 core_sib;
449 u32 thread_sib;
450 char **core_siblings;
451 char **thread_siblings;
452};
453
454static int build_cpu_topo(struct cpu_topo *tp, int cpu)
455{
456 FILE *fp;
457 char filename[MAXPATHLEN];
458 char *buf = NULL, *p;
459 size_t len = 0;
460 u32 i = 0;
461 int ret = -1;
462
463 sprintf(filename, CORE_SIB_FMT, cpu);
464 fp = fopen(filename, "r");
465 if (!fp)
466 return -1;
467
468 if (getline(&buf, &len, fp) <= 0)
469 goto done;
470
471 fclose(fp);
472
473 p = strchr(buf, '\n');
474 if (p)
475 *p = '\0';
476
477 for (i = 0; i < tp->core_sib; i++) {
478 if (!strcmp(buf, tp->core_siblings[i]))
479 break;
480 }
481 if (i == tp->core_sib) {
482 tp->core_siblings[i] = buf;
483 tp->core_sib++;
484 buf = NULL;
485 len = 0;
486 }
487
488 sprintf(filename, THRD_SIB_FMT, cpu);
489 fp = fopen(filename, "r");
490 if (!fp)
491 goto done;
492
493 if (getline(&buf, &len, fp) <= 0)
494 goto done;
495
496 p = strchr(buf, '\n');
497 if (p)
498 *p = '\0';
499
500 for (i = 0; i < tp->thread_sib; i++) {
501 if (!strcmp(buf, tp->thread_siblings[i]))
502 break;
503 }
504 if (i == tp->thread_sib) {
505 tp->thread_siblings[i] = buf;
506 tp->thread_sib++;
507 buf = NULL;
508 }
509 ret = 0;
510done:
511 if(fp)
512 fclose(fp);
513 free(buf);
514 return ret;
515}
516
517static void free_cpu_topo(struct cpu_topo *tp)
518{
519 u32 i;
520
521 if (!tp)
522 return;
523
524 for (i = 0 ; i < tp->core_sib; i++)
525 free(tp->core_siblings[i]);
526
527 for (i = 0 ; i < tp->thread_sib; i++)
528 free(tp->thread_siblings[i]);
529
530 free(tp);
531}
532
533static struct cpu_topo *build_cpu_topology(void)
534{
535 struct cpu_topo *tp;
536 void *addr;
537 u32 nr, i;
538 size_t sz;
539 long ncpus;
540 int ret = -1;
541
542 ncpus = sysconf(_SC_NPROCESSORS_CONF);
543 if (ncpus < 0)
544 return NULL;
545
546 nr = (u32)(ncpus & UINT_MAX);
547
548 sz = nr * sizeof(char *);
549
550 addr = calloc(1, sizeof(*tp) + 2 * sz);
551 if (!addr)
552 return NULL;
553
554 tp = addr;
555
556 addr += sizeof(*tp);
557 tp->core_siblings = addr;
558 addr += sz;
559 tp->thread_siblings = addr;
560
561 for (i = 0; i < nr; i++) {
562 ret = build_cpu_topo(tp, i);
563 if (ret < 0)
564 break;
565 }
566 if (ret) {
567 free_cpu_topo(tp);
568 tp = NULL;
569 }
570 return tp;
571}
572
573static int write_cpu_topology(int fd, struct perf_header *h __used,
574 struct perf_evlist *evlist __used)
575{
576 struct cpu_topo *tp;
577 u32 i;
578 int ret;
579
580 tp = build_cpu_topology();
581 if (!tp)
582 return -1;
583
584 ret = do_write(fd, &tp->core_sib, sizeof(tp->core_sib));
585 if (ret < 0)
586 goto done;
587
588 for (i = 0; i < tp->core_sib; i++) {
589 ret = do_write_string(fd, tp->core_siblings[i]);
590 if (ret < 0)
591 goto done;
592 }
593 ret = do_write(fd, &tp->thread_sib, sizeof(tp->thread_sib));
594 if (ret < 0)
595 goto done;
596
597 for (i = 0; i < tp->thread_sib; i++) {
598 ret = do_write_string(fd, tp->thread_siblings[i]);
599 if (ret < 0)
600 break;
601 }
602done:
603 free_cpu_topo(tp);
604 return ret;
605}
606
607
608
609static int write_total_mem(int fd, struct perf_header *h __used,
610 struct perf_evlist *evlist __used)
611{
612 char *buf = NULL;
613 FILE *fp;
614 size_t len = 0;
615 int ret = -1, n;
616 uint64_t mem;
617
618 fp = fopen("/proc/meminfo", "r");
619 if (!fp)
620 return -1;
621
622 while (getline(&buf, &len, fp) > 0) {
623 ret = strncmp(buf, "MemTotal:", 9);
624 if (!ret)
625 break;
626 }
627 if (!ret) {
628 n = sscanf(buf, "%*s %"PRIu64, &mem);
629 if (n == 1)
630 ret = do_write(fd, &mem, sizeof(mem));
631 }
632 free(buf);
633 fclose(fp);
634 return ret;
635}
636
637static int write_topo_node(int fd, int node)
638{
639 char str[MAXPATHLEN];
640 char field[32];
641 char *buf = NULL, *p;
642 size_t len = 0;
643 FILE *fp;
644 u64 mem_total, mem_free, mem;
645 int ret = -1;
646
647 sprintf(str, "/sys/devices/system/node/node%d/meminfo", node);
648 fp = fopen(str, "r");
649 if (!fp)
650 return -1;
651
652 while (getline(&buf, &len, fp) > 0) {
653 /* skip over invalid lines */
654 if (!strchr(buf, ':'))
655 continue;
656 if (sscanf(buf, "%*s %*d %s %"PRIu64, field, &mem) != 2)
657 goto done;
658 if (!strcmp(field, "MemTotal:"))
659 mem_total = mem;
660 if (!strcmp(field, "MemFree:"))
661 mem_free = mem;
662 }
663
664 fclose(fp);
665
666 ret = do_write(fd, &mem_total, sizeof(u64));
667 if (ret)
668 goto done;
669
670 ret = do_write(fd, &mem_free, sizeof(u64));
671 if (ret)
672 goto done;
673
674 ret = -1;
675 sprintf(str, "/sys/devices/system/node/node%d/cpulist", node);
676
677 fp = fopen(str, "r");
678 if (!fp)
679 goto done;
680
681 if (getline(&buf, &len, fp) <= 0)
682 goto done;
683
684 p = strchr(buf, '\n');
685 if (p)
686 *p = '\0';
687
688 ret = do_write_string(fd, buf);
689done:
690 free(buf);
691 fclose(fp);
692 return ret;
693}
694
695static int write_numa_topology(int fd, struct perf_header *h __used,
696 struct perf_evlist *evlist __used)
697{
698 char *buf = NULL;
699 size_t len = 0;
700 FILE *fp;
701 struct cpu_map *node_map = NULL;
702 char *c;
703 u32 nr, i, j;
704 int ret = -1;
705
706 fp = fopen("/sys/devices/system/node/online", "r");
707 if (!fp)
708 return -1;
709
710 if (getline(&buf, &len, fp) <= 0)
711 goto done;
712
713 c = strchr(buf, '\n');
714 if (c)
715 *c = '\0';
716
717 node_map = cpu_map__new(buf);
718 if (!node_map)
719 goto done;
720
721 nr = (u32)node_map->nr;
722
723 ret = do_write(fd, &nr, sizeof(nr));
724 if (ret < 0)
725 goto done;
726
727 for (i = 0; i < nr; i++) {
728 j = (u32)node_map->map[i];
729 ret = do_write(fd, &j, sizeof(j));
730 if (ret < 0)
731 break;
732
733 ret = write_topo_node(fd, i);
734 if (ret < 0)
735 break;
736 }
737done:
738 free(buf);
739 fclose(fp);
740 free(node_map);
741 return ret;
742}
743
744/*
745 * default get_cpuid(): nothing gets recorded
746 * actual implementation must be in arch/$(ARCH)/util/header.c
747 */
748int __attribute__((weak)) get_cpuid(char *buffer __used, size_t sz __used)
749{
750 return -1;
751}
752
753static int write_cpuid(int fd, struct perf_header *h __used,
754 struct perf_evlist *evlist __used)
755{
756 char buffer[64];
757 int ret;
758
759 ret = get_cpuid(buffer, sizeof(buffer));
760 if (!ret)
761 goto write_it;
762
763 return -1;
764write_it:
765 return do_write_string(fd, buffer);
766}
767
768static void print_hostname(struct perf_header *ph, int fd, FILE *fp)
769{
770 char *str = do_read_string(fd, ph);
771 fprintf(fp, "# hostname : %s\n", str);
772 free(str);
773}
774
775static void print_osrelease(struct perf_header *ph, int fd, FILE *fp)
776{
777 char *str = do_read_string(fd, ph);
778 fprintf(fp, "# os release : %s\n", str);
779 free(str);
780}
781
782static void print_arch(struct perf_header *ph, int fd, FILE *fp)
783{
784 char *str = do_read_string(fd, ph);
785 fprintf(fp, "# arch : %s\n", str);
786 free(str);
787}
788
789static void print_cpudesc(struct perf_header *ph, int fd, FILE *fp)
790{
791 char *str = do_read_string(fd, ph);
792 fprintf(fp, "# cpudesc : %s\n", str);
793 free(str);
794}
795
796static void print_nrcpus(struct perf_header *ph, int fd, FILE *fp)
797{
798 ssize_t ret;
799 u32 nr;
800
801 ret = read(fd, &nr, sizeof(nr));
802 if (ret != (ssize_t)sizeof(nr))
803 nr = -1; /* interpreted as error */
804
805 if (ph->needs_swap)
806 nr = bswap_32(nr);
807
808 fprintf(fp, "# nrcpus online : %u\n", nr);
809
810 ret = read(fd, &nr, sizeof(nr));
811 if (ret != (ssize_t)sizeof(nr))
812 nr = -1; /* interpreted as error */
813
814 if (ph->needs_swap)
815 nr = bswap_32(nr);
816
817 fprintf(fp, "# nrcpus avail : %u\n", nr);
818}
819
820static void print_version(struct perf_header *ph, int fd, FILE *fp)
821{
822 char *str = do_read_string(fd, ph);
823 fprintf(fp, "# perf version : %s\n", str);
824 free(str);
825}
826
827static void print_cmdline(struct perf_header *ph, int fd, FILE *fp)
828{
829 ssize_t ret;
830 char *str;
831 u32 nr, i;
832
833 ret = read(fd, &nr, sizeof(nr));
834 if (ret != (ssize_t)sizeof(nr))
835 return;
836
837 if (ph->needs_swap)
838 nr = bswap_32(nr);
839
840 fprintf(fp, "# cmdline : ");
841
842 for (i = 0; i < nr; i++) {
843 str = do_read_string(fd, ph);
844 fprintf(fp, "%s ", str);
845 free(str);
846 }
847 fputc('\n', fp);
848}
849
850static void print_cpu_topology(struct perf_header *ph, int fd, FILE *fp)
851{
852 ssize_t ret;
853 u32 nr, i;
854 char *str;
855
856 ret = read(fd, &nr, sizeof(nr));
857 if (ret != (ssize_t)sizeof(nr))
858 return;
859
860 if (ph->needs_swap)
861 nr = bswap_32(nr);
862
863 for (i = 0; i < nr; i++) {
864 str = do_read_string(fd, ph);
865 fprintf(fp, "# sibling cores : %s\n", str);
866 free(str);
867 }
868
869 ret = read(fd, &nr, sizeof(nr));
870 if (ret != (ssize_t)sizeof(nr))
871 return;
872
873 if (ph->needs_swap)
874 nr = bswap_32(nr);
875
876 for (i = 0; i < nr; i++) {
877 str = do_read_string(fd, ph);
878 fprintf(fp, "# sibling threads : %s\n", str);
879 free(str);
880 }
881}
882
883static void print_event_desc(struct perf_header *ph, int fd, FILE *fp)
884{
885 struct perf_event_attr attr;
886 uint64_t id;
887 void *buf = NULL;
888 char *str;
889 u32 nre, sz, nr, i, j, msz;
890 int ret;
891
892 /* number of events */
893 ret = read(fd, &nre, sizeof(nre));
894 if (ret != (ssize_t)sizeof(nre))
895 goto error;
896
897 if (ph->needs_swap)
898 nre = bswap_32(nre);
899
900 ret = read(fd, &sz, sizeof(sz));
901 if (ret != (ssize_t)sizeof(sz))
902 goto error;
903
904 if (ph->needs_swap)
905 sz = bswap_32(sz);
906
907 /*
908 * ensure it is at least to our ABI rev
909 */
910 if (sz < (u32)sizeof(attr))
911 goto error;
912
913 memset(&attr, 0, sizeof(attr));
914
915 /* read entire region to sync up to next field */
916 buf = malloc(sz);
917 if (!buf)
918 goto error;
919
920 msz = sizeof(attr);
921 if (sz < msz)
922 msz = sz;
923
924 for (i = 0 ; i < nre; i++) {
925
926 ret = read(fd, buf, sz);
927 if (ret != (ssize_t)sz)
928 goto error;
929
930 if (ph->needs_swap)
931 perf_event__attr_swap(buf);
932
933 memcpy(&attr, buf, msz);
934
935 ret = read(fd, &nr, sizeof(nr));
936 if (ret != (ssize_t)sizeof(nr))
937 goto error;
938
939 if (ph->needs_swap)
940 nr = bswap_32(nr);
941
942 str = do_read_string(fd, ph);
943 fprintf(fp, "# event : name = %s, ", str);
944 free(str);
945
946 fprintf(fp, "type = %d, config = 0x%"PRIx64
947 ", config1 = 0x%"PRIx64", config2 = 0x%"PRIx64,
948 attr.type,
949 (u64)attr.config,
950 (u64)attr.config1,
951 (u64)attr.config2);
952
953 fprintf(fp, ", excl_usr = %d, excl_kern = %d",
954 attr.exclude_user,
955 attr.exclude_kernel);
956
957 if (nr)
958 fprintf(fp, ", id = {");
959
960 for (j = 0 ; j < nr; j++) {
961 ret = read(fd, &id, sizeof(id));
962 if (ret != (ssize_t)sizeof(id))
963 goto error;
964
965 if (ph->needs_swap)
966 id = bswap_64(id);
967
968 if (j)
969 fputc(',', fp);
970
971 fprintf(fp, " %"PRIu64, id);
972 }
973 if (nr && j == nr)
974 fprintf(fp, " }");
975 fputc('\n', fp);
976 }
977 free(buf);
978 return;
979error:
980 fprintf(fp, "# event desc: not available or unable to read\n");
981}
982
983static void print_total_mem(struct perf_header *h __used, int fd, FILE *fp)
984{
985 uint64_t mem;
986 ssize_t ret;
987
988 ret = read(fd, &mem, sizeof(mem));
989 if (ret != sizeof(mem))
990 goto error;
991
992 if (h->needs_swap)
993 mem = bswap_64(mem);
994
995 fprintf(fp, "# total memory : %"PRIu64" kB\n", mem);
996 return;
997error:
998 fprintf(fp, "# total memory : unknown\n");
999}
1000
1001static void print_numa_topology(struct perf_header *h __used, int fd, FILE *fp)
1002{
1003 ssize_t ret;
1004 u32 nr, c, i;
1005 char *str;
1006 uint64_t mem_total, mem_free;
1007
1008 /* nr nodes */
1009 ret = read(fd, &nr, sizeof(nr));
1010 if (ret != (ssize_t)sizeof(nr))
1011 goto error;
1012
1013 if (h->needs_swap)
1014 nr = bswap_32(nr);
1015
1016 for (i = 0; i < nr; i++) {
1017
1018 /* node number */
1019 ret = read(fd, &c, sizeof(c));
1020 if (ret != (ssize_t)sizeof(c))
1021 goto error;
1022
1023 if (h->needs_swap)
1024 c = bswap_32(c);
1025
1026 ret = read(fd, &mem_total, sizeof(u64));
1027 if (ret != sizeof(u64))
1028 goto error;
1029
1030 ret = read(fd, &mem_free, sizeof(u64));
1031 if (ret != sizeof(u64))
1032 goto error;
1033
1034 if (h->needs_swap) {
1035 mem_total = bswap_64(mem_total);
1036 mem_free = bswap_64(mem_free);
1037 }
1038
1039 fprintf(fp, "# node%u meminfo : total = %"PRIu64" kB,"
1040 " free = %"PRIu64" kB\n",
1041 c,
1042 mem_total,
1043 mem_free);
1044
1045 str = do_read_string(fd, h);
1046 fprintf(fp, "# node%u cpu list : %s\n", c, str);
1047 free(str);
1048 }
1049 return;
1050error:
1051 fprintf(fp, "# numa topology : not available\n");
1052}
1053
1054static void print_cpuid(struct perf_header *ph, int fd, FILE *fp)
1055{
1056 char *str = do_read_string(fd, ph);
1057 fprintf(fp, "# cpuid : %s\n", str);
1058 free(str);
1059}
1060
1061struct feature_ops {
1062 int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist);
1063 void (*print)(struct perf_header *h, int fd, FILE *fp);
1064 const char *name;
1065 bool full_only;
1066};
1067
1068#define FEAT_OPA(n, w, p) \
1069 [n] = { .name = #n, .write = w, .print = p }
1070#define FEAT_OPF(n, w, p) \
1071 [n] = { .name = #n, .write = w, .print = p, .full_only = true }
1072
1073static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
1074 FEAT_OPA(HEADER_TRACE_INFO, write_trace_info, NULL),
1075 FEAT_OPA(HEADER_BUILD_ID, write_build_id, NULL),
1076 FEAT_OPA(HEADER_HOSTNAME, write_hostname, print_hostname),
1077 FEAT_OPA(HEADER_OSRELEASE, write_osrelease, print_osrelease),
1078 FEAT_OPA(HEADER_VERSION, write_version, print_version),
1079 FEAT_OPA(HEADER_ARCH, write_arch, print_arch),
1080 FEAT_OPA(HEADER_NRCPUS, write_nrcpus, print_nrcpus),
1081 FEAT_OPA(HEADER_CPUDESC, write_cpudesc, print_cpudesc),
1082 FEAT_OPA(HEADER_CPUID, write_cpuid, print_cpuid),
1083 FEAT_OPA(HEADER_TOTAL_MEM, write_total_mem, print_total_mem),
1084 FEAT_OPA(HEADER_EVENT_DESC, write_event_desc, print_event_desc),
1085 FEAT_OPA(HEADER_CMDLINE, write_cmdline, print_cmdline),
1086 FEAT_OPF(HEADER_CPU_TOPOLOGY, write_cpu_topology, print_cpu_topology),
1087 FEAT_OPF(HEADER_NUMA_TOPOLOGY, write_numa_topology, print_numa_topology),
1088};
1089
1090struct header_print_data {
1091 FILE *fp;
1092 bool full; /* extended list of headers */
1093};
1094
1095static int perf_file_section__fprintf_info(struct perf_file_section *section,
1096 struct perf_header *ph,
1097 int feat, int fd, void *data)
1098{
1099 struct header_print_data *hd = data;
1100
1101 if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) {
1102 pr_debug("Failed to lseek to %" PRIu64 " offset for feature "
1103 "%d, continuing...\n", section->offset, feat);
1104 return 0;
1105 }
1106 if (feat < HEADER_TRACE_INFO || feat >= HEADER_LAST_FEATURE) {
1107 pr_warning("unknown feature %d\n", feat);
1108 return -1;
1109 }
1110 if (!feat_ops[feat].print)
1111 return 0;
1112
1113 if (!feat_ops[feat].full_only || hd->full)
1114 feat_ops[feat].print(ph, fd, hd->fp);
1115 else
1116 fprintf(hd->fp, "# %s info available, use -I to display\n",
1117 feat_ops[feat].name);
1118
1119 return 0;
1120}
1121
1122int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full)
1123{
1124 struct header_print_data hd;
1125 struct perf_header *header = &session->header;
1126 int fd = session->fd;
1127 hd.fp = fp;
1128 hd.full = full;
1129
1130 perf_header__process_sections(header, fd, &hd,
1131 perf_file_section__fprintf_info);
1132 return 0;
1133}
1134
113#define dsos__for_each_with_build_id(pos, head) \ 1135#define dsos__for_each_with_build_id(pos, head) \
114 list_for_each_entry(pos, head, node) \ 1136 list_for_each_entry(pos, head, node) \
115 if (!pos->has_build_id) \ 1137 if (!pos->has_build_id) \
@@ -267,7 +1289,7 @@ int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir)
267 if (access(linkname, F_OK)) 1289 if (access(linkname, F_OK))
268 goto out_free; 1290 goto out_free;
269 1291
270 if (readlink(linkname, filename, size) < 0) 1292 if (readlink(linkname, filename, size - 1) < 0)
271 goto out_free; 1293 goto out_free;
272 1294
273 if (unlink(linkname)) 1295 if (unlink(linkname))
@@ -356,15 +1378,41 @@ static bool perf_session__read_build_ids(struct perf_session *session, bool with
356 return ret; 1378 return ret;
357} 1379}
358 1380
1381static int do_write_feat(int fd, struct perf_header *h, int type,
1382 struct perf_file_section **p,
1383 struct perf_evlist *evlist)
1384{
1385 int err;
1386 int ret = 0;
1387
1388 if (perf_header__has_feat(h, type)) {
1389
1390 (*p)->offset = lseek(fd, 0, SEEK_CUR);
1391
1392 err = feat_ops[type].write(fd, h, evlist);
1393 if (err < 0) {
1394 pr_debug("failed to write feature %d\n", type);
1395
1396 /* undo anything written */
1397 lseek(fd, (*p)->offset, SEEK_SET);
1398
1399 return -1;
1400 }
1401 (*p)->size = lseek(fd, 0, SEEK_CUR) - (*p)->offset;
1402 (*p)++;
1403 }
1404 return ret;
1405}
1406
359static int perf_header__adds_write(struct perf_header *header, 1407static int perf_header__adds_write(struct perf_header *header,
360 struct perf_evlist *evlist, int fd) 1408 struct perf_evlist *evlist, int fd)
361{ 1409{
362 int nr_sections; 1410 int nr_sections;
363 struct perf_session *session; 1411 struct perf_session *session;
364 struct perf_file_section *feat_sec; 1412 struct perf_file_section *feat_sec, *p;
365 int sec_size; 1413 int sec_size;
366 u64 sec_start; 1414 u64 sec_start;
367 int idx = 0, err; 1415 int err;
368 1416
369 session = container_of(header, struct perf_session, header); 1417 session = container_of(header, struct perf_session, header);
370 1418
@@ -376,7 +1424,7 @@ static int perf_header__adds_write(struct perf_header *header,
376 if (!nr_sections) 1424 if (!nr_sections)
377 return 0; 1425 return 0;
378 1426
379 feat_sec = calloc(sizeof(*feat_sec), nr_sections); 1427 feat_sec = p = calloc(sizeof(*feat_sec), nr_sections);
380 if (feat_sec == NULL) 1428 if (feat_sec == NULL)
381 return -ENOMEM; 1429 return -ENOMEM;
382 1430
@@ -385,36 +1433,69 @@ static int perf_header__adds_write(struct perf_header *header,
385 sec_start = header->data_offset + header->data_size; 1433 sec_start = header->data_offset + header->data_size;
386 lseek(fd, sec_start + sec_size, SEEK_SET); 1434 lseek(fd, sec_start + sec_size, SEEK_SET);
387 1435
388 if (perf_header__has_feat(header, HEADER_TRACE_INFO)) { 1436 err = do_write_feat(fd, header, HEADER_TRACE_INFO, &p, evlist);
389 struct perf_file_section *trace_sec; 1437 if (err)
390 1438 goto out_free;
391 trace_sec = &feat_sec[idx++];
392 1439
393 /* Write trace info */ 1440 err = do_write_feat(fd, header, HEADER_BUILD_ID, &p, evlist);
394 trace_sec->offset = lseek(fd, 0, SEEK_CUR); 1441 if (err) {
395 read_tracing_data(fd, &evlist->entries); 1442 perf_header__clear_feat(header, HEADER_BUILD_ID);
396 trace_sec->size = lseek(fd, 0, SEEK_CUR) - trace_sec->offset; 1443 goto out_free;
397 } 1444 }
398 1445
399 if (perf_header__has_feat(header, HEADER_BUILD_ID)) { 1446 err = do_write_feat(fd, header, HEADER_HOSTNAME, &p, evlist);
400 struct perf_file_section *buildid_sec; 1447 if (err)
1448 perf_header__clear_feat(header, HEADER_HOSTNAME);
401 1449
402 buildid_sec = &feat_sec[idx++]; 1450 err = do_write_feat(fd, header, HEADER_OSRELEASE, &p, evlist);
1451 if (err)
1452 perf_header__clear_feat(header, HEADER_OSRELEASE);
403 1453
404 /* Write build-ids */ 1454 err = do_write_feat(fd, header, HEADER_VERSION, &p, evlist);
405 buildid_sec->offset = lseek(fd, 0, SEEK_CUR); 1455 if (err)
406 err = dsos__write_buildid_table(header, fd); 1456 perf_header__clear_feat(header, HEADER_VERSION);
407 if (err < 0) { 1457
408 pr_debug("failed to write buildid table\n"); 1458 err = do_write_feat(fd, header, HEADER_ARCH, &p, evlist);
409 goto out_free; 1459 if (err)
410 } 1460 perf_header__clear_feat(header, HEADER_ARCH);
411 buildid_sec->size = lseek(fd, 0, SEEK_CUR) - 1461
412 buildid_sec->offset; 1462 err = do_write_feat(fd, header, HEADER_NRCPUS, &p, evlist);
413 if (!no_buildid_cache) 1463 if (err)
414 perf_session__cache_build_ids(session); 1464 perf_header__clear_feat(header, HEADER_NRCPUS);
415 } 1465
1466 err = do_write_feat(fd, header, HEADER_CPUDESC, &p, evlist);
1467 if (err)
1468 perf_header__clear_feat(header, HEADER_CPUDESC);
1469
1470 err = do_write_feat(fd, header, HEADER_CPUID, &p, evlist);
1471 if (err)
1472 perf_header__clear_feat(header, HEADER_CPUID);
1473
1474 err = do_write_feat(fd, header, HEADER_TOTAL_MEM, &p, evlist);
1475 if (err)
1476 perf_header__clear_feat(header, HEADER_TOTAL_MEM);
1477
1478 err = do_write_feat(fd, header, HEADER_CMDLINE, &p, evlist);
1479 if (err)
1480 perf_header__clear_feat(header, HEADER_CMDLINE);
1481
1482 err = do_write_feat(fd, header, HEADER_EVENT_DESC, &p, evlist);
1483 if (err)
1484 perf_header__clear_feat(header, HEADER_EVENT_DESC);
1485
1486 err = do_write_feat(fd, header, HEADER_CPU_TOPOLOGY, &p, evlist);
1487 if (err)
1488 perf_header__clear_feat(header, HEADER_CPU_TOPOLOGY);
1489
1490 err = do_write_feat(fd, header, HEADER_NUMA_TOPOLOGY, &p, evlist);
1491 if (err)
1492 perf_header__clear_feat(header, HEADER_NUMA_TOPOLOGY);
416 1493
417 lseek(fd, sec_start, SEEK_SET); 1494 lseek(fd, sec_start, SEEK_SET);
1495 /*
1496 * may write more than needed due to dropped feature, but
1497 * this is okay, reader will skip the mising entries
1498 */
418 err = do_write(fd, feat_sec, sec_size); 1499 err = do_write(fd, feat_sec, sec_size);
419 if (err < 0) 1500 if (err < 0)
420 pr_debug("failed to write feature section\n"); 1501 pr_debug("failed to write feature section\n");
@@ -554,9 +1635,10 @@ static int perf_header__getbuffer64(struct perf_header *header,
554} 1635}
555 1636
556int perf_header__process_sections(struct perf_header *header, int fd, 1637int perf_header__process_sections(struct perf_header *header, int fd,
1638 void *data,
557 int (*process)(struct perf_file_section *section, 1639 int (*process)(struct perf_file_section *section,
558 struct perf_header *ph, 1640 struct perf_header *ph,
559 int feat, int fd)) 1641 int feat, int fd, void *data))
560{ 1642{
561 struct perf_file_section *feat_sec; 1643 struct perf_file_section *feat_sec;
562 int nr_sections; 1644 int nr_sections;
@@ -584,7 +1666,7 @@ int perf_header__process_sections(struct perf_header *header, int fd,
584 if (perf_header__has_feat(header, feat)) { 1666 if (perf_header__has_feat(header, feat)) {
585 struct perf_file_section *sec = &feat_sec[idx++]; 1667 struct perf_file_section *sec = &feat_sec[idx++];
586 1668
587 err = process(sec, header, feat, fd); 1669 err = process(sec, header, feat, fd, data);
588 if (err < 0) 1670 if (err < 0)
589 break; 1671 break;
590 } 1672 }
@@ -621,21 +1703,41 @@ int perf_file_header__read(struct perf_file_header *header,
621 bitmap_zero(header->adds_features, HEADER_FEAT_BITS); 1703 bitmap_zero(header->adds_features, HEADER_FEAT_BITS);
622 else 1704 else
623 return -1; 1705 return -1;
1706 } else if (ph->needs_swap) {
1707 unsigned int i;
1708 /*
1709 * feature bitmap is declared as an array of unsigned longs --
1710 * not good since its size can differ between the host that
1711 * generated the data file and the host analyzing the file.
1712 *
1713 * We need to handle endianness, but we don't know the size of
1714 * the unsigned long where the file was generated. Take a best
1715 * guess at determining it: try 64-bit swap first (ie., file
1716 * created on a 64-bit host), and check if the hostname feature
1717 * bit is set (this feature bit is forced on as of fbe96f2).
1718 * If the bit is not, undo the 64-bit swap and try a 32-bit
1719 * swap. If the hostname bit is still not set (e.g., older data
1720 * file), punt and fallback to the original behavior --
1721 * clearing all feature bits and setting buildid.
1722 */
1723 for (i = 0; i < BITS_TO_LONGS(HEADER_FEAT_BITS); ++i)
1724 header->adds_features[i] = bswap_64(header->adds_features[i]);
1725
1726 if (!test_bit(HEADER_HOSTNAME, header->adds_features)) {
1727 for (i = 0; i < BITS_TO_LONGS(HEADER_FEAT_BITS); ++i) {
1728 header->adds_features[i] = bswap_64(header->adds_features[i]);
1729 header->adds_features[i] = bswap_32(header->adds_features[i]);
1730 }
1731 }
1732
1733 if (!test_bit(HEADER_HOSTNAME, header->adds_features)) {
1734 bitmap_zero(header->adds_features, HEADER_FEAT_BITS);
1735 set_bit(HEADER_BUILD_ID, header->adds_features);
1736 }
624 } 1737 }
625 1738
626 memcpy(&ph->adds_features, &header->adds_features, 1739 memcpy(&ph->adds_features, &header->adds_features,
627 sizeof(ph->adds_features)); 1740 sizeof(ph->adds_features));
628 /*
629 * FIXME: hack that assumes that if we need swap the perf.data file
630 * may be coming from an arch with a different word-size, ergo different
631 * DEFINE_BITMAP format, investigate more later, but for now its mostly
632 * safe to assume that we have a build-id section. Trace files probably
633 * have several other issues in this realm anyway...
634 */
635 if (ph->needs_swap) {
636 memset(&ph->adds_features, 0, sizeof(ph->adds_features));
637 perf_header__set_feat(ph, HEADER_BUILD_ID);
638 }
639 1741
640 ph->event_offset = header->event_types.offset; 1742 ph->event_offset = header->event_types.offset;
641 ph->event_size = header->event_types.size; 1743 ph->event_size = header->event_types.size;
@@ -796,7 +1898,7 @@ out:
796 1898
797static int perf_file_section__process(struct perf_file_section *section, 1899static int perf_file_section__process(struct perf_file_section *section,
798 struct perf_header *ph, 1900 struct perf_header *ph,
799 int feat, int fd) 1901 int feat, int fd, void *data __used)
800{ 1902{
801 if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) { 1903 if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) {
802 pr_debug("Failed to lseek to %" PRIu64 " offset for feature " 1904 pr_debug("Failed to lseek to %" PRIu64 " offset for feature "
@@ -813,6 +1915,21 @@ static int perf_file_section__process(struct perf_file_section *section,
813 if (perf_header__read_build_ids(ph, fd, section->offset, section->size)) 1915 if (perf_header__read_build_ids(ph, fd, section->offset, section->size))
814 pr_debug("Failed to read buildids, continuing...\n"); 1916 pr_debug("Failed to read buildids, continuing...\n");
815 break; 1917 break;
1918
1919 case HEADER_HOSTNAME:
1920 case HEADER_OSRELEASE:
1921 case HEADER_VERSION:
1922 case HEADER_ARCH:
1923 case HEADER_NRCPUS:
1924 case HEADER_CPUDESC:
1925 case HEADER_CPUID:
1926 case HEADER_TOTAL_MEM:
1927 case HEADER_CMDLINE:
1928 case HEADER_EVENT_DESC:
1929 case HEADER_CPU_TOPOLOGY:
1930 case HEADER_NUMA_TOPOLOGY:
1931 break;
1932
816 default: 1933 default:
817 pr_debug("unknown feature %d, continuing...\n", feat); 1934 pr_debug("unknown feature %d, continuing...\n", feat);
818 } 1935 }
@@ -935,7 +2052,8 @@ int perf_session__read_header(struct perf_session *session, int fd)
935 event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type); 2052 event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type);
936 } 2053 }
937 2054
938 perf_header__process_sections(header, fd, perf_file_section__process); 2055 perf_header__process_sections(header, fd, NULL,
2056 perf_file_section__process);
939 2057
940 lseek(fd, header->data_offset, SEEK_SET); 2058 lseek(fd, header->data_offset, SEEK_SET);
941 2059
@@ -1100,15 +2218,29 @@ int perf_event__synthesize_tracing_data(int fd, struct perf_evlist *evlist,
1100 struct perf_session *session __unused) 2218 struct perf_session *session __unused)
1101{ 2219{
1102 union perf_event ev; 2220 union perf_event ev;
2221 struct tracing_data *tdata;
1103 ssize_t size = 0, aligned_size = 0, padding; 2222 ssize_t size = 0, aligned_size = 0, padding;
1104 int err __used = 0; 2223 int err __used = 0;
1105 2224
2225 /*
2226 * We are going to store the size of the data followed
2227 * by the data contents. Since the fd descriptor is a pipe,
2228 * we cannot seek back to store the size of the data once
2229 * we know it. Instead we:
2230 *
2231 * - write the tracing data to the temp file
2232 * - get/write the data size to pipe
2233 * - write the tracing data from the temp file
2234 * to the pipe
2235 */
2236 tdata = tracing_data_get(&evlist->entries, fd, true);
2237 if (!tdata)
2238 return -1;
2239
1106 memset(&ev, 0, sizeof(ev)); 2240 memset(&ev, 0, sizeof(ev));
1107 2241
1108 ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA; 2242 ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA;
1109 size = read_tracing_data_size(fd, &evlist->entries); 2243 size = tdata->size;
1110 if (size <= 0)
1111 return size;
1112 aligned_size = ALIGN(size, sizeof(u64)); 2244 aligned_size = ALIGN(size, sizeof(u64));
1113 padding = aligned_size - size; 2245 padding = aligned_size - size;
1114 ev.tracing_data.header.size = sizeof(ev.tracing_data); 2246 ev.tracing_data.header.size = sizeof(ev.tracing_data);
@@ -1116,7 +2248,12 @@ int perf_event__synthesize_tracing_data(int fd, struct perf_evlist *evlist,
1116 2248
1117 process(&ev, NULL, session); 2249 process(&ev, NULL, session);
1118 2250
1119 err = read_tracing_data(fd, &evlist->entries); 2251 /*
2252 * The put function will copy all the tracing data
2253 * stored in temp file to the pipe.
2254 */
2255 tracing_data_put(tdata);
2256
1120 write_padded(fd, NULL, 0, padding); 2257 write_padded(fd, NULL, 0, padding);
1121 2258
1122 return aligned_size; 2259 return aligned_size;
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 1886256768a1..3d5a742f4a2a 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -12,6 +12,20 @@
12enum { 12enum {
13 HEADER_TRACE_INFO = 1, 13 HEADER_TRACE_INFO = 1,
14 HEADER_BUILD_ID, 14 HEADER_BUILD_ID,
15
16 HEADER_HOSTNAME,
17 HEADER_OSRELEASE,
18 HEADER_VERSION,
19 HEADER_ARCH,
20 HEADER_NRCPUS,
21 HEADER_CPUDESC,
22 HEADER_CPUID,
23 HEADER_TOTAL_MEM,
24 HEADER_CMDLINE,
25 HEADER_EVENT_DESC,
26 HEADER_CPU_TOPOLOGY,
27 HEADER_NUMA_TOPOLOGY,
28
15 HEADER_LAST_FEATURE, 29 HEADER_LAST_FEATURE,
16}; 30};
17 31
@@ -68,10 +82,15 @@ void perf_header__set_feat(struct perf_header *header, int feat);
68void perf_header__clear_feat(struct perf_header *header, int feat); 82void perf_header__clear_feat(struct perf_header *header, int feat);
69bool perf_header__has_feat(const struct perf_header *header, int feat); 83bool perf_header__has_feat(const struct perf_header *header, int feat);
70 84
85int perf_header__set_cmdline(int argc, const char **argv);
86
71int perf_header__process_sections(struct perf_header *header, int fd, 87int perf_header__process_sections(struct perf_header *header, int fd,
88 void *data,
72 int (*process)(struct perf_file_section *section, 89 int (*process)(struct perf_file_section *section,
73 struct perf_header *ph, 90 struct perf_header *ph,
74 int feat, int fd)); 91 int feat, int fd, void *data));
92
93int perf_header__fprintf_info(struct perf_session *s, FILE *fp, bool full);
75 94
76int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, 95int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
77 const char *name, bool is_kallsyms); 96 const char *name, bool is_kallsyms);
@@ -104,4 +123,10 @@ int perf_event__synthesize_build_id(struct dso *pos, u16 misc,
104 struct perf_session *session); 123 struct perf_session *session);
105int perf_event__process_build_id(union perf_event *event, 124int perf_event__process_build_id(union perf_event *event,
106 struct perf_session *session); 125 struct perf_session *session);
126
127/*
128 * arch specific callback
129 */
130int get_cpuid(char *buffer, size_t sz);
131
107#endif /* __PERF_HEADER_H */ 132#endif /* __PERF_HEADER_H */
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 677e1da6bb3e..f6a993963a1e 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -6,6 +6,11 @@
6#include "sort.h" 6#include "sort.h"
7#include <math.h> 7#include <math.h>
8 8
9static bool hists__filter_entry_by_dso(struct hists *hists,
10 struct hist_entry *he);
11static bool hists__filter_entry_by_thread(struct hists *hists,
12 struct hist_entry *he);
13
9enum hist_filter { 14enum hist_filter {
10 HIST_FILTER__DSO, 15 HIST_FILTER__DSO,
11 HIST_FILTER__THREAD, 16 HIST_FILTER__THREAD,
@@ -18,56 +23,56 @@ struct callchain_param callchain_param = {
18 .order = ORDER_CALLEE 23 .order = ORDER_CALLEE
19}; 24};
20 25
21u16 hists__col_len(struct hists *self, enum hist_column col) 26u16 hists__col_len(struct hists *hists, enum hist_column col)
22{ 27{
23 return self->col_len[col]; 28 return hists->col_len[col];
24} 29}
25 30
26void hists__set_col_len(struct hists *self, enum hist_column col, u16 len) 31void hists__set_col_len(struct hists *hists, enum hist_column col, u16 len)
27{ 32{
28 self->col_len[col] = len; 33 hists->col_len[col] = len;
29} 34}
30 35
31bool hists__new_col_len(struct hists *self, enum hist_column col, u16 len) 36bool hists__new_col_len(struct hists *hists, enum hist_column col, u16 len)
32{ 37{
33 if (len > hists__col_len(self, col)) { 38 if (len > hists__col_len(hists, col)) {
34 hists__set_col_len(self, col, len); 39 hists__set_col_len(hists, col, len);
35 return true; 40 return true;
36 } 41 }
37 return false; 42 return false;
38} 43}
39 44
40static void hists__reset_col_len(struct hists *self) 45static void hists__reset_col_len(struct hists *hists)
41{ 46{
42 enum hist_column col; 47 enum hist_column col;
43 48
44 for (col = 0; col < HISTC_NR_COLS; ++col) 49 for (col = 0; col < HISTC_NR_COLS; ++col)
45 hists__set_col_len(self, col, 0); 50 hists__set_col_len(hists, col, 0);
46} 51}
47 52
48static void hists__calc_col_len(struct hists *self, struct hist_entry *h) 53static void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
49{ 54{
50 u16 len; 55 u16 len;
51 56
52 if (h->ms.sym) 57 if (h->ms.sym)
53 hists__new_col_len(self, HISTC_SYMBOL, h->ms.sym->namelen); 58 hists__new_col_len(hists, HISTC_SYMBOL, h->ms.sym->namelen);
54 else { 59 else {
55 const unsigned int unresolved_col_width = BITS_PER_LONG / 4; 60 const unsigned int unresolved_col_width = BITS_PER_LONG / 4;
56 61
57 if (hists__col_len(self, HISTC_DSO) < unresolved_col_width && 62 if (hists__col_len(hists, HISTC_DSO) < unresolved_col_width &&
58 !symbol_conf.col_width_list_str && !symbol_conf.field_sep && 63 !symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
59 !symbol_conf.dso_list) 64 !symbol_conf.dso_list)
60 hists__set_col_len(self, HISTC_DSO, 65 hists__set_col_len(hists, HISTC_DSO,
61 unresolved_col_width); 66 unresolved_col_width);
62 } 67 }
63 68
64 len = thread__comm_len(h->thread); 69 len = thread__comm_len(h->thread);
65 if (hists__new_col_len(self, HISTC_COMM, len)) 70 if (hists__new_col_len(hists, HISTC_COMM, len))
66 hists__set_col_len(self, HISTC_THREAD, len + 6); 71 hists__set_col_len(hists, HISTC_THREAD, len + 6);
67 72
68 if (h->ms.map) { 73 if (h->ms.map) {
69 len = dso__name_len(h->ms.map->dso); 74 len = dso__name_len(h->ms.map->dso);
70 hists__new_col_len(self, HISTC_DSO, len); 75 hists__new_col_len(hists, HISTC_DSO, len);
71 } 76 }
72} 77}
73 78
@@ -92,6 +97,67 @@ static void hist_entry__add_cpumode_period(struct hist_entry *self,
92 } 97 }
93} 98}
94 99
100static void hist_entry__decay(struct hist_entry *he)
101{
102 he->period = (he->period * 7) / 8;
103 he->nr_events = (he->nr_events * 7) / 8;
104}
105
106static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
107{
108 u64 prev_period = he->period;
109
110 if (prev_period == 0)
111 return true;
112
113 hist_entry__decay(he);
114
115 if (!he->filtered)
116 hists->stats.total_period -= prev_period - he->period;
117
118 return he->period == 0;
119}
120
121static void __hists__decay_entries(struct hists *hists, bool zap_user,
122 bool zap_kernel, bool threaded)
123{
124 struct rb_node *next = rb_first(&hists->entries);
125 struct hist_entry *n;
126
127 while (next) {
128 n = rb_entry(next, struct hist_entry, rb_node);
129 next = rb_next(&n->rb_node);
130 /*
131 * We may be annotating this, for instance, so keep it here in
132 * case some it gets new samples, we'll eventually free it when
133 * the user stops browsing and it agains gets fully decayed.
134 */
135 if (((zap_user && n->level == '.') ||
136 (zap_kernel && n->level != '.') ||
137 hists__decay_entry(hists, n)) &&
138 !n->used) {
139 rb_erase(&n->rb_node, &hists->entries);
140
141 if (sort__need_collapse || threaded)
142 rb_erase(&n->rb_node_in, &hists->entries_collapsed);
143
144 hist_entry__free(n);
145 --hists->nr_entries;
146 }
147 }
148}
149
150void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel)
151{
152 return __hists__decay_entries(hists, zap_user, zap_kernel, false);
153}
154
155void hists__decay_entries_threaded(struct hists *hists,
156 bool zap_user, bool zap_kernel)
157{
158 return __hists__decay_entries(hists, zap_user, zap_kernel, true);
159}
160
95/* 161/*
96 * histogram, sorted on item, collects periods 162 * histogram, sorted on item, collects periods
97 */ 163 */
@@ -113,11 +179,12 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)
113 return self; 179 return self;
114} 180}
115 181
116static void hists__inc_nr_entries(struct hists *self, struct hist_entry *h) 182static void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h)
117{ 183{
118 if (!h->filtered) { 184 if (!h->filtered) {
119 hists__calc_col_len(self, h); 185 hists__calc_col_len(hists, h);
120 ++self->nr_entries; 186 ++hists->nr_entries;
187 hists->stats.total_period += h->period;
121 } 188 }
122} 189}
123 190
@@ -128,11 +195,11 @@ static u8 symbol__parent_filter(const struct symbol *parent)
128 return 0; 195 return 0;
129} 196}
130 197
131struct hist_entry *__hists__add_entry(struct hists *self, 198struct hist_entry *__hists__add_entry(struct hists *hists,
132 struct addr_location *al, 199 struct addr_location *al,
133 struct symbol *sym_parent, u64 period) 200 struct symbol *sym_parent, u64 period)
134{ 201{
135 struct rb_node **p = &self->entries.rb_node; 202 struct rb_node **p;
136 struct rb_node *parent = NULL; 203 struct rb_node *parent = NULL;
137 struct hist_entry *he; 204 struct hist_entry *he;
138 struct hist_entry entry = { 205 struct hist_entry entry = {
@@ -150,9 +217,13 @@ struct hist_entry *__hists__add_entry(struct hists *self,
150 }; 217 };
151 int cmp; 218 int cmp;
152 219
220 pthread_mutex_lock(&hists->lock);
221
222 p = &hists->entries_in->rb_node;
223
153 while (*p != NULL) { 224 while (*p != NULL) {
154 parent = *p; 225 parent = *p;
155 he = rb_entry(parent, struct hist_entry, rb_node); 226 he = rb_entry(parent, struct hist_entry, rb_node_in);
156 227
157 cmp = hist_entry__cmp(&entry, he); 228 cmp = hist_entry__cmp(&entry, he);
158 229
@@ -170,12 +241,14 @@ struct hist_entry *__hists__add_entry(struct hists *self,
170 241
171 he = hist_entry__new(&entry); 242 he = hist_entry__new(&entry);
172 if (!he) 243 if (!he)
173 return NULL; 244 goto out_unlock;
174 rb_link_node(&he->rb_node, parent, p); 245
175 rb_insert_color(&he->rb_node, &self->entries); 246 rb_link_node(&he->rb_node_in, parent, p);
176 hists__inc_nr_entries(self, he); 247 rb_insert_color(&he->rb_node_in, hists->entries_in);
177out: 248out:
178 hist_entry__add_cpumode_period(he, al->cpumode, period); 249 hist_entry__add_cpumode_period(he, al->cpumode, period);
250out_unlock:
251 pthread_mutex_unlock(&hists->lock);
179 return he; 252 return he;
180} 253}
181 254
@@ -222,7 +295,7 @@ void hist_entry__free(struct hist_entry *he)
222 * collapse the histogram 295 * collapse the histogram
223 */ 296 */
224 297
225static bool hists__collapse_insert_entry(struct hists *self, 298static bool hists__collapse_insert_entry(struct hists *hists,
226 struct rb_root *root, 299 struct rb_root *root,
227 struct hist_entry *he) 300 struct hist_entry *he)
228{ 301{
@@ -233,15 +306,16 @@ static bool hists__collapse_insert_entry(struct hists *self,
233 306
234 while (*p != NULL) { 307 while (*p != NULL) {
235 parent = *p; 308 parent = *p;
236 iter = rb_entry(parent, struct hist_entry, rb_node); 309 iter = rb_entry(parent, struct hist_entry, rb_node_in);
237 310
238 cmp = hist_entry__collapse(iter, he); 311 cmp = hist_entry__collapse(iter, he);
239 312
240 if (!cmp) { 313 if (!cmp) {
241 iter->period += he->period; 314 iter->period += he->period;
315 iter->nr_events += he->nr_events;
242 if (symbol_conf.use_callchain) { 316 if (symbol_conf.use_callchain) {
243 callchain_cursor_reset(&self->callchain_cursor); 317 callchain_cursor_reset(&hists->callchain_cursor);
244 callchain_merge(&self->callchain_cursor, iter->callchain, 318 callchain_merge(&hists->callchain_cursor, iter->callchain,
245 he->callchain); 319 he->callchain);
246 } 320 }
247 hist_entry__free(he); 321 hist_entry__free(he);
@@ -254,35 +328,70 @@ static bool hists__collapse_insert_entry(struct hists *self,
254 p = &(*p)->rb_right; 328 p = &(*p)->rb_right;
255 } 329 }
256 330
257 rb_link_node(&he->rb_node, parent, p); 331 rb_link_node(&he->rb_node_in, parent, p);
258 rb_insert_color(&he->rb_node, root); 332 rb_insert_color(&he->rb_node_in, root);
259 return true; 333 return true;
260} 334}
261 335
262void hists__collapse_resort(struct hists *self) 336static struct rb_root *hists__get_rotate_entries_in(struct hists *hists)
337{
338 struct rb_root *root;
339
340 pthread_mutex_lock(&hists->lock);
341
342 root = hists->entries_in;
343 if (++hists->entries_in > &hists->entries_in_array[1])
344 hists->entries_in = &hists->entries_in_array[0];
345
346 pthread_mutex_unlock(&hists->lock);
347
348 return root;
349}
350
351static void hists__apply_filters(struct hists *hists, struct hist_entry *he)
352{
353 hists__filter_entry_by_dso(hists, he);
354 hists__filter_entry_by_thread(hists, he);
355}
356
357static void __hists__collapse_resort(struct hists *hists, bool threaded)
263{ 358{
264 struct rb_root tmp; 359 struct rb_root *root;
265 struct rb_node *next; 360 struct rb_node *next;
266 struct hist_entry *n; 361 struct hist_entry *n;
267 362
268 if (!sort__need_collapse) 363 if (!sort__need_collapse && !threaded)
269 return; 364 return;
270 365
271 tmp = RB_ROOT; 366 root = hists__get_rotate_entries_in(hists);
272 next = rb_first(&self->entries); 367 next = rb_first(root);
273 self->nr_entries = 0; 368 hists->stats.total_period = 0;
274 hists__reset_col_len(self);
275 369
276 while (next) { 370 while (next) {
277 n = rb_entry(next, struct hist_entry, rb_node); 371 n = rb_entry(next, struct hist_entry, rb_node_in);
278 next = rb_next(&n->rb_node); 372 next = rb_next(&n->rb_node_in);
279 373
280 rb_erase(&n->rb_node, &self->entries); 374 rb_erase(&n->rb_node_in, root);
281 if (hists__collapse_insert_entry(self, &tmp, n)) 375 if (hists__collapse_insert_entry(hists, &hists->entries_collapsed, n)) {
282 hists__inc_nr_entries(self, n); 376 /*
377 * If it wasn't combined with one of the entries already
378 * collapsed, we need to apply the filters that may have
379 * been set by, say, the hist_browser.
380 */
381 hists__apply_filters(hists, n);
382 hists__inc_nr_entries(hists, n);
383 }
283 } 384 }
385}
284 386
285 self->entries = tmp; 387void hists__collapse_resort(struct hists *hists)
388{
389 return __hists__collapse_resort(hists, false);
390}
391
392void hists__collapse_resort_threaded(struct hists *hists)
393{
394 return __hists__collapse_resort(hists, true);
286} 395}
287 396
288/* 397/*
@@ -315,31 +424,43 @@ static void __hists__insert_output_entry(struct rb_root *entries,
315 rb_insert_color(&he->rb_node, entries); 424 rb_insert_color(&he->rb_node, entries);
316} 425}
317 426
318void hists__output_resort(struct hists *self) 427static void __hists__output_resort(struct hists *hists, bool threaded)
319{ 428{
320 struct rb_root tmp; 429 struct rb_root *root;
321 struct rb_node *next; 430 struct rb_node *next;
322 struct hist_entry *n; 431 struct hist_entry *n;
323 u64 min_callchain_hits; 432 u64 min_callchain_hits;
324 433
325 min_callchain_hits = self->stats.total_period * (callchain_param.min_percent / 100); 434 min_callchain_hits = hists->stats.total_period * (callchain_param.min_percent / 100);
435
436 if (sort__need_collapse || threaded)
437 root = &hists->entries_collapsed;
438 else
439 root = hists->entries_in;
326 440
327 tmp = RB_ROOT; 441 next = rb_first(root);
328 next = rb_first(&self->entries); 442 hists->entries = RB_ROOT;
329 443
330 self->nr_entries = 0; 444 hists->nr_entries = 0;
331 hists__reset_col_len(self); 445 hists__reset_col_len(hists);
332 446
333 while (next) { 447 while (next) {
334 n = rb_entry(next, struct hist_entry, rb_node); 448 n = rb_entry(next, struct hist_entry, rb_node_in);
335 next = rb_next(&n->rb_node); 449 next = rb_next(&n->rb_node_in);
336 450
337 rb_erase(&n->rb_node, &self->entries); 451 __hists__insert_output_entry(&hists->entries, n, min_callchain_hits);
338 __hists__insert_output_entry(&tmp, n, min_callchain_hits); 452 hists__inc_nr_entries(hists, n);
339 hists__inc_nr_entries(self, n);
340 } 453 }
454}
341 455
342 self->entries = tmp; 456void hists__output_resort(struct hists *hists)
457{
458 return __hists__output_resort(hists, false);
459}
460
461void hists__output_resort_threaded(struct hists *hists)
462{
463 return __hists__output_resort(hists, true);
343} 464}
344 465
345static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin) 466static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
@@ -594,12 +715,27 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
594 return ret; 715 return ret;
595} 716}
596 717
597int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size, 718void hists__output_recalc_col_len(struct hists *hists, int max_rows)
598 struct hists *hists, struct hists *pair_hists, 719{
599 bool show_displacement, long displacement, 720 struct rb_node *next = rb_first(&hists->entries);
600 bool color, u64 session_total) 721 struct hist_entry *n;
722 int row = 0;
723
724 hists__reset_col_len(hists);
725
726 while (next && row++ < max_rows) {
727 n = rb_entry(next, struct hist_entry, rb_node);
728 if (!n->filtered)
729 hists__calc_col_len(hists, n);
730 next = rb_next(&n->rb_node);
731 }
732}
733
734static int hist_entry__pcnt_snprintf(struct hist_entry *self, char *s,
735 size_t size, struct hists *pair_hists,
736 bool show_displacement, long displacement,
737 bool color, u64 session_total)
601{ 738{
602 struct sort_entry *se;
603 u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us; 739 u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us;
604 u64 nr_events; 740 u64 nr_events;
605 const char *sep = symbol_conf.field_sep; 741 const char *sep = symbol_conf.field_sep;
@@ -664,6 +800,13 @@ int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size,
664 ret += snprintf(s + ret, size - ret, "%11" PRIu64, nr_events); 800 ret += snprintf(s + ret, size - ret, "%11" PRIu64, nr_events);
665 } 801 }
666 802
803 if (symbol_conf.show_total_period) {
804 if (sep)
805 ret += snprintf(s + ret, size - ret, "%c%" PRIu64, *sep, period);
806 else
807 ret += snprintf(s + ret, size - ret, " %12" PRIu64, period);
808 }
809
667 if (pair_hists) { 810 if (pair_hists) {
668 char bf[32]; 811 char bf[32];
669 double old_percent = 0, new_percent = 0, diff; 812 double old_percent = 0, new_percent = 0, diff;
@@ -698,26 +841,42 @@ int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size,
698 } 841 }
699 } 842 }
700 843
844 return ret;
845}
846
847int hist_entry__snprintf(struct hist_entry *he, char *s, size_t size,
848 struct hists *hists)
849{
850 const char *sep = symbol_conf.field_sep;
851 struct sort_entry *se;
852 int ret = 0;
853
701 list_for_each_entry(se, &hist_entry__sort_list, list) { 854 list_for_each_entry(se, &hist_entry__sort_list, list) {
702 if (se->elide) 855 if (se->elide)
703 continue; 856 continue;
704 857
705 ret += snprintf(s + ret, size - ret, "%s", sep ?: " "); 858 ret += snprintf(s + ret, size - ret, "%s", sep ?: " ");
706 ret += se->se_snprintf(self, s + ret, size - ret, 859 ret += se->se_snprintf(he, s + ret, size - ret,
707 hists__col_len(hists, se->se_width_idx)); 860 hists__col_len(hists, se->se_width_idx));
708 } 861 }
709 862
710 return ret; 863 return ret;
711} 864}
712 865
713int hist_entry__fprintf(struct hist_entry *self, struct hists *hists, 866int hist_entry__fprintf(struct hist_entry *he, size_t size, struct hists *hists,
714 struct hists *pair_hists, bool show_displacement, 867 struct hists *pair_hists, bool show_displacement,
715 long displacement, FILE *fp, u64 session_total) 868 long displacement, FILE *fp, u64 session_total)
716{ 869{
717 char bf[512]; 870 char bf[512];
718 hist_entry__snprintf(self, bf, sizeof(bf), hists, pair_hists, 871 int ret;
719 show_displacement, displacement, 872
720 true, session_total); 873 if (size == 0 || size > sizeof(bf))
874 size = sizeof(bf);
875
876 ret = hist_entry__pcnt_snprintf(he, bf, size, pair_hists,
877 show_displacement, displacement,
878 true, session_total);
879 hist_entry__snprintf(he, bf + ret, size - ret, hists);
721 return fprintf(fp, "%s\n", bf); 880 return fprintf(fp, "%s\n", bf);
722} 881}
723 882
@@ -738,8 +897,9 @@ static size_t hist_entry__fprintf_callchain(struct hist_entry *self,
738 left_margin); 897 left_margin);
739} 898}
740 899
741size_t hists__fprintf(struct hists *self, struct hists *pair, 900size_t hists__fprintf(struct hists *hists, struct hists *pair,
742 bool show_displacement, FILE *fp) 901 bool show_displacement, bool show_header, int max_rows,
902 int max_cols, FILE *fp)
743{ 903{
744 struct sort_entry *se; 904 struct sort_entry *se;
745 struct rb_node *nd; 905 struct rb_node *nd;
@@ -749,9 +909,13 @@ size_t hists__fprintf(struct hists *self, struct hists *pair,
749 unsigned int width; 909 unsigned int width;
750 const char *sep = symbol_conf.field_sep; 910 const char *sep = symbol_conf.field_sep;
751 const char *col_width = symbol_conf.col_width_list_str; 911 const char *col_width = symbol_conf.col_width_list_str;
912 int nr_rows = 0;
752 913
753 init_rem_hits(); 914 init_rem_hits();
754 915
916 if (!show_header)
917 goto print_entries;
918
755 fprintf(fp, "# %s", pair ? "Baseline" : "Overhead"); 919 fprintf(fp, "# %s", pair ? "Baseline" : "Overhead");
756 920
757 if (symbol_conf.show_nr_samples) { 921 if (symbol_conf.show_nr_samples) {
@@ -761,6 +925,13 @@ size_t hists__fprintf(struct hists *self, struct hists *pair,
761 fputs(" Samples ", fp); 925 fputs(" Samples ", fp);
762 } 926 }
763 927
928 if (symbol_conf.show_total_period) {
929 if (sep)
930 ret += fprintf(fp, "%cPeriod", *sep);
931 else
932 ret += fprintf(fp, " Period ");
933 }
934
764 if (symbol_conf.show_cpu_utilization) { 935 if (symbol_conf.show_cpu_utilization) {
765 if (sep) { 936 if (sep) {
766 ret += fprintf(fp, "%csys", *sep); 937 ret += fprintf(fp, "%csys", *sep);
@@ -803,18 +974,21 @@ size_t hists__fprintf(struct hists *self, struct hists *pair,
803 width = strlen(se->se_header); 974 width = strlen(se->se_header);
804 if (symbol_conf.col_width_list_str) { 975 if (symbol_conf.col_width_list_str) {
805 if (col_width) { 976 if (col_width) {
806 hists__set_col_len(self, se->se_width_idx, 977 hists__set_col_len(hists, se->se_width_idx,
807 atoi(col_width)); 978 atoi(col_width));
808 col_width = strchr(col_width, ','); 979 col_width = strchr(col_width, ',');
809 if (col_width) 980 if (col_width)
810 ++col_width; 981 ++col_width;
811 } 982 }
812 } 983 }
813 if (!hists__new_col_len(self, se->se_width_idx, width)) 984 if (!hists__new_col_len(hists, se->se_width_idx, width))
814 width = hists__col_len(self, se->se_width_idx); 985 width = hists__col_len(hists, se->se_width_idx);
815 fprintf(fp, " %*s", width, se->se_header); 986 fprintf(fp, " %*s", width, se->se_header);
816 } 987 }
988
817 fprintf(fp, "\n"); 989 fprintf(fp, "\n");
990 if (max_rows && ++nr_rows >= max_rows)
991 goto out;
818 992
819 if (sep) 993 if (sep)
820 goto print_entries; 994 goto print_entries;
@@ -822,6 +996,8 @@ size_t hists__fprintf(struct hists *self, struct hists *pair,
822 fprintf(fp, "# ........"); 996 fprintf(fp, "# ........");
823 if (symbol_conf.show_nr_samples) 997 if (symbol_conf.show_nr_samples)
824 fprintf(fp, " .........."); 998 fprintf(fp, " ..........");
999 if (symbol_conf.show_total_period)
1000 fprintf(fp, " ............");
825 if (pair) { 1001 if (pair) {
826 fprintf(fp, " .........."); 1002 fprintf(fp, " ..........");
827 if (show_displacement) 1003 if (show_displacement)
@@ -834,17 +1010,23 @@ size_t hists__fprintf(struct hists *self, struct hists *pair,
834 continue; 1010 continue;
835 1011
836 fprintf(fp, " "); 1012 fprintf(fp, " ");
837 width = hists__col_len(self, se->se_width_idx); 1013 width = hists__col_len(hists, se->se_width_idx);
838 if (width == 0) 1014 if (width == 0)
839 width = strlen(se->se_header); 1015 width = strlen(se->se_header);
840 for (i = 0; i < width; i++) 1016 for (i = 0; i < width; i++)
841 fprintf(fp, "."); 1017 fprintf(fp, ".");
842 } 1018 }
843 1019
844 fprintf(fp, "\n#\n"); 1020 fprintf(fp, "\n");
1021 if (max_rows && ++nr_rows >= max_rows)
1022 goto out;
1023
1024 fprintf(fp, "#\n");
1025 if (max_rows && ++nr_rows >= max_rows)
1026 goto out;
845 1027
846print_entries: 1028print_entries:
847 for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { 1029 for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
848 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 1030 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
849 1031
850 if (h->filtered) 1032 if (h->filtered)
@@ -858,19 +1040,22 @@ print_entries:
858 displacement = 0; 1040 displacement = 0;
859 ++position; 1041 ++position;
860 } 1042 }
861 ret += hist_entry__fprintf(h, self, pair, show_displacement, 1043 ret += hist_entry__fprintf(h, max_cols, hists, pair, show_displacement,
862 displacement, fp, self->stats.total_period); 1044 displacement, fp, hists->stats.total_period);
863 1045
864 if (symbol_conf.use_callchain) 1046 if (symbol_conf.use_callchain)
865 ret += hist_entry__fprintf_callchain(h, self, fp, 1047 ret += hist_entry__fprintf_callchain(h, hists, fp,
866 self->stats.total_period); 1048 hists->stats.total_period);
1049 if (max_rows && ++nr_rows >= max_rows)
1050 goto out;
1051
867 if (h->ms.map == NULL && verbose > 1) { 1052 if (h->ms.map == NULL && verbose > 1) {
868 __map_groups__fprintf_maps(&h->thread->mg, 1053 __map_groups__fprintf_maps(&h->thread->mg,
869 MAP__FUNCTION, verbose, fp); 1054 MAP__FUNCTION, verbose, fp);
870 fprintf(fp, "%.10s end\n", graph_dotted_line); 1055 fprintf(fp, "%.10s end\n", graph_dotted_line);
871 } 1056 }
872 } 1057 }
873 1058out:
874 free(rem_sq_bracket); 1059 free(rem_sq_bracket);
875 1060
876 return ret; 1061 return ret;
@@ -879,7 +1064,7 @@ print_entries:
879/* 1064/*
880 * See hists__fprintf to match the column widths 1065 * See hists__fprintf to match the column widths
881 */ 1066 */
882unsigned int hists__sort_list_width(struct hists *self) 1067unsigned int hists__sort_list_width(struct hists *hists)
883{ 1068{
884 struct sort_entry *se; 1069 struct sort_entry *se;
885 int ret = 9; /* total % */ 1070 int ret = 9; /* total % */
@@ -896,9 +1081,12 @@ unsigned int hists__sort_list_width(struct hists *self)
896 if (symbol_conf.show_nr_samples) 1081 if (symbol_conf.show_nr_samples)
897 ret += 11; 1082 ret += 11;
898 1083
1084 if (symbol_conf.show_total_period)
1085 ret += 13;
1086
899 list_for_each_entry(se, &hist_entry__sort_list, list) 1087 list_for_each_entry(se, &hist_entry__sort_list, list)
900 if (!se->elide) 1088 if (!se->elide)
901 ret += 2 + hists__col_len(self, se->se_width_idx); 1089 ret += 2 + hists__col_len(hists, se->se_width_idx);
902 1090
903 if (verbose) /* Addr + origin */ 1091 if (verbose) /* Addr + origin */
904 ret += 3 + BITS_PER_LONG / 4; 1092 ret += 3 + BITS_PER_LONG / 4;
@@ -906,63 +1094,84 @@ unsigned int hists__sort_list_width(struct hists *self)
906 return ret; 1094 return ret;
907} 1095}
908 1096
909static void hists__remove_entry_filter(struct hists *self, struct hist_entry *h, 1097static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h,
910 enum hist_filter filter) 1098 enum hist_filter filter)
911{ 1099{
912 h->filtered &= ~(1 << filter); 1100 h->filtered &= ~(1 << filter);
913 if (h->filtered) 1101 if (h->filtered)
914 return; 1102 return;
915 1103
916 ++self->nr_entries; 1104 ++hists->nr_entries;
917 if (h->ms.unfolded) 1105 if (h->ms.unfolded)
918 self->nr_entries += h->nr_rows; 1106 hists->nr_entries += h->nr_rows;
919 h->row_offset = 0; 1107 h->row_offset = 0;
920 self->stats.total_period += h->period; 1108 hists->stats.total_period += h->period;
921 self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events; 1109 hists->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events;
922 1110
923 hists__calc_col_len(self, h); 1111 hists__calc_col_len(hists, h);
924} 1112}
925 1113
926void hists__filter_by_dso(struct hists *self, const struct dso *dso) 1114
1115static bool hists__filter_entry_by_dso(struct hists *hists,
1116 struct hist_entry *he)
1117{
1118 if (hists->dso_filter != NULL &&
1119 (he->ms.map == NULL || he->ms.map->dso != hists->dso_filter)) {
1120 he->filtered |= (1 << HIST_FILTER__DSO);
1121 return true;
1122 }
1123
1124 return false;
1125}
1126
1127void hists__filter_by_dso(struct hists *hists)
927{ 1128{
928 struct rb_node *nd; 1129 struct rb_node *nd;
929 1130
930 self->nr_entries = self->stats.total_period = 0; 1131 hists->nr_entries = hists->stats.total_period = 0;
931 self->stats.nr_events[PERF_RECORD_SAMPLE] = 0; 1132 hists->stats.nr_events[PERF_RECORD_SAMPLE] = 0;
932 hists__reset_col_len(self); 1133 hists__reset_col_len(hists);
933 1134
934 for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { 1135 for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
935 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 1136 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
936 1137
937 if (symbol_conf.exclude_other && !h->parent) 1138 if (symbol_conf.exclude_other && !h->parent)
938 continue; 1139 continue;
939 1140
940 if (dso != NULL && (h->ms.map == NULL || h->ms.map->dso != dso)) { 1141 if (hists__filter_entry_by_dso(hists, h))
941 h->filtered |= (1 << HIST_FILTER__DSO);
942 continue; 1142 continue;
943 }
944 1143
945 hists__remove_entry_filter(self, h, HIST_FILTER__DSO); 1144 hists__remove_entry_filter(hists, h, HIST_FILTER__DSO);
946 } 1145 }
947} 1146}
948 1147
949void hists__filter_by_thread(struct hists *self, const struct thread *thread) 1148static bool hists__filter_entry_by_thread(struct hists *hists,
1149 struct hist_entry *he)
1150{
1151 if (hists->thread_filter != NULL &&
1152 he->thread != hists->thread_filter) {
1153 he->filtered |= (1 << HIST_FILTER__THREAD);
1154 return true;
1155 }
1156
1157 return false;
1158}
1159
1160void hists__filter_by_thread(struct hists *hists)
950{ 1161{
951 struct rb_node *nd; 1162 struct rb_node *nd;
952 1163
953 self->nr_entries = self->stats.total_period = 0; 1164 hists->nr_entries = hists->stats.total_period = 0;
954 self->stats.nr_events[PERF_RECORD_SAMPLE] = 0; 1165 hists->stats.nr_events[PERF_RECORD_SAMPLE] = 0;
955 hists__reset_col_len(self); 1166 hists__reset_col_len(hists);
956 1167
957 for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { 1168 for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
958 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 1169 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
959 1170
960 if (thread != NULL && h->thread != thread) { 1171 if (hists__filter_entry_by_thread(hists, h))
961 h->filtered |= (1 << HIST_FILTER__THREAD);
962 continue; 1172 continue;
963 }
964 1173
965 hists__remove_entry_filter(self, h, HIST_FILTER__THREAD); 1174 hists__remove_entry_filter(hists, h, HIST_FILTER__THREAD);
966 } 1175 }
967} 1176}
968 1177
@@ -976,13 +1185,13 @@ int hist_entry__annotate(struct hist_entry *he, size_t privsize)
976 return symbol__annotate(he->ms.sym, he->ms.map, privsize); 1185 return symbol__annotate(he->ms.sym, he->ms.map, privsize);
977} 1186}
978 1187
979void hists__inc_nr_events(struct hists *self, u32 type) 1188void hists__inc_nr_events(struct hists *hists, u32 type)
980{ 1189{
981 ++self->stats.nr_events[0]; 1190 ++hists->stats.nr_events[0];
982 ++self->stats.nr_events[type]; 1191 ++hists->stats.nr_events[type];
983} 1192}
984 1193
985size_t hists__fprintf_nr_events(struct hists *self, FILE *fp) 1194size_t hists__fprintf_nr_events(struct hists *hists, FILE *fp)
986{ 1195{
987 int i; 1196 int i;
988 size_t ret = 0; 1197 size_t ret = 0;
@@ -990,7 +1199,7 @@ size_t hists__fprintf_nr_events(struct hists *self, FILE *fp)
990 for (i = 0; i < PERF_RECORD_HEADER_MAX; ++i) { 1199 for (i = 0; i < PERF_RECORD_HEADER_MAX; ++i) {
991 const char *name; 1200 const char *name;
992 1201
993 if (self->stats.nr_events[i] == 0) 1202 if (hists->stats.nr_events[i] == 0)
994 continue; 1203 continue;
995 1204
996 name = perf_event__name(i); 1205 name = perf_event__name(i);
@@ -998,8 +1207,18 @@ size_t hists__fprintf_nr_events(struct hists *self, FILE *fp)
998 continue; 1207 continue;
999 1208
1000 ret += fprintf(fp, "%16s events: %10d\n", name, 1209 ret += fprintf(fp, "%16s events: %10d\n", name,
1001 self->stats.nr_events[i]); 1210 hists->stats.nr_events[i]);
1002 } 1211 }
1003 1212
1004 return ret; 1213 return ret;
1005} 1214}
1215
1216void hists__init(struct hists *hists)
1217{
1218 memset(hists, 0, sizeof(*hists));
1219 hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT;
1220 hists->entries_in = &hists->entries_in_array[0];
1221 hists->entries_collapsed = RB_ROOT;
1222 hists->entries = RB_ROOT;
1223 pthread_mutex_init(&hists->lock, NULL);
1224}
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 3beb97c4d822..ff93ddc91c5c 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -2,6 +2,7 @@
2#define __PERF_HIST_H 2#define __PERF_HIST_H
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5#include <pthread.h>
5#include "callchain.h" 6#include "callchain.h"
6 7
7extern struct callchain_param callchain_param; 8extern struct callchain_param callchain_param;
@@ -42,9 +43,18 @@ enum hist_column {
42 HISTC_NR_COLS, /* Last entry */ 43 HISTC_NR_COLS, /* Last entry */
43}; 44};
44 45
46struct thread;
47struct dso;
48
45struct hists { 49struct hists {
50 struct rb_root entries_in_array[2];
51 struct rb_root *entries_in;
46 struct rb_root entries; 52 struct rb_root entries;
53 struct rb_root entries_collapsed;
47 u64 nr_entries; 54 u64 nr_entries;
55 const struct thread *thread_filter;
56 const struct dso *dso_filter;
57 pthread_mutex_t lock;
48 struct events_stats stats; 58 struct events_stats stats;
49 u64 event_stream; 59 u64 event_stream;
50 u16 col_len[HISTC_NR_COLS]; 60 u16 col_len[HISTC_NR_COLS];
@@ -52,34 +62,42 @@ struct hists {
52 struct callchain_cursor callchain_cursor; 62 struct callchain_cursor callchain_cursor;
53}; 63};
54 64
65void hists__init(struct hists *hists);
66
55struct hist_entry *__hists__add_entry(struct hists *self, 67struct hist_entry *__hists__add_entry(struct hists *self,
56 struct addr_location *al, 68 struct addr_location *al,
57 struct symbol *parent, u64 period); 69 struct symbol *parent, u64 period);
58extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); 70extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *);
59extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); 71extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *);
60int hist_entry__fprintf(struct hist_entry *self, struct hists *hists, 72int hist_entry__fprintf(struct hist_entry *he, size_t size, struct hists *hists,
61 struct hists *pair_hists, bool show_displacement, 73 struct hists *pair_hists, bool show_displacement,
62 long displacement, FILE *fp, u64 total); 74 long displacement, FILE *fp, u64 session_total);
63int hist_entry__snprintf(struct hist_entry *self, char *bf, size_t size, 75int hist_entry__snprintf(struct hist_entry *self, char *bf, size_t size,
64 struct hists *hists, struct hists *pair_hists, 76 struct hists *hists);
65 bool show_displacement, long displacement,
66 bool color, u64 total);
67void hist_entry__free(struct hist_entry *); 77void hist_entry__free(struct hist_entry *);
68 78
69void hists__output_resort(struct hists *self); 79void hists__output_resort(struct hists *self);
80void hists__output_resort_threaded(struct hists *hists);
70void hists__collapse_resort(struct hists *self); 81void hists__collapse_resort(struct hists *self);
82void hists__collapse_resort_threaded(struct hists *hists);
83
84void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel);
85void hists__decay_entries_threaded(struct hists *hists, bool zap_user,
86 bool zap_kernel);
87void hists__output_recalc_col_len(struct hists *hists, int max_rows);
71 88
72void hists__inc_nr_events(struct hists *self, u32 type); 89void hists__inc_nr_events(struct hists *self, u32 type);
73size_t hists__fprintf_nr_events(struct hists *self, FILE *fp); 90size_t hists__fprintf_nr_events(struct hists *self, FILE *fp);
74 91
75size_t hists__fprintf(struct hists *self, struct hists *pair, 92size_t hists__fprintf(struct hists *self, struct hists *pair,
76 bool show_displacement, FILE *fp); 93 bool show_displacement, bool show_header,
94 int max_rows, int max_cols, FILE *fp);
77 95
78int hist_entry__inc_addr_samples(struct hist_entry *self, int evidx, u64 addr); 96int hist_entry__inc_addr_samples(struct hist_entry *self, int evidx, u64 addr);
79int hist_entry__annotate(struct hist_entry *self, size_t privsize); 97int hist_entry__annotate(struct hist_entry *self, size_t privsize);
80 98
81void hists__filter_by_dso(struct hists *self, const struct dso *dso); 99void hists__filter_by_dso(struct hists *hists);
82void hists__filter_by_thread(struct hists *self, const struct thread *thread); 100void hists__filter_by_thread(struct hists *hists);
83 101
84u16 hists__col_len(struct hists *self, enum hist_column col); 102u16 hists__col_len(struct hists *self, enum hist_column col);
85void hists__set_col_len(struct hists *self, enum hist_column col, u16 len); 103void hists__set_col_len(struct hists *self, enum hist_column col, u16 len);
@@ -90,26 +108,33 @@ struct perf_evlist;
90#ifdef NO_NEWT_SUPPORT 108#ifdef NO_NEWT_SUPPORT
91static inline 109static inline
92int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __used, 110int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __used,
93 const char *help __used) 111 const char *help __used,
112 void(*timer)(void *arg) __used,
113 void *arg __used,
114 int refresh __used)
94{ 115{
95 return 0; 116 return 0;
96} 117}
97 118
98static inline int hist_entry__tui_annotate(struct hist_entry *self __used, 119static inline int hist_entry__tui_annotate(struct hist_entry *self __used,
99 int evidx __used) 120 int evidx __used,
121 int nr_events __used,
122 void(*timer)(void *arg) __used,
123 void *arg __used,
124 int delay_secs __used)
100{ 125{
101 return 0; 126 return 0;
102} 127}
103#define KEY_LEFT -1 128#define K_LEFT -1
104#define KEY_RIGHT -2 129#define K_RIGHT -2
105#else 130#else
106#include <newt.h> 131#include "ui/keysyms.h"
107int hist_entry__tui_annotate(struct hist_entry *self, int evidx); 132int hist_entry__tui_annotate(struct hist_entry *he, int evidx, int nr_events,
108 133 void(*timer)(void *arg), void *arg, int delay_secs);
109#define KEY_LEFT NEWT_KEY_LEFT
110#define KEY_RIGHT NEWT_KEY_RIGHT
111 134
112int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help); 135int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
136 void(*timer)(void *arg), void *arg,
137 int refresh);
113#endif 138#endif
114 139
115unsigned int hists__sort_list_width(struct hists *self); 140unsigned int hists__sort_list_width(struct hists *self);
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index a16ecab5229d..78284b13e808 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -18,6 +18,13 @@ static inline int is_anon_memory(const char *filename)
18 return strcmp(filename, "//anon") == 0; 18 return strcmp(filename, "//anon") == 0;
19} 19}
20 20
21static inline int is_no_dso_memory(const char *filename)
22{
23 return !strcmp(filename, "[stack]") ||
24 !strcmp(filename, "[vdso]") ||
25 !strcmp(filename, "[heap]");
26}
27
21void map__init(struct map *self, enum map_type type, 28void map__init(struct map *self, enum map_type type,
22 u64 start, u64 end, u64 pgoff, struct dso *dso) 29 u64 start, u64 end, u64 pgoff, struct dso *dso)
23{ 30{
@@ -42,9 +49,10 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
42 if (self != NULL) { 49 if (self != NULL) {
43 char newfilename[PATH_MAX]; 50 char newfilename[PATH_MAX];
44 struct dso *dso; 51 struct dso *dso;
45 int anon; 52 int anon, no_dso;
46 53
47 anon = is_anon_memory(filename); 54 anon = is_anon_memory(filename);
55 no_dso = is_no_dso_memory(filename);
48 56
49 if (anon) { 57 if (anon) {
50 snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid); 58 snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
@@ -57,12 +65,16 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
57 65
58 map__init(self, type, start, start + len, pgoff, dso); 66 map__init(self, type, start, start + len, pgoff, dso);
59 67
60 if (anon) { 68 if (anon || no_dso) {
61set_identity:
62 self->map_ip = self->unmap_ip = identity__map_ip; 69 self->map_ip = self->unmap_ip = identity__map_ip;
63 } else if (strcmp(filename, "[vdso]") == 0) { 70
64 dso__set_loaded(dso, self->type); 71 /*
65 goto set_identity; 72 * Set memory without DSO as loaded. All map__find_*
73 * functions still return NULL, and we avoid the
74 * unnecessary map__load warning.
75 */
76 if (no_dso)
77 dso__set_loaded(dso, self->type);
66 } 78 }
67 } 79 }
68 return self; 80 return self;
@@ -127,8 +139,8 @@ int map__load(struct map *self, symbol_filter_t filter)
127 139
128 if (len > sizeof(DSO__DELETED) && 140 if (len > sizeof(DSO__DELETED) &&
129 strcmp(name + real_len + 1, DSO__DELETED) == 0) { 141 strcmp(name + real_len + 1, DSO__DELETED) == 0) {
130 pr_warning("%.*s was updated, restart the long " 142 pr_warning("%.*s was updated (is prelink enabled?). "
131 "running apps that use it!\n", 143 "Restart the long running apps that use it!\n",
132 (int)real_len, name); 144 (int)real_len, name);
133 } else { 145 } else {
134 pr_warning("no symbols found in %s, maybe install " 146 pr_warning("no symbols found in %s, maybe install "
@@ -220,55 +232,55 @@ u64 map__objdump_2ip(struct map *map, u64 addr)
220 return ip; 232 return ip;
221} 233}
222 234
223void map_groups__init(struct map_groups *self) 235void map_groups__init(struct map_groups *mg)
224{ 236{
225 int i; 237 int i;
226 for (i = 0; i < MAP__NR_TYPES; ++i) { 238 for (i = 0; i < MAP__NR_TYPES; ++i) {
227 self->maps[i] = RB_ROOT; 239 mg->maps[i] = RB_ROOT;
228 INIT_LIST_HEAD(&self->removed_maps[i]); 240 INIT_LIST_HEAD(&mg->removed_maps[i]);
229 } 241 }
230 self->machine = NULL; 242 mg->machine = NULL;
231} 243}
232 244
233static void maps__delete(struct rb_root *self) 245static void maps__delete(struct rb_root *maps)
234{ 246{
235 struct rb_node *next = rb_first(self); 247 struct rb_node *next = rb_first(maps);
236 248
237 while (next) { 249 while (next) {
238 struct map *pos = rb_entry(next, struct map, rb_node); 250 struct map *pos = rb_entry(next, struct map, rb_node);
239 251
240 next = rb_next(&pos->rb_node); 252 next = rb_next(&pos->rb_node);
241 rb_erase(&pos->rb_node, self); 253 rb_erase(&pos->rb_node, maps);
242 map__delete(pos); 254 map__delete(pos);
243 } 255 }
244} 256}
245 257
246static void maps__delete_removed(struct list_head *self) 258static void maps__delete_removed(struct list_head *maps)
247{ 259{
248 struct map *pos, *n; 260 struct map *pos, *n;
249 261
250 list_for_each_entry_safe(pos, n, self, node) { 262 list_for_each_entry_safe(pos, n, maps, node) {
251 list_del(&pos->node); 263 list_del(&pos->node);
252 map__delete(pos); 264 map__delete(pos);
253 } 265 }
254} 266}
255 267
256void map_groups__exit(struct map_groups *self) 268void map_groups__exit(struct map_groups *mg)
257{ 269{
258 int i; 270 int i;
259 271
260 for (i = 0; i < MAP__NR_TYPES; ++i) { 272 for (i = 0; i < MAP__NR_TYPES; ++i) {
261 maps__delete(&self->maps[i]); 273 maps__delete(&mg->maps[i]);
262 maps__delete_removed(&self->removed_maps[i]); 274 maps__delete_removed(&mg->removed_maps[i]);
263 } 275 }
264} 276}
265 277
266void map_groups__flush(struct map_groups *self) 278void map_groups__flush(struct map_groups *mg)
267{ 279{
268 int type; 280 int type;
269 281
270 for (type = 0; type < MAP__NR_TYPES; type++) { 282 for (type = 0; type < MAP__NR_TYPES; type++) {
271 struct rb_root *root = &self->maps[type]; 283 struct rb_root *root = &mg->maps[type];
272 struct rb_node *next = rb_first(root); 284 struct rb_node *next = rb_first(root);
273 285
274 while (next) { 286 while (next) {
@@ -280,17 +292,17 @@ void map_groups__flush(struct map_groups *self)
280 * instance in some hist_entry instances, so 292 * instance in some hist_entry instances, so
281 * just move them to a separate list. 293 * just move them to a separate list.
282 */ 294 */
283 list_add_tail(&pos->node, &self->removed_maps[pos->type]); 295 list_add_tail(&pos->node, &mg->removed_maps[pos->type]);
284 } 296 }
285 } 297 }
286} 298}
287 299
288struct symbol *map_groups__find_symbol(struct map_groups *self, 300struct symbol *map_groups__find_symbol(struct map_groups *mg,
289 enum map_type type, u64 addr, 301 enum map_type type, u64 addr,
290 struct map **mapp, 302 struct map **mapp,
291 symbol_filter_t filter) 303 symbol_filter_t filter)
292{ 304{
293 struct map *map = map_groups__find(self, type, addr); 305 struct map *map = map_groups__find(mg, type, addr);
294 306
295 if (map != NULL) { 307 if (map != NULL) {
296 if (mapp != NULL) 308 if (mapp != NULL)
@@ -301,7 +313,7 @@ struct symbol *map_groups__find_symbol(struct map_groups *self,
301 return NULL; 313 return NULL;
302} 314}
303 315
304struct symbol *map_groups__find_symbol_by_name(struct map_groups *self, 316struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
305 enum map_type type, 317 enum map_type type,
306 const char *name, 318 const char *name,
307 struct map **mapp, 319 struct map **mapp,
@@ -309,7 +321,7 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
309{ 321{
310 struct rb_node *nd; 322 struct rb_node *nd;
311 323
312 for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) { 324 for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
313 struct map *pos = rb_entry(nd, struct map, rb_node); 325 struct map *pos = rb_entry(nd, struct map, rb_node);
314 struct symbol *sym = map__find_symbol_by_name(pos, name, filter); 326 struct symbol *sym = map__find_symbol_by_name(pos, name, filter);
315 327
@@ -323,13 +335,13 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
323 return NULL; 335 return NULL;
324} 336}
325 337
326size_t __map_groups__fprintf_maps(struct map_groups *self, 338size_t __map_groups__fprintf_maps(struct map_groups *mg,
327 enum map_type type, int verbose, FILE *fp) 339 enum map_type type, int verbose, FILE *fp)
328{ 340{
329 size_t printed = fprintf(fp, "%s:\n", map_type__name[type]); 341 size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
330 struct rb_node *nd; 342 struct rb_node *nd;
331 343
332 for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) { 344 for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
333 struct map *pos = rb_entry(nd, struct map, rb_node); 345 struct map *pos = rb_entry(nd, struct map, rb_node);
334 printed += fprintf(fp, "Map:"); 346 printed += fprintf(fp, "Map:");
335 printed += map__fprintf(pos, fp); 347 printed += map__fprintf(pos, fp);
@@ -342,22 +354,22 @@ size_t __map_groups__fprintf_maps(struct map_groups *self,
342 return printed; 354 return printed;
343} 355}
344 356
345size_t map_groups__fprintf_maps(struct map_groups *self, int verbose, FILE *fp) 357size_t map_groups__fprintf_maps(struct map_groups *mg, int verbose, FILE *fp)
346{ 358{
347 size_t printed = 0, i; 359 size_t printed = 0, i;
348 for (i = 0; i < MAP__NR_TYPES; ++i) 360 for (i = 0; i < MAP__NR_TYPES; ++i)
349 printed += __map_groups__fprintf_maps(self, i, verbose, fp); 361 printed += __map_groups__fprintf_maps(mg, i, verbose, fp);
350 return printed; 362 return printed;
351} 363}
352 364
353static size_t __map_groups__fprintf_removed_maps(struct map_groups *self, 365static size_t __map_groups__fprintf_removed_maps(struct map_groups *mg,
354 enum map_type type, 366 enum map_type type,
355 int verbose, FILE *fp) 367 int verbose, FILE *fp)
356{ 368{
357 struct map *pos; 369 struct map *pos;
358 size_t printed = 0; 370 size_t printed = 0;
359 371
360 list_for_each_entry(pos, &self->removed_maps[type], node) { 372 list_for_each_entry(pos, &mg->removed_maps[type], node) {
361 printed += fprintf(fp, "Map:"); 373 printed += fprintf(fp, "Map:");
362 printed += map__fprintf(pos, fp); 374 printed += map__fprintf(pos, fp);
363 if (verbose > 1) { 375 if (verbose > 1) {
@@ -368,26 +380,26 @@ static size_t __map_groups__fprintf_removed_maps(struct map_groups *self,
368 return printed; 380 return printed;
369} 381}
370 382
371static size_t map_groups__fprintf_removed_maps(struct map_groups *self, 383static size_t map_groups__fprintf_removed_maps(struct map_groups *mg,
372 int verbose, FILE *fp) 384 int verbose, FILE *fp)
373{ 385{
374 size_t printed = 0, i; 386 size_t printed = 0, i;
375 for (i = 0; i < MAP__NR_TYPES; ++i) 387 for (i = 0; i < MAP__NR_TYPES; ++i)
376 printed += __map_groups__fprintf_removed_maps(self, i, verbose, fp); 388 printed += __map_groups__fprintf_removed_maps(mg, i, verbose, fp);
377 return printed; 389 return printed;
378} 390}
379 391
380size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp) 392size_t map_groups__fprintf(struct map_groups *mg, int verbose, FILE *fp)
381{ 393{
382 size_t printed = map_groups__fprintf_maps(self, verbose, fp); 394 size_t printed = map_groups__fprintf_maps(mg, verbose, fp);
383 printed += fprintf(fp, "Removed maps:\n"); 395 printed += fprintf(fp, "Removed maps:\n");
384 return printed + map_groups__fprintf_removed_maps(self, verbose, fp); 396 return printed + map_groups__fprintf_removed_maps(mg, verbose, fp);
385} 397}
386 398
387int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, 399int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
388 int verbose, FILE *fp) 400 int verbose, FILE *fp)
389{ 401{
390 struct rb_root *root = &self->maps[map->type]; 402 struct rb_root *root = &mg->maps[map->type];
391 struct rb_node *next = rb_first(root); 403 struct rb_node *next = rb_first(root);
392 int err = 0; 404 int err = 0;
393 405
@@ -418,7 +430,7 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
418 } 430 }
419 431
420 before->end = map->start - 1; 432 before->end = map->start - 1;
421 map_groups__insert(self, before); 433 map_groups__insert(mg, before);
422 if (verbose >= 2) 434 if (verbose >= 2)
423 map__fprintf(before, fp); 435 map__fprintf(before, fp);
424 } 436 }
@@ -432,7 +444,7 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
432 } 444 }
433 445
434 after->start = map->end + 1; 446 after->start = map->end + 1;
435 map_groups__insert(self, after); 447 map_groups__insert(mg, after);
436 if (verbose >= 2) 448 if (verbose >= 2)
437 map__fprintf(after, fp); 449 map__fprintf(after, fp);
438 } 450 }
@@ -441,7 +453,7 @@ move_map:
441 * If we have references, just move them to a separate list. 453 * If we have references, just move them to a separate list.
442 */ 454 */
443 if (pos->referenced) 455 if (pos->referenced)
444 list_add_tail(&pos->node, &self->removed_maps[map->type]); 456 list_add_tail(&pos->node, &mg->removed_maps[map->type]);
445 else 457 else
446 map__delete(pos); 458 map__delete(pos);
447 459
@@ -455,7 +467,7 @@ move_map:
455/* 467/*
456 * XXX This should not really _copy_ te maps, but refcount them. 468 * XXX This should not really _copy_ te maps, but refcount them.
457 */ 469 */
458int map_groups__clone(struct map_groups *self, 470int map_groups__clone(struct map_groups *mg,
459 struct map_groups *parent, enum map_type type) 471 struct map_groups *parent, enum map_type type)
460{ 472{
461 struct rb_node *nd; 473 struct rb_node *nd;
@@ -464,7 +476,7 @@ int map_groups__clone(struct map_groups *self,
464 struct map *new = map__clone(map); 476 struct map *new = map__clone(map);
465 if (new == NULL) 477 if (new == NULL)
466 return -ENOMEM; 478 return -ENOMEM;
467 map_groups__insert(self, new); 479 map_groups__insert(mg, new);
468 } 480 }
469 return 0; 481 return 0;
470} 482}
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index b397c0383728..890d85545d0f 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -123,17 +123,17 @@ void map__fixup_end(struct map *self);
123 123
124void map__reloc_vmlinux(struct map *self); 124void map__reloc_vmlinux(struct map *self);
125 125
126size_t __map_groups__fprintf_maps(struct map_groups *self, 126size_t __map_groups__fprintf_maps(struct map_groups *mg,
127 enum map_type type, int verbose, FILE *fp); 127 enum map_type type, int verbose, FILE *fp);
128void maps__insert(struct rb_root *maps, struct map *map); 128void maps__insert(struct rb_root *maps, struct map *map);
129void maps__remove(struct rb_root *self, struct map *map); 129void maps__remove(struct rb_root *maps, struct map *map);
130struct map *maps__find(struct rb_root *maps, u64 addr); 130struct map *maps__find(struct rb_root *maps, u64 addr);
131void map_groups__init(struct map_groups *self); 131void map_groups__init(struct map_groups *mg);
132void map_groups__exit(struct map_groups *self); 132void map_groups__exit(struct map_groups *mg);
133int map_groups__clone(struct map_groups *self, 133int map_groups__clone(struct map_groups *mg,
134 struct map_groups *parent, enum map_type type); 134 struct map_groups *parent, enum map_type type);
135size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp); 135size_t map_groups__fprintf(struct map_groups *mg, int verbose, FILE *fp);
136size_t map_groups__fprintf_maps(struct map_groups *self, int verbose, FILE *fp); 136size_t map_groups__fprintf_maps(struct map_groups *mg, int verbose, FILE *fp);
137 137
138typedef void (*machine__process_t)(struct machine *self, void *data); 138typedef void (*machine__process_t)(struct machine *self, void *data);
139 139
@@ -162,29 +162,29 @@ static inline bool machine__is_host(struct machine *self)
162 return self ? self->pid == HOST_KERNEL_ID : false; 162 return self ? self->pid == HOST_KERNEL_ID : false;
163} 163}
164 164
165static inline void map_groups__insert(struct map_groups *self, struct map *map) 165static inline void map_groups__insert(struct map_groups *mg, struct map *map)
166{ 166{
167 maps__insert(&self->maps[map->type], map); 167 maps__insert(&mg->maps[map->type], map);
168 map->groups = self; 168 map->groups = mg;
169} 169}
170 170
171static inline void map_groups__remove(struct map_groups *self, struct map *map) 171static inline void map_groups__remove(struct map_groups *mg, struct map *map)
172{ 172{
173 maps__remove(&self->maps[map->type], map); 173 maps__remove(&mg->maps[map->type], map);
174} 174}
175 175
176static inline struct map *map_groups__find(struct map_groups *self, 176static inline struct map *map_groups__find(struct map_groups *mg,
177 enum map_type type, u64 addr) 177 enum map_type type, u64 addr)
178{ 178{
179 return maps__find(&self->maps[type], addr); 179 return maps__find(&mg->maps[type], addr);
180} 180}
181 181
182struct symbol *map_groups__find_symbol(struct map_groups *self, 182struct symbol *map_groups__find_symbol(struct map_groups *mg,
183 enum map_type type, u64 addr, 183 enum map_type type, u64 addr,
184 struct map **mapp, 184 struct map **mapp,
185 symbol_filter_t filter); 185 symbol_filter_t filter);
186 186
187struct symbol *map_groups__find_symbol_by_name(struct map_groups *self, 187struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
188 enum map_type type, 188 enum map_type type,
189 const char *name, 189 const char *name,
190 struct map **mapp, 190 struct map **mapp,
@@ -208,11 +208,11 @@ struct symbol *machine__find_kernel_function(struct machine *self, u64 addr,
208} 208}
209 209
210static inline 210static inline
211struct symbol *map_groups__find_function_by_name(struct map_groups *self, 211struct symbol *map_groups__find_function_by_name(struct map_groups *mg,
212 const char *name, struct map **mapp, 212 const char *name, struct map **mapp,
213 symbol_filter_t filter) 213 symbol_filter_t filter)
214{ 214{
215 return map_groups__find_symbol_by_name(self, MAP__FUNCTION, name, mapp, filter); 215 return map_groups__find_symbol_by_name(mg, MAP__FUNCTION, name, mapp, filter);
216} 216}
217 217
218static inline 218static inline
@@ -225,13 +225,13 @@ struct symbol *machine__find_kernel_function_by_name(struct machine *self,
225 filter); 225 filter);
226} 226}
227 227
228int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, 228int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
229 int verbose, FILE *fp); 229 int verbose, FILE *fp);
230 230
231struct map *map_groups__find_by_name(struct map_groups *self, 231struct map *map_groups__find_by_name(struct map_groups *mg,
232 enum map_type type, const char *name); 232 enum map_type type, const char *name);
233struct map *machine__new_module(struct machine *self, u64 start, const char *filename); 233struct map *machine__new_module(struct machine *self, u64 start, const char *filename);
234 234
235void map_groups__flush(struct map_groups *self); 235void map_groups__flush(struct map_groups *mg);
236 236
237#endif /* __PERF_MAP_H */ 237#endif /* __PERF_MAP_H */
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 1c7bfa5fe0a8..eb25900e2211 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1956,8 +1956,10 @@ static int __del_trace_probe_event(int fd, struct str_node *ent)
1956 1956
1957 pr_debug("Writing event: %s\n", buf); 1957 pr_debug("Writing event: %s\n", buf);
1958 ret = write(fd, buf, strlen(buf)); 1958 ret = write(fd, buf, strlen(buf));
1959 if (ret < 0) 1959 if (ret < 0) {
1960 ret = -errno;
1960 goto error; 1961 goto error;
1962 }
1961 1963
1962 printf("Remove event: %s\n", ent->s); 1964 printf("Remove event: %s\n", ent->s);
1963 return 0; 1965 return 0;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 72458d9da5b1..20e011c99a94 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1326,3 +1326,22 @@ int perf_session__cpu_bitmap(struct perf_session *session,
1326 1326
1327 return 0; 1327 return 0;
1328} 1328}
1329
1330void perf_session__fprintf_info(struct perf_session *session, FILE *fp,
1331 bool full)
1332{
1333 struct stat st;
1334 int ret;
1335
1336 if (session == NULL || fp == NULL)
1337 return;
1338
1339 ret = fstat(session->fd, &st);
1340 if (ret == -1)
1341 return;
1342
1343 fprintf(fp, "# ========\n");
1344 fprintf(fp, "# captured on: %s", ctime(&st.st_ctime));
1345 perf_header__fprintf_info(session, fp, full);
1346 fprintf(fp, "# ========\n#\n");
1347}
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 974d0cbee5e9..514b06d41f05 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -177,4 +177,5 @@ void perf_session__print_ip(union perf_event *event,
177int perf_session__cpu_bitmap(struct perf_session *session, 177int perf_session__cpu_bitmap(struct perf_session *session,
178 const char *cpu_list, unsigned long *cpu_bitmap); 178 const char *cpu_list, unsigned long *cpu_bitmap);
179 179
180void perf_session__fprintf_info(struct perf_session *s, FILE *fp, bool full);
180#endif /* __PERF_SESSION_H */ 181#endif /* __PERF_SESSION_H */
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 1ee8f1e40f18..16da30d8d765 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -177,7 +177,9 @@ static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
177 BITS_PER_LONG / 4, self->ip, o); 177 BITS_PER_LONG / 4, self->ip, o);
178 } 178 }
179 179
180 ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", self->level); 180 if (!sort_dso.elide)
181 ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", self->level);
182
181 if (self->ms.sym) 183 if (self->ms.sym)
182 ret += repsep_snprintf(bf + ret, size - ret, "%s", 184 ret += repsep_snprintf(bf + ret, size - ret, "%s",
183 self->ms.sym->name); 185 self->ms.sym->name);
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 77d0388ad415..3f67ae395752 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -45,6 +45,7 @@ extern enum sort_type sort__first_dimension;
45 * @nr_rows - rows expanded in callchain, recalculated on folding/unfolding 45 * @nr_rows - rows expanded in callchain, recalculated on folding/unfolding
46 */ 46 */
47struct hist_entry { 47struct hist_entry {
48 struct rb_node rb_node_in;
48 struct rb_node rb_node; 49 struct rb_node rb_node;
49 u64 period; 50 u64 period;
50 u64 period_sys; 51 u64 period_sys;
@@ -63,6 +64,7 @@ struct hist_entry {
63 64
64 bool init_have_children; 65 bool init_have_children;
65 char level; 66 char level;
67 bool used;
66 u8 filtered; 68 u8 filtered;
67 struct symbol *parent; 69 struct symbol *parent;
68 union { 70 union {
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 40eeaf07725b..632b50c7bc26 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -24,7 +24,7 @@
24#include <sys/utsname.h> 24#include <sys/utsname.h>
25 25
26#ifndef KSYM_NAME_LEN 26#ifndef KSYM_NAME_LEN
27#define KSYM_NAME_LEN 128 27#define KSYM_NAME_LEN 256
28#endif 28#endif
29 29
30#ifndef NT_GNU_BUILD_ID 30#ifndef NT_GNU_BUILD_ID
@@ -46,6 +46,7 @@ struct symbol_conf symbol_conf = {
46 .exclude_other = true, 46 .exclude_other = true,
47 .use_modules = true, 47 .use_modules = true,
48 .try_vmlinux_path = true, 48 .try_vmlinux_path = true,
49 .annotate_src = true,
49 .symfs = "", 50 .symfs = "",
50}; 51};
51 52
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 4f377d92e75a..29f8d742e92f 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -72,11 +72,14 @@ struct symbol_conf {
72 use_modules, 72 use_modules,
73 sort_by_name, 73 sort_by_name,
74 show_nr_samples, 74 show_nr_samples,
75 show_total_period,
75 use_callchain, 76 use_callchain,
76 exclude_other, 77 exclude_other,
77 show_cpu_utilization, 78 show_cpu_utilization,
78 initialized, 79 initialized,
79 kptr_restrict; 80 kptr_restrict,
81 annotate_asm_raw,
82 annotate_src;
80 const char *vmlinux_name, 83 const char *vmlinux_name,
81 *kallsyms_name, 84 *kallsyms_name,
82 *source_prefix, 85 *source_prefix,
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c
index a11f60735a18..500471dffa4f 100644
--- a/tools/perf/util/top.c
+++ b/tools/perf/util/top.c
@@ -15,52 +15,6 @@
15#include "top.h" 15#include "top.h"
16#include <inttypes.h> 16#include <inttypes.h>
17 17
18/*
19 * Ordering weight: count-1 * count-2 * ... / count-n
20 */
21static double sym_weight(const struct sym_entry *sym, struct perf_top *top)
22{
23 double weight = sym->snap_count;
24 int counter;
25
26 if (!top->display_weighted)
27 return weight;
28
29 for (counter = 1; counter < top->evlist->nr_entries - 1; counter++)
30 weight *= sym->count[counter];
31
32 weight /= (sym->count[counter] + 1);
33
34 return weight;
35}
36
37static void perf_top__remove_active_sym(struct perf_top *top, struct sym_entry *syme)
38{
39 pthread_mutex_lock(&top->active_symbols_lock);
40 list_del_init(&syme->node);
41 pthread_mutex_unlock(&top->active_symbols_lock);
42}
43
44static void rb_insert_active_sym(struct rb_root *tree, struct sym_entry *se)
45{
46 struct rb_node **p = &tree->rb_node;
47 struct rb_node *parent = NULL;
48 struct sym_entry *iter;
49
50 while (*p != NULL) {
51 parent = *p;
52 iter = rb_entry(parent, struct sym_entry, rb_node);
53
54 if (se->weight > iter->weight)
55 p = &(*p)->rb_left;
56 else
57 p = &(*p)->rb_right;
58 }
59
60 rb_link_node(&se->rb_node, parent, p);
61 rb_insert_color(&se->rb_node, tree);
62}
63
64#define SNPRINTF(buf, size, fmt, args...) \ 18#define SNPRINTF(buf, size, fmt, args...) \
65({ \ 19({ \
66 size_t r = snprintf(buf, size, fmt, ## args); \ 20 size_t r = snprintf(buf, size, fmt, ## args); \
@@ -69,7 +23,6 @@ static void rb_insert_active_sym(struct rb_root *tree, struct sym_entry *se)
69 23
70size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) 24size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
71{ 25{
72 struct perf_evsel *counter;
73 float samples_per_sec = top->samples / top->delay_secs; 26 float samples_per_sec = top->samples / top->delay_secs;
74 float ksamples_per_sec = top->kernel_samples / top->delay_secs; 27 float ksamples_per_sec = top->kernel_samples / top->delay_secs;
75 float esamples_percent = (100.0 * top->exact_samples) / top->samples; 28 float esamples_percent = (100.0 * top->exact_samples) / top->samples;
@@ -104,7 +57,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
104 esamples_percent); 57 esamples_percent);
105 } 58 }
106 59
107 if (top->evlist->nr_entries == 1 || !top->display_weighted) { 60 if (top->evlist->nr_entries == 1) {
108 struct perf_evsel *first; 61 struct perf_evsel *first;
109 first = list_entry(top->evlist->entries.next, struct perf_evsel, node); 62 first = list_entry(top->evlist->entries.next, struct perf_evsel, node);
110 ret += SNPRINTF(bf + ret, size - ret, "%" PRIu64 "%s ", 63 ret += SNPRINTF(bf + ret, size - ret, "%" PRIu64 "%s ",
@@ -112,27 +65,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
112 top->freq ? "Hz" : ""); 65 top->freq ? "Hz" : "");
113 } 66 }
114 67
115 if (!top->display_weighted) { 68 ret += SNPRINTF(bf + ret, size - ret, "%s", event_name(top->sym_evsel));
116 ret += SNPRINTF(bf + ret, size - ret, "%s",
117 event_name(top->sym_evsel));
118 } else {
119 /*
120 * Don't let events eat all the space. Leaving 30 bytes
121 * for the rest should be enough.
122 */
123 size_t last_pos = size - 30;
124
125 list_for_each_entry(counter, &top->evlist->entries, node) {
126 ret += SNPRINTF(bf + ret, size - ret, "%s%s",
127 counter->idx ? "/" : "",
128 event_name(counter));
129 if (ret > last_pos) {
130 sprintf(bf + last_pos - 3, "..");
131 ret = last_pos - 1;
132 break;
133 }
134 }
135 }
136 69
137 ret += SNPRINTF(bf + ret, size - ret, "], "); 70 ret += SNPRINTF(bf + ret, size - ret, "], ");
138 71
@@ -166,73 +99,3 @@ void perf_top__reset_sample_counters(struct perf_top *top)
166 top->exact_samples = top->guest_kernel_samples = 99 top->exact_samples = top->guest_kernel_samples =
167 top->guest_us_samples = 0; 100 top->guest_us_samples = 0;
168} 101}
169
170float perf_top__decay_samples(struct perf_top *top, struct rb_root *root)
171{
172 struct sym_entry *syme, *n;
173 float sum_ksamples = 0.0;
174 int snap = !top->display_weighted ? top->sym_evsel->idx : 0, j;
175
176 /* Sort the active symbols */
177 pthread_mutex_lock(&top->active_symbols_lock);
178 syme = list_entry(top->active_symbols.next, struct sym_entry, node);
179 pthread_mutex_unlock(&top->active_symbols_lock);
180
181 top->rb_entries = 0;
182 list_for_each_entry_safe_from(syme, n, &top->active_symbols, node) {
183 syme->snap_count = syme->count[snap];
184 if (syme->snap_count != 0) {
185
186 if ((top->hide_user_symbols &&
187 syme->map->dso->kernel == DSO_TYPE_USER) ||
188 (top->hide_kernel_symbols &&
189 syme->map->dso->kernel == DSO_TYPE_KERNEL)) {
190 perf_top__remove_active_sym(top, syme);
191 continue;
192 }
193 syme->weight = sym_weight(syme, top);
194
195 if ((int)syme->snap_count >= top->count_filter) {
196 rb_insert_active_sym(root, syme);
197 ++top->rb_entries;
198 }
199 sum_ksamples += syme->snap_count;
200
201 for (j = 0; j < top->evlist->nr_entries; j++)
202 syme->count[j] = top->zero ? 0 : syme->count[j] * 7 / 8;
203 } else
204 perf_top__remove_active_sym(top, syme);
205 }
206
207 return sum_ksamples;
208}
209
210/*
211 * Find the longest symbol name that will be displayed
212 */
213void perf_top__find_widths(struct perf_top *top, struct rb_root *root,
214 int *dso_width, int *dso_short_width, int *sym_width)
215{
216 struct rb_node *nd;
217 int printed = 0;
218
219 *sym_width = *dso_width = *dso_short_width = 0;
220
221 for (nd = rb_first(root); nd; nd = rb_next(nd)) {
222 struct sym_entry *syme = rb_entry(nd, struct sym_entry, rb_node);
223 struct symbol *sym = sym_entry__symbol(syme);
224
225 if (++printed > top->print_entries ||
226 (int)syme->snap_count < top->count_filter)
227 continue;
228
229 if (syme->map->dso->long_name_len > *dso_width)
230 *dso_width = syme->map->dso->long_name_len;
231
232 if (syme->map->dso->short_name_len > *dso_short_width)
233 *dso_short_width = syme->map->dso->short_name_len;
234
235 if (sym->namelen > *sym_width)
236 *sym_width = sym->namelen;
237 }
238}
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h
index bfbf95bcc603..01d1057f3074 100644
--- a/tools/perf/util/top.h
+++ b/tools/perf/util/top.h
@@ -4,26 +4,10 @@
4#include "types.h" 4#include "types.h"
5#include "../perf.h" 5#include "../perf.h"
6#include <stddef.h> 6#include <stddef.h>
7#include <pthread.h>
8#include <linux/list.h>
9#include <linux/rbtree.h>
10 7
11struct perf_evlist; 8struct perf_evlist;
12struct perf_evsel; 9struct perf_evsel;
13 10struct perf_session;
14struct sym_entry {
15 struct rb_node rb_node;
16 struct list_head node;
17 unsigned long snap_count;
18 double weight;
19 struct map *map;
20 unsigned long count[0];
21};
22
23static inline struct symbol *sym_entry__symbol(struct sym_entry *self)
24{
25 return ((void *)self) + symbol_conf.priv_size;
26}
27 11
28struct perf_top { 12struct perf_top {
29 struct perf_evlist *evlist; 13 struct perf_evlist *evlist;
@@ -31,34 +15,21 @@ struct perf_top {
31 * Symbols will be added here in perf_event__process_sample and will 15 * Symbols will be added here in perf_event__process_sample and will
32 * get out after decayed. 16 * get out after decayed.
33 */ 17 */
34 struct list_head active_symbols;
35 pthread_mutex_t active_symbols_lock;
36 pthread_cond_t active_symbols_cond;
37 u64 samples; 18 u64 samples;
38 u64 kernel_samples, us_samples; 19 u64 kernel_samples, us_samples;
39 u64 exact_samples; 20 u64 exact_samples;
40 u64 guest_us_samples, guest_kernel_samples; 21 u64 guest_us_samples, guest_kernel_samples;
22 u64 total_lost_warned;
41 int print_entries, count_filter, delay_secs; 23 int print_entries, count_filter, delay_secs;
42 int display_weighted, freq, rb_entries; 24 int freq;
43 pid_t target_pid, target_tid; 25 pid_t target_pid, target_tid;
44 bool hide_kernel_symbols, hide_user_symbols, zero; 26 bool hide_kernel_symbols, hide_user_symbols, zero;
45 const char *cpu_list; 27 const char *cpu_list;
46 struct sym_entry *sym_filter_entry; 28 struct hist_entry *sym_filter_entry;
47 struct perf_evsel *sym_evsel; 29 struct perf_evsel *sym_evsel;
30 struct perf_session *session;
48}; 31};
49 32
50size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size); 33size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size);
51void perf_top__reset_sample_counters(struct perf_top *top); 34void perf_top__reset_sample_counters(struct perf_top *top);
52float perf_top__decay_samples(struct perf_top *top, struct rb_root *root);
53void perf_top__find_widths(struct perf_top *top, struct rb_root *root,
54 int *dso_width, int *dso_short_width, int *sym_width);
55
56#ifdef NO_NEWT_SUPPORT
57static inline int perf_top__tui_browser(struct perf_top *top __used)
58{
59 return 0;
60}
61#else
62int perf_top__tui_browser(struct perf_top *top);
63#endif
64#endif /* __PERF_TOP_H */ 35#endif /* __PERF_TOP_H */
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index 3403f814ad72..2d530cf74f43 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -196,7 +196,8 @@ static void record_file(const char *file, size_t hdr_sz)
196 die("Can't read '%s'", file); 196 die("Can't read '%s'", file);
197 197
198 /* put in zeros for file size, then fill true size later */ 198 /* put in zeros for file size, then fill true size later */
199 write_or_die(&size, hdr_sz); 199 if (hdr_sz)
200 write_or_die(&size, hdr_sz);
200 201
201 do { 202 do {
202 r = read(fd, buf, BUFSIZ); 203 r = read(fd, buf, BUFSIZ);
@@ -212,7 +213,7 @@ static void record_file(const char *file, size_t hdr_sz)
212 if (bigendian()) 213 if (bigendian())
213 sizep += sizeof(u64) - hdr_sz; 214 sizep += sizeof(u64) - hdr_sz;
214 215
215 if (pwrite(output_fd, sizep, hdr_sz, hdr_pos) < 0) 216 if (hdr_sz && pwrite(output_fd, sizep, hdr_sz, hdr_pos) < 0)
216 die("writing to %s", output_file); 217 die("writing to %s", output_file);
217} 218}
218 219
@@ -428,6 +429,19 @@ get_tracepoints_path(struct list_head *pattrs)
428 return nr_tracepoints > 0 ? path.next : NULL; 429 return nr_tracepoints > 0 ? path.next : NULL;
429} 430}
430 431
432static void
433put_tracepoints_path(struct tracepoint_path *tps)
434{
435 while (tps) {
436 struct tracepoint_path *t = tps;
437
438 tps = tps->next;
439 free(t->name);
440 free(t->system);
441 free(t);
442 }
443}
444
431bool have_tracepoints(struct list_head *pattrs) 445bool have_tracepoints(struct list_head *pattrs)
432{ 446{
433 struct perf_evsel *pos; 447 struct perf_evsel *pos;
@@ -439,19 +453,11 @@ bool have_tracepoints(struct list_head *pattrs)
439 return false; 453 return false;
440} 454}
441 455
442int read_tracing_data(int fd, struct list_head *pattrs) 456static void tracing_data_header(void)
443{ 457{
444 char buf[BUFSIZ]; 458 char buf[20];
445 struct tracepoint_path *tps = get_tracepoints_path(pattrs);
446
447 /*
448 * What? No tracepoints? No sense writing anything here, bail out.
449 */
450 if (tps == NULL)
451 return -1;
452
453 output_fd = fd;
454 459
460 /* just guessing this is someone's birthday.. ;) */
455 buf[0] = 23; 461 buf[0] = 23;
456 buf[1] = 8; 462 buf[1] = 8;
457 buf[2] = 68; 463 buf[2] = 68;
@@ -476,28 +482,86 @@ int read_tracing_data(int fd, struct list_head *pattrs)
476 /* save page_size */ 482 /* save page_size */
477 page_size = sysconf(_SC_PAGESIZE); 483 page_size = sysconf(_SC_PAGESIZE);
478 write_or_die(&page_size, 4); 484 write_or_die(&page_size, 4);
485}
486
487struct tracing_data *tracing_data_get(struct list_head *pattrs,
488 int fd, bool temp)
489{
490 struct tracepoint_path *tps;
491 struct tracing_data *tdata;
492
493 output_fd = fd;
494
495 tps = get_tracepoints_path(pattrs);
496 if (!tps)
497 return NULL;
479 498
499 tdata = malloc_or_die(sizeof(*tdata));
500 tdata->temp = temp;
501 tdata->size = 0;
502
503 if (temp) {
504 int temp_fd;
505
506 snprintf(tdata->temp_file, sizeof(tdata->temp_file),
507 "/tmp/perf-XXXXXX");
508 if (!mkstemp(tdata->temp_file))
509 die("Can't make temp file");
510
511 temp_fd = open(tdata->temp_file, O_RDWR);
512 if (temp_fd < 0)
513 die("Can't read '%s'", tdata->temp_file);
514
515 /*
516 * Set the temp file the default output, so all the
517 * tracing data are stored into it.
518 */
519 output_fd = temp_fd;
520 }
521
522 tracing_data_header();
480 read_header_files(); 523 read_header_files();
481 read_ftrace_files(tps); 524 read_ftrace_files(tps);
482 read_event_files(tps); 525 read_event_files(tps);
483 read_proc_kallsyms(); 526 read_proc_kallsyms();
484 read_ftrace_printk(); 527 read_ftrace_printk();
485 528
486 return 0; 529 /*
530 * All tracing data are stored by now, we can restore
531 * the default output file in case we used temp file.
532 */
533 if (temp) {
534 tdata->size = lseek(output_fd, 0, SEEK_CUR);
535 close(output_fd);
536 output_fd = fd;
537 }
538
539 put_tracepoints_path(tps);
540 return tdata;
487} 541}
488 542
489ssize_t read_tracing_data_size(int fd, struct list_head *pattrs) 543void tracing_data_put(struct tracing_data *tdata)
490{ 544{
491 ssize_t size; 545 if (tdata->temp) {
492 int err = 0; 546 record_file(tdata->temp_file, 0);
547 unlink(tdata->temp_file);
548 }
493 549
494 calc_data_size = 1; 550 free(tdata);
495 err = read_tracing_data(fd, pattrs); 551}
496 size = calc_data_size - 1;
497 calc_data_size = 0;
498 552
499 if (err < 0) 553int read_tracing_data(int fd, struct list_head *pattrs)
500 return err; 554{
555 struct tracing_data *tdata;
501 556
502 return size; 557 /*
558 * We work over the real file, so we can write data
559 * directly, no temp file is needed.
560 */
561 tdata = tracing_data_get(pattrs, fd, false);
562 if (!tdata)
563 return -ENOMEM;
564
565 tracing_data_put(tdata);
566 return 0;
503} 567}
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index f674dda3363b..a84100817649 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -263,7 +263,18 @@ void *raw_field_ptr(struct event *event, const char *name, void *data);
263unsigned long long eval_flag(const char *flag); 263unsigned long long eval_flag(const char *flag);
264 264
265int read_tracing_data(int fd, struct list_head *pattrs); 265int read_tracing_data(int fd, struct list_head *pattrs);
266ssize_t read_tracing_data_size(int fd, struct list_head *pattrs); 266
267struct tracing_data {
268 /* size is only valid if temp is 'true' */
269 ssize_t size;
270 bool temp;
271 char temp_file[50];
272};
273
274struct tracing_data *tracing_data_get(struct list_head *pattrs,
275 int fd, bool temp);
276void tracing_data_put(struct tracing_data *tdata);
277
267 278
268/* taken from kernel/trace/trace.h */ 279/* taken from kernel/trace/trace.h */
269enum trace_flag_type { 280enum trace_flag_type {
diff --git a/tools/perf/util/ui/browser.c b/tools/perf/util/ui/browser.c
index 611219f80680..5359f371d30a 100644
--- a/tools/perf/util/ui/browser.c
+++ b/tools/perf/util/ui/browser.c
@@ -1,4 +1,8 @@
1#include "../util.h"
2#include "../cache.h"
3#include "../../perf.h"
1#include "libslang.h" 4#include "libslang.h"
5#include <newt.h>
2#include "ui.h" 6#include "ui.h"
3#include <linux/compiler.h> 7#include <linux/compiler.h>
4#include <linux/list.h> 8#include <linux/list.h>
@@ -7,13 +11,13 @@
7#include <sys/ttydefaults.h> 11#include <sys/ttydefaults.h>
8#include "browser.h" 12#include "browser.h"
9#include "helpline.h" 13#include "helpline.h"
14#include "keysyms.h"
10#include "../color.h" 15#include "../color.h"
11#include "../util.h"
12#include <stdio.h>
13 16
14static int ui_browser__percent_color(double percent, bool current) 17static int ui_browser__percent_color(struct ui_browser *browser,
18 double percent, bool current)
15{ 19{
16 if (current) 20 if (current && (!browser->use_navkeypressed || browser->navkeypressed))
17 return HE_COLORSET_SELECTED; 21 return HE_COLORSET_SELECTED;
18 if (percent >= MIN_RED) 22 if (percent >= MIN_RED)
19 return HE_COLORSET_TOP; 23 return HE_COLORSET_TOP;
@@ -30,7 +34,7 @@ void ui_browser__set_color(struct ui_browser *self __used, int color)
30void ui_browser__set_percent_color(struct ui_browser *self, 34void ui_browser__set_percent_color(struct ui_browser *self,
31 double percent, bool current) 35 double percent, bool current)
32{ 36{
33 int color = ui_browser__percent_color(percent, current); 37 int color = ui_browser__percent_color(self, percent, current);
34 ui_browser__set_color(self, color); 38 ui_browser__set_color(self, color);
35} 39}
36 40
@@ -39,31 +43,62 @@ void ui_browser__gotorc(struct ui_browser *self, int y, int x)
39 SLsmg_gotorc(self->y + y, self->x + x); 43 SLsmg_gotorc(self->y + y, self->x + x);
40} 44}
41 45
46static struct list_head *
47ui_browser__list_head_filter_entries(struct ui_browser *browser,
48 struct list_head *pos)
49{
50 do {
51 if (!browser->filter || !browser->filter(browser, pos))
52 return pos;
53 pos = pos->next;
54 } while (pos != browser->entries);
55
56 return NULL;
57}
58
59static struct list_head *
60ui_browser__list_head_filter_prev_entries(struct ui_browser *browser,
61 struct list_head *pos)
62{
63 do {
64 if (!browser->filter || !browser->filter(browser, pos))
65 return pos;
66 pos = pos->prev;
67 } while (pos != browser->entries);
68
69 return NULL;
70}
71
42void ui_browser__list_head_seek(struct ui_browser *self, off_t offset, int whence) 72void ui_browser__list_head_seek(struct ui_browser *self, off_t offset, int whence)
43{ 73{
44 struct list_head *head = self->entries; 74 struct list_head *head = self->entries;
45 struct list_head *pos; 75 struct list_head *pos;
46 76
77 if (self->nr_entries == 0)
78 return;
79
47 switch (whence) { 80 switch (whence) {
48 case SEEK_SET: 81 case SEEK_SET:
49 pos = head->next; 82 pos = ui_browser__list_head_filter_entries(self, head->next);
50 break; 83 break;
51 case SEEK_CUR: 84 case SEEK_CUR:
52 pos = self->top; 85 pos = self->top;
53 break; 86 break;
54 case SEEK_END: 87 case SEEK_END:
55 pos = head->prev; 88 pos = ui_browser__list_head_filter_prev_entries(self, head->prev);
56 break; 89 break;
57 default: 90 default:
58 return; 91 return;
59 } 92 }
60 93
94 assert(pos != NULL);
95
61 if (offset > 0) { 96 if (offset > 0) {
62 while (offset-- != 0) 97 while (offset-- != 0)
63 pos = pos->next; 98 pos = ui_browser__list_head_filter_entries(self, pos->next);
64 } else { 99 } else {
65 while (offset++ != 0) 100 while (offset++ != 0)
66 pos = pos->prev; 101 pos = ui_browser__list_head_filter_prev_entries(self, pos->prev);
67 } 102 }
68 103
69 self->top = pos; 104 self->top = pos;
@@ -127,11 +162,8 @@ bool ui_browser__is_current_entry(struct ui_browser *self, unsigned row)
127 162
128void ui_browser__refresh_dimensions(struct ui_browser *self) 163void ui_browser__refresh_dimensions(struct ui_browser *self)
129{ 164{
130 int cols, rows; 165 self->width = SLtt_Screen_Cols - 1;
131 newtGetScreenSize(&cols, &rows); 166 self->height = SLtt_Screen_Rows - 2;
132
133 self->width = cols - 1;
134 self->height = rows - 2;
135 self->y = 1; 167 self->y = 1;
136 self->x = 0; 168 self->x = 0;
137} 169}
@@ -142,26 +174,11 @@ void ui_browser__reset_index(struct ui_browser *self)
142 self->seek(self, 0, SEEK_SET); 174 self->seek(self, 0, SEEK_SET);
143} 175}
144 176
145void ui_browser__add_exit_key(struct ui_browser *self, int key)
146{
147 newtFormAddHotKey(self->form, key);
148}
149
150void ui_browser__add_exit_keys(struct ui_browser *self, int keys[])
151{
152 int i = 0;
153
154 while (keys[i] && i < 64) {
155 ui_browser__add_exit_key(self, keys[i]);
156 ++i;
157 }
158}
159
160void __ui_browser__show_title(struct ui_browser *browser, const char *title) 177void __ui_browser__show_title(struct ui_browser *browser, const char *title)
161{ 178{
162 SLsmg_gotorc(0, 0); 179 SLsmg_gotorc(0, 0);
163 ui_browser__set_color(browser, NEWT_COLORSET_ROOT); 180 ui_browser__set_color(browser, NEWT_COLORSET_ROOT);
164 slsmg_write_nstring(title, browser->width); 181 slsmg_write_nstring(title, browser->width + 1);
165} 182}
166 183
167void ui_browser__show_title(struct ui_browser *browser, const char *title) 184void ui_browser__show_title(struct ui_browser *browser, const char *title)
@@ -174,78 +191,189 @@ void ui_browser__show_title(struct ui_browser *browser, const char *title)
174int ui_browser__show(struct ui_browser *self, const char *title, 191int ui_browser__show(struct ui_browser *self, const char *title,
175 const char *helpline, ...) 192 const char *helpline, ...)
176{ 193{
194 int err;
177 va_list ap; 195 va_list ap;
178 int keys[] = { NEWT_KEY_UP, NEWT_KEY_DOWN, NEWT_KEY_PGUP,
179 NEWT_KEY_PGDN, NEWT_KEY_HOME, NEWT_KEY_END, ' ',
180 NEWT_KEY_LEFT, NEWT_KEY_ESCAPE, 'q', CTRL('c'), 0 };
181
182 if (self->form != NULL)
183 newtFormDestroy(self->form);
184 196
185 ui_browser__refresh_dimensions(self); 197 ui_browser__refresh_dimensions(self);
186 self->form = newtForm(NULL, NULL, 0);
187 if (self->form == NULL)
188 return -1;
189
190 self->sb = newtVerticalScrollbar(self->width, 1, self->height,
191 HE_COLORSET_NORMAL,
192 HE_COLORSET_SELECTED);
193 if (self->sb == NULL)
194 return -1;
195 198
196 pthread_mutex_lock(&ui__lock); 199 pthread_mutex_lock(&ui__lock);
197 __ui_browser__show_title(self, title); 200 __ui_browser__show_title(self, title);
198 201
199 ui_browser__add_exit_keys(self, keys); 202 self->title = title;
200 newtFormAddComponent(self->form, self->sb); 203 free(self->helpline);
204 self->helpline = NULL;
201 205
202 va_start(ap, helpline); 206 va_start(ap, helpline);
203 ui_helpline__vpush(helpline, ap); 207 err = vasprintf(&self->helpline, helpline, ap);
204 va_end(ap); 208 va_end(ap);
209 if (err > 0)
210 ui_helpline__push(self->helpline);
205 pthread_mutex_unlock(&ui__lock); 211 pthread_mutex_unlock(&ui__lock);
206 return 0; 212 return err ? 0 : -1;
207} 213}
208 214
209void ui_browser__hide(struct ui_browser *self) 215void ui_browser__hide(struct ui_browser *browser __used)
210{ 216{
211 pthread_mutex_lock(&ui__lock); 217 pthread_mutex_lock(&ui__lock);
212 newtFormDestroy(self->form);
213 self->form = NULL;
214 ui_helpline__pop(); 218 ui_helpline__pop();
215 pthread_mutex_unlock(&ui__lock); 219 pthread_mutex_unlock(&ui__lock);
216} 220}
217 221
218int ui_browser__refresh(struct ui_browser *self) 222static void ui_browser__scrollbar_set(struct ui_browser *browser)
223{
224 int height = browser->height, h = 0, pct = 0,
225 col = browser->width,
226 row = browser->y - 1;
227
228 if (browser->nr_entries > 1) {
229 pct = ((browser->index * (browser->height - 1)) /
230 (browser->nr_entries - 1));
231 }
232
233 while (h < height) {
234 ui_browser__gotorc(browser, row++, col);
235 SLsmg_set_char_set(1);
236 SLsmg_write_char(h == pct ? SLSMG_DIAMOND_CHAR : SLSMG_BOARD_CHAR);
237 SLsmg_set_char_set(0);
238 ++h;
239 }
240}
241
242static int __ui_browser__refresh(struct ui_browser *browser)
219{ 243{
220 int row; 244 int row;
245 int width = browser->width;
246
247 row = browser->refresh(browser);
248 ui_browser__set_color(browser, HE_COLORSET_NORMAL);
249
250 if (!browser->use_navkeypressed || browser->navkeypressed)
251 ui_browser__scrollbar_set(browser);
252 else
253 width += 1;
221 254
255 SLsmg_fill_region(browser->y + row, browser->x,
256 browser->height - row, width, ' ');
257
258 return 0;
259}
260
261int ui_browser__refresh(struct ui_browser *browser)
262{
222 pthread_mutex_lock(&ui__lock); 263 pthread_mutex_lock(&ui__lock);
223 newtScrollbarSet(self->sb, self->index, self->nr_entries - 1); 264 __ui_browser__refresh(browser);
224 row = self->refresh(self);
225 ui_browser__set_color(self, HE_COLORSET_NORMAL);
226 SLsmg_fill_region(self->y + row, self->x,
227 self->height - row, self->width, ' ');
228 pthread_mutex_unlock(&ui__lock); 265 pthread_mutex_unlock(&ui__lock);
229 266
230 return 0; 267 return 0;
231} 268}
232 269
233int ui_browser__run(struct ui_browser *self) 270/*
271 * Here we're updating nr_entries _after_ we started browsing, i.e. we have to
272 * forget about any reference to any entry in the underlying data structure,
273 * that is why we do a SEEK_SET. Think about 'perf top' in the hists browser
274 * after an output_resort and hist decay.
275 */
276void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries)
234{ 277{
235 struct newtExitStruct es; 278 off_t offset = nr_entries - browser->nr_entries;
279
280 browser->nr_entries = nr_entries;
236 281
237 if (ui_browser__refresh(self) < 0) 282 if (offset < 0) {
238 return -1; 283 if (browser->top_idx < (u64)-offset)
284 offset = -browser->top_idx;
285
286 browser->index += offset;
287 browser->top_idx += offset;
288 }
289
290 browser->top = NULL;
291 browser->seek(browser, browser->top_idx, SEEK_SET);
292}
293
294static int ui__getch(int delay_secs)
295{
296 struct timeval timeout, *ptimeout = delay_secs ? &timeout : NULL;
297 fd_set read_set;
298 int err, key;
299
300 FD_ZERO(&read_set);
301 FD_SET(0, &read_set);
302
303 if (delay_secs) {
304 timeout.tv_sec = delay_secs;
305 timeout.tv_usec = 0;
306 }
307
308 err = select(1, &read_set, NULL, NULL, ptimeout);
309
310 if (err == 0)
311 return K_TIMER;
312
313 if (err == -1) {
314 if (errno == EINTR)
315 return K_RESIZE;
316 return K_ERROR;
317 }
318
319 key = SLang_getkey();
320 if (key != K_ESC)
321 return key;
322
323 FD_ZERO(&read_set);
324 FD_SET(0, &read_set);
325 timeout.tv_sec = 0;
326 timeout.tv_usec = 20;
327 err = select(1, &read_set, NULL, NULL, &timeout);
328 if (err == 0)
329 return K_ESC;
330
331 SLang_ungetkey(key);
332 return SLkp_getkey();
333}
334
335int ui_browser__run(struct ui_browser *self, int delay_secs)
336{
337 int err, key;
338
339 pthread__unblock_sigwinch();
239 340
240 while (1) { 341 while (1) {
241 off_t offset; 342 off_t offset;
242 343
243 newtFormRun(self->form, &es); 344 pthread_mutex_lock(&ui__lock);
244 345 err = __ui_browser__refresh(self);
245 if (es.reason != NEWT_EXIT_HOTKEY) 346 SLsmg_refresh();
347 pthread_mutex_unlock(&ui__lock);
348 if (err < 0)
246 break; 349 break;
247 switch (es.u.key) { 350
248 case NEWT_KEY_DOWN: 351 key = ui__getch(delay_secs);
352
353 if (key == K_RESIZE) {
354 pthread_mutex_lock(&ui__lock);
355 SLtt_get_screen_size();
356 SLsmg_reinit_smg();
357 pthread_mutex_unlock(&ui__lock);
358 ui_browser__refresh_dimensions(self);
359 __ui_browser__show_title(self, self->title);
360 ui_helpline__puts(self->helpline);
361 continue;
362 }
363
364 if (self->use_navkeypressed && !self->navkeypressed) {
365 if (key == K_DOWN || key == K_UP ||
366 key == K_PGDN || key == K_PGUP ||
367 key == K_HOME || key == K_END ||
368 key == ' ') {
369 self->navkeypressed = true;
370 continue;
371 } else
372 return key;
373 }
374
375 switch (key) {
376 case K_DOWN:
249 if (self->index == self->nr_entries - 1) 377 if (self->index == self->nr_entries - 1)
250 break; 378 break;
251 ++self->index; 379 ++self->index;
@@ -254,7 +382,7 @@ int ui_browser__run(struct ui_browser *self)
254 self->seek(self, +1, SEEK_CUR); 382 self->seek(self, +1, SEEK_CUR);
255 } 383 }
256 break; 384 break;
257 case NEWT_KEY_UP: 385 case K_UP:
258 if (self->index == 0) 386 if (self->index == 0)
259 break; 387 break;
260 --self->index; 388 --self->index;
@@ -263,7 +391,7 @@ int ui_browser__run(struct ui_browser *self)
263 self->seek(self, -1, SEEK_CUR); 391 self->seek(self, -1, SEEK_CUR);
264 } 392 }
265 break; 393 break;
266 case NEWT_KEY_PGDN: 394 case K_PGDN:
267 case ' ': 395 case ' ':
268 if (self->top_idx + self->height > self->nr_entries - 1) 396 if (self->top_idx + self->height > self->nr_entries - 1)
269 break; 397 break;
@@ -275,7 +403,7 @@ int ui_browser__run(struct ui_browser *self)
275 self->top_idx += offset; 403 self->top_idx += offset;
276 self->seek(self, +offset, SEEK_CUR); 404 self->seek(self, +offset, SEEK_CUR);
277 break; 405 break;
278 case NEWT_KEY_PGUP: 406 case K_PGUP:
279 if (self->top_idx == 0) 407 if (self->top_idx == 0)
280 break; 408 break;
281 409
@@ -288,10 +416,10 @@ int ui_browser__run(struct ui_browser *self)
288 self->top_idx -= offset; 416 self->top_idx -= offset;
289 self->seek(self, -offset, SEEK_CUR); 417 self->seek(self, -offset, SEEK_CUR);
290 break; 418 break;
291 case NEWT_KEY_HOME: 419 case K_HOME:
292 ui_browser__reset_index(self); 420 ui_browser__reset_index(self);
293 break; 421 break;
294 case NEWT_KEY_END: 422 case K_END:
295 offset = self->height - 1; 423 offset = self->height - 1;
296 if (offset >= self->nr_entries) 424 if (offset >= self->nr_entries)
297 offset = self->nr_entries - 1; 425 offset = self->nr_entries - 1;
@@ -301,10 +429,8 @@ int ui_browser__run(struct ui_browser *self)
301 self->seek(self, -offset, SEEK_END); 429 self->seek(self, -offset, SEEK_END);
302 break; 430 break;
303 default: 431 default:
304 return es.u.key; 432 return key;
305 } 433 }
306 if (ui_browser__refresh(self) < 0)
307 return -1;
308 } 434 }
309 return -1; 435 return -1;
310} 436}
@@ -316,41 +442,105 @@ unsigned int ui_browser__list_head_refresh(struct ui_browser *self)
316 int row = 0; 442 int row = 0;
317 443
318 if (self->top == NULL || self->top == self->entries) 444 if (self->top == NULL || self->top == self->entries)
319 self->top = head->next; 445 self->top = ui_browser__list_head_filter_entries(self, head->next);
320 446
321 pos = self->top; 447 pos = self->top;
322 448
323 list_for_each_from(pos, head) { 449 list_for_each_from(pos, head) {
324 ui_browser__gotorc(self, row, 0); 450 if (!self->filter || !self->filter(self, pos)) {
325 self->write(self, pos, row); 451 ui_browser__gotorc(self, row, 0);
326 if (++row == self->height) 452 self->write(self, pos, row);
327 break; 453 if (++row == self->height)
454 break;
455 }
328 } 456 }
329 457
330 return row; 458 return row;
331} 459}
332 460
333static struct newtPercentTreeColors { 461static struct ui_browser__colorset {
334 const char *topColorFg, *topColorBg; 462 const char *name, *fg, *bg;
335 const char *mediumColorFg, *mediumColorBg; 463 int colorset;
336 const char *normalColorFg, *normalColorBg; 464} ui_browser__colorsets[] = {
337 const char *selColorFg, *selColorBg; 465 {
338 const char *codeColorFg, *codeColorBg; 466 .colorset = HE_COLORSET_TOP,
339} defaultPercentTreeColors = { 467 .name = "top",
340 "red", "lightgray", 468 .fg = "red",
341 "green", "lightgray", 469 .bg = "default",
342 "black", "lightgray", 470 },
343 "lightgray", "magenta", 471 {
344 "blue", "lightgray", 472 .colorset = HE_COLORSET_MEDIUM,
473 .name = "medium",
474 .fg = "green",
475 .bg = "default",
476 },
477 {
478 .colorset = HE_COLORSET_NORMAL,
479 .name = "normal",
480 .fg = "default",
481 .bg = "default",
482 },
483 {
484 .colorset = HE_COLORSET_SELECTED,
485 .name = "selected",
486 .fg = "black",
487 .bg = "lightgray",
488 },
489 {
490 .colorset = HE_COLORSET_CODE,
491 .name = "code",
492 .fg = "blue",
493 .bg = "default",
494 },
495 {
496 .name = NULL,
497 }
345}; 498};
346 499
500
501static int ui_browser__color_config(const char *var, const char *value,
502 void *data __used)
503{
504 char *fg = NULL, *bg;
505 int i;
506
507 /* same dir for all commands */
508 if (prefixcmp(var, "colors.") != 0)
509 return 0;
510
511 for (i = 0; ui_browser__colorsets[i].name != NULL; ++i) {
512 const char *name = var + 7;
513
514 if (strcmp(ui_browser__colorsets[i].name, name) != 0)
515 continue;
516
517 fg = strdup(value);
518 if (fg == NULL)
519 break;
520
521 bg = strchr(fg, ',');
522 if (bg == NULL)
523 break;
524
525 *bg = '\0';
526 while (isspace(*++bg));
527 ui_browser__colorsets[i].bg = bg;
528 ui_browser__colorsets[i].fg = fg;
529 return 0;
530 }
531
532 free(fg);
533 return -1;
534}
535
347void ui_browser__init(void) 536void ui_browser__init(void)
348{ 537{
349 struct newtPercentTreeColors *c = &defaultPercentTreeColors; 538 int i = 0;
350 539
351 sltt_set_color(HE_COLORSET_TOP, NULL, c->topColorFg, c->topColorBg); 540 perf_config(ui_browser__color_config, NULL);
352 sltt_set_color(HE_COLORSET_MEDIUM, NULL, c->mediumColorFg, c->mediumColorBg); 541
353 sltt_set_color(HE_COLORSET_NORMAL, NULL, c->normalColorFg, c->normalColorBg); 542 while (ui_browser__colorsets[i].name) {
354 sltt_set_color(HE_COLORSET_SELECTED, NULL, c->selColorFg, c->selColorBg); 543 struct ui_browser__colorset *c = &ui_browser__colorsets[i++];
355 sltt_set_color(HE_COLORSET_CODE, NULL, c->codeColorFg, c->codeColorBg); 544 sltt_set_color(c->colorset, c->name, c->fg, c->bg);
545 }
356} 546}
diff --git a/tools/perf/util/ui/browser.h b/tools/perf/util/ui/browser.h
index fc63dda10910..a2c707d33c5e 100644
--- a/tools/perf/util/ui/browser.h
+++ b/tools/perf/util/ui/browser.h
@@ -2,7 +2,6 @@
2#define _PERF_UI_BROWSER_H_ 1 2#define _PERF_UI_BROWSER_H_ 1
3 3
4#include <stdbool.h> 4#include <stdbool.h>
5#include <newt.h>
6#include <sys/types.h> 5#include <sys/types.h>
7#include "../types.h" 6#include "../types.h"
8 7
@@ -13,15 +12,19 @@
13#define HE_COLORSET_CODE 54 12#define HE_COLORSET_CODE 54
14 13
15struct ui_browser { 14struct ui_browser {
16 newtComponent form, sb;
17 u64 index, top_idx; 15 u64 index, top_idx;
18 void *top, *entries; 16 void *top, *entries;
19 u16 y, x, width, height; 17 u16 y, x, width, height;
20 void *priv; 18 void *priv;
19 const char *title;
20 char *helpline;
21 unsigned int (*refresh)(struct ui_browser *self); 21 unsigned int (*refresh)(struct ui_browser *self);
22 void (*write)(struct ui_browser *self, void *entry, int row); 22 void (*write)(struct ui_browser *self, void *entry, int row);
23 void (*seek)(struct ui_browser *self, off_t offset, int whence); 23 void (*seek)(struct ui_browser *self, off_t offset, int whence);
24 bool (*filter)(struct ui_browser *self, void *entry);
24 u32 nr_entries; 25 u32 nr_entries;
26 bool navkeypressed;
27 bool use_navkeypressed;
25}; 28};
26 29
27void ui_browser__set_color(struct ui_browser *self, int color); 30void ui_browser__set_color(struct ui_browser *self, int color);
@@ -32,15 +35,14 @@ void ui_browser__refresh_dimensions(struct ui_browser *self);
32void ui_browser__reset_index(struct ui_browser *self); 35void ui_browser__reset_index(struct ui_browser *self);
33 36
34void ui_browser__gotorc(struct ui_browser *self, int y, int x); 37void ui_browser__gotorc(struct ui_browser *self, int y, int x);
35void ui_browser__add_exit_key(struct ui_browser *self, int key);
36void ui_browser__add_exit_keys(struct ui_browser *self, int keys[]);
37void __ui_browser__show_title(struct ui_browser *browser, const char *title); 38void __ui_browser__show_title(struct ui_browser *browser, const char *title);
38void ui_browser__show_title(struct ui_browser *browser, const char *title); 39void ui_browser__show_title(struct ui_browser *browser, const char *title);
39int ui_browser__show(struct ui_browser *self, const char *title, 40int ui_browser__show(struct ui_browser *self, const char *title,
40 const char *helpline, ...); 41 const char *helpline, ...);
41void ui_browser__hide(struct ui_browser *self); 42void ui_browser__hide(struct ui_browser *self);
42int ui_browser__refresh(struct ui_browser *self); 43int ui_browser__refresh(struct ui_browser *self);
43int ui_browser__run(struct ui_browser *self); 44int ui_browser__run(struct ui_browser *browser, int delay_secs);
45void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries);
44 46
45void ui_browser__rb_tree_seek(struct ui_browser *self, off_t offset, int whence); 47void ui_browser__rb_tree_seek(struct ui_browser *self, off_t offset, int whence);
46unsigned int ui_browser__rb_tree_refresh(struct ui_browser *self); 48unsigned int ui_browser__rb_tree_refresh(struct ui_browser *self);
diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c
index 0229723aceb3..4e0cb7fea7d9 100644
--- a/tools/perf/util/ui/browsers/annotate.c
+++ b/tools/perf/util/ui/browsers/annotate.c
@@ -6,6 +6,7 @@
6#include "../../sort.h" 6#include "../../sort.h"
7#include "../../symbol.h" 7#include "../../symbol.h"
8#include <pthread.h> 8#include <pthread.h>
9#include <newt.h>
9 10
10static void ui__error_window(const char *fmt, ...) 11static void ui__error_window(const char *fmt, ...)
11{ 12{
@@ -20,12 +21,17 @@ struct annotate_browser {
20 struct ui_browser b; 21 struct ui_browser b;
21 struct rb_root entries; 22 struct rb_root entries;
22 struct rb_node *curr_hot; 23 struct rb_node *curr_hot;
24 struct objdump_line *selection;
25 int nr_asm_entries;
26 int nr_entries;
27 bool hide_src_code;
23}; 28};
24 29
25struct objdump_line_rb_node { 30struct objdump_line_rb_node {
26 struct rb_node rb_node; 31 struct rb_node rb_node;
27 double percent; 32 double percent;
28 u32 idx; 33 u32 idx;
34 int idx_asm;
29}; 35};
30 36
31static inline 37static inline
@@ -34,9 +40,22 @@ struct objdump_line_rb_node *objdump_line__rb(struct objdump_line *self)
34 return (struct objdump_line_rb_node *)(self + 1); 40 return (struct objdump_line_rb_node *)(self + 1);
35} 41}
36 42
43static bool objdump_line__filter(struct ui_browser *browser, void *entry)
44{
45 struct annotate_browser *ab = container_of(browser, struct annotate_browser, b);
46
47 if (ab->hide_src_code) {
48 struct objdump_line *ol = list_entry(entry, struct objdump_line, node);
49 return ol->offset == -1;
50 }
51
52 return false;
53}
54
37static void annotate_browser__write(struct ui_browser *self, void *entry, int row) 55static void annotate_browser__write(struct ui_browser *self, void *entry, int row)
38{ 56{
39 struct objdump_line *ol = rb_entry(entry, struct objdump_line, node); 57 struct annotate_browser *ab = container_of(self, struct annotate_browser, b);
58 struct objdump_line *ol = list_entry(entry, struct objdump_line, node);
40 bool current_entry = ui_browser__is_current_entry(self, row); 59 bool current_entry = ui_browser__is_current_entry(self, row);
41 int width = self->width; 60 int width = self->width;
42 61
@@ -51,6 +70,11 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro
51 70
52 SLsmg_write_char(':'); 71 SLsmg_write_char(':');
53 slsmg_write_nstring(" ", 8); 72 slsmg_write_nstring(" ", 8);
73
74 /* The scroll bar isn't being used */
75 if (!self->navkeypressed)
76 width += 1;
77
54 if (!*ol->line) 78 if (!*ol->line)
55 slsmg_write_nstring(" ", width - 18); 79 slsmg_write_nstring(" ", width - 18);
56 else 80 else
@@ -58,6 +82,8 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro
58 82
59 if (!current_entry) 83 if (!current_entry)
60 ui_browser__set_color(self, HE_COLORSET_CODE); 84 ui_browser__set_color(self, HE_COLORSET_CODE);
85 else
86 ab->selection = ol;
61} 87}
62 88
63static double objdump_line__calc_percent(struct objdump_line *self, 89static double objdump_line__calc_percent(struct objdump_line *self,
@@ -141,7 +167,8 @@ static void annotate_browser__set_top(struct annotate_browser *self,
141static void annotate_browser__calc_percent(struct annotate_browser *browser, 167static void annotate_browser__calc_percent(struct annotate_browser *browser,
142 int evidx) 168 int evidx)
143{ 169{
144 struct symbol *sym = browser->b.priv; 170 struct map_symbol *ms = browser->b.priv;
171 struct symbol *sym = ms->sym;
145 struct annotation *notes = symbol__annotation(sym); 172 struct annotation *notes = symbol__annotation(sym);
146 struct objdump_line *pos; 173 struct objdump_line *pos;
147 174
@@ -163,25 +190,60 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,
163 browser->curr_hot = rb_last(&browser->entries); 190 browser->curr_hot = rb_last(&browser->entries);
164} 191}
165 192
193static bool annotate_browser__toggle_source(struct annotate_browser *browser)
194{
195 struct objdump_line *ol;
196 struct objdump_line_rb_node *olrb;
197 off_t offset = browser->b.index - browser->b.top_idx;
198
199 browser->b.seek(&browser->b, offset, SEEK_CUR);
200 ol = list_entry(browser->b.top, struct objdump_line, node);
201 olrb = objdump_line__rb(ol);
202
203 if (browser->hide_src_code) {
204 if (olrb->idx_asm < offset)
205 offset = olrb->idx;
206
207 browser->b.nr_entries = browser->nr_entries;
208 browser->hide_src_code = false;
209 browser->b.seek(&browser->b, -offset, SEEK_CUR);
210 browser->b.top_idx = olrb->idx - offset;
211 browser->b.index = olrb->idx;
212 } else {
213 if (olrb->idx_asm < 0) {
214 ui_helpline__puts("Only available for assembly lines.");
215 browser->b.seek(&browser->b, -offset, SEEK_CUR);
216 return false;
217 }
218
219 if (olrb->idx_asm < offset)
220 offset = olrb->idx_asm;
221
222 browser->b.nr_entries = browser->nr_asm_entries;
223 browser->hide_src_code = true;
224 browser->b.seek(&browser->b, -offset, SEEK_CUR);
225 browser->b.top_idx = olrb->idx_asm - offset;
226 browser->b.index = olrb->idx_asm;
227 }
228
229 return true;
230}
231
166static int annotate_browser__run(struct annotate_browser *self, int evidx, 232static int annotate_browser__run(struct annotate_browser *self, int evidx,
167 int refresh) 233 int nr_events, void(*timer)(void *arg),
234 void *arg, int delay_secs)
168{ 235{
169 struct rb_node *nd = NULL; 236 struct rb_node *nd = NULL;
170 struct symbol *sym = self->b.priv; 237 struct map_symbol *ms = self->b.priv;
171 /* 238 struct symbol *sym = ms->sym;
172 * RIGHT To allow builtin-annotate to cycle thru multiple symbols by 239 const char *help = "<-, ESC: exit, TAB/shift+TAB: cycle hottest lines, "
173 * examining the exit key for this function. 240 "H: Hottest, -> Line action, S -> Toggle source "
174 */ 241 "code view";
175 int exit_keys[] = { 'H', NEWT_KEY_TAB, NEWT_KEY_UNTAB,
176 NEWT_KEY_RIGHT, 0 };
177 int key; 242 int key;
178 243
179 if (ui_browser__show(&self->b, sym->name, 244 if (ui_browser__show(&self->b, sym->name, help) < 0)
180 "<-, -> or ESC: exit, TAB/shift+TAB: "
181 "cycle hottest lines, H: Hottest") < 0)
182 return -1; 245 return -1;
183 246
184 ui_browser__add_exit_keys(&self->b, exit_keys);
185 annotate_browser__calc_percent(self, evidx); 247 annotate_browser__calc_percent(self, evidx);
186 248
187 if (self->curr_hot) 249 if (self->curr_hot)
@@ -189,13 +251,10 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
189 251
190 nd = self->curr_hot; 252 nd = self->curr_hot;
191 253
192 if (refresh != 0)
193 newtFormSetTimer(self->b.form, refresh);
194
195 while (1) { 254 while (1) {
196 key = ui_browser__run(&self->b); 255 key = ui_browser__run(&self->b, delay_secs);
197 256
198 if (refresh != 0) { 257 if (delay_secs != 0) {
199 annotate_browser__calc_percent(self, evidx); 258 annotate_browser__calc_percent(self, evidx);
200 /* 259 /*
201 * Current line focus got out of the list of most active 260 * Current line focus got out of the list of most active
@@ -207,15 +266,14 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
207 } 266 }
208 267
209 switch (key) { 268 switch (key) {
210 case -1: 269 case K_TIMER:
211 /* 270 if (timer != NULL)
212 * FIXME we need to check if it was 271 timer(arg);
213 * es.reason == NEWT_EXIT_TIMER 272
214 */ 273 if (delay_secs != 0)
215 if (refresh != 0)
216 symbol__annotate_decay_histogram(sym, evidx); 274 symbol__annotate_decay_histogram(sym, evidx);
217 continue; 275 continue;
218 case NEWT_KEY_TAB: 276 case K_TAB:
219 if (nd != NULL) { 277 if (nd != NULL) {
220 nd = rb_prev(nd); 278 nd = rb_prev(nd);
221 if (nd == NULL) 279 if (nd == NULL)
@@ -223,7 +281,7 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
223 } else 281 } else
224 nd = self->curr_hot; 282 nd = self->curr_hot;
225 break; 283 break;
226 case NEWT_KEY_UNTAB: 284 case K_UNTAB:
227 if (nd != NULL) 285 if (nd != NULL)
228 nd = rb_next(nd); 286 nd = rb_next(nd);
229 if (nd == NULL) 287 if (nd == NULL)
@@ -234,8 +292,68 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
234 case 'H': 292 case 'H':
235 nd = self->curr_hot; 293 nd = self->curr_hot;
236 break; 294 break;
237 default: 295 case 'S':
296 if (annotate_browser__toggle_source(self))
297 ui_helpline__puts(help);
298 continue;
299 case K_ENTER:
300 case K_RIGHT:
301 if (self->selection == NULL) {
302 ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org");
303 continue;
304 }
305
306 if (self->selection->offset == -1) {
307 ui_helpline__puts("Actions are only available for assembly lines.");
308 continue;
309 } else {
310 char *s = strstr(self->selection->line, "callq ");
311 struct annotation *notes;
312 struct symbol *target;
313 u64 ip;
314
315 if (s == NULL) {
316 ui_helpline__puts("Actions are only available for the 'callq' instruction.");
317 continue;
318 }
319
320 s = strchr(s, ' ');
321 if (s++ == NULL) {
322 ui_helpline__puts("Invallid callq instruction.");
323 continue;
324 }
325
326 ip = strtoull(s, NULL, 16);
327 ip = ms->map->map_ip(ms->map, ip);
328 target = map__find_symbol(ms->map, ip, NULL);
329 if (target == NULL) {
330 ui_helpline__puts("The called function was not found.");
331 continue;
332 }
333
334 notes = symbol__annotation(target);
335 pthread_mutex_lock(&notes->lock);
336
337 if (notes->src == NULL &&
338 symbol__alloc_hist(target, nr_events) < 0) {
339 pthread_mutex_unlock(&notes->lock);
340 ui__warning("Not enough memory for annotating '%s' symbol!\n",
341 target->name);
342 continue;
343 }
344
345 pthread_mutex_unlock(&notes->lock);
346 symbol__tui_annotate(target, ms->map, evidx, nr_events,
347 timer, arg, delay_secs);
348 }
349 continue;
350 case K_LEFT:
351 case K_ESC:
352 case 'q':
353 case CTRL('c'):
238 goto out; 354 goto out;
355 default:
356 continue;
239 } 357 }
240 358
241 if (nd != NULL) 359 if (nd != NULL)
@@ -246,22 +364,31 @@ out:
246 return key; 364 return key;
247} 365}
248 366
249int hist_entry__tui_annotate(struct hist_entry *he, int evidx) 367int hist_entry__tui_annotate(struct hist_entry *he, int evidx, int nr_events,
368 void(*timer)(void *arg), void *arg, int delay_secs)
250{ 369{
251 return symbol__tui_annotate(he->ms.sym, he->ms.map, evidx, 0); 370 return symbol__tui_annotate(he->ms.sym, he->ms.map, evidx, nr_events,
371 timer, arg, delay_secs);
252} 372}
253 373
254int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, 374int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
255 int refresh) 375 int nr_events, void(*timer)(void *arg), void *arg,
376 int delay_secs)
256{ 377{
257 struct objdump_line *pos, *n; 378 struct objdump_line *pos, *n;
258 struct annotation *notes; 379 struct annotation *notes;
380 struct map_symbol ms = {
381 .map = map,
382 .sym = sym,
383 };
259 struct annotate_browser browser = { 384 struct annotate_browser browser = {
260 .b = { 385 .b = {
261 .refresh = ui_browser__list_head_refresh, 386 .refresh = ui_browser__list_head_refresh,
262 .seek = ui_browser__list_head_seek, 387 .seek = ui_browser__list_head_seek,
263 .write = annotate_browser__write, 388 .write = annotate_browser__write,
264 .priv = sym, 389 .filter = objdump_line__filter,
390 .priv = &ms,
391 .use_navkeypressed = true,
265 }, 392 },
266 }; 393 };
267 int ret; 394 int ret;
@@ -288,12 +415,18 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
288 if (browser.b.width < line_len) 415 if (browser.b.width < line_len)
289 browser.b.width = line_len; 416 browser.b.width = line_len;
290 rbpos = objdump_line__rb(pos); 417 rbpos = objdump_line__rb(pos);
291 rbpos->idx = browser.b.nr_entries++; 418 rbpos->idx = browser.nr_entries++;
419 if (pos->offset != -1)
420 rbpos->idx_asm = browser.nr_asm_entries++;
421 else
422 rbpos->idx_asm = -1;
292 } 423 }
293 424
425 browser.b.nr_entries = browser.nr_entries;
294 browser.b.entries = &notes->src->source, 426 browser.b.entries = &notes->src->source,
295 browser.b.width += 18; /* Percentage */ 427 browser.b.width += 18; /* Percentage */
296 ret = annotate_browser__run(&browser, evidx, refresh); 428 ret = annotate_browser__run(&browser, evidx, nr_events,
429 timer, arg, delay_secs);
297 list_for_each_entry_safe(pos, n, &notes->src->source, node) { 430 list_for_each_entry_safe(pos, n, &notes->src->source, node) {
298 list_del(&pos->node); 431 list_del(&pos->node);
299 objdump_line__free(pos); 432 objdump_line__free(pos);
diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c
index 5d767c622dfc..4663dcb2a19b 100644
--- a/tools/perf/util/ui/browsers/hists.c
+++ b/tools/perf/util/ui/browsers/hists.c
@@ -24,8 +24,12 @@ struct hist_browser {
24 struct hists *hists; 24 struct hists *hists;
25 struct hist_entry *he_selection; 25 struct hist_entry *he_selection;
26 struct map_symbol *selection; 26 struct map_symbol *selection;
27 bool has_symbols;
27}; 28};
28 29
30static int hists__browser_title(struct hists *self, char *bf, size_t size,
31 const char *ev_name);
32
29static void hist_browser__refresh_dimensions(struct hist_browser *self) 33static void hist_browser__refresh_dimensions(struct hist_browser *self)
30{ 34{
31 /* 3 == +/- toggle symbol before actual hist_entry rendering */ 35 /* 3 == +/- toggle symbol before actual hist_entry rendering */
@@ -290,28 +294,34 @@ static void hist_browser__set_folding(struct hist_browser *self, bool unfold)
290 ui_browser__reset_index(&self->b); 294 ui_browser__reset_index(&self->b);
291} 295}
292 296
293static int hist_browser__run(struct hist_browser *self, const char *title) 297static int hist_browser__run(struct hist_browser *self, const char *ev_name,
298 void(*timer)(void *arg), void *arg, int delay_secs)
294{ 299{
295 int key; 300 int key;
296 int exit_keys[] = { 'a', '?', 'h', 'C', 'd', 'D', 'E', 't', 301 char title[160];
297 NEWT_KEY_ENTER, NEWT_KEY_RIGHT, NEWT_KEY_LEFT,
298 NEWT_KEY_TAB, NEWT_KEY_UNTAB, 0, };
299 302
300 self->b.entries = &self->hists->entries; 303 self->b.entries = &self->hists->entries;
301 self->b.nr_entries = self->hists->nr_entries; 304 self->b.nr_entries = self->hists->nr_entries;
302 305
303 hist_browser__refresh_dimensions(self); 306 hist_browser__refresh_dimensions(self);
307 hists__browser_title(self->hists, title, sizeof(title), ev_name);
304 308
305 if (ui_browser__show(&self->b, title, 309 if (ui_browser__show(&self->b, title,
306 "Press '?' for help on key bindings") < 0) 310 "Press '?' for help on key bindings") < 0)
307 return -1; 311 return -1;
308 312
309 ui_browser__add_exit_keys(&self->b, exit_keys);
310
311 while (1) { 313 while (1) {
312 key = ui_browser__run(&self->b); 314 key = ui_browser__run(&self->b, delay_secs);
313 315
314 switch (key) { 316 switch (key) {
317 case -1:
318 /* FIXME we need to check if it was es.reason == NEWT_EXIT_TIMER */
319 timer(arg);
320 ui_browser__update_nr_entries(&self->b, self->hists->nr_entries);
321 hists__browser_title(self->hists, title, sizeof(title),
322 ev_name);
323 ui_browser__show_title(&self->b, title);
324 continue;
315 case 'D': { /* Debug */ 325 case 'D': { /* Debug */
316 static int seq; 326 static int seq;
317 struct hist_entry *h = rb_entry(self->b.top, 327 struct hist_entry *h = rb_entry(self->b.top,
@@ -334,7 +344,7 @@ static int hist_browser__run(struct hist_browser *self, const char *title)
334 /* Expand the whole world. */ 344 /* Expand the whole world. */
335 hist_browser__set_folding(self, true); 345 hist_browser__set_folding(self, true);
336 break; 346 break;
337 case NEWT_KEY_ENTER: 347 case K_ENTER:
338 if (hist_browser__toggle_fold(self)) 348 if (hist_browser__toggle_fold(self))
339 break; 349 break;
340 /* fall thru */ 350 /* fall thru */
@@ -532,7 +542,7 @@ static int hist_browser__show_entry(struct hist_browser *self,
532 char s[256]; 542 char s[256];
533 double percent; 543 double percent;
534 int printed = 0; 544 int printed = 0;
535 int color, width = self->b.width; 545 int width = self->b.width - 6; /* The percentage */
536 char folded_sign = ' '; 546 char folded_sign = ' ';
537 bool current_entry = ui_browser__is_current_entry(&self->b, row); 547 bool current_entry = ui_browser__is_current_entry(&self->b, row);
538 off_t row_offset = entry->row_offset; 548 off_t row_offset = entry->row_offset;
@@ -548,26 +558,35 @@ static int hist_browser__show_entry(struct hist_browser *self,
548 } 558 }
549 559
550 if (row_offset == 0) { 560 if (row_offset == 0) {
551 hist_entry__snprintf(entry, s, sizeof(s), self->hists, NULL, false, 561 hist_entry__snprintf(entry, s, sizeof(s), self->hists);
552 0, false, self->hists->stats.total_period);
553 percent = (entry->period * 100.0) / self->hists->stats.total_period; 562 percent = (entry->period * 100.0) / self->hists->stats.total_period;
554 563
555 color = HE_COLORSET_SELECTED; 564 ui_browser__set_percent_color(&self->b, percent, current_entry);
556 if (!current_entry) {
557 if (percent >= MIN_RED)
558 color = HE_COLORSET_TOP;
559 else if (percent >= MIN_GREEN)
560 color = HE_COLORSET_MEDIUM;
561 else
562 color = HE_COLORSET_NORMAL;
563 }
564
565 ui_browser__set_color(&self->b, color);
566 ui_browser__gotorc(&self->b, row, 0); 565 ui_browser__gotorc(&self->b, row, 0);
567 if (symbol_conf.use_callchain) { 566 if (symbol_conf.use_callchain) {
568 slsmg_printf("%c ", folded_sign); 567 slsmg_printf("%c ", folded_sign);
569 width -= 2; 568 width -= 2;
570 } 569 }
570
571 slsmg_printf(" %5.2f%%", percent);
572
573 /* The scroll bar isn't being used */
574 if (!self->b.navkeypressed)
575 width += 1;
576
577 if (!current_entry || !self->b.navkeypressed)
578 ui_browser__set_color(&self->b, HE_COLORSET_NORMAL);
579
580 if (symbol_conf.show_nr_samples) {
581 slsmg_printf(" %11u", entry->nr_events);
582 width -= 12;
583 }
584
585 if (symbol_conf.show_total_period) {
586 slsmg_printf(" %12" PRIu64, entry->period);
587 width -= 13;
588 }
589
571 slsmg_write_nstring(s, width); 590 slsmg_write_nstring(s, width);
572 ++row; 591 ++row;
573 ++printed; 592 ++printed;
@@ -585,14 +604,23 @@ static int hist_browser__show_entry(struct hist_browser *self,
585 return printed; 604 return printed;
586} 605}
587 606
607static void ui_browser__hists_init_top(struct ui_browser *browser)
608{
609 if (browser->top == NULL) {
610 struct hist_browser *hb;
611
612 hb = container_of(browser, struct hist_browser, b);
613 browser->top = rb_first(&hb->hists->entries);
614 }
615}
616
588static unsigned int hist_browser__refresh(struct ui_browser *self) 617static unsigned int hist_browser__refresh(struct ui_browser *self)
589{ 618{
590 unsigned row = 0; 619 unsigned row = 0;
591 struct rb_node *nd; 620 struct rb_node *nd;
592 struct hist_browser *hb = container_of(self, struct hist_browser, b); 621 struct hist_browser *hb = container_of(self, struct hist_browser, b);
593 622
594 if (self->top == NULL) 623 ui_browser__hists_init_top(self);
595 self->top = rb_first(&hb->hists->entries);
596 624
597 for (nd = self->top; nd; nd = rb_next(nd)) { 625 for (nd = self->top; nd; nd = rb_next(nd)) {
598 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 626 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
@@ -644,6 +672,8 @@ static void ui_browser__hists_seek(struct ui_browser *self,
644 if (self->nr_entries == 0) 672 if (self->nr_entries == 0)
645 return; 673 return;
646 674
675 ui_browser__hists_init_top(self);
676
647 switch (whence) { 677 switch (whence) {
648 case SEEK_SET: 678 case SEEK_SET:
649 nd = hists__filter_entries(rb_first(self->entries)); 679 nd = hists__filter_entries(rb_first(self->entries));
@@ -761,6 +791,8 @@ static struct hist_browser *hist_browser__new(struct hists *hists)
761 self->hists = hists; 791 self->hists = hists;
762 self->b.refresh = hist_browser__refresh; 792 self->b.refresh = hist_browser__refresh;
763 self->b.seek = ui_browser__hists_seek; 793 self->b.seek = ui_browser__hists_seek;
794 self->b.use_navkeypressed = true,
795 self->has_symbols = sort_sym.list.next != NULL;
764 } 796 }
765 797
766 return self; 798 return self;
@@ -782,11 +814,12 @@ static struct thread *hist_browser__selected_thread(struct hist_browser *self)
782} 814}
783 815
784static int hists__browser_title(struct hists *self, char *bf, size_t size, 816static int hists__browser_title(struct hists *self, char *bf, size_t size,
785 const char *ev_name, const struct dso *dso, 817 const char *ev_name)
786 const struct thread *thread)
787{ 818{
788 char unit; 819 char unit;
789 int printed; 820 int printed;
821 const struct dso *dso = self->dso_filter;
822 const struct thread *thread = self->thread_filter;
790 unsigned long nr_events = self->stats.nr_events[PERF_RECORD_SAMPLE]; 823 unsigned long nr_events = self->stats.nr_events[PERF_RECORD_SAMPLE];
791 824
792 nr_events = convert_unit(nr_events, &unit); 825 nr_events = convert_unit(nr_events, &unit);
@@ -803,16 +836,15 @@ static int hists__browser_title(struct hists *self, char *bf, size_t size,
803 return printed; 836 return printed;
804} 837}
805 838
806static int perf_evsel__hists_browse(struct perf_evsel *evsel, 839static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
807 const char *helpline, const char *ev_name, 840 const char *helpline, const char *ev_name,
808 bool left_exits) 841 bool left_exits,
842 void(*timer)(void *arg), void *arg,
843 int delay_secs)
809{ 844{
810 struct hists *self = &evsel->hists; 845 struct hists *self = &evsel->hists;
811 struct hist_browser *browser = hist_browser__new(self); 846 struct hist_browser *browser = hist_browser__new(self);
812 struct pstack *fstack; 847 struct pstack *fstack;
813 const struct thread *thread_filter = NULL;
814 const struct dso *dso_filter = NULL;
815 char msg[160];
816 int key = -1; 848 int key = -1;
817 849
818 if (browser == NULL) 850 if (browser == NULL)
@@ -824,8 +856,6 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel,
824 856
825 ui_helpline__push(helpline); 857 ui_helpline__push(helpline);
826 858
827 hists__browser_title(self, msg, sizeof(msg), ev_name,
828 dso_filter, thread_filter);
829 while (1) { 859 while (1) {
830 const struct thread *thread = NULL; 860 const struct thread *thread = NULL;
831 const struct dso *dso = NULL; 861 const struct dso *dso = NULL;
@@ -834,7 +864,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel,
834 annotate = -2, zoom_dso = -2, zoom_thread = -2, 864 annotate = -2, zoom_dso = -2, zoom_thread = -2,
835 browse_map = -2; 865 browse_map = -2;
836 866
837 key = hist_browser__run(browser, msg); 867 key = hist_browser__run(browser, ev_name, timer, arg, delay_secs);
838 868
839 if (browser->he_selection != NULL) { 869 if (browser->he_selection != NULL) {
840 thread = hist_browser__selected_thread(browser); 870 thread = hist_browser__selected_thread(browser);
@@ -842,14 +872,23 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel,
842 } 872 }
843 873
844 switch (key) { 874 switch (key) {
845 case NEWT_KEY_TAB: 875 case K_TAB:
846 case NEWT_KEY_UNTAB: 876 case K_UNTAB:
877 if (nr_events == 1)
878 continue;
847 /* 879 /*
848 * Exit the browser, let hists__browser_tree 880 * Exit the browser, let hists__browser_tree
849 * go to the next or previous 881 * go to the next or previous
850 */ 882 */
851 goto out_free_stack; 883 goto out_free_stack;
852 case 'a': 884 case 'a':
885 if (!browser->has_symbols) {
886 ui__warning(
887 "Annotation is only available for symbolic views, "
888 "include \"sym\" in --sort to use it.");
889 continue;
890 }
891
853 if (browser->selection == NULL || 892 if (browser->selection == NULL ||
854 browser->selection->sym == NULL || 893 browser->selection->sym == NULL ||
855 browser->selection->map->dso->annotate_warned) 894 browser->selection->map->dso->annotate_warned)
@@ -859,25 +898,29 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel,
859 goto zoom_dso; 898 goto zoom_dso;
860 case 't': 899 case 't':
861 goto zoom_thread; 900 goto zoom_thread;
862 case NEWT_KEY_F1: 901 case K_F1:
863 case 'h': 902 case 'h':
864 case '?': 903 case '?':
865 ui__help_window("-> Zoom into DSO/Threads & Annotate current symbol\n" 904 ui__help_window("h/?/F1 Show this window\n"
866 "<- Zoom out\n" 905 "UP/DOWN/PGUP\n"
867 "a Annotate current symbol\n" 906 "PGDN/SPACE Navigate\n"
868 "h/?/F1 Show this window\n" 907 "q/ESC/CTRL+C Exit browser\n\n"
869 "C Collapse all callchains\n" 908 "For multiple event sessions:\n\n"
870 "E Expand all callchains\n" 909 "TAB/UNTAB Switch events\n\n"
871 "d Zoom into current DSO\n" 910 "For symbolic views (--sort has sym):\n\n"
872 "t Zoom into current Thread\n" 911 "-> Zoom into DSO/Threads & Annotate current symbol\n"
873 "TAB/UNTAB Switch events\n" 912 "<- Zoom out\n"
874 "q/CTRL+C Exit browser"); 913 "a Annotate current symbol\n"
914 "C Collapse all callchains\n"
915 "E Expand all callchains\n"
916 "d Zoom into current DSO\n"
917 "t Zoom into current Thread\n");
875 continue; 918 continue;
876 case NEWT_KEY_ENTER: 919 case K_ENTER:
877 case NEWT_KEY_RIGHT: 920 case K_RIGHT:
878 /* menu */ 921 /* menu */
879 break; 922 break;
880 case NEWT_KEY_LEFT: { 923 case K_LEFT: {
881 const void *top; 924 const void *top;
882 925
883 if (pstack__empty(fstack)) { 926 if (pstack__empty(fstack)) {
@@ -889,21 +932,27 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel,
889 continue; 932 continue;
890 } 933 }
891 top = pstack__pop(fstack); 934 top = pstack__pop(fstack);
892 if (top == &dso_filter) 935 if (top == &browser->hists->dso_filter)
893 goto zoom_out_dso; 936 goto zoom_out_dso;
894 if (top == &thread_filter) 937 if (top == &browser->hists->thread_filter)
895 goto zoom_out_thread; 938 goto zoom_out_thread;
896 continue; 939 continue;
897 } 940 }
898 case NEWT_KEY_ESCAPE: 941 case K_ESC:
899 if (!left_exits && 942 if (!left_exits &&
900 !ui__dialog_yesno("Do you really want to exit?")) 943 !ui__dialog_yesno("Do you really want to exit?"))
901 continue; 944 continue;
902 /* Fall thru */ 945 /* Fall thru */
903 default: 946 case 'q':
947 case CTRL('c'):
904 goto out_free_stack; 948 goto out_free_stack;
949 default:
950 continue;
905 } 951 }
906 952
953 if (!browser->has_symbols)
954 goto add_exit_option;
955
907 if (browser->selection != NULL && 956 if (browser->selection != NULL &&
908 browser->selection->sym != NULL && 957 browser->selection->sym != NULL &&
909 !browser->selection->map->dso->annotate_warned && 958 !browser->selection->map->dso->annotate_warned &&
@@ -913,14 +962,14 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel,
913 962
914 if (thread != NULL && 963 if (thread != NULL &&
915 asprintf(&options[nr_options], "Zoom %s %s(%d) thread", 964 asprintf(&options[nr_options], "Zoom %s %s(%d) thread",
916 (thread_filter ? "out of" : "into"), 965 (browser->hists->thread_filter ? "out of" : "into"),
917 (thread->comm_set ? thread->comm : ""), 966 (thread->comm_set ? thread->comm : ""),
918 thread->pid) > 0) 967 thread->pid) > 0)
919 zoom_thread = nr_options++; 968 zoom_thread = nr_options++;
920 969
921 if (dso != NULL && 970 if (dso != NULL &&
922 asprintf(&options[nr_options], "Zoom %s %s DSO", 971 asprintf(&options[nr_options], "Zoom %s %s DSO",
923 (dso_filter ? "out of" : "into"), 972 (browser->hists->dso_filter ? "out of" : "into"),
924 (dso->kernel ? "the Kernel" : dso->short_name)) > 0) 973 (dso->kernel ? "the Kernel" : dso->short_name)) > 0)
925 zoom_dso = nr_options++; 974 zoom_dso = nr_options++;
926 975
@@ -928,7 +977,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel,
928 browser->selection->map != NULL && 977 browser->selection->map != NULL &&
929 asprintf(&options[nr_options], "Browse map details") > 0) 978 asprintf(&options[nr_options], "Browse map details") > 0)
930 browse_map = nr_options++; 979 browse_map = nr_options++;
931 980add_exit_option:
932 options[nr_options++] = (char *)"Exit"; 981 options[nr_options++] = (char *)"Exit";
933 982
934 choice = ui__popup_menu(nr_options, options); 983 choice = ui__popup_menu(nr_options, options);
@@ -948,46 +997,52 @@ do_annotate:
948 he = hist_browser__selected_entry(browser); 997 he = hist_browser__selected_entry(browser);
949 if (he == NULL) 998 if (he == NULL)
950 continue; 999 continue;
951 1000 /*
952 hist_entry__tui_annotate(he, evsel->idx); 1001 * Don't let this be freed, say, by hists__decay_entry.
1002 */
1003 he->used = true;
1004 hist_entry__tui_annotate(he, evsel->idx, nr_events,
1005 timer, arg, delay_secs);
1006 he->used = false;
1007 ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries);
953 } else if (choice == browse_map) 1008 } else if (choice == browse_map)
954 map__browse(browser->selection->map); 1009 map__browse(browser->selection->map);
955 else if (choice == zoom_dso) { 1010 else if (choice == zoom_dso) {
956zoom_dso: 1011zoom_dso:
957 if (dso_filter) { 1012 if (browser->hists->dso_filter) {
958 pstack__remove(fstack, &dso_filter); 1013 pstack__remove(fstack, &browser->hists->dso_filter);
959zoom_out_dso: 1014zoom_out_dso:
960 ui_helpline__pop(); 1015 ui_helpline__pop();
961 dso_filter = NULL; 1016 browser->hists->dso_filter = NULL;
1017 sort_dso.elide = false;
962 } else { 1018 } else {
963 if (dso == NULL) 1019 if (dso == NULL)
964 continue; 1020 continue;
965 ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s DSO\"", 1021 ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s DSO\"",
966 dso->kernel ? "the Kernel" : dso->short_name); 1022 dso->kernel ? "the Kernel" : dso->short_name);
967 dso_filter = dso; 1023 browser->hists->dso_filter = dso;
968 pstack__push(fstack, &dso_filter); 1024 sort_dso.elide = true;
1025 pstack__push(fstack, &browser->hists->dso_filter);
969 } 1026 }
970 hists__filter_by_dso(self, dso_filter); 1027 hists__filter_by_dso(self);
971 hists__browser_title(self, msg, sizeof(msg), ev_name,
972 dso_filter, thread_filter);
973 hist_browser__reset(browser); 1028 hist_browser__reset(browser);
974 } else if (choice == zoom_thread) { 1029 } else if (choice == zoom_thread) {
975zoom_thread: 1030zoom_thread:
976 if (thread_filter) { 1031 if (browser->hists->thread_filter) {
977 pstack__remove(fstack, &thread_filter); 1032 pstack__remove(fstack, &browser->hists->thread_filter);
978zoom_out_thread: 1033zoom_out_thread:
979 ui_helpline__pop(); 1034 ui_helpline__pop();
980 thread_filter = NULL; 1035 browser->hists->thread_filter = NULL;
1036 sort_thread.elide = false;
981 } else { 1037 } else {
982 ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s(%d) thread\"", 1038 ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s(%d) thread\"",
983 thread->comm_set ? thread->comm : "", 1039 thread->comm_set ? thread->comm : "",
984 thread->pid); 1040 thread->pid);
985 thread_filter = thread; 1041 browser->hists->thread_filter = thread;
986 pstack__push(fstack, &thread_filter); 1042 sort_thread.elide = true;
1043 pstack__push(fstack, &browser->hists->thread_filter);
987 } 1044 }
988 hists__filter_by_thread(self, thread_filter); 1045 hists__filter_by_thread(self);
989 hists__browser_title(self, msg, sizeof(msg), ev_name,
990 dso_filter, thread_filter);
991 hist_browser__reset(browser); 1046 hist_browser__reset(browser);
992 } 1047 }
993 } 1048 }
@@ -1026,9 +1081,10 @@ static void perf_evsel_menu__write(struct ui_browser *browser,
1026 menu->selection = evsel; 1081 menu->selection = evsel;
1027} 1082}
1028 1083
1029static int perf_evsel_menu__run(struct perf_evsel_menu *menu, const char *help) 1084static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
1085 int nr_events, const char *help,
1086 void(*timer)(void *arg), void *arg, int delay_secs)
1030{ 1087{
1031 int exit_keys[] = { NEWT_KEY_ENTER, NEWT_KEY_RIGHT, 0, };
1032 struct perf_evlist *evlist = menu->b.priv; 1088 struct perf_evlist *evlist = menu->b.priv;
1033 struct perf_evsel *pos; 1089 struct perf_evsel *pos;
1034 const char *ev_name, *title = "Available samples"; 1090 const char *ev_name, *title = "Available samples";
@@ -1038,50 +1094,65 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu, const char *help)
1038 "ESC: exit, ENTER|->: Browse histograms") < 0) 1094 "ESC: exit, ENTER|->: Browse histograms") < 0)
1039 return -1; 1095 return -1;
1040 1096
1041 ui_browser__add_exit_keys(&menu->b, exit_keys);
1042
1043 while (1) { 1097 while (1) {
1044 key = ui_browser__run(&menu->b); 1098 key = ui_browser__run(&menu->b, delay_secs);
1045 1099
1046 switch (key) { 1100 switch (key) {
1047 case NEWT_KEY_RIGHT: 1101 case K_TIMER:
1048 case NEWT_KEY_ENTER: 1102 timer(arg);
1103 continue;
1104 case K_RIGHT:
1105 case K_ENTER:
1049 if (!menu->selection) 1106 if (!menu->selection)
1050 continue; 1107 continue;
1051 pos = menu->selection; 1108 pos = menu->selection;
1052browse_hists: 1109browse_hists:
1110 perf_evlist__set_selected(evlist, pos);
1111 /*
1112 * Give the calling tool a chance to populate the non
1113 * default evsel resorted hists tree.
1114 */
1115 if (timer)
1116 timer(arg);
1053 ev_name = event_name(pos); 1117 ev_name = event_name(pos);
1054 key = perf_evsel__hists_browse(pos, help, ev_name, true); 1118 key = perf_evsel__hists_browse(pos, nr_events, help,
1119 ev_name, true, timer,
1120 arg, delay_secs);
1055 ui_browser__show_title(&menu->b, title); 1121 ui_browser__show_title(&menu->b, title);
1056 break; 1122 switch (key) {
1057 case NEWT_KEY_LEFT: 1123 case K_TAB:
1124 if (pos->node.next == &evlist->entries)
1125 pos = list_entry(evlist->entries.next, struct perf_evsel, node);
1126 else
1127 pos = list_entry(pos->node.next, struct perf_evsel, node);
1128 goto browse_hists;
1129 case K_UNTAB:
1130 if (pos->node.prev == &evlist->entries)
1131 pos = list_entry(evlist->entries.prev, struct perf_evsel, node);
1132 else
1133 pos = list_entry(pos->node.prev, struct perf_evsel, node);
1134 goto browse_hists;
1135 case K_ESC:
1136 if (!ui__dialog_yesno("Do you really want to exit?"))
1137 continue;
1138 /* Fall thru */
1139 case 'q':
1140 case CTRL('c'):
1141 goto out;
1142 default:
1143 continue;
1144 }
1145 case K_LEFT:
1058 continue; 1146 continue;
1059 case NEWT_KEY_ESCAPE: 1147 case K_ESC:
1060 if (!ui__dialog_yesno("Do you really want to exit?")) 1148 if (!ui__dialog_yesno("Do you really want to exit?"))
1061 continue; 1149 continue;
1062 /* Fall thru */ 1150 /* Fall thru */
1063 default:
1064 goto out;
1065 }
1066
1067 switch (key) {
1068 case NEWT_KEY_TAB:
1069 if (pos->node.next == &evlist->entries)
1070 pos = list_entry(evlist->entries.next, struct perf_evsel, node);
1071 else
1072 pos = list_entry(pos->node.next, struct perf_evsel, node);
1073 goto browse_hists;
1074 case NEWT_KEY_UNTAB:
1075 if (pos->node.prev == &evlist->entries)
1076 pos = list_entry(evlist->entries.prev, struct perf_evsel, node);
1077 else
1078 pos = list_entry(pos->node.prev, struct perf_evsel, node);
1079 goto browse_hists;
1080 case 'q': 1151 case 'q':
1081 case CTRL('c'): 1152 case CTRL('c'):
1082 goto out; 1153 goto out;
1083 default: 1154 default:
1084 break; 1155 continue;
1085 } 1156 }
1086 } 1157 }
1087 1158
@@ -1091,7 +1162,9 @@ out:
1091} 1162}
1092 1163
1093static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, 1164static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
1094 const char *help) 1165 const char *help,
1166 void(*timer)(void *arg), void *arg,
1167 int delay_secs)
1095{ 1168{
1096 struct perf_evsel *pos; 1169 struct perf_evsel *pos;
1097 struct perf_evsel_menu menu = { 1170 struct perf_evsel_menu menu = {
@@ -1121,18 +1194,24 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
1121 pos->name = strdup(ev_name); 1194 pos->name = strdup(ev_name);
1122 } 1195 }
1123 1196
1124 return perf_evsel_menu__run(&menu, help); 1197 return perf_evsel_menu__run(&menu, evlist->nr_entries, help, timer,
1198 arg, delay_secs);
1125} 1199}
1126 1200
1127int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help) 1201int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
1202 void(*timer)(void *arg), void *arg,
1203 int delay_secs)
1128{ 1204{
1129 1205
1130 if (evlist->nr_entries == 1) { 1206 if (evlist->nr_entries == 1) {
1131 struct perf_evsel *first = list_entry(evlist->entries.next, 1207 struct perf_evsel *first = list_entry(evlist->entries.next,
1132 struct perf_evsel, node); 1208 struct perf_evsel, node);
1133 const char *ev_name = event_name(first); 1209 const char *ev_name = event_name(first);
1134 return perf_evsel__hists_browse(first, help, ev_name, false); 1210 return perf_evsel__hists_browse(first, evlist->nr_entries, help,
1211 ev_name, false, timer, arg,
1212 delay_secs);
1135 } 1213 }
1136 1214
1137 return __perf_evlist__tui_browse_hists(evlist, help); 1215 return __perf_evlist__tui_browse_hists(evlist, help,
1216 timer, arg, delay_secs);
1138} 1217}
diff --git a/tools/perf/util/ui/browsers/map.c b/tools/perf/util/ui/browsers/map.c
index 8462bffe20bc..6905bcc8be2d 100644
--- a/tools/perf/util/ui/browsers/map.c
+++ b/tools/perf/util/ui/browsers/map.c
@@ -1,5 +1,6 @@
1#include "../libslang.h" 1#include "../libslang.h"
2#include <elf.h> 2#include <elf.h>
3#include <newt.h>
3#include <inttypes.h> 4#include <inttypes.h>
4#include <sys/ttydefaults.h> 5#include <sys/ttydefaults.h>
5#include <ctype.h> 6#include <ctype.h>
@@ -108,11 +109,8 @@ static int map_browser__run(struct map_browser *self)
108 verbose ? "" : "restart with -v to use") < 0) 109 verbose ? "" : "restart with -v to use") < 0)
109 return -1; 110 return -1;
110 111
111 if (verbose)
112 ui_browser__add_exit_key(&self->b, '/');
113
114 while (1) { 112 while (1) {
115 key = ui_browser__run(&self->b); 113 key = ui_browser__run(&self->b, 0);
116 114
117 if (verbose && key == '/') 115 if (verbose && key == '/')
118 map_browser__search(self); 116 map_browser__search(self);
diff --git a/tools/perf/util/ui/browsers/top.c b/tools/perf/util/ui/browsers/top.c
deleted file mode 100644
index 88403cf8396a..000000000000
--- a/tools/perf/util/ui/browsers/top.c
+++ /dev/null
@@ -1,212 +0,0 @@
1/*
2 * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
3 *
4 * Parts came from builtin-{top,stat,record}.c, see those files for further
5 * copyright notes.
6 *
7 * Released under the GPL v2. (and only v2, not any later version)
8 */
9#include "../browser.h"
10#include "../../annotate.h"
11#include "../helpline.h"
12#include "../libslang.h"
13#include "../util.h"
14#include "../../evlist.h"
15#include "../../hist.h"
16#include "../../sort.h"
17#include "../../symbol.h"
18#include "../../top.h"
19
20struct perf_top_browser {
21 struct ui_browser b;
22 struct rb_root root;
23 struct sym_entry *selection;
24 float sum_ksamples;
25 int dso_width;
26 int dso_short_width;
27 int sym_width;
28};
29
30static void perf_top_browser__write(struct ui_browser *browser, void *entry, int row)
31{
32 struct perf_top_browser *top_browser = container_of(browser, struct perf_top_browser, b);
33 struct sym_entry *syme = rb_entry(entry, struct sym_entry, rb_node);
34 bool current_entry = ui_browser__is_current_entry(browser, row);
35 struct symbol *symbol = sym_entry__symbol(syme);
36 struct perf_top *top = browser->priv;
37 int width = browser->width;
38 double pcnt;
39
40 pcnt = 100.0 - (100.0 * ((top_browser->sum_ksamples - syme->snap_count) /
41 top_browser->sum_ksamples));
42 ui_browser__set_percent_color(browser, pcnt, current_entry);
43
44 if (top->evlist->nr_entries == 1 || !top->display_weighted) {
45 slsmg_printf("%20.2f ", syme->weight);
46 width -= 24;
47 } else {
48 slsmg_printf("%9.1f %10ld ", syme->weight, syme->snap_count);
49 width -= 23;
50 }
51
52 slsmg_printf("%4.1f%%", pcnt);
53 width -= 7;
54
55 if (verbose) {
56 slsmg_printf(" %016" PRIx64, symbol->start);
57 width -= 17;
58 }
59
60 slsmg_printf(" %-*.*s ", top_browser->sym_width, top_browser->sym_width,
61 symbol->name);
62 width -= top_browser->sym_width;
63 slsmg_write_nstring(width >= syme->map->dso->long_name_len ?
64 syme->map->dso->long_name :
65 syme->map->dso->short_name, width);
66
67 if (current_entry)
68 top_browser->selection = syme;
69}
70
71static void perf_top_browser__update_rb_tree(struct perf_top_browser *browser)
72{
73 struct perf_top *top = browser->b.priv;
74 u64 top_idx = browser->b.top_idx;
75
76 browser->root = RB_ROOT;
77 browser->b.top = NULL;
78 browser->sum_ksamples = perf_top__decay_samples(top, &browser->root);
79 /*
80 * No active symbols
81 */
82 if (top->rb_entries == 0)
83 return;
84
85 perf_top__find_widths(top, &browser->root, &browser->dso_width,
86 &browser->dso_short_width,
87 &browser->sym_width);
88 if (browser->sym_width + browser->dso_width > browser->b.width - 29) {
89 browser->dso_width = browser->dso_short_width;
90 if (browser->sym_width + browser->dso_width > browser->b.width - 29)
91 browser->sym_width = browser->b.width - browser->dso_width - 29;
92 }
93
94 /*
95 * Adjust the ui_browser indexes since the entries in the browser->root
96 * rb_tree may have changed, then seek it from start, so that we get a
97 * possible new top of the screen.
98 */
99 browser->b.nr_entries = top->rb_entries;
100
101 if (top_idx >= browser->b.nr_entries) {
102 if (browser->b.height >= browser->b.nr_entries)
103 top_idx = browser->b.nr_entries - browser->b.height;
104 else
105 top_idx = 0;
106 }
107
108 if (browser->b.index >= top_idx + browser->b.height)
109 browser->b.index = top_idx + browser->b.index - browser->b.top_idx;
110
111 if (browser->b.index >= browser->b.nr_entries)
112 browser->b.index = browser->b.nr_entries - 1;
113
114 browser->b.top_idx = top_idx;
115 browser->b.seek(&browser->b, top_idx, SEEK_SET);
116}
117
118static void perf_top_browser__annotate(struct perf_top_browser *browser)
119{
120 struct sym_entry *syme = browser->selection;
121 struct symbol *sym = sym_entry__symbol(syme);
122 struct annotation *notes = symbol__annotation(sym);
123 struct perf_top *top = browser->b.priv;
124
125 if (notes->src != NULL)
126 goto do_annotation;
127
128 pthread_mutex_lock(&notes->lock);
129
130 top->sym_filter_entry = NULL;
131
132 if (symbol__alloc_hist(sym, top->evlist->nr_entries) < 0) {
133 pr_err("Not enough memory for annotating '%s' symbol!\n",
134 sym->name);
135 pthread_mutex_unlock(&notes->lock);
136 return;
137 }
138
139 top->sym_filter_entry = syme;
140
141 pthread_mutex_unlock(&notes->lock);
142do_annotation:
143 symbol__tui_annotate(sym, syme->map, 0, top->delay_secs * 1000);
144}
145
146static int perf_top_browser__run(struct perf_top_browser *browser)
147{
148 int key;
149 char title[160];
150 struct perf_top *top = browser->b.priv;
151 int delay_msecs = top->delay_secs * 1000;
152 int exit_keys[] = { 'a', NEWT_KEY_ENTER, NEWT_KEY_RIGHT, 0, };
153
154 perf_top_browser__update_rb_tree(browser);
155 perf_top__header_snprintf(top, title, sizeof(title));
156 perf_top__reset_sample_counters(top);
157
158 if (ui_browser__show(&browser->b, title,
159 "ESC: exit, ENTER|->|a: Live Annotate") < 0)
160 return -1;
161
162 newtFormSetTimer(browser->b.form, delay_msecs);
163 ui_browser__add_exit_keys(&browser->b, exit_keys);
164
165 while (1) {
166 key = ui_browser__run(&browser->b);
167
168 switch (key) {
169 case -1:
170 /* FIXME we need to check if it was es.reason == NEWT_EXIT_TIMER */
171 perf_top_browser__update_rb_tree(browser);
172 perf_top__header_snprintf(top, title, sizeof(title));
173 perf_top__reset_sample_counters(top);
174 ui_browser__set_color(&browser->b, NEWT_COLORSET_ROOT);
175 SLsmg_gotorc(0, 0);
176 slsmg_write_nstring(title, browser->b.width);
177 break;
178 case 'a':
179 case NEWT_KEY_RIGHT:
180 case NEWT_KEY_ENTER:
181 if (browser->selection)
182 perf_top_browser__annotate(browser);
183 break;
184 case NEWT_KEY_LEFT:
185 continue;
186 case NEWT_KEY_ESCAPE:
187 if (!ui__dialog_yesno("Do you really want to exit?"))
188 continue;
189 /* Fall thru */
190 default:
191 goto out;
192 }
193 }
194out:
195 ui_browser__hide(&browser->b);
196 return key;
197}
198
199int perf_top__tui_browser(struct perf_top *top)
200{
201 struct perf_top_browser browser = {
202 .b = {
203 .entries = &browser.root,
204 .refresh = ui_browser__rb_tree_refresh,
205 .seek = ui_browser__rb_tree_seek,
206 .write = perf_top_browser__write,
207 .priv = top,
208 },
209 };
210
211 return perf_top_browser__run(&browser);
212}
diff --git a/tools/perf/util/ui/helpline.h b/tools/perf/util/ui/helpline.h
index ab6028d0c401..fdcbc0270acd 100644
--- a/tools/perf/util/ui/helpline.h
+++ b/tools/perf/util/ui/helpline.h
@@ -1,6 +1,9 @@
1#ifndef _PERF_UI_HELPLINE_H_ 1#ifndef _PERF_UI_HELPLINE_H_
2#define _PERF_UI_HELPLINE_H_ 1 2#define _PERF_UI_HELPLINE_H_ 1
3 3
4#include <stdio.h>
5#include <stdarg.h>
6
4void ui_helpline__init(void); 7void ui_helpline__init(void);
5void ui_helpline__pop(void); 8void ui_helpline__pop(void);
6void ui_helpline__push(const char *msg); 9void ui_helpline__push(const char *msg);
diff --git a/tools/perf/util/ui/keysyms.h b/tools/perf/util/ui/keysyms.h
new file mode 100644
index 000000000000..3458b1985761
--- /dev/null
+++ b/tools/perf/util/ui/keysyms.h
@@ -0,0 +1,25 @@
1#ifndef _PERF_KEYSYMS_H_
2#define _PERF_KEYSYMS_H_ 1
3
4#include "libslang.h"
5
6#define K_DOWN SL_KEY_DOWN
7#define K_END SL_KEY_END
8#define K_ENTER '\r'
9#define K_ESC 033
10#define K_F1 SL_KEY_F(1)
11#define K_HOME SL_KEY_HOME
12#define K_LEFT SL_KEY_LEFT
13#define K_PGDN SL_KEY_NPAGE
14#define K_PGUP SL_KEY_PPAGE
15#define K_RIGHT SL_KEY_RIGHT
16#define K_TAB '\t'
17#define K_UNTAB SL_KEY_UNTAB
18#define K_UP SL_KEY_UP
19
20/* Not really keys */
21#define K_TIMER -1
22#define K_ERROR -2
23#define K_RESIZE -3
24
25#endif /* _PERF_KEYSYMS_H_ */
diff --git a/tools/perf/util/ui/libslang.h b/tools/perf/util/ui/libslang.h
index 2b63e1c9b181..4d54b6450f5b 100644
--- a/tools/perf/util/ui/libslang.h
+++ b/tools/perf/util/ui/libslang.h
@@ -24,4 +24,6 @@
24#define sltt_set_color SLtt_set_color 24#define sltt_set_color SLtt_set_color
25#endif 25#endif
26 26
27#define SL_KEY_UNTAB 0x1000
28
27#endif /* _PERF_UI_SLANG_H_ */ 29#endif /* _PERF_UI_SLANG_H_ */
diff --git a/tools/perf/util/ui/setup.c b/tools/perf/util/ui/setup.c
index ee46d671db59..1e6ba06980c4 100644
--- a/tools/perf/util/ui/setup.c
+++ b/tools/perf/util/ui/setup.c
@@ -7,6 +7,7 @@
7#include "browser.h" 7#include "browser.h"
8#include "helpline.h" 8#include "helpline.h"
9#include "ui.h" 9#include "ui.h"
10#include "libslang.h"
10 11
11pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; 12pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;
12 13
@@ -17,6 +18,33 @@ static void newt_suspend(void *d __used)
17 newtResume(); 18 newtResume();
18} 19}
19 20
21static int ui__init(void)
22{
23 int err = SLkp_init();
24
25 if (err < 0)
26 goto out;
27
28 SLkp_define_keysym((char *)"^(kB)", SL_KEY_UNTAB);
29out:
30 return err;
31}
32
33static void ui__exit(void)
34{
35 SLtt_set_cursor_visibility(1);
36 SLsmg_refresh();
37 SLsmg_reset_smg();
38 SLang_reset_tty();
39}
40
41static void ui__signal(int sig)
42{
43 ui__exit();
44 psignal(sig, "perf");
45 exit(0);
46}
47
20void setup_browser(bool fallback_to_pager) 48void setup_browser(bool fallback_to_pager)
21{ 49{
22 if (!isatty(1) || !use_browser || dump_trace) { 50 if (!isatty(1) || !use_browser || dump_trace) {
@@ -28,10 +56,16 @@ void setup_browser(bool fallback_to_pager)
28 56
29 use_browser = 1; 57 use_browser = 1;
30 newtInit(); 58 newtInit();
31 newtCls(); 59 ui__init();
32 newtSetSuspendCallback(newt_suspend, NULL); 60 newtSetSuspendCallback(newt_suspend, NULL);
33 ui_helpline__init(); 61 ui_helpline__init();
34 ui_browser__init(); 62 ui_browser__init();
63
64 signal(SIGSEGV, ui__signal);
65 signal(SIGFPE, ui__signal);
66 signal(SIGINT, ui__signal);
67 signal(SIGQUIT, ui__signal);
68 signal(SIGTERM, ui__signal);
35} 69}
36 70
37void exit_browser(bool wait_for_ok) 71void exit_browser(bool wait_for_ok)
@@ -41,6 +75,6 @@ void exit_browser(bool wait_for_ok)
41 char title[] = "Fatal Error", ok[] = "Ok"; 75 char title[] = "Fatal Error", ok[] = "Ok";
42 newtWinMessage(title, ok, ui_helpline__last_msg); 76 newtWinMessage(title, ok, ui_helpline__last_msg);
43 } 77 }
44 newtFinished(); 78 ui__exit();
45 } 79 }
46} 80}