aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-22 14:10:36 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-22 14:10:36 -0400
commit2eafeb6a415864bc4c59df79151cf40f6ac74b9e (patch)
tree331ee730275276aebbda5dd278a97c941067d5fd
parent16d286e656250859946786de0df0fb01f8f241bc (diff)
parent6e0f17be0361444862637e8986c8c1a3b3f8dcf8 (diff)
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf events changes from Ingo Molnar: "- kernel side: - Intel uncore PMU support for Nehalem and Sandy Bridge CPUs, we support both the events available via the MSR and via the PCI access space. - various uprobes cleanups and restructurings - PMU driver quirks by microcode version and required x86 microcode loader cleanups/robustization - various tracing robustness updates - static keys: remove obsolete static_branch() - tooling side: - GTK browser improvements - perf report browser: support screenshots to file - more automated tests - perf kvm improvements - perf bench refinements - build environment improvements - pipe mode improvements - libtraceevent updates, we have now hopefully merged most bits with the out of tree forked code base ... and many other goodies." * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (138 commits) tracing: Check for allocation failure in __tracing_open() perf/x86: Fix intel_perfmon_event_mapformatting jump label: Remove static_branch() tracepoint: Use static_key_false(), since static_branch() is deprecated perf/x86: Uncore filter support for SandyBridge-EP perf/x86: Detect number of instances of uncore CBox perf/x86: Fix event constraint for SandyBridge-EP C-Box perf/x86: Use 0xff as pseudo code for fixed uncore event perf/x86: Save a few bytes in 'struct x86_pmu' perf/x86: Add a microcode revision check for SNB-PEBS perf/x86: Improve debug output in check_hw_exists() perf/x86/amd: Unify AMD's generic and family 15h pmus perf/x86: Move Intel specific code to intel_pmu_init() perf/x86: Rename Intel specific macros perf/x86: Fix USER/KERNEL tagging of samples perf tools: Split event symbols arrays to hw and sw parts perf tools: Split out PE_VALUE_SYM parsing token to SW and HW tokens perf tools: Add empty rule for new line in event syntax parsing perf test: Use ARRAY_SIZE in parse events tests tools lib traceevent: Cleanup realloc use ...
-rw-r--r--arch/x86/include/asm/kvm_host.h4
-rw-r--r--arch/x86/include/asm/msr.h46
-rw-r--r--arch/x86/include/asm/paravirt.h41
-rw-r--r--arch/x86/include/asm/paravirt_types.h2
-rw-r--r--arch/x86/include/asm/perf_event.h22
-rw-r--r--arch/x86/include/asm/uprobes.h2
-rw-r--r--arch/x86/kernel/cpu/Makefile4
-rw-r--r--arch/x86/kernel/cpu/amd.c39
-rw-r--r--arch/x86/kernel/cpu/common.c2
-rw-r--r--arch/x86/kernel/cpu/perf_event.c111
-rw-r--r--arch/x86/kernel/cpu/perf_event.h26
-rw-r--r--arch/x86/kernel/cpu/perf_event_amd.c103
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c122
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_ds.c12
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore.c1850
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore.h424
-rw-r--r--arch/x86/kernel/cpu/perf_event_p4.c16
-rw-r--r--arch/x86/kernel/cpu/perf_event_p6.c4
-rw-r--r--arch/x86/kernel/microcode_core.c64
-rw-r--r--arch/x86/kernel/paravirt.c2
-rw-r--r--arch/x86/kernel/process_64.c4
-rw-r--r--arch/x86/kernel/uprobes.c3
-rw-r--r--arch/x86/kvm/pmu.c22
-rw-r--r--arch/x86/kvm/trace.h12
-rw-r--r--arch/x86/lib/msr-reg-export.c4
-rw-r--r--arch/x86/lib/msr-reg.S10
-rw-r--r--arch/x86/oprofile/op_model_amd.c4
-rw-r--r--arch/x86/vdso/vdso32-setup.c6
-rw-r--r--arch/x86/xen/enlighten.c2
-rw-r--r--drivers/oprofile/oprofile_perf.c23
-rw-r--r--include/linux/ftrace_event.h5
-rw-r--r--include/linux/jump_label.h17
-rw-r--r--include/linux/pci_ids.h11
-rw-r--r--include/linux/perf_event.h3
-rw-r--r--include/linux/sched.h1
-rw-r--r--include/linux/tracepoint.h2
-rw-r--r--include/trace/ftrace.h1
-rw-r--r--kernel/events/core.c49
-rw-r--r--kernel/events/uprobes.c461
-rw-r--r--kernel/trace/ftrace.c8
-rw-r--r--kernel/trace/ring_buffer.c4
-rw-r--r--kernel/trace/trace.c33
-rw-r--r--kernel/trace/trace.h8
-rw-r--r--kernel/trace/trace_functions_graph.c2
-rw-r--r--kernel/trace/trace_output.c2
-rw-r--r--tools/lib/traceevent/Makefile14
-rw-r--r--tools/lib/traceevent/event-parse.c399
-rw-r--r--tools/lib/traceevent/event-parse.h7
-rw-r--r--tools/lib/traceevent/parse-filter.c86
-rw-r--r--tools/perf/Documentation/perf-bench.txt78
-rw-r--r--tools/perf/Documentation/perf-report.txt2
-rw-r--r--tools/perf/Documentation/perf-top.txt2
-rw-r--r--tools/perf/Makefile8
-rw-r--r--tools/perf/bench/mem-memcpy.c84
-rw-r--r--tools/perf/bench/mem-memset.c88
-rw-r--r--tools/perf/builtin-bench.c4
-rw-r--r--tools/perf/builtin-evlist.c2
-rw-r--r--tools/perf/builtin-kmem.c37
-rw-r--r--tools/perf/builtin-lock.c4
-rw-r--r--tools/perf/builtin-record.c4
-rw-r--r--tools/perf/builtin-report.c16
-rw-r--r--tools/perf/builtin-sched.c38
-rw-r--r--tools/perf/builtin-script.c106
-rw-r--r--tools/perf/builtin-stat.c12
-rw-r--r--tools/perf/builtin-test.c2
-rw-r--r--tools/perf/builtin-top.c12
-rw-r--r--tools/perf/config/feature-tests.mak13
-rw-r--r--tools/perf/ui/browsers/annotate.c4
-rw-r--r--tools/perf/ui/browsers/hists.c210
-rw-r--r--tools/perf/ui/gtk/browser.c69
-rw-r--r--tools/perf/ui/gtk/gtk.h31
-rw-r--r--tools/perf/ui/gtk/setup.c5
-rw-r--r--tools/perf/ui/gtk/util.c129
-rw-r--r--tools/perf/ui/tui/setup.c6
-rw-r--r--tools/perf/ui/tui/util.c243
-rw-r--r--tools/perf/ui/util.c277
-rw-r--r--tools/perf/ui/util.h9
-rw-r--r--tools/perf/util/debug.c2
-rw-r--r--tools/perf/util/debug.h23
-rw-r--r--tools/perf/util/evlist.c4
-rw-r--r--tools/perf/util/evlist.h3
-rw-r--r--tools/perf/util/evsel.c227
-rw-r--r--tools/perf/util/evsel.h15
-rw-r--r--tools/perf/util/header.c33
-rw-r--r--tools/perf/util/hist.h1
-rw-r--r--tools/perf/util/include/linux/kernel.h10
-rw-r--r--tools/perf/util/map.h2
-rw-r--r--tools/perf/util/parse-events-test.c179
-rw-r--r--tools/perf/util/parse-events.c470
-rw-r--r--tools/perf/util/parse-events.h17
-rw-r--r--tools/perf/util/parse-events.l134
-rw-r--r--tools/perf/util/parse-events.y86
-rw-r--r--tools/perf/util/pmu.c169
-rw-r--r--tools/perf/util/pmu.h11
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c32
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c25
-rw-r--r--tools/perf/util/session.c65
-rw-r--r--tools/perf/util/session.h14
-rw-r--r--tools/perf/util/sort.c49
-rw-r--r--tools/perf/util/sort.h2
-rw-r--r--tools/perf/util/string.c22
-rw-r--r--tools/perf/util/symbol.c94
-rw-r--r--tools/perf/util/symbol.h1
-rw-r--r--tools/perf/util/top.c2
-rw-r--r--tools/perf/util/trace-event-parse.c58
-rw-r--r--tools/perf/util/trace-event-read.c97
-rw-r--r--tools/perf/util/trace-event-scripting.c7
-rw-r--r--tools/perf/util/trace-event.h38
-rw-r--r--tools/perf/util/util.h2
109 files changed, 5782 insertions, 1706 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index db7c1f2709a2..2da88c0cda14 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -313,8 +313,8 @@ struct kvm_pmu {
313 u64 counter_bitmask[2]; 313 u64 counter_bitmask[2];
314 u64 global_ctrl_mask; 314 u64 global_ctrl_mask;
315 u8 version; 315 u8 version;
316 struct kvm_pmc gp_counters[X86_PMC_MAX_GENERIC]; 316 struct kvm_pmc gp_counters[INTEL_PMC_MAX_GENERIC];
317 struct kvm_pmc fixed_counters[X86_PMC_MAX_FIXED]; 317 struct kvm_pmc fixed_counters[INTEL_PMC_MAX_FIXED];
318 struct irq_work irq_work; 318 struct irq_work irq_work;
319 u64 reprogram_pmi; 319 u64 reprogram_pmi;
320}; 320};
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 084ef95274cd..813ed103f45e 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -115,8 +115,8 @@ notrace static inline int native_write_msr_safe(unsigned int msr,
115 115
116extern unsigned long long native_read_tsc(void); 116extern unsigned long long native_read_tsc(void);
117 117
118extern int native_rdmsr_safe_regs(u32 regs[8]); 118extern int rdmsr_safe_regs(u32 regs[8]);
119extern int native_wrmsr_safe_regs(u32 regs[8]); 119extern int wrmsr_safe_regs(u32 regs[8]);
120 120
121static __always_inline unsigned long long __native_read_tsc(void) 121static __always_inline unsigned long long __native_read_tsc(void)
122{ 122{
@@ -187,43 +187,6 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
187 return err; 187 return err;
188} 188}
189 189
190static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
191{
192 u32 gprs[8] = { 0 };
193 int err;
194
195 gprs[1] = msr;
196 gprs[7] = 0x9c5a203a;
197
198 err = native_rdmsr_safe_regs(gprs);
199
200 *p = gprs[0] | ((u64)gprs[2] << 32);
201
202 return err;
203}
204
205static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val)
206{
207 u32 gprs[8] = { 0 };
208
209 gprs[0] = (u32)val;
210 gprs[1] = msr;
211 gprs[2] = val >> 32;
212 gprs[7] = 0x9c5a203a;
213
214 return native_wrmsr_safe_regs(gprs);
215}
216
217static inline int rdmsr_safe_regs(u32 regs[8])
218{
219 return native_rdmsr_safe_regs(regs);
220}
221
222static inline int wrmsr_safe_regs(u32 regs[8])
223{
224 return native_wrmsr_safe_regs(regs);
225}
226
227#define rdtscl(low) \ 190#define rdtscl(low) \
228 ((low) = (u32)__native_read_tsc()) 191 ((low) = (u32)__native_read_tsc())
229 192
@@ -237,6 +200,8 @@ do { \
237 (high) = (u32)(_l >> 32); \ 200 (high) = (u32)(_l >> 32); \
238} while (0) 201} while (0)
239 202
203#define rdpmcl(counter, val) ((val) = native_read_pmc(counter))
204
240#define rdtscp(low, high, aux) \ 205#define rdtscp(low, high, aux) \
241do { \ 206do { \
242 unsigned long long _val = native_read_tscp(&(aux)); \ 207 unsigned long long _val = native_read_tscp(&(aux)); \
@@ -248,8 +213,7 @@ do { \
248 213
249#endif /* !CONFIG_PARAVIRT */ 214#endif /* !CONFIG_PARAVIRT */
250 215
251 216#define wrmsrl_safe(msr, val) wrmsr_safe((msr), (u32)(val), \
252#define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val), \
253 (u32)((val) >> 32)) 217 (u32)((val) >> 32))
254 218
255#define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2)) 219#define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2))
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 6cbbabf52707..0b47ddb6f00b 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -128,21 +128,11 @@ static inline u64 paravirt_read_msr(unsigned msr, int *err)
128 return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err); 128 return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err);
129} 129}
130 130
131static inline int paravirt_rdmsr_regs(u32 *regs)
132{
133 return PVOP_CALL1(int, pv_cpu_ops.rdmsr_regs, regs);
134}
135
136static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high) 131static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high)
137{ 132{
138 return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high); 133 return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high);
139} 134}
140 135
141static inline int paravirt_wrmsr_regs(u32 *regs)
142{
143 return PVOP_CALL1(int, pv_cpu_ops.wrmsr_regs, regs);
144}
145
146/* These should all do BUG_ON(_err), but our headers are too tangled. */ 136/* These should all do BUG_ON(_err), but our headers are too tangled. */
147#define rdmsr(msr, val1, val2) \ 137#define rdmsr(msr, val1, val2) \
148do { \ 138do { \
@@ -176,9 +166,6 @@ do { \
176 _err; \ 166 _err; \
177}) 167})
178 168
179#define rdmsr_safe_regs(regs) paravirt_rdmsr_regs(regs)
180#define wrmsr_safe_regs(regs) paravirt_wrmsr_regs(regs)
181
182static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) 169static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
183{ 170{
184 int err; 171 int err;
@@ -186,32 +173,6 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
186 *p = paravirt_read_msr(msr, &err); 173 *p = paravirt_read_msr(msr, &err);
187 return err; 174 return err;
188} 175}
189static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
190{
191 u32 gprs[8] = { 0 };
192 int err;
193
194 gprs[1] = msr;
195 gprs[7] = 0x9c5a203a;
196
197 err = paravirt_rdmsr_regs(gprs);
198
199 *p = gprs[0] | ((u64)gprs[2] << 32);
200
201 return err;
202}
203
204static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val)
205{
206 u32 gprs[8] = { 0 };
207
208 gprs[0] = (u32)val;
209 gprs[1] = msr;
210 gprs[2] = val >> 32;
211 gprs[7] = 0x9c5a203a;
212
213 return paravirt_wrmsr_regs(gprs);
214}
215 176
216static inline u64 paravirt_read_tsc(void) 177static inline u64 paravirt_read_tsc(void)
217{ 178{
@@ -252,6 +213,8 @@ do { \
252 high = _l >> 32; \ 213 high = _l >> 32; \
253} while (0) 214} while (0)
254 215
216#define rdpmcl(counter, val) ((val) = paravirt_read_pmc(counter))
217
255static inline unsigned long long paravirt_rdtscp(unsigned int *aux) 218static inline unsigned long long paravirt_rdtscp(unsigned int *aux)
256{ 219{
257 return PVOP_CALL1(u64, pv_cpu_ops.read_tscp, aux); 220 return PVOP_CALL1(u64, pv_cpu_ops.read_tscp, aux);
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
index 8e8b9a4987ee..8613cbb7ba41 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -153,9 +153,7 @@ struct pv_cpu_ops {
153 /* MSR, PMC and TSR operations. 153 /* MSR, PMC and TSR operations.
154 err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */ 154 err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */
155 u64 (*read_msr)(unsigned int msr, int *err); 155 u64 (*read_msr)(unsigned int msr, int *err);
156 int (*rdmsr_regs)(u32 *regs);
157 int (*write_msr)(unsigned int msr, unsigned low, unsigned high); 156 int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
158 int (*wrmsr_regs)(u32 *regs);
159 157
160 u64 (*read_tsc)(void); 158 u64 (*read_tsc)(void);
161 u64 (*read_pmc)(int counter); 159 u64 (*read_pmc)(int counter);
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 588f52ea810e..c78f14a0df00 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -5,11 +5,10 @@
5 * Performance event hw details: 5 * Performance event hw details:
6 */ 6 */
7 7
8#define X86_PMC_MAX_GENERIC 32 8#define INTEL_PMC_MAX_GENERIC 32
9#define X86_PMC_MAX_FIXED 3 9#define INTEL_PMC_MAX_FIXED 3
10#define INTEL_PMC_IDX_FIXED 32
10 11
11#define X86_PMC_IDX_GENERIC 0
12#define X86_PMC_IDX_FIXED 32
13#define X86_PMC_IDX_MAX 64 12#define X86_PMC_IDX_MAX 64
14 13
15#define MSR_ARCH_PERFMON_PERFCTR0 0xc1 14#define MSR_ARCH_PERFMON_PERFCTR0 0xc1
@@ -48,8 +47,7 @@
48 (X86_RAW_EVENT_MASK | \ 47 (X86_RAW_EVENT_MASK | \
49 AMD64_EVENTSEL_EVENT) 48 AMD64_EVENTSEL_EVENT)
50#define AMD64_NUM_COUNTERS 4 49#define AMD64_NUM_COUNTERS 4
51#define AMD64_NUM_COUNTERS_F15H 6 50#define AMD64_NUM_COUNTERS_CORE 6
52#define AMD64_NUM_COUNTERS_MAX AMD64_NUM_COUNTERS_F15H
53 51
54#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL 0x3c 52#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL 0x3c
55#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8) 53#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8)
@@ -121,16 +119,16 @@ struct x86_pmu_capability {
121 119
122/* Instr_Retired.Any: */ 120/* Instr_Retired.Any: */
123#define MSR_ARCH_PERFMON_FIXED_CTR0 0x309 121#define MSR_ARCH_PERFMON_FIXED_CTR0 0x309
124#define X86_PMC_IDX_FIXED_INSTRUCTIONS (X86_PMC_IDX_FIXED + 0) 122#define INTEL_PMC_IDX_FIXED_INSTRUCTIONS (INTEL_PMC_IDX_FIXED + 0)
125 123
126/* CPU_CLK_Unhalted.Core: */ 124/* CPU_CLK_Unhalted.Core: */
127#define MSR_ARCH_PERFMON_FIXED_CTR1 0x30a 125#define MSR_ARCH_PERFMON_FIXED_CTR1 0x30a
128#define X86_PMC_IDX_FIXED_CPU_CYCLES (X86_PMC_IDX_FIXED + 1) 126#define INTEL_PMC_IDX_FIXED_CPU_CYCLES (INTEL_PMC_IDX_FIXED + 1)
129 127
130/* CPU_CLK_Unhalted.Ref: */ 128/* CPU_CLK_Unhalted.Ref: */
131#define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b 129#define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b
132#define X86_PMC_IDX_FIXED_REF_CYCLES (X86_PMC_IDX_FIXED + 2) 130#define INTEL_PMC_IDX_FIXED_REF_CYCLES (INTEL_PMC_IDX_FIXED + 2)
133#define X86_PMC_MSK_FIXED_REF_CYCLES (1ULL << X86_PMC_IDX_FIXED_REF_CYCLES) 131#define INTEL_PMC_MSK_FIXED_REF_CYCLES (1ULL << INTEL_PMC_IDX_FIXED_REF_CYCLES)
134 132
135/* 133/*
136 * We model BTS tracing as another fixed-mode PMC. 134 * We model BTS tracing as another fixed-mode PMC.
@@ -139,7 +137,7 @@ struct x86_pmu_capability {
139 * values are used by actual fixed events and higher values are used 137 * values are used by actual fixed events and higher values are used
140 * to indicate other overflow conditions in the PERF_GLOBAL_STATUS msr. 138 * to indicate other overflow conditions in the PERF_GLOBAL_STATUS msr.
141 */ 139 */
142#define X86_PMC_IDX_FIXED_BTS (X86_PMC_IDX_FIXED + 16) 140#define INTEL_PMC_IDX_FIXED_BTS (INTEL_PMC_IDX_FIXED + 16)
143 141
144/* 142/*
145 * IBS cpuid feature detection 143 * IBS cpuid feature detection
@@ -234,6 +232,7 @@ struct perf_guest_switch_msr {
234 232
235extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr); 233extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr);
236extern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap); 234extern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap);
235extern void perf_check_microcode(void);
237#else 236#else
238static inline perf_guest_switch_msr *perf_guest_get_msrs(int *nr) 237static inline perf_guest_switch_msr *perf_guest_get_msrs(int *nr)
239{ 238{
@@ -247,6 +246,7 @@ static inline void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap)
247} 246}
248 247
249static inline void perf_events_lapic_init(void) { } 248static inline void perf_events_lapic_init(void) { }
249static inline void perf_check_microcode(void) { }
250#endif 250#endif
251 251
252#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) 252#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD)
diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h
index 1e9bed14f7ae..f3971bbcd1de 100644
--- a/arch/x86/include/asm/uprobes.h
+++ b/arch/x86/include/asm/uprobes.h
@@ -48,7 +48,7 @@ struct arch_uprobe_task {
48#endif 48#endif
49}; 49};
50 50
51extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm); 51extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr);
52extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs); 52extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs);
53extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs); 53extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs);
54extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); 54extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk);
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index 6ab6aa2fdfdd..bac4c3804cc7 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -32,7 +32,9 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o
32 32
33ifdef CONFIG_PERF_EVENTS 33ifdef CONFIG_PERF_EVENTS
34obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd.o 34obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd.o
35obj-$(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 35obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_p4.o
36obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o
37obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore.o
36endif 38endif
37 39
38obj-$(CONFIG_X86_MCE) += mcheck/ 40obj-$(CONFIG_X86_MCE) += mcheck/
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 146bb6218eec..9d92e19039f0 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -19,6 +19,39 @@
19 19
20#include "cpu.h" 20#include "cpu.h"
21 21
22static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
23{
24 struct cpuinfo_x86 *c = &cpu_data(smp_processor_id());
25 u32 gprs[8] = { 0 };
26 int err;
27
28 WARN_ONCE((c->x86 != 0xf), "%s should only be used on K8!\n", __func__);
29
30 gprs[1] = msr;
31 gprs[7] = 0x9c5a203a;
32
33 err = rdmsr_safe_regs(gprs);
34
35 *p = gprs[0] | ((u64)gprs[2] << 32);
36
37 return err;
38}
39
40static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val)
41{
42 struct cpuinfo_x86 *c = &cpu_data(smp_processor_id());
43 u32 gprs[8] = { 0 };
44
45 WARN_ONCE((c->x86 != 0xf), "%s should only be used on K8!\n", __func__);
46
47 gprs[0] = (u32)val;
48 gprs[1] = msr;
49 gprs[2] = val >> 32;
50 gprs[7] = 0x9c5a203a;
51
52 return wrmsr_safe_regs(gprs);
53}
54
22#ifdef CONFIG_X86_32 55#ifdef CONFIG_X86_32
23/* 56/*
24 * B step AMD K6 before B 9730xxxx have hardware bugs that can cause 57 * B step AMD K6 before B 9730xxxx have hardware bugs that can cause
@@ -586,9 +619,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
586 !cpu_has(c, X86_FEATURE_TOPOEXT)) { 619 !cpu_has(c, X86_FEATURE_TOPOEXT)) {
587 u64 val; 620 u64 val;
588 621
589 if (!rdmsrl_amd_safe(0xc0011005, &val)) { 622 if (!rdmsrl_safe(0xc0011005, &val)) {
590 val |= 1ULL << 54; 623 val |= 1ULL << 54;
591 wrmsrl_amd_safe(0xc0011005, val); 624 wrmsrl_safe(0xc0011005, val);
592 rdmsrl(0xc0011005, val); 625 rdmsrl(0xc0011005, val);
593 if (val & (1ULL << 54)) { 626 if (val & (1ULL << 54)) {
594 set_cpu_cap(c, X86_FEATURE_TOPOEXT); 627 set_cpu_cap(c, X86_FEATURE_TOPOEXT);
@@ -679,7 +712,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
679 err = rdmsrl_safe(MSR_AMD64_MCx_MASK(4), &mask); 712 err = rdmsrl_safe(MSR_AMD64_MCx_MASK(4), &mask);
680 if (err == 0) { 713 if (err == 0) {
681 mask |= (1 << 10); 714 mask |= (1 << 10);
682 checking_wrmsrl(MSR_AMD64_MCx_MASK(4), mask); 715 wrmsrl_safe(MSR_AMD64_MCx_MASK(4), mask);
683 } 716 }
684 } 717 }
685 718
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 6b9333b429ba..5bbc082c47ad 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -947,7 +947,7 @@ static void __cpuinit __print_cpu_msr(void)
947 index_max = msr_range_array[i].max; 947 index_max = msr_range_array[i].max;
948 948
949 for (index = index_min; index < index_max; index++) { 949 for (index = index_min; index < index_max; index++) {
950 if (rdmsrl_amd_safe(index, &val)) 950 if (rdmsrl_safe(index, &val))
951 continue; 951 continue;
952 printk(KERN_INFO " MSR%08x: %016llx\n", index, val); 952 printk(KERN_INFO " MSR%08x: %016llx\n", index, val);
953 } 953 }
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index c4706cf9c011..29557aa06dda 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -35,17 +35,6 @@
35 35
36#include "perf_event.h" 36#include "perf_event.h"
37 37
38#if 0
39#undef wrmsrl
40#define wrmsrl(msr, val) \
41do { \
42 trace_printk("wrmsrl(%lx, %lx)\n", (unsigned long)(msr),\
43 (unsigned long)(val)); \
44 native_write_msr((msr), (u32)((u64)(val)), \
45 (u32)((u64)(val) >> 32)); \
46} while (0)
47#endif
48
49struct x86_pmu x86_pmu __read_mostly; 38struct x86_pmu x86_pmu __read_mostly;
50 39
51DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { 40DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
@@ -74,7 +63,7 @@ u64 x86_perf_event_update(struct perf_event *event)
74 int idx = hwc->idx; 63 int idx = hwc->idx;
75 s64 delta; 64 s64 delta;
76 65
77 if (idx == X86_PMC_IDX_FIXED_BTS) 66 if (idx == INTEL_PMC_IDX_FIXED_BTS)
78 return 0; 67 return 0;
79 68
80 /* 69 /*
@@ -86,7 +75,7 @@ u64 x86_perf_event_update(struct perf_event *event)
86 */ 75 */
87again: 76again:
88 prev_raw_count = local64_read(&hwc->prev_count); 77 prev_raw_count = local64_read(&hwc->prev_count);
89 rdmsrl(hwc->event_base, new_raw_count); 78 rdpmcl(hwc->event_base_rdpmc, new_raw_count);
90 79
91 if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, 80 if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
92 new_raw_count) != prev_raw_count) 81 new_raw_count) != prev_raw_count)
@@ -189,7 +178,7 @@ static void release_pmc_hardware(void) {}
189 178
190static bool check_hw_exists(void) 179static bool check_hw_exists(void)
191{ 180{
192 u64 val, val_new = 0; 181 u64 val, val_new = ~0;
193 int i, reg, ret = 0; 182 int i, reg, ret = 0;
194 183
195 /* 184 /*
@@ -222,8 +211,9 @@ static bool check_hw_exists(void)
222 * that don't trap on the MSR access and always return 0s. 211 * that don't trap on the MSR access and always return 0s.
223 */ 212 */
224 val = 0xabcdUL; 213 val = 0xabcdUL;
225 ret = checking_wrmsrl(x86_pmu_event_addr(0), val); 214 reg = x86_pmu_event_addr(0);
226 ret |= rdmsrl_safe(x86_pmu_event_addr(0), &val_new); 215 ret = wrmsrl_safe(reg, val);
216 ret |= rdmsrl_safe(reg, &val_new);
227 if (ret || val != val_new) 217 if (ret || val != val_new)
228 goto msr_fail; 218 goto msr_fail;
229 219
@@ -240,6 +230,7 @@ bios_fail:
240 230
241msr_fail: 231msr_fail:
242 printk(KERN_CONT "Broken PMU hardware detected, using software events only.\n"); 232 printk(KERN_CONT "Broken PMU hardware detected, using software events only.\n");
233 printk(KERN_ERR "Failed to access perfctr msr (MSR %x is %Lx)\n", reg, val_new);
243 234
244 return false; 235 return false;
245} 236}
@@ -388,7 +379,7 @@ int x86_pmu_hw_config(struct perf_event *event)
388 int precise = 0; 379 int precise = 0;
389 380
390 /* Support for constant skid */ 381 /* Support for constant skid */
391 if (x86_pmu.pebs_active) { 382 if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) {
392 precise++; 383 precise++;
393 384
394 /* Support for IP fixup */ 385 /* Support for IP fixup */
@@ -637,8 +628,8 @@ static bool __perf_sched_find_counter(struct perf_sched *sched)
637 c = sched->constraints[sched->state.event]; 628 c = sched->constraints[sched->state.event];
638 629
639 /* Prefer fixed purpose counters */ 630 /* Prefer fixed purpose counters */
640 if (x86_pmu.num_counters_fixed) { 631 if (c->idxmsk64 & (~0ULL << INTEL_PMC_IDX_FIXED)) {
641 idx = X86_PMC_IDX_FIXED; 632 idx = INTEL_PMC_IDX_FIXED;
642 for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_MAX) { 633 for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_MAX) {
643 if (!__test_and_set_bit(idx, sched->state.used)) 634 if (!__test_and_set_bit(idx, sched->state.used))
644 goto done; 635 goto done;
@@ -646,7 +637,7 @@ static bool __perf_sched_find_counter(struct perf_sched *sched)
646 } 637 }
647 /* Grab the first unused counter starting with idx */ 638 /* Grab the first unused counter starting with idx */
648 idx = sched->state.counter; 639 idx = sched->state.counter;
649 for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_FIXED) { 640 for_each_set_bit_from(idx, c->idxmsk, INTEL_PMC_IDX_FIXED) {
650 if (!__test_and_set_bit(idx, sched->state.used)) 641 if (!__test_and_set_bit(idx, sched->state.used))
651 goto done; 642 goto done;
652 } 643 }
@@ -704,8 +695,8 @@ static bool perf_sched_next_event(struct perf_sched *sched)
704/* 695/*
705 * Assign a counter for each event. 696 * Assign a counter for each event.
706 */ 697 */
707static int perf_assign_events(struct event_constraint **constraints, int n, 698int perf_assign_events(struct event_constraint **constraints, int n,
708 int wmin, int wmax, int *assign) 699 int wmin, int wmax, int *assign)
709{ 700{
710 struct perf_sched sched; 701 struct perf_sched sched;
711 702
@@ -824,15 +815,17 @@ static inline void x86_assign_hw_event(struct perf_event *event,
824 hwc->last_cpu = smp_processor_id(); 815 hwc->last_cpu = smp_processor_id();
825 hwc->last_tag = ++cpuc->tags[i]; 816 hwc->last_tag = ++cpuc->tags[i];
826 817
827 if (hwc->idx == X86_PMC_IDX_FIXED_BTS) { 818 if (hwc->idx == INTEL_PMC_IDX_FIXED_BTS) {
828 hwc->config_base = 0; 819 hwc->config_base = 0;
829 hwc->event_base = 0; 820 hwc->event_base = 0;
830 } else if (hwc->idx >= X86_PMC_IDX_FIXED) { 821 } else if (hwc->idx >= INTEL_PMC_IDX_FIXED) {
831 hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL; 822 hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL;
832 hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0 + (hwc->idx - X86_PMC_IDX_FIXED); 823 hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0 + (hwc->idx - INTEL_PMC_IDX_FIXED);
824 hwc->event_base_rdpmc = (hwc->idx - INTEL_PMC_IDX_FIXED) | 1<<30;
833 } else { 825 } else {
834 hwc->config_base = x86_pmu_config_addr(hwc->idx); 826 hwc->config_base = x86_pmu_config_addr(hwc->idx);
835 hwc->event_base = x86_pmu_event_addr(hwc->idx); 827 hwc->event_base = x86_pmu_event_addr(hwc->idx);
828 hwc->event_base_rdpmc = hwc->idx;
836 } 829 }
837} 830}
838 831
@@ -930,7 +923,7 @@ int x86_perf_event_set_period(struct perf_event *event)
930 s64 period = hwc->sample_period; 923 s64 period = hwc->sample_period;
931 int ret = 0, idx = hwc->idx; 924 int ret = 0, idx = hwc->idx;
932 925
933 if (idx == X86_PMC_IDX_FIXED_BTS) 926 if (idx == INTEL_PMC_IDX_FIXED_BTS)
934 return 0; 927 return 0;
935 928
936 /* 929 /*
@@ -1316,7 +1309,6 @@ static struct attribute_group x86_pmu_format_group = {
1316static int __init init_hw_perf_events(void) 1309static int __init init_hw_perf_events(void)
1317{ 1310{
1318 struct x86_pmu_quirk *quirk; 1311 struct x86_pmu_quirk *quirk;
1319 struct event_constraint *c;
1320 int err; 1312 int err;
1321 1313
1322 pr_info("Performance Events: "); 1314 pr_info("Performance Events: ");
@@ -1347,21 +1339,8 @@ static int __init init_hw_perf_events(void)
1347 for (quirk = x86_pmu.quirks; quirk; quirk = quirk->next) 1339 for (quirk = x86_pmu.quirks; quirk; quirk = quirk->next)
1348 quirk->func(); 1340 quirk->func();
1349 1341
1350 if (x86_pmu.num_counters > X86_PMC_MAX_GENERIC) { 1342 if (!x86_pmu.intel_ctrl)
1351 WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!", 1343 x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
1352 x86_pmu.num_counters, X86_PMC_MAX_GENERIC);
1353 x86_pmu.num_counters = X86_PMC_MAX_GENERIC;
1354 }
1355 x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
1356
1357 if (x86_pmu.num_counters_fixed > X86_PMC_MAX_FIXED) {
1358 WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",
1359 x86_pmu.num_counters_fixed, X86_PMC_MAX_FIXED);
1360 x86_pmu.num_counters_fixed = X86_PMC_MAX_FIXED;
1361 }
1362
1363 x86_pmu.intel_ctrl |=
1364 ((1LL << x86_pmu.num_counters_fixed)-1) << X86_PMC_IDX_FIXED;
1365 1344
1366 perf_events_lapic_init(); 1345 perf_events_lapic_init();
1367 register_nmi_handler(NMI_LOCAL, perf_event_nmi_handler, 0, "PMI"); 1346 register_nmi_handler(NMI_LOCAL, perf_event_nmi_handler, 0, "PMI");
@@ -1370,22 +1349,6 @@ static int __init init_hw_perf_events(void)
1370 __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1, 1349 __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1,
1371 0, x86_pmu.num_counters, 0); 1350 0, x86_pmu.num_counters, 0);
1372 1351
1373 if (x86_pmu.event_constraints) {
1374 /*
1375 * event on fixed counter2 (REF_CYCLES) only works on this
1376 * counter, so do not extend mask to generic counters
1377 */
1378 for_each_event_constraint(c, x86_pmu.event_constraints) {
1379 if (c->cmask != X86_RAW_EVENT_MASK
1380 || c->idxmsk64 == X86_PMC_MSK_FIXED_REF_CYCLES) {
1381 continue;
1382 }
1383
1384 c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1;
1385 c->weight += x86_pmu.num_counters;
1386 }
1387 }
1388
1389 x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */ 1352 x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */
1390 x86_pmu_format_group.attrs = x86_pmu.format_attrs; 1353 x86_pmu_format_group.attrs = x86_pmu.format_attrs;
1391 1354
@@ -1620,8 +1583,8 @@ static int x86_pmu_event_idx(struct perf_event *event)
1620 if (!x86_pmu.attr_rdpmc) 1583 if (!x86_pmu.attr_rdpmc)
1621 return 0; 1584 return 0;
1622 1585
1623 if (x86_pmu.num_counters_fixed && idx >= X86_PMC_IDX_FIXED) { 1586 if (x86_pmu.num_counters_fixed && idx >= INTEL_PMC_IDX_FIXED) {
1624 idx -= X86_PMC_IDX_FIXED; 1587 idx -= INTEL_PMC_IDX_FIXED;
1625 idx |= 1 << 30; 1588 idx |= 1 << 30;
1626 } 1589 }
1627 1590
@@ -1649,7 +1612,12 @@ static ssize_t set_attr_rdpmc(struct device *cdev,
1649 struct device_attribute *attr, 1612 struct device_attribute *attr,
1650 const char *buf, size_t count) 1613 const char *buf, size_t count)
1651{ 1614{
1652 unsigned long val = simple_strtoul(buf, NULL, 0); 1615 unsigned long val;
1616 ssize_t ret;
1617
1618 ret = kstrtoul(buf, 0, &val);
1619 if (ret)
1620 return ret;
1653 1621
1654 if (!!val != !!x86_pmu.attr_rdpmc) { 1622 if (!!val != !!x86_pmu.attr_rdpmc) {
1655 x86_pmu.attr_rdpmc = !!val; 1623 x86_pmu.attr_rdpmc = !!val;
@@ -1682,13 +1650,20 @@ static void x86_pmu_flush_branch_stack(void)
1682 x86_pmu.flush_branch_stack(); 1650 x86_pmu.flush_branch_stack();
1683} 1651}
1684 1652
1653void perf_check_microcode(void)
1654{
1655 if (x86_pmu.check_microcode)
1656 x86_pmu.check_microcode();
1657}
1658EXPORT_SYMBOL_GPL(perf_check_microcode);
1659
1685static struct pmu pmu = { 1660static struct pmu pmu = {
1686 .pmu_enable = x86_pmu_enable, 1661 .pmu_enable = x86_pmu_enable,
1687 .pmu_disable = x86_pmu_disable, 1662 .pmu_disable = x86_pmu_disable,
1688 1663
1689 .attr_groups = x86_pmu_attr_groups, 1664 .attr_groups = x86_pmu_attr_groups,
1690 1665
1691 .event_init = x86_pmu_event_init, 1666 .event_init = x86_pmu_event_init,
1692 1667
1693 .add = x86_pmu_add, 1668 .add = x86_pmu_add,
1694 .del = x86_pmu_del, 1669 .del = x86_pmu_del,
@@ -1696,11 +1671,11 @@ static struct pmu pmu = {
1696 .stop = x86_pmu_stop, 1671 .stop = x86_pmu_stop,
1697 .read = x86_pmu_read, 1672 .read = x86_pmu_read,
1698 1673
1699 .start_txn = x86_pmu_start_txn, 1674 .start_txn = x86_pmu_start_txn,
1700 .cancel_txn = x86_pmu_cancel_txn, 1675 .cancel_txn = x86_pmu_cancel_txn,
1701 .commit_txn = x86_pmu_commit_txn, 1676 .commit_txn = x86_pmu_commit_txn,
1702 1677
1703 .event_idx = x86_pmu_event_idx, 1678 .event_idx = x86_pmu_event_idx,
1704 .flush_branch_stack = x86_pmu_flush_branch_stack, 1679 .flush_branch_stack = x86_pmu_flush_branch_stack,
1705}; 1680};
1706 1681
@@ -1863,7 +1838,7 @@ unsigned long perf_misc_flags(struct pt_regs *regs)
1863 else 1838 else
1864 misc |= PERF_RECORD_MISC_GUEST_KERNEL; 1839 misc |= PERF_RECORD_MISC_GUEST_KERNEL;
1865 } else { 1840 } else {
1866 if (user_mode(regs)) 1841 if (!kernel_ip(regs->ip))
1867 misc |= PERF_RECORD_MISC_USER; 1842 misc |= PERF_RECORD_MISC_USER;
1868 else 1843 else
1869 misc |= PERF_RECORD_MISC_KERNEL; 1844 misc |= PERF_RECORD_MISC_KERNEL;
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 7241e2fc3c17..a15df4be151f 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -14,6 +14,18 @@
14 14
15#include <linux/perf_event.h> 15#include <linux/perf_event.h>
16 16
17#if 0
18#undef wrmsrl
19#define wrmsrl(msr, val) \
20do { \
21 unsigned int _msr = (msr); \
22 u64 _val = (val); \
23 trace_printk("wrmsrl(%x, %Lx)\n", (unsigned int)(_msr), \
24 (unsigned long long)(_val)); \
25 native_write_msr((_msr), (u32)(_val), (u32)(_val >> 32)); \
26} while (0)
27#endif
28
17/* 29/*
18 * | NHM/WSM | SNB | 30 * | NHM/WSM | SNB |
19 * register ------------------------------- 31 * register -------------------------------
@@ -57,7 +69,7 @@ struct amd_nb {
57}; 69};
58 70
59/* The maximal number of PEBS events: */ 71/* The maximal number of PEBS events: */
60#define MAX_PEBS_EVENTS 4 72#define MAX_PEBS_EVENTS 8
61 73
62/* 74/*
63 * A debug store configuration. 75 * A debug store configuration.
@@ -349,6 +361,8 @@ struct x86_pmu {
349 void (*cpu_starting)(int cpu); 361 void (*cpu_starting)(int cpu);
350 void (*cpu_dying)(int cpu); 362 void (*cpu_dying)(int cpu);
351 void (*cpu_dead)(int cpu); 363 void (*cpu_dead)(int cpu);
364
365 void (*check_microcode)(void);
352 void (*flush_branch_stack)(void); 366 void (*flush_branch_stack)(void);
353 367
354 /* 368 /*
@@ -360,12 +374,16 @@ struct x86_pmu {
360 /* 374 /*
361 * Intel DebugStore bits 375 * Intel DebugStore bits
362 */ 376 */
363 int bts, pebs; 377 int bts :1,
364 int bts_active, pebs_active; 378 bts_active :1,
379 pebs :1,
380 pebs_active :1,
381 pebs_broken :1;
365 int pebs_record_size; 382 int pebs_record_size;
366 void (*drain_pebs)(struct pt_regs *regs); 383 void (*drain_pebs)(struct pt_regs *regs);
367 struct event_constraint *pebs_constraints; 384 struct event_constraint *pebs_constraints;
368 void (*pebs_aliases)(struct perf_event *event); 385 void (*pebs_aliases)(struct perf_event *event);
386 int max_pebs_events;
369 387
370 /* 388 /*
371 * Intel LBR 389 * Intel LBR
@@ -468,6 +486,8 @@ static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc,
468 486
469void x86_pmu_enable_all(int added); 487void x86_pmu_enable_all(int added);
470 488
489int perf_assign_events(struct event_constraint **constraints, int n,
490 int wmin, int wmax, int *assign);
471int 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);
472 492
473void x86_pmu_stop(struct perf_event *event, int flags); 493void x86_pmu_stop(struct perf_event *event, int flags);
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c
index 11a4eb9131d5..4528ae7b6ec4 100644
--- a/arch/x86/kernel/cpu/perf_event_amd.c
+++ b/arch/x86/kernel/cpu/perf_event_amd.c
@@ -366,7 +366,7 @@ static void amd_pmu_cpu_starting(int cpu)
366 366
367 cpuc->perf_ctr_virt_mask = AMD_PERFMON_EVENTSEL_HOSTONLY; 367 cpuc->perf_ctr_virt_mask = AMD_PERFMON_EVENTSEL_HOSTONLY;
368 368
369 if (boot_cpu_data.x86_max_cores < 2 || boot_cpu_data.x86 == 0x15) 369 if (boot_cpu_data.x86_max_cores < 2)
370 return; 370 return;
371 371
372 nb_id = amd_get_nb_id(cpu); 372 nb_id = amd_get_nb_id(cpu);
@@ -422,35 +422,6 @@ static struct attribute *amd_format_attr[] = {
422 NULL, 422 NULL,
423}; 423};
424 424
425static __initconst const struct x86_pmu amd_pmu = {
426 .name = "AMD",
427 .handle_irq = x86_pmu_handle_irq,
428 .disable_all = x86_pmu_disable_all,
429 .enable_all = x86_pmu_enable_all,
430 .enable = x86_pmu_enable_event,
431 .disable = x86_pmu_disable_event,
432 .hw_config = amd_pmu_hw_config,
433 .schedule_events = x86_schedule_events,
434 .eventsel = MSR_K7_EVNTSEL0,
435 .perfctr = MSR_K7_PERFCTR0,
436 .event_map = amd_pmu_event_map,
437 .max_events = ARRAY_SIZE(amd_perfmon_event_map),
438 .num_counters = AMD64_NUM_COUNTERS,
439 .cntval_bits = 48,
440 .cntval_mask = (1ULL << 48) - 1,
441 .apic = 1,
442 /* use highest bit to detect overflow */
443 .max_period = (1ULL << 47) - 1,
444 .get_event_constraints = amd_get_event_constraints,
445 .put_event_constraints = amd_put_event_constraints,
446
447 .format_attrs = amd_format_attr,
448
449 .cpu_prepare = amd_pmu_cpu_prepare,
450 .cpu_starting = amd_pmu_cpu_starting,
451 .cpu_dead = amd_pmu_cpu_dead,
452};
453
454/* AMD Family 15h */ 425/* AMD Family 15h */
455 426
456#define AMD_EVENT_TYPE_MASK 0x000000F0ULL 427#define AMD_EVENT_TYPE_MASK 0x000000F0ULL
@@ -597,8 +568,8 @@ amd_get_event_constraints_f15h(struct cpu_hw_events *cpuc, struct perf_event *ev
597 } 568 }
598} 569}
599 570
600static __initconst const struct x86_pmu amd_pmu_f15h = { 571static __initconst const struct x86_pmu amd_pmu = {
601 .name = "AMD Family 15h", 572 .name = "AMD",
602 .handle_irq = x86_pmu_handle_irq, 573 .handle_irq = x86_pmu_handle_irq,
603 .disable_all = x86_pmu_disable_all, 574 .disable_all = x86_pmu_disable_all,
604 .enable_all = x86_pmu_enable_all, 575 .enable_all = x86_pmu_enable_all,
@@ -606,50 +577,68 @@ static __initconst const struct x86_pmu amd_pmu_f15h = {
606 .disable = x86_pmu_disable_event, 577 .disable = x86_pmu_disable_event,
607 .hw_config = amd_pmu_hw_config, 578 .hw_config = amd_pmu_hw_config,
608 .schedule_events = x86_schedule_events, 579 .schedule_events = x86_schedule_events,
609 .eventsel = MSR_F15H_PERF_CTL, 580 .eventsel = MSR_K7_EVNTSEL0,
610 .perfctr = MSR_F15H_PERF_CTR, 581 .perfctr = MSR_K7_PERFCTR0,
611 .event_map = amd_pmu_event_map, 582 .event_map = amd_pmu_event_map,
612 .max_events = ARRAY_SIZE(amd_perfmon_event_map), 583 .max_events = ARRAY_SIZE(amd_perfmon_event_map),
613 .num_counters = AMD64_NUM_COUNTERS_F15H, 584 .num_counters = AMD64_NUM_COUNTERS,
614 .cntval_bits = 48, 585 .cntval_bits = 48,
615 .cntval_mask = (1ULL << 48) - 1, 586 .cntval_mask = (1ULL << 48) - 1,
616 .apic = 1, 587 .apic = 1,
617 /* use highest bit to detect overflow */ 588 /* use highest bit to detect overflow */
618 .max_period = (1ULL << 47) - 1, 589 .max_period = (1ULL << 47) - 1,
619 .get_event_constraints = amd_get_event_constraints_f15h, 590 .get_event_constraints = amd_get_event_constraints,
620 /* nortbridge counters not yet implemented: */
621#if 0
622 .put_event_constraints = amd_put_event_constraints, 591 .put_event_constraints = amd_put_event_constraints,
623 592
593 .format_attrs = amd_format_attr,
594
624 .cpu_prepare = amd_pmu_cpu_prepare, 595 .cpu_prepare = amd_pmu_cpu_prepare,
625 .cpu_dead = amd_pmu_cpu_dead,
626#endif
627 .cpu_starting = amd_pmu_cpu_starting, 596 .cpu_starting = amd_pmu_cpu_starting,
628 .format_attrs = amd_format_attr, 597 .cpu_dead = amd_pmu_cpu_dead,
629}; 598};
630 599
600static int setup_event_constraints(void)
601{
602 if (boot_cpu_data.x86 >= 0x15)
603 x86_pmu.get_event_constraints = amd_get_event_constraints_f15h;
604 return 0;
605}
606
607static int setup_perfctr_core(void)
608{
609 if (!cpu_has_perfctr_core) {
610 WARN(x86_pmu.get_event_constraints == amd_get_event_constraints_f15h,
611 KERN_ERR "Odd, counter constraints enabled but no core perfctrs detected!");
612 return -ENODEV;
613 }
614
615 WARN(x86_pmu.get_event_constraints == amd_get_event_constraints,
616 KERN_ERR "hw perf events core counters need constraints handler!");
617
618 /*
619 * If core performance counter extensions exists, we must use
620 * MSR_F15H_PERF_CTL/MSR_F15H_PERF_CTR msrs. See also
621 * x86_pmu_addr_offset().
622 */
623 x86_pmu.eventsel = MSR_F15H_PERF_CTL;
624 x86_pmu.perfctr = MSR_F15H_PERF_CTR;
625 x86_pmu.num_counters = AMD64_NUM_COUNTERS_CORE;
626
627 printk(KERN_INFO "perf: AMD core performance counters detected\n");
628
629 return 0;
630}
631
631__init int amd_pmu_init(void) 632__init int amd_pmu_init(void)
632{ 633{
633 /* Performance-monitoring supported from K7 and later: */ 634 /* Performance-monitoring supported from K7 and later: */
634 if (boot_cpu_data.x86 < 6) 635 if (boot_cpu_data.x86 < 6)
635 return -ENODEV; 636 return -ENODEV;
636 637
637 /* 638 x86_pmu = amd_pmu;
638 * If core performance counter extensions exists, it must be 639
639 * family 15h, otherwise fail. See x86_pmu_addr_offset(). 640 setup_event_constraints();
640 */ 641 setup_perfctr_core();
641 switch (boot_cpu_data.x86) {
642 case 0x15:
643 if (!cpu_has_perfctr_core)
644 return -ENODEV;
645 x86_pmu = amd_pmu_f15h;
646 break;
647 default:
648 if (cpu_has_perfctr_core)
649 return -ENODEV;
650 x86_pmu = amd_pmu;
651 break;
652 }
653 642
654 /* Events are common for all AMDs */ 643 /* Events are common for all AMDs */
655 memcpy(hw_cache_event_ids, amd_hw_cache_event_ids, 644 memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 187c294bc658..1f4c8add6759 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -21,14 +21,14 @@
21 */ 21 */
22static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly = 22static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly =
23{ 23{
24 [PERF_COUNT_HW_CPU_CYCLES] = 0x003c, 24 [PERF_COUNT_HW_CPU_CYCLES] = 0x003c,
25 [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, 25 [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
26 [PERF_COUNT_HW_CACHE_REFERENCES] = 0x4f2e, 26 [PERF_COUNT_HW_CACHE_REFERENCES] = 0x4f2e,
27 [PERF_COUNT_HW_CACHE_MISSES] = 0x412e, 27 [PERF_COUNT_HW_CACHE_MISSES] = 0x412e,
28 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, 28 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4,
29 [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, 29 [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5,
30 [PERF_COUNT_HW_BUS_CYCLES] = 0x013c, 30 [PERF_COUNT_HW_BUS_CYCLES] = 0x013c,
31 [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding */ 31 [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding */
32}; 32};
33 33
34static struct event_constraint intel_core_event_constraints[] __read_mostly = 34static struct event_constraint intel_core_event_constraints[] __read_mostly =
@@ -747,7 +747,7 @@ static void intel_pmu_disable_all(void)
747 747
748 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0); 748 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
749 749
750 if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) 750 if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask))
751 intel_pmu_disable_bts(); 751 intel_pmu_disable_bts();
752 752
753 intel_pmu_pebs_disable_all(); 753 intel_pmu_pebs_disable_all();
@@ -763,9 +763,9 @@ static void intel_pmu_enable_all(int added)
763 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 763 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL,
764 x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask); 764 x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask);
765 765
766 if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) { 766 if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
767 struct perf_event *event = 767 struct perf_event *event =
768 cpuc->events[X86_PMC_IDX_FIXED_BTS]; 768 cpuc->events[INTEL_PMC_IDX_FIXED_BTS];
769 769
770 if (WARN_ON_ONCE(!event)) 770 if (WARN_ON_ONCE(!event))
771 return; 771 return;
@@ -871,7 +871,7 @@ static inline void intel_pmu_ack_status(u64 ack)
871 871
872static void intel_pmu_disable_fixed(struct hw_perf_event *hwc) 872static void intel_pmu_disable_fixed(struct hw_perf_event *hwc)
873{ 873{
874 int idx = hwc->idx - X86_PMC_IDX_FIXED; 874 int idx = hwc->idx - INTEL_PMC_IDX_FIXED;
875 u64 ctrl_val, mask; 875 u64 ctrl_val, mask;
876 876
877 mask = 0xfULL << (idx * 4); 877 mask = 0xfULL << (idx * 4);
@@ -886,7 +886,7 @@ static void intel_pmu_disable_event(struct perf_event *event)
886 struct hw_perf_event *hwc = &event->hw; 886 struct hw_perf_event *hwc = &event->hw;
887 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 887 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
888 888
889 if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) { 889 if (unlikely(hwc->idx == INTEL_PMC_IDX_FIXED_BTS)) {
890 intel_pmu_disable_bts(); 890 intel_pmu_disable_bts();
891 intel_pmu_drain_bts_buffer(); 891 intel_pmu_drain_bts_buffer();
892 return; 892 return;
@@ -915,7 +915,7 @@ static void intel_pmu_disable_event(struct perf_event *event)
915 915
916static void intel_pmu_enable_fixed(struct hw_perf_event *hwc) 916static void intel_pmu_enable_fixed(struct hw_perf_event *hwc)
917{ 917{
918 int idx = hwc->idx - X86_PMC_IDX_FIXED; 918 int idx = hwc->idx - INTEL_PMC_IDX_FIXED;
919 u64 ctrl_val, bits, mask; 919 u64 ctrl_val, bits, mask;
920 920
921 /* 921 /*
@@ -949,7 +949,7 @@ static void intel_pmu_enable_event(struct perf_event *event)
949 struct hw_perf_event *hwc = &event->hw; 949 struct hw_perf_event *hwc = &event->hw;
950 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 950 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
951 951
952 if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) { 952 if (unlikely(hwc->idx == INTEL_PMC_IDX_FIXED_BTS)) {
953 if (!__this_cpu_read(cpu_hw_events.enabled)) 953 if (!__this_cpu_read(cpu_hw_events.enabled))
954 return; 954 return;
955 955
@@ -1003,11 +1003,11 @@ static void intel_pmu_reset(void)
1003 printk("clearing PMU state on CPU#%d\n", smp_processor_id()); 1003 printk("clearing PMU state on CPU#%d\n", smp_processor_id());
1004 1004
1005 for (idx = 0; idx < x86_pmu.num_counters; idx++) { 1005 for (idx = 0; idx < x86_pmu.num_counters; idx++) {
1006 checking_wrmsrl(x86_pmu_config_addr(idx), 0ull); 1006 wrmsrl_safe(x86_pmu_config_addr(idx), 0ull);
1007 checking_wrmsrl(x86_pmu_event_addr(idx), 0ull); 1007 wrmsrl_safe(x86_pmu_event_addr(idx), 0ull);
1008 } 1008 }
1009 for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) 1009 for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++)
1010 checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull); 1010 wrmsrl_safe(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
1011 1011
1012 if (ds) 1012 if (ds)
1013 ds->bts_index = ds->bts_buffer_base; 1013 ds->bts_index = ds->bts_buffer_base;
@@ -1712,11 +1712,56 @@ static __init void intel_clovertown_quirk(void)
1712 x86_pmu.pebs_constraints = NULL; 1712 x86_pmu.pebs_constraints = NULL;
1713} 1713}
1714 1714
1715static int intel_snb_pebs_broken(int cpu)
1716{
1717 u32 rev = UINT_MAX; /* default to broken for unknown models */
1718
1719 switch (cpu_data(cpu).x86_model) {
1720 case 42: /* SNB */
1721 rev = 0x28;
1722 break;
1723
1724 case 45: /* SNB-EP */
1725 switch (cpu_data(cpu).x86_mask) {
1726 case 6: rev = 0x618; break;
1727 case 7: rev = 0x70c; break;
1728 }
1729 }
1730
1731 return (cpu_data(cpu).microcode < rev);
1732}
1733
1734static void intel_snb_check_microcode(void)
1735{
1736 int pebs_broken = 0;
1737 int cpu;
1738
1739 get_online_cpus();
1740 for_each_online_cpu(cpu) {
1741 if ((pebs_broken = intel_snb_pebs_broken(cpu)))
1742 break;
1743 }
1744 put_online_cpus();
1745
1746 if (pebs_broken == x86_pmu.pebs_broken)
1747 return;
1748
1749 /*
1750 * Serialized by the microcode lock..
1751 */
1752 if (x86_pmu.pebs_broken) {
1753 pr_info("PEBS enabled due to microcode update\n");
1754 x86_pmu.pebs_broken = 0;
1755 } else {
1756 pr_info("PEBS disabled due to CPU errata, please upgrade microcode\n");
1757 x86_pmu.pebs_broken = 1;
1758 }
1759}
1760
1715static __init void intel_sandybridge_quirk(void) 1761static __init void intel_sandybridge_quirk(void)
1716{ 1762{
1717 printk(KERN_WARNING "PEBS disabled due to CPU errata.\n"); 1763 x86_pmu.check_microcode = intel_snb_check_microcode;
1718 x86_pmu.pebs = 0; 1764 intel_snb_check_microcode();
1719 x86_pmu.pebs_constraints = NULL;
1720} 1765}
1721 1766
1722static const struct { int id; char *name; } intel_arch_events_map[] __initconst = { 1767static const struct { int id; char *name; } intel_arch_events_map[] __initconst = {
@@ -1765,6 +1810,7 @@ __init int intel_pmu_init(void)
1765 union cpuid10_edx edx; 1810 union cpuid10_edx edx;
1766 union cpuid10_eax eax; 1811 union cpuid10_eax eax;
1767 union cpuid10_ebx ebx; 1812 union cpuid10_ebx ebx;
1813 struct event_constraint *c;
1768 unsigned int unused; 1814 unsigned int unused;
1769 int version; 1815 int version;
1770 1816
@@ -1800,6 +1846,8 @@ __init int intel_pmu_init(void)
1800 x86_pmu.events_maskl = ebx.full; 1846 x86_pmu.events_maskl = ebx.full;
1801 x86_pmu.events_mask_len = eax.split.mask_length; 1847 x86_pmu.events_mask_len = eax.split.mask_length;
1802 1848
1849 x86_pmu.max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters);
1850
1803 /* 1851 /*
1804 * Quirk: v2 perfmon does not report fixed-purpose events, so 1852 * Quirk: v2 perfmon does not report fixed-purpose events, so
1805 * assume at least 3 events: 1853 * assume at least 3 events:
@@ -1951,5 +1999,37 @@ __init int intel_pmu_init(void)
1951 } 1999 }
1952 } 2000 }
1953 2001
2002 if (x86_pmu.num_counters > INTEL_PMC_MAX_GENERIC) {
2003 WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
2004 x86_pmu.num_counters, INTEL_PMC_MAX_GENERIC);
2005 x86_pmu.num_counters = INTEL_PMC_MAX_GENERIC;
2006 }
2007 x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
2008
2009 if (x86_pmu.num_counters_fixed > INTEL_PMC_MAX_FIXED) {
2010 WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",
2011 x86_pmu.num_counters_fixed, INTEL_PMC_MAX_FIXED);
2012 x86_pmu.num_counters_fixed = INTEL_PMC_MAX_FIXED;
2013 }
2014
2015 x86_pmu.intel_ctrl |=
2016 ((1LL << x86_pmu.num_counters_fixed)-1) << INTEL_PMC_IDX_FIXED;
2017
2018 if (x86_pmu.event_constraints) {
2019 /*
2020 * event on fixed counter2 (REF_CYCLES) only works on this
2021 * counter, so do not extend mask to generic counters
2022 */
2023 for_each_event_constraint(c, x86_pmu.event_constraints) {
2024 if (c->cmask != X86_RAW_EVENT_MASK
2025 || c->idxmsk64 == INTEL_PMC_MSK_FIXED_REF_CYCLES) {
2026 continue;
2027 }
2028
2029 c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1;
2030 c->weight += x86_pmu.num_counters;
2031 }
2032 }
2033
1954 return 0; 2034 return 0;
1955} 2035}
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index 35e2192df9f4..629ae0b7ad90 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -248,7 +248,7 @@ void reserve_ds_buffers(void)
248 */ 248 */
249 249
250struct event_constraint bts_constraint = 250struct event_constraint bts_constraint =
251 EVENT_CONSTRAINT(0, 1ULL << X86_PMC_IDX_FIXED_BTS, 0); 251 EVENT_CONSTRAINT(0, 1ULL << INTEL_PMC_IDX_FIXED_BTS, 0);
252 252
253void intel_pmu_enable_bts(u64 config) 253void intel_pmu_enable_bts(u64 config)
254{ 254{
@@ -295,7 +295,7 @@ int intel_pmu_drain_bts_buffer(void)
295 u64 to; 295 u64 to;
296 u64 flags; 296 u64 flags;
297 }; 297 };
298 struct perf_event *event = cpuc->events[X86_PMC_IDX_FIXED_BTS]; 298 struct perf_event *event = cpuc->events[INTEL_PMC_IDX_FIXED_BTS];
299 struct bts_record *at, *top; 299 struct bts_record *at, *top;
300 struct perf_output_handle handle; 300 struct perf_output_handle handle;
301 struct perf_event_header header; 301 struct perf_event_header header;
@@ -620,7 +620,7 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
620 * Should not happen, we program the threshold at 1 and do not 620 * Should not happen, we program the threshold at 1 and do not
621 * set a reset value. 621 * set a reset value.
622 */ 622 */
623 WARN_ON_ONCE(n > 1); 623 WARN_ONCE(n > 1, "bad leftover pebs %d\n", n);
624 at += n - 1; 624 at += n - 1;
625 625
626 __intel_pmu_pebs_event(event, iregs, at); 626 __intel_pmu_pebs_event(event, iregs, at);
@@ -651,10 +651,10 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
651 * Should not happen, we program the threshold at 1 and do not 651 * Should not happen, we program the threshold at 1 and do not
652 * set a reset value. 652 * set a reset value.
653 */ 653 */
654 WARN_ON_ONCE(n > MAX_PEBS_EVENTS); 654 WARN_ONCE(n > x86_pmu.max_pebs_events, "Unexpected number of pebs records %d\n", n);
655 655
656 for ( ; at < top; at++) { 656 for ( ; at < top; at++) {
657 for_each_set_bit(bit, (unsigned long *)&at->status, MAX_PEBS_EVENTS) { 657 for_each_set_bit(bit, (unsigned long *)&at->status, x86_pmu.max_pebs_events) {
658 event = cpuc->events[bit]; 658 event = cpuc->events[bit];
659 if (!test_bit(bit, cpuc->active_mask)) 659 if (!test_bit(bit, cpuc->active_mask))
660 continue; 660 continue;
@@ -670,7 +670,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
670 break; 670 break;
671 } 671 }
672 672
673 if (!event || bit >= MAX_PEBS_EVENTS) 673 if (!event || bit >= x86_pmu.max_pebs_events)
674 continue; 674 continue;
675 675
676 __intel_pmu_pebs_event(event, iregs, at); 676 __intel_pmu_pebs_event(event, iregs, at);
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
new file mode 100644
index 000000000000..19faffc60886
--- /dev/null
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
@@ -0,0 +1,1850 @@
1#include "perf_event_intel_uncore.h"
2
3static struct intel_uncore_type *empty_uncore[] = { NULL, };
4static struct intel_uncore_type **msr_uncores = empty_uncore;
5static struct intel_uncore_type **pci_uncores = empty_uncore;
6/* pci bus to socket mapping */
7static int pcibus_to_physid[256] = { [0 ... 255] = -1, };
8
9static DEFINE_RAW_SPINLOCK(uncore_box_lock);
10
11/* mask of cpus that collect uncore events */
12static cpumask_t uncore_cpu_mask;
13
14/* constraint for the fixed counter */
15static struct event_constraint constraint_fixed =
16 EVENT_CONSTRAINT(~0ULL, 1 << UNCORE_PMC_IDX_FIXED, ~0ULL);
17static struct event_constraint constraint_empty =
18 EVENT_CONSTRAINT(0, 0, 0);
19
20DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
21DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
22DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
23DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19");
24DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
25DEFINE_UNCORE_FORMAT_ATTR(cmask5, cmask, "config:24-28");
26DEFINE_UNCORE_FORMAT_ATTR(cmask8, cmask, "config:24-31");
27DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31");
28DEFINE_UNCORE_FORMAT_ATTR(thresh5, thresh, "config:24-28");
29DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15");
30DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30");
31DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51");
32DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4");
33DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17");
34DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22");
35DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31");
36DEFINE_UNCORE_FORMAT_ATTR(filter_brand0, filter_brand0, "config1:0-7");
37DEFINE_UNCORE_FORMAT_ATTR(filter_brand1, filter_brand1, "config1:8-15");
38DEFINE_UNCORE_FORMAT_ATTR(filter_brand2, filter_brand2, "config1:16-23");
39DEFINE_UNCORE_FORMAT_ATTR(filter_brand3, filter_brand3, "config1:24-31");
40
41/* Sandy Bridge-EP uncore support */
42static struct intel_uncore_type snbep_uncore_cbox;
43static struct intel_uncore_type snbep_uncore_pcu;
44
45static void snbep_uncore_pci_disable_box(struct intel_uncore_box *box)
46{
47 struct pci_dev *pdev = box->pci_dev;
48 int box_ctl = uncore_pci_box_ctl(box);
49 u32 config;
50
51 pci_read_config_dword(pdev, box_ctl, &config);
52 config |= SNBEP_PMON_BOX_CTL_FRZ;
53 pci_write_config_dword(pdev, box_ctl, config);
54}
55
56static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box)
57{
58 struct pci_dev *pdev = box->pci_dev;
59 int box_ctl = uncore_pci_box_ctl(box);
60 u32 config;
61
62 pci_read_config_dword(pdev, box_ctl, &config);
63 config &= ~SNBEP_PMON_BOX_CTL_FRZ;
64 pci_write_config_dword(pdev, box_ctl, config);
65}
66
67static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box,
68 struct perf_event *event)
69{
70 struct pci_dev *pdev = box->pci_dev;
71 struct hw_perf_event *hwc = &event->hw;
72
73 pci_write_config_dword(pdev, hwc->config_base, hwc->config |
74 SNBEP_PMON_CTL_EN);
75}
76
77static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box,
78 struct perf_event *event)
79{
80 struct pci_dev *pdev = box->pci_dev;
81 struct hw_perf_event *hwc = &event->hw;
82
83 pci_write_config_dword(pdev, hwc->config_base, hwc->config);
84}
85
86static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box,
87 struct perf_event *event)
88{
89 struct pci_dev *pdev = box->pci_dev;
90 struct hw_perf_event *hwc = &event->hw;
91 u64 count;
92
93 pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count);
94 pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1);
95 return count;
96}
97
98static void snbep_uncore_pci_init_box(struct intel_uncore_box *box)
99{
100 struct pci_dev *pdev = box->pci_dev;
101 pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL,
102 SNBEP_PMON_BOX_CTL_INT);
103}
104
105static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box)
106{
107 u64 config;
108 unsigned msr;
109
110 msr = uncore_msr_box_ctl(box);
111 if (msr) {
112 rdmsrl(msr, config);
113 config |= SNBEP_PMON_BOX_CTL_FRZ;
114 wrmsrl(msr, config);
115 return;
116 }
117}
118
119static void snbep_uncore_msr_enable_box(struct intel_uncore_box *box)
120{
121 u64 config;
122 unsigned msr;
123
124 msr = uncore_msr_box_ctl(box);
125 if (msr) {
126 rdmsrl(msr, config);
127 config &= ~SNBEP_PMON_BOX_CTL_FRZ;
128 wrmsrl(msr, config);
129 return;
130 }
131}
132
133static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box,
134 struct perf_event *event)
135{
136 struct hw_perf_event *hwc = &event->hw;
137 struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
138
139 if (reg1->idx != EXTRA_REG_NONE)
140 wrmsrl(reg1->reg, reg1->config);
141
142 wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
143}
144
145static void snbep_uncore_msr_disable_event(struct intel_uncore_box *box,
146 struct perf_event *event)
147{
148 struct hw_perf_event *hwc = &event->hw;
149
150 wrmsrl(hwc->config_base, hwc->config);
151}
152
153static u64 snbep_uncore_msr_read_counter(struct intel_uncore_box *box,
154 struct perf_event *event)
155{
156 struct hw_perf_event *hwc = &event->hw;
157 u64 count;
158
159 rdmsrl(hwc->event_base, count);
160 return count;
161}
162
163static void snbep_uncore_msr_init_box(struct intel_uncore_box *box)
164{
165 unsigned msr = uncore_msr_box_ctl(box);
166 if (msr)
167 wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT);
168}
169
170static struct event_constraint *
171snbep_uncore_get_constraint(struct intel_uncore_box *box,
172 struct perf_event *event)
173{
174 struct intel_uncore_extra_reg *er;
175 struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
176 unsigned long flags;
177 bool ok = false;
178
179 if (reg1->idx == EXTRA_REG_NONE || (box->phys_id >= 0 && reg1->alloc))
180 return NULL;
181
182 er = &box->shared_regs[reg1->idx];
183 raw_spin_lock_irqsave(&er->lock, flags);
184 if (!atomic_read(&er->ref) || er->config1 == reg1->config) {
185 atomic_inc(&er->ref);
186 er->config1 = reg1->config;
187 ok = true;
188 }
189 raw_spin_unlock_irqrestore(&er->lock, flags);
190
191 if (ok) {
192 if (box->phys_id >= 0)
193 reg1->alloc = 1;
194 return NULL;
195 }
196 return &constraint_empty;
197}
198
199static void snbep_uncore_put_constraint(struct intel_uncore_box *box,
200 struct perf_event *event)
201{
202 struct intel_uncore_extra_reg *er;
203 struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
204
205 if (box->phys_id < 0 || !reg1->alloc)
206 return;
207
208 er = &box->shared_regs[reg1->idx];
209 atomic_dec(&er->ref);
210 reg1->alloc = 0;
211}
212
213static int snbep_uncore_hw_config(struct intel_uncore_box *box,
214 struct perf_event *event)
215{
216 struct hw_perf_event *hwc = &event->hw;
217 struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
218
219 if (box->pmu->type == &snbep_uncore_cbox) {
220 reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER +
221 SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
222 reg1->config = event->attr.config1 &
223 SNBEP_CB0_MSR_PMON_BOX_FILTER_MASK;
224 } else if (box->pmu->type == &snbep_uncore_pcu) {
225 reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER;
226 reg1->config = event->attr.config1 &
227 SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK;
228 } else {
229 return 0;
230 }
231 reg1->idx = 0;
232 return 0;
233}
234
235static struct attribute *snbep_uncore_formats_attr[] = {
236 &format_attr_event.attr,
237 &format_attr_umask.attr,
238 &format_attr_edge.attr,
239 &format_attr_inv.attr,
240 &format_attr_thresh8.attr,
241 NULL,
242};
243
244static struct attribute *snbep_uncore_ubox_formats_attr[] = {
245 &format_attr_event.attr,
246 &format_attr_umask.attr,
247 &format_attr_edge.attr,
248 &format_attr_inv.attr,
249 &format_attr_thresh5.attr,
250 NULL,
251};
252
253static struct attribute *snbep_uncore_cbox_formats_attr[] = {
254 &format_attr_event.attr,
255 &format_attr_umask.attr,
256 &format_attr_edge.attr,
257 &format_attr_tid_en.attr,
258 &format_attr_inv.attr,
259 &format_attr_thresh8.attr,
260 &format_attr_filter_tid.attr,
261 &format_attr_filter_nid.attr,
262 &format_attr_filter_state.attr,
263 &format_attr_filter_opc.attr,
264 NULL,
265};
266
267static struct attribute *snbep_uncore_pcu_formats_attr[] = {
268 &format_attr_event.attr,
269 &format_attr_occ_sel.attr,
270 &format_attr_edge.attr,
271 &format_attr_inv.attr,
272 &format_attr_thresh5.attr,
273 &format_attr_occ_invert.attr,
274 &format_attr_occ_edge.attr,
275 &format_attr_filter_brand0.attr,
276 &format_attr_filter_brand1.attr,
277 &format_attr_filter_brand2.attr,
278 &format_attr_filter_brand3.attr,
279 NULL,
280};
281
282static struct uncore_event_desc snbep_uncore_imc_events[] = {
283 INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
284 INTEL_UNCORE_EVENT_DESC(cas_count_read, "event=0x04,umask=0x03"),
285 INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"),
286 { /* end: all zeroes */ },
287};
288
289static struct uncore_event_desc snbep_uncore_qpi_events[] = {
290 INTEL_UNCORE_EVENT_DESC(clockticks, "event=0x14"),
291 INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"),
292 INTEL_UNCORE_EVENT_DESC(drs_data, "event=0x02,umask=0x08"),
293 INTEL_UNCORE_EVENT_DESC(ncb_data, "event=0x03,umask=0x04"),
294 { /* end: all zeroes */ },
295};
296
297static struct attribute_group snbep_uncore_format_group = {
298 .name = "format",
299 .attrs = snbep_uncore_formats_attr,
300};
301
302static struct attribute_group snbep_uncore_ubox_format_group = {
303 .name = "format",
304 .attrs = snbep_uncore_ubox_formats_attr,
305};
306
307static struct attribute_group snbep_uncore_cbox_format_group = {
308 .name = "format",
309 .attrs = snbep_uncore_cbox_formats_attr,
310};
311
312static struct attribute_group snbep_uncore_pcu_format_group = {
313 .name = "format",
314 .attrs = snbep_uncore_pcu_formats_attr,
315};
316
317static struct intel_uncore_ops snbep_uncore_msr_ops = {
318 .init_box = snbep_uncore_msr_init_box,
319 .disable_box = snbep_uncore_msr_disable_box,
320 .enable_box = snbep_uncore_msr_enable_box,
321 .disable_event = snbep_uncore_msr_disable_event,
322 .enable_event = snbep_uncore_msr_enable_event,
323 .read_counter = snbep_uncore_msr_read_counter,
324 .get_constraint = snbep_uncore_get_constraint,
325 .put_constraint = snbep_uncore_put_constraint,
326 .hw_config = snbep_uncore_hw_config,
327};
328
329static struct intel_uncore_ops snbep_uncore_pci_ops = {
330 .init_box = snbep_uncore_pci_init_box,
331 .disable_box = snbep_uncore_pci_disable_box,
332 .enable_box = snbep_uncore_pci_enable_box,
333 .disable_event = snbep_uncore_pci_disable_event,
334 .enable_event = snbep_uncore_pci_enable_event,
335 .read_counter = snbep_uncore_pci_read_counter,
336};
337
338static struct event_constraint snbep_uncore_cbox_constraints[] = {
339 UNCORE_EVENT_CONSTRAINT(0x01, 0x1),
340 UNCORE_EVENT_CONSTRAINT(0x02, 0x3),
341 UNCORE_EVENT_CONSTRAINT(0x04, 0x3),
342 UNCORE_EVENT_CONSTRAINT(0x05, 0x3),
343 UNCORE_EVENT_CONSTRAINT(0x07, 0x3),
344 UNCORE_EVENT_CONSTRAINT(0x11, 0x1),
345 UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
346 UNCORE_EVENT_CONSTRAINT(0x13, 0x3),
347 UNCORE_EVENT_CONSTRAINT(0x1b, 0xc),
348 UNCORE_EVENT_CONSTRAINT(0x1c, 0xc),
349 UNCORE_EVENT_CONSTRAINT(0x1d, 0xc),
350 UNCORE_EVENT_CONSTRAINT(0x1e, 0xc),
351 EVENT_CONSTRAINT_OVERLAP(0x1f, 0xe, 0xff),
352 UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
353 UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
354 UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
355 UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
356 UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
357 UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
358 UNCORE_EVENT_CONSTRAINT(0x35, 0x3),
359 UNCORE_EVENT_CONSTRAINT(0x36, 0x1),
360 UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
361 UNCORE_EVENT_CONSTRAINT(0x38, 0x3),
362 UNCORE_EVENT_CONSTRAINT(0x39, 0x3),
363 UNCORE_EVENT_CONSTRAINT(0x3b, 0x1),
364 EVENT_CONSTRAINT_END
365};
366
367static struct event_constraint snbep_uncore_r2pcie_constraints[] = {
368 UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
369 UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
370 UNCORE_EVENT_CONSTRAINT(0x12, 0x1),
371 UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
372 UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
373 UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
374 UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
375 UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
376 UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
377 UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
378 EVENT_CONSTRAINT_END
379};
380
381static struct event_constraint snbep_uncore_r3qpi_constraints[] = {
382 UNCORE_EVENT_CONSTRAINT(0x10, 0x3),
383 UNCORE_EVENT_CONSTRAINT(0x11, 0x3),
384 UNCORE_EVENT_CONSTRAINT(0x12, 0x3),
385 UNCORE_EVENT_CONSTRAINT(0x13, 0x1),
386 UNCORE_EVENT_CONSTRAINT(0x20, 0x3),
387 UNCORE_EVENT_CONSTRAINT(0x21, 0x3),
388 UNCORE_EVENT_CONSTRAINT(0x22, 0x3),
389 UNCORE_EVENT_CONSTRAINT(0x23, 0x3),
390 UNCORE_EVENT_CONSTRAINT(0x24, 0x3),
391 UNCORE_EVENT_CONSTRAINT(0x25, 0x3),
392 UNCORE_EVENT_CONSTRAINT(0x26, 0x3),
393 UNCORE_EVENT_CONSTRAINT(0x30, 0x3),
394 UNCORE_EVENT_CONSTRAINT(0x31, 0x3),
395 UNCORE_EVENT_CONSTRAINT(0x32, 0x3),
396 UNCORE_EVENT_CONSTRAINT(0x33, 0x3),
397 UNCORE_EVENT_CONSTRAINT(0x34, 0x3),
398 UNCORE_EVENT_CONSTRAINT(0x36, 0x3),
399 UNCORE_EVENT_CONSTRAINT(0x37, 0x3),
400 EVENT_CONSTRAINT_END
401};
402
403static struct intel_uncore_type snbep_uncore_ubox = {
404 .name = "ubox",
405 .num_counters = 2,
406 .num_boxes = 1,
407 .perf_ctr_bits = 44,
408 .fixed_ctr_bits = 48,
409 .perf_ctr = SNBEP_U_MSR_PMON_CTR0,
410 .event_ctl = SNBEP_U_MSR_PMON_CTL0,
411 .event_mask = SNBEP_U_MSR_PMON_RAW_EVENT_MASK,
412 .fixed_ctr = SNBEP_U_MSR_PMON_UCLK_FIXED_CTR,
413 .fixed_ctl = SNBEP_U_MSR_PMON_UCLK_FIXED_CTL,
414 .ops = &snbep_uncore_msr_ops,
415 .format_group = &snbep_uncore_ubox_format_group,
416};
417
418static struct intel_uncore_type snbep_uncore_cbox = {
419 .name = "cbox",
420 .num_counters = 4,
421 .num_boxes = 8,
422 .perf_ctr_bits = 44,
423 .event_ctl = SNBEP_C0_MSR_PMON_CTL0,
424 .perf_ctr = SNBEP_C0_MSR_PMON_CTR0,
425 .event_mask = SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK,
426 .box_ctl = SNBEP_C0_MSR_PMON_BOX_CTL,
427 .msr_offset = SNBEP_CBO_MSR_OFFSET,
428 .num_shared_regs = 1,
429 .constraints = snbep_uncore_cbox_constraints,
430 .ops = &snbep_uncore_msr_ops,
431 .format_group = &snbep_uncore_cbox_format_group,
432};
433
434static struct intel_uncore_type snbep_uncore_pcu = {
435 .name = "pcu",
436 .num_counters = 4,
437 .num_boxes = 1,
438 .perf_ctr_bits = 48,
439 .perf_ctr = SNBEP_PCU_MSR_PMON_CTR0,
440 .event_ctl = SNBEP_PCU_MSR_PMON_CTL0,
441 .event_mask = SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK,
442 .box_ctl = SNBEP_PCU_MSR_PMON_BOX_CTL,
443 .num_shared_regs = 1,
444 .ops = &snbep_uncore_msr_ops,
445 .format_group = &snbep_uncore_pcu_format_group,
446};
447
448static struct intel_uncore_type *snbep_msr_uncores[] = {
449 &snbep_uncore_ubox,
450 &snbep_uncore_cbox,
451 &snbep_uncore_pcu,
452 NULL,
453};
454
455#define SNBEP_UNCORE_PCI_COMMON_INIT() \
456 .perf_ctr = SNBEP_PCI_PMON_CTR0, \
457 .event_ctl = SNBEP_PCI_PMON_CTL0, \
458 .event_mask = SNBEP_PMON_RAW_EVENT_MASK, \
459 .box_ctl = SNBEP_PCI_PMON_BOX_CTL, \
460 .ops = &snbep_uncore_pci_ops, \
461 .format_group = &snbep_uncore_format_group
462
463static struct intel_uncore_type snbep_uncore_ha = {
464 .name = "ha",
465 .num_counters = 4,
466 .num_boxes = 1,
467 .perf_ctr_bits = 48,
468 SNBEP_UNCORE_PCI_COMMON_INIT(),
469};
470
471static struct intel_uncore_type snbep_uncore_imc = {
472 .name = "imc",
473 .num_counters = 4,
474 .num_boxes = 4,
475 .perf_ctr_bits = 48,
476 .fixed_ctr_bits = 48,
477 .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR,
478 .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL,
479 .event_descs = snbep_uncore_imc_events,
480 SNBEP_UNCORE_PCI_COMMON_INIT(),
481};
482
483static struct intel_uncore_type snbep_uncore_qpi = {
484 .name = "qpi",
485 .num_counters = 4,
486 .num_boxes = 2,
487 .perf_ctr_bits = 48,
488 .event_descs = snbep_uncore_qpi_events,
489 SNBEP_UNCORE_PCI_COMMON_INIT(),
490};
491
492
493static struct intel_uncore_type snbep_uncore_r2pcie = {
494 .name = "r2pcie",
495 .num_counters = 4,
496 .num_boxes = 1,
497 .perf_ctr_bits = 44,
498 .constraints = snbep_uncore_r2pcie_constraints,
499 SNBEP_UNCORE_PCI_COMMON_INIT(),
500};
501
502static struct intel_uncore_type snbep_uncore_r3qpi = {
503 .name = "r3qpi",
504 .num_counters = 3,
505 .num_boxes = 2,
506 .perf_ctr_bits = 44,
507 .constraints = snbep_uncore_r3qpi_constraints,
508 SNBEP_UNCORE_PCI_COMMON_INIT(),
509};
510
511static struct intel_uncore_type *snbep_pci_uncores[] = {
512 &snbep_uncore_ha,
513 &snbep_uncore_imc,
514 &snbep_uncore_qpi,
515 &snbep_uncore_r2pcie,
516 &snbep_uncore_r3qpi,
517 NULL,
518};
519
520static DEFINE_PCI_DEVICE_TABLE(snbep_uncore_pci_ids) = {
521 { /* Home Agent */
522 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA),
523 .driver_data = (unsigned long)&snbep_uncore_ha,
524 },
525 { /* MC Channel 0 */
526 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0),
527 .driver_data = (unsigned long)&snbep_uncore_imc,
528 },
529 { /* MC Channel 1 */
530 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1),
531 .driver_data = (unsigned long)&snbep_uncore_imc,
532 },
533 { /* MC Channel 2 */
534 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2),
535 .driver_data = (unsigned long)&snbep_uncore_imc,
536 },
537 { /* MC Channel 3 */
538 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3),
539 .driver_data = (unsigned long)&snbep_uncore_imc,
540 },
541 { /* QPI Port 0 */
542 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0),
543 .driver_data = (unsigned long)&snbep_uncore_qpi,
544 },
545 { /* QPI Port 1 */
546 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1),
547 .driver_data = (unsigned long)&snbep_uncore_qpi,
548 },
549 { /* P2PCIe */
550 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE),
551 .driver_data = (unsigned long)&snbep_uncore_r2pcie,
552 },
553 { /* R3QPI Link 0 */
554 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0),
555 .driver_data = (unsigned long)&snbep_uncore_r3qpi,
556 },
557 { /* R3QPI Link 1 */
558 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1),
559 .driver_data = (unsigned long)&snbep_uncore_r3qpi,
560 },
561 { /* end: all zeroes */ }
562};
563
564static struct pci_driver snbep_uncore_pci_driver = {
565 .name = "snbep_uncore",
566 .id_table = snbep_uncore_pci_ids,
567};
568
569/*
570 * build pci bus to socket mapping
571 */
572static void snbep_pci2phy_map_init(void)
573{
574 struct pci_dev *ubox_dev = NULL;
575 int i, bus, nodeid;
576 u32 config;
577
578 while (1) {
579 /* find the UBOX device */
580 ubox_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
581 PCI_DEVICE_ID_INTEL_JAKETOWN_UBOX,
582 ubox_dev);
583 if (!ubox_dev)
584 break;
585 bus = ubox_dev->bus->number;
586 /* get the Node ID of the local register */
587 pci_read_config_dword(ubox_dev, 0x40, &config);
588 nodeid = config;
589 /* get the Node ID mapping */
590 pci_read_config_dword(ubox_dev, 0x54, &config);
591 /*
592 * every three bits in the Node ID mapping register maps
593 * to a particular node.
594 */
595 for (i = 0; i < 8; i++) {
596 if (nodeid == ((config >> (3 * i)) & 0x7)) {
597 pcibus_to_physid[bus] = i;
598 break;
599 }
600 }
601 };
602 return;
603}
604/* end of Sandy Bridge-EP uncore support */
605
606
607/* Sandy Bridge uncore support */
608static void snb_uncore_msr_enable_event(struct intel_uncore_box *box,
609 struct perf_event *event)
610{
611 struct hw_perf_event *hwc = &event->hw;
612
613 if (hwc->idx < UNCORE_PMC_IDX_FIXED)
614 wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN);
615 else
616 wrmsrl(hwc->config_base, SNB_UNC_CTL_EN);
617}
618
619static void snb_uncore_msr_disable_event(struct intel_uncore_box *box,
620 struct perf_event *event)
621{
622 wrmsrl(event->hw.config_base, 0);
623}
624
625static u64 snb_uncore_msr_read_counter(struct intel_uncore_box *box,
626 struct perf_event *event)
627{
628 u64 count;
629 rdmsrl(event->hw.event_base, count);
630 return count;
631}
632
633static void snb_uncore_msr_init_box(struct intel_uncore_box *box)
634{
635 if (box->pmu->pmu_idx == 0) {
636 wrmsrl(SNB_UNC_PERF_GLOBAL_CTL,
637 SNB_UNC_GLOBAL_CTL_EN | SNB_UNC_GLOBAL_CTL_CORE_ALL);
638 }
639}
640
641static struct attribute *snb_uncore_formats_attr[] = {
642 &format_attr_event.attr,
643 &format_attr_umask.attr,
644 &format_attr_edge.attr,
645 &format_attr_inv.attr,
646 &format_attr_cmask5.attr,
647 NULL,
648};
649
650static struct attribute_group snb_uncore_format_group = {
651 .name = "format",
652 .attrs = snb_uncore_formats_attr,
653};
654
655static struct intel_uncore_ops snb_uncore_msr_ops = {
656 .init_box = snb_uncore_msr_init_box,
657 .disable_event = snb_uncore_msr_disable_event,
658 .enable_event = snb_uncore_msr_enable_event,
659 .read_counter = snb_uncore_msr_read_counter,
660};
661
662static struct event_constraint snb_uncore_cbox_constraints[] = {
663 UNCORE_EVENT_CONSTRAINT(0x80, 0x1),
664 UNCORE_EVENT_CONSTRAINT(0x83, 0x1),
665 EVENT_CONSTRAINT_END
666};
667
668static struct intel_uncore_type snb_uncore_cbox = {
669 .name = "cbox",
670 .num_counters = 2,
671 .num_boxes = 4,
672 .perf_ctr_bits = 44,
673 .fixed_ctr_bits = 48,
674 .perf_ctr = SNB_UNC_CBO_0_PER_CTR0,
675 .event_ctl = SNB_UNC_CBO_0_PERFEVTSEL0,
676 .fixed_ctr = SNB_UNC_FIXED_CTR,
677 .fixed_ctl = SNB_UNC_FIXED_CTR_CTRL,
678 .single_fixed = 1,
679 .event_mask = SNB_UNC_RAW_EVENT_MASK,
680 .msr_offset = SNB_UNC_CBO_MSR_OFFSET,
681 .constraints = snb_uncore_cbox_constraints,
682 .ops = &snb_uncore_msr_ops,
683 .format_group = &snb_uncore_format_group,
684};
685
686static struct intel_uncore_type *snb_msr_uncores[] = {
687 &snb_uncore_cbox,
688 NULL,
689};
690/* end of Sandy Bridge uncore support */
691
692/* Nehalem uncore support */
693static void nhm_uncore_msr_disable_box(struct intel_uncore_box *box)
694{
695 wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, 0);
696}
697
698static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box)
699{
700 wrmsrl(NHM_UNC_PERF_GLOBAL_CTL,
701 NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC);
702}
703
704static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box,
705 struct perf_event *event)
706{
707 struct hw_perf_event *hwc = &event->hw;
708
709 if (hwc->idx < UNCORE_PMC_IDX_FIXED)
710 wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN);
711 else
712 wrmsrl(hwc->config_base, NHM_UNC_FIXED_CTR_CTL_EN);
713}
714
715static struct attribute *nhm_uncore_formats_attr[] = {
716 &format_attr_event.attr,
717 &format_attr_umask.attr,
718 &format_attr_edge.attr,
719 &format_attr_inv.attr,
720 &format_attr_cmask8.attr,
721 NULL,
722};
723
724static struct attribute_group nhm_uncore_format_group = {
725 .name = "format",
726 .attrs = nhm_uncore_formats_attr,
727};
728
729static struct uncore_event_desc nhm_uncore_events[] = {
730 INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
731 INTEL_UNCORE_EVENT_DESC(qmc_writes_full_any, "event=0x2f,umask=0x0f"),
732 INTEL_UNCORE_EVENT_DESC(qmc_normal_reads_any, "event=0x2c,umask=0x0f"),
733 INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_reads, "event=0x20,umask=0x01"),
734 INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_writes, "event=0x20,umask=0x02"),
735 INTEL_UNCORE_EVENT_DESC(qhl_request_remote_reads, "event=0x20,umask=0x04"),
736 INTEL_UNCORE_EVENT_DESC(qhl_request_remote_writes, "event=0x20,umask=0x08"),
737 INTEL_UNCORE_EVENT_DESC(qhl_request_local_reads, "event=0x20,umask=0x10"),
738 INTEL_UNCORE_EVENT_DESC(qhl_request_local_writes, "event=0x20,umask=0x20"),
739 { /* end: all zeroes */ },
740};
741
742static struct intel_uncore_ops nhm_uncore_msr_ops = {
743 .disable_box = nhm_uncore_msr_disable_box,
744 .enable_box = nhm_uncore_msr_enable_box,
745 .disable_event = snb_uncore_msr_disable_event,
746 .enable_event = nhm_uncore_msr_enable_event,
747 .read_counter = snb_uncore_msr_read_counter,
748};
749
750static struct intel_uncore_type nhm_uncore = {
751 .name = "",
752 .num_counters = 8,
753 .num_boxes = 1,
754 .perf_ctr_bits = 48,
755 .fixed_ctr_bits = 48,
756 .event_ctl = NHM_UNC_PERFEVTSEL0,
757 .perf_ctr = NHM_UNC_UNCORE_PMC0,
758 .fixed_ctr = NHM_UNC_FIXED_CTR,
759 .fixed_ctl = NHM_UNC_FIXED_CTR_CTRL,
760 .event_mask = NHM_UNC_RAW_EVENT_MASK,
761 .event_descs = nhm_uncore_events,
762 .ops = &nhm_uncore_msr_ops,
763 .format_group = &nhm_uncore_format_group,
764};
765
766static struct intel_uncore_type *nhm_msr_uncores[] = {
767 &nhm_uncore,
768 NULL,
769};
770/* end of Nehalem uncore support */
771
772static void uncore_assign_hw_event(struct intel_uncore_box *box,
773 struct perf_event *event, int idx)
774{
775 struct hw_perf_event *hwc = &event->hw;
776
777 hwc->idx = idx;
778 hwc->last_tag = ++box->tags[idx];
779
780 if (hwc->idx == UNCORE_PMC_IDX_FIXED) {
781 hwc->event_base = uncore_fixed_ctr(box);
782 hwc->config_base = uncore_fixed_ctl(box);
783 return;
784 }
785
786 hwc->config_base = uncore_event_ctl(box, hwc->idx);
787 hwc->event_base = uncore_perf_ctr(box, hwc->idx);
788}
789
790static void uncore_perf_event_update(struct intel_uncore_box *box,
791 struct perf_event *event)
792{
793 u64 prev_count, new_count, delta;
794 int shift;
795
796 if (event->hw.idx >= UNCORE_PMC_IDX_FIXED)
797 shift = 64 - uncore_fixed_ctr_bits(box);
798 else
799 shift = 64 - uncore_perf_ctr_bits(box);
800
801 /* the hrtimer might modify the previous event value */
802again:
803 prev_count = local64_read(&event->hw.prev_count);
804 new_count = uncore_read_counter(box, event);
805 if (local64_xchg(&event->hw.prev_count, new_count) != prev_count)
806 goto again;
807
808 delta = (new_count << shift) - (prev_count << shift);
809 delta >>= shift;
810
811 local64_add(delta, &event->count);
812}
813
814/*
815 * The overflow interrupt is unavailable for SandyBridge-EP, is broken
816 * for SandyBridge. So we use hrtimer to periodically poll the counter
817 * to avoid overflow.
818 */
819static enum hrtimer_restart uncore_pmu_hrtimer(struct hrtimer *hrtimer)
820{
821 struct intel_uncore_box *box;
822 unsigned long flags;
823 int bit;
824
825 box = container_of(hrtimer, struct intel_uncore_box, hrtimer);
826 if (!box->n_active || box->cpu != smp_processor_id())
827 return HRTIMER_NORESTART;
828 /*
829 * disable local interrupt to prevent uncore_pmu_event_start/stop
830 * to interrupt the update process
831 */
832 local_irq_save(flags);
833
834 for_each_set_bit(bit, box->active_mask, UNCORE_PMC_IDX_MAX)
835 uncore_perf_event_update(box, box->events[bit]);
836
837 local_irq_restore(flags);
838
839 hrtimer_forward_now(hrtimer, ns_to_ktime(UNCORE_PMU_HRTIMER_INTERVAL));
840 return HRTIMER_RESTART;
841}
842
843static void uncore_pmu_start_hrtimer(struct intel_uncore_box *box)
844{
845 __hrtimer_start_range_ns(&box->hrtimer,
846 ns_to_ktime(UNCORE_PMU_HRTIMER_INTERVAL), 0,
847 HRTIMER_MODE_REL_PINNED, 0);
848}
849
850static void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box)
851{
852 hrtimer_cancel(&box->hrtimer);
853}
854
855static void uncore_pmu_init_hrtimer(struct intel_uncore_box *box)
856{
857 hrtimer_init(&box->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
858 box->hrtimer.function = uncore_pmu_hrtimer;
859}
860
861struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type,
862 int cpu)
863{
864 struct intel_uncore_box *box;
865 int i, size;
866
867 size = sizeof(*box) + type->num_shared_regs *
868 sizeof(struct intel_uncore_extra_reg);
869
870 box = kmalloc_node(size, GFP_KERNEL | __GFP_ZERO, cpu_to_node(cpu));
871 if (!box)
872 return NULL;
873
874 for (i = 0; i < type->num_shared_regs; i++)
875 raw_spin_lock_init(&box->shared_regs[i].lock);
876
877 uncore_pmu_init_hrtimer(box);
878 atomic_set(&box->refcnt, 1);
879 box->cpu = -1;
880 box->phys_id = -1;
881
882 return box;
883}
884
885static struct intel_uncore_box *
886uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu)
887{
888 static struct intel_uncore_box *box;
889
890 box = *per_cpu_ptr(pmu->box, cpu);
891 if (box)
892 return box;
893
894 raw_spin_lock(&uncore_box_lock);
895 list_for_each_entry(box, &pmu->box_list, list) {
896 if (box->phys_id == topology_physical_package_id(cpu)) {
897 atomic_inc(&box->refcnt);
898 *per_cpu_ptr(pmu->box, cpu) = box;
899 break;
900 }
901 }
902 raw_spin_unlock(&uncore_box_lock);
903
904 return *per_cpu_ptr(pmu->box, cpu);
905}
906
907static struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event)
908{
909 return container_of(event->pmu, struct intel_uncore_pmu, pmu);
910}
911
912static struct intel_uncore_box *uncore_event_to_box(struct perf_event *event)
913{
914 /*
915 * perf core schedules event on the basis of cpu, uncore events are
916 * collected by one of the cpus inside a physical package.
917 */
918 return uncore_pmu_to_box(uncore_event_to_pmu(event),
919 smp_processor_id());
920}
921
922static int uncore_collect_events(struct intel_uncore_box *box,
923 struct perf_event *leader, bool dogrp)
924{
925 struct perf_event *event;
926 int n, max_count;
927
928 max_count = box->pmu->type->num_counters;
929 if (box->pmu->type->fixed_ctl)
930 max_count++;
931
932 if (box->n_events >= max_count)
933 return -EINVAL;
934
935 n = box->n_events;
936 box->event_list[n] = leader;
937 n++;
938 if (!dogrp)
939 return n;
940
941 list_for_each_entry(event, &leader->sibling_list, group_entry) {
942 if (event->state <= PERF_EVENT_STATE_OFF)
943 continue;
944
945 if (n >= max_count)
946 return -EINVAL;
947
948 box->event_list[n] = event;
949 n++;
950 }
951 return n;
952}
953
954static struct event_constraint *
955uncore_get_event_constraint(struct intel_uncore_box *box,
956 struct perf_event *event)
957{
958 struct intel_uncore_type *type = box->pmu->type;
959 struct event_constraint *c;
960
961 if (type->ops->get_constraint) {
962 c = type->ops->get_constraint(box, event);
963 if (c)
964 return c;
965 }
966
967 if (event->hw.config == ~0ULL)
968 return &constraint_fixed;
969
970 if (type->constraints) {
971 for_each_event_constraint(c, type->constraints) {
972 if ((event->hw.config & c->cmask) == c->code)
973 return c;
974 }
975 }
976
977 return &type->unconstrainted;
978}
979
980static void uncore_put_event_constraint(struct intel_uncore_box *box,
981 struct perf_event *event)
982{
983 if (box->pmu->type->ops->put_constraint)
984 box->pmu->type->ops->put_constraint(box, event);
985}
986
987static int uncore_assign_events(struct intel_uncore_box *box,
988 int assign[], int n)
989{
990 unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)];
991 struct event_constraint *c, *constraints[UNCORE_PMC_IDX_MAX];
992 int i, wmin, wmax, ret = 0;
993 struct hw_perf_event *hwc;
994
995 bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX);
996
997 for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) {
998 c = uncore_get_event_constraint(box, box->event_list[i]);
999 constraints[i] = c;
1000 wmin = min(wmin, c->weight);
1001 wmax = max(wmax, c->weight);
1002 }
1003
1004 /* fastpath, try to reuse previous register */
1005 for (i = 0; i < n; i++) {
1006 hwc = &box->event_list[i]->hw;
1007 c = constraints[i];
1008
1009 /* never assigned */
1010 if (hwc->idx == -1)
1011 break;
1012
1013 /* constraint still honored */
1014 if (!test_bit(hwc->idx, c->idxmsk))
1015 break;
1016
1017 /* not already used */
1018 if (test_bit(hwc->idx, used_mask))
1019 break;
1020
1021 __set_bit(hwc->idx, used_mask);
1022 if (assign)
1023 assign[i] = hwc->idx;
1024 }
1025 /* slow path */
1026 if (i != n)
1027 ret = perf_assign_events(constraints, n, wmin, wmax, assign);
1028
1029 if (!assign || ret) {
1030 for (i = 0; i < n; i++)
1031 uncore_put_event_constraint(box, box->event_list[i]);
1032 }
1033 return ret ? -EINVAL : 0;
1034}
1035
1036static void uncore_pmu_event_start(struct perf_event *event, int flags)
1037{
1038 struct intel_uncore_box *box = uncore_event_to_box(event);
1039 int idx = event->hw.idx;
1040
1041 if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
1042 return;
1043
1044 if (WARN_ON_ONCE(idx == -1 || idx >= UNCORE_PMC_IDX_MAX))
1045 return;
1046
1047 event->hw.state = 0;
1048 box->events[idx] = event;
1049 box->n_active++;
1050 __set_bit(idx, box->active_mask);
1051
1052 local64_set(&event->hw.prev_count, uncore_read_counter(box, event));
1053 uncore_enable_event(box, event);
1054
1055 if (box->n_active == 1) {
1056 uncore_enable_box(box);
1057 uncore_pmu_start_hrtimer(box);
1058 }
1059}
1060
1061static void uncore_pmu_event_stop(struct perf_event *event, int flags)
1062{
1063 struct intel_uncore_box *box = uncore_event_to_box(event);
1064 struct hw_perf_event *hwc = &event->hw;
1065
1066 if (__test_and_clear_bit(hwc->idx, box->active_mask)) {
1067 uncore_disable_event(box, event);
1068 box->n_active--;
1069 box->events[hwc->idx] = NULL;
1070 WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
1071 hwc->state |= PERF_HES_STOPPED;
1072
1073 if (box->n_active == 0) {
1074 uncore_disable_box(box);
1075 uncore_pmu_cancel_hrtimer(box);
1076 }
1077 }
1078
1079 if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
1080 /*
1081 * Drain the remaining delta count out of a event
1082 * that we are disabling:
1083 */
1084 uncore_perf_event_update(box, event);
1085 hwc->state |= PERF_HES_UPTODATE;
1086 }
1087}
1088
1089static int uncore_pmu_event_add(struct perf_event *event, int flags)
1090{
1091 struct intel_uncore_box *box = uncore_event_to_box(event);
1092 struct hw_perf_event *hwc = &event->hw;
1093 int assign[UNCORE_PMC_IDX_MAX];
1094 int i, n, ret;
1095
1096 if (!box)
1097 return -ENODEV;
1098
1099 ret = n = uncore_collect_events(box, event, false);
1100 if (ret < 0)
1101 return ret;
1102
1103 hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
1104 if (!(flags & PERF_EF_START))
1105 hwc->state |= PERF_HES_ARCH;
1106
1107 ret = uncore_assign_events(box, assign, n);
1108 if (ret)
1109 return ret;
1110
1111 /* save events moving to new counters */
1112 for (i = 0; i < box->n_events; i++) {
1113 event = box->event_list[i];
1114 hwc = &event->hw;
1115
1116 if (hwc->idx == assign[i] &&
1117 hwc->last_tag == box->tags[assign[i]])
1118 continue;
1119 /*
1120 * Ensure we don't accidentally enable a stopped
1121 * counter simply because we rescheduled.
1122 */
1123 if (hwc->state & PERF_HES_STOPPED)
1124 hwc->state |= PERF_HES_ARCH;
1125
1126 uncore_pmu_event_stop(event, PERF_EF_UPDATE);
1127 }
1128
1129 /* reprogram moved events into new counters */
1130 for (i = 0; i < n; i++) {
1131 event = box->event_list[i];
1132 hwc = &event->hw;
1133
1134 if (hwc->idx != assign[i] ||
1135 hwc->last_tag != box->tags[assign[i]])
1136 uncore_assign_hw_event(box, event, assign[i]);
1137 else if (i < box->n_events)
1138 continue;
1139
1140 if (hwc->state & PERF_HES_ARCH)
1141 continue;
1142
1143 uncore_pmu_event_start(event, 0);
1144 }
1145 box->n_events = n;
1146
1147 return 0;
1148}
1149
1150static void uncore_pmu_event_del(struct perf_event *event, int flags)
1151{
1152 struct intel_uncore_box *box = uncore_event_to_box(event);
1153 int i;
1154
1155 uncore_pmu_event_stop(event, PERF_EF_UPDATE);
1156
1157 for (i = 0; i < box->n_events; i++) {
1158 if (event == box->event_list[i]) {
1159 uncore_put_event_constraint(box, event);
1160
1161 while (++i < box->n_events)
1162 box->event_list[i - 1] = box->event_list[i];
1163
1164 --box->n_events;
1165 break;
1166 }
1167 }
1168
1169 event->hw.idx = -1;
1170 event->hw.last_tag = ~0ULL;
1171}
1172
1173static void uncore_pmu_event_read(struct perf_event *event)
1174{
1175 struct intel_uncore_box *box = uncore_event_to_box(event);
1176 uncore_perf_event_update(box, event);
1177}
1178
1179/*
1180 * validation ensures the group can be loaded onto the
1181 * PMU if it was the only group available.
1182 */
1183static int uncore_validate_group(struct intel_uncore_pmu *pmu,
1184 struct perf_event *event)
1185{
1186 struct perf_event *leader = event->group_leader;
1187 struct intel_uncore_box *fake_box;
1188 int ret = -EINVAL, n;
1189
1190 fake_box = uncore_alloc_box(pmu->type, smp_processor_id());
1191 if (!fake_box)
1192 return -ENOMEM;
1193
1194 fake_box->pmu = pmu;
1195 /*
1196 * the event is not yet connected with its
1197 * siblings therefore we must first collect
1198 * existing siblings, then add the new event
1199 * before we can simulate the scheduling
1200 */
1201 n = uncore_collect_events(fake_box, leader, true);
1202 if (n < 0)
1203 goto out;
1204
1205 fake_box->n_events = n;
1206 n = uncore_collect_events(fake_box, event, false);
1207 if (n < 0)
1208 goto out;
1209
1210 fake_box->n_events = n;
1211
1212 ret = uncore_assign_events(fake_box, NULL, n);
1213out:
1214 kfree(fake_box);
1215 return ret;
1216}
1217
1218int uncore_pmu_event_init(struct perf_event *event)
1219{
1220 struct intel_uncore_pmu *pmu;
1221 struct intel_uncore_box *box;
1222 struct hw_perf_event *hwc = &event->hw;
1223 int ret;
1224
1225 if (event->attr.type != event->pmu->type)
1226 return -ENOENT;
1227
1228 pmu = uncore_event_to_pmu(event);
1229 /* no device found for this pmu */
1230 if (pmu->func_id < 0)
1231 return -ENOENT;
1232
1233 /*
1234 * Uncore PMU does measure at all privilege level all the time.
1235 * So it doesn't make sense to specify any exclude bits.
1236 */
1237 if (event->attr.exclude_user || event->attr.exclude_kernel ||
1238 event->attr.exclude_hv || event->attr.exclude_idle)
1239 return -EINVAL;
1240
1241 /* Sampling not supported yet */
1242 if (hwc->sample_period)
1243 return -EINVAL;
1244
1245 /*
1246 * Place all uncore events for a particular physical package
1247 * onto a single cpu
1248 */
1249 if (event->cpu < 0)
1250 return -EINVAL;
1251 box = uncore_pmu_to_box(pmu, event->cpu);
1252 if (!box || box->cpu < 0)
1253 return -EINVAL;
1254 event->cpu = box->cpu;
1255
1256 event->hw.idx = -1;
1257 event->hw.last_tag = ~0ULL;
1258 event->hw.extra_reg.idx = EXTRA_REG_NONE;
1259
1260 if (event->attr.config == UNCORE_FIXED_EVENT) {
1261 /* no fixed counter */
1262 if (!pmu->type->fixed_ctl)
1263 return -EINVAL;
1264 /*
1265 * if there is only one fixed counter, only the first pmu
1266 * can access the fixed counter
1267 */
1268 if (pmu->type->single_fixed && pmu->pmu_idx > 0)
1269 return -EINVAL;
1270 hwc->config = ~0ULL;
1271 } else {
1272 hwc->config = event->attr.config & pmu->type->event_mask;
1273 if (pmu->type->ops->hw_config) {
1274 ret = pmu->type->ops->hw_config(box, event);
1275 if (ret)
1276 return ret;
1277 }
1278 }
1279
1280 if (event->group_leader != event)
1281 ret = uncore_validate_group(pmu, event);
1282 else
1283 ret = 0;
1284
1285 return ret;
1286}
1287
1288static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu)
1289{
1290 int ret;
1291
1292 pmu->pmu = (struct pmu) {
1293 .attr_groups = pmu->type->attr_groups,
1294 .task_ctx_nr = perf_invalid_context,
1295 .event_init = uncore_pmu_event_init,
1296 .add = uncore_pmu_event_add,
1297 .del = uncore_pmu_event_del,
1298 .start = uncore_pmu_event_start,
1299 .stop = uncore_pmu_event_stop,
1300 .read = uncore_pmu_event_read,
1301 };
1302
1303 if (pmu->type->num_boxes == 1) {
1304 if (strlen(pmu->type->name) > 0)
1305 sprintf(pmu->name, "uncore_%s", pmu->type->name);
1306 else
1307 sprintf(pmu->name, "uncore");
1308 } else {
1309 sprintf(pmu->name, "uncore_%s_%d", pmu->type->name,
1310 pmu->pmu_idx);
1311 }
1312
1313 ret = perf_pmu_register(&pmu->pmu, pmu->name, -1);
1314 return ret;
1315}
1316
1317static void __init uncore_type_exit(struct intel_uncore_type *type)
1318{
1319 int i;
1320
1321 for (i = 0; i < type->num_boxes; i++)
1322 free_percpu(type->pmus[i].box);
1323 kfree(type->pmus);
1324 type->pmus = NULL;
1325 kfree(type->attr_groups[1]);
1326 type->attr_groups[1] = NULL;
1327}
1328
1329static void uncore_types_exit(struct intel_uncore_type **types)
1330{
1331 int i;
1332 for (i = 0; types[i]; i++)
1333 uncore_type_exit(types[i]);
1334}
1335
1336static int __init uncore_type_init(struct intel_uncore_type *type)
1337{
1338 struct intel_uncore_pmu *pmus;
1339 struct attribute_group *events_group;
1340 struct attribute **attrs;
1341 int i, j;
1342
1343 pmus = kzalloc(sizeof(*pmus) * type->num_boxes, GFP_KERNEL);
1344 if (!pmus)
1345 return -ENOMEM;
1346
1347 type->unconstrainted = (struct event_constraint)
1348 __EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1,
1349 0, type->num_counters, 0);
1350
1351 for (i = 0; i < type->num_boxes; i++) {
1352 pmus[i].func_id = -1;
1353 pmus[i].pmu_idx = i;
1354 pmus[i].type = type;
1355 INIT_LIST_HEAD(&pmus[i].box_list);
1356 pmus[i].box = alloc_percpu(struct intel_uncore_box *);
1357 if (!pmus[i].box)
1358 goto fail;
1359 }
1360
1361 if (type->event_descs) {
1362 i = 0;
1363 while (type->event_descs[i].attr.attr.name)
1364 i++;
1365
1366 events_group = kzalloc(sizeof(struct attribute *) * (i + 1) +
1367 sizeof(*events_group), GFP_KERNEL);
1368 if (!events_group)
1369 goto fail;
1370
1371 attrs = (struct attribute **)(events_group + 1);
1372 events_group->name = "events";
1373 events_group->attrs = attrs;
1374
1375 for (j = 0; j < i; j++)
1376 attrs[j] = &type->event_descs[j].attr.attr;
1377
1378 type->attr_groups[1] = events_group;
1379 }
1380
1381 type->pmus = pmus;
1382 return 0;
1383fail:
1384 uncore_type_exit(type);
1385 return -ENOMEM;
1386}
1387
1388static int __init uncore_types_init(struct intel_uncore_type **types)
1389{
1390 int i, ret;
1391
1392 for (i = 0; types[i]; i++) {
1393 ret = uncore_type_init(types[i]);
1394 if (ret)
1395 goto fail;
1396 }
1397 return 0;
1398fail:
1399 while (--i >= 0)
1400 uncore_type_exit(types[i]);
1401 return ret;
1402}
1403
1404static struct pci_driver *uncore_pci_driver;
1405static bool pcidrv_registered;
1406
1407/*
1408 * add a pci uncore device
1409 */
1410static int __devinit uncore_pci_add(struct intel_uncore_type *type,
1411 struct pci_dev *pdev)
1412{
1413 struct intel_uncore_pmu *pmu;
1414 struct intel_uncore_box *box;
1415 int i, phys_id;
1416
1417 phys_id = pcibus_to_physid[pdev->bus->number];
1418 if (phys_id < 0)
1419 return -ENODEV;
1420
1421 box = uncore_alloc_box(type, 0);
1422 if (!box)
1423 return -ENOMEM;
1424
1425 /*
1426 * for performance monitoring unit with multiple boxes,
1427 * each box has a different function id.
1428 */
1429 for (i = 0; i < type->num_boxes; i++) {
1430 pmu = &type->pmus[i];
1431 if (pmu->func_id == pdev->devfn)
1432 break;
1433 if (pmu->func_id < 0) {
1434 pmu->func_id = pdev->devfn;
1435 break;
1436 }
1437 pmu = NULL;
1438 }
1439
1440 if (!pmu) {
1441 kfree(box);
1442 return -EINVAL;
1443 }
1444
1445 box->phys_id = phys_id;
1446 box->pci_dev = pdev;
1447 box->pmu = pmu;
1448 uncore_box_init(box);
1449 pci_set_drvdata(pdev, box);
1450
1451 raw_spin_lock(&uncore_box_lock);
1452 list_add_tail(&box->list, &pmu->box_list);
1453 raw_spin_unlock(&uncore_box_lock);
1454
1455 return 0;
1456}
1457
1458static void uncore_pci_remove(struct pci_dev *pdev)
1459{
1460 struct intel_uncore_box *box = pci_get_drvdata(pdev);
1461 struct intel_uncore_pmu *pmu = box->pmu;
1462 int cpu, phys_id = pcibus_to_physid[pdev->bus->number];
1463
1464 if (WARN_ON_ONCE(phys_id != box->phys_id))
1465 return;
1466
1467 raw_spin_lock(&uncore_box_lock);
1468 list_del(&box->list);
1469 raw_spin_unlock(&uncore_box_lock);
1470
1471 for_each_possible_cpu(cpu) {
1472 if (*per_cpu_ptr(pmu->box, cpu) == box) {
1473 *per_cpu_ptr(pmu->box, cpu) = NULL;
1474 atomic_dec(&box->refcnt);
1475 }
1476 }
1477
1478 WARN_ON_ONCE(atomic_read(&box->refcnt) != 1);
1479 kfree(box);
1480}
1481
1482static int __devinit uncore_pci_probe(struct pci_dev *pdev,
1483 const struct pci_device_id *id)
1484{
1485 struct intel_uncore_type *type;
1486
1487 type = (struct intel_uncore_type *)id->driver_data;
1488 return uncore_pci_add(type, pdev);
1489}
1490
1491static int __init uncore_pci_init(void)
1492{
1493 int ret;
1494
1495 switch (boot_cpu_data.x86_model) {
1496 case 45: /* Sandy Bridge-EP */
1497 pci_uncores = snbep_pci_uncores;
1498 uncore_pci_driver = &snbep_uncore_pci_driver;
1499 snbep_pci2phy_map_init();
1500 break;
1501 default:
1502 return 0;
1503 }
1504
1505 ret = uncore_types_init(pci_uncores);
1506 if (ret)
1507 return ret;
1508
1509 uncore_pci_driver->probe = uncore_pci_probe;
1510 uncore_pci_driver->remove = uncore_pci_remove;
1511
1512 ret = pci_register_driver(uncore_pci_driver);
1513 if (ret == 0)
1514 pcidrv_registered = true;
1515 else
1516 uncore_types_exit(pci_uncores);
1517
1518 return ret;
1519}
1520
1521static void __init uncore_pci_exit(void)
1522{
1523 if (pcidrv_registered) {
1524 pcidrv_registered = false;
1525 pci_unregister_driver(uncore_pci_driver);
1526 uncore_types_exit(pci_uncores);
1527 }
1528}
1529
1530static void __cpuinit uncore_cpu_dying(int cpu)
1531{
1532 struct intel_uncore_type *type;
1533 struct intel_uncore_pmu *pmu;
1534 struct intel_uncore_box *box;
1535 int i, j;
1536
1537 for (i = 0; msr_uncores[i]; i++) {
1538 type = msr_uncores[i];
1539 for (j = 0; j < type->num_boxes; j++) {
1540 pmu = &type->pmus[j];
1541 box = *per_cpu_ptr(pmu->box, cpu);
1542 *per_cpu_ptr(pmu->box, cpu) = NULL;
1543 if (box && atomic_dec_and_test(&box->refcnt))
1544 kfree(box);
1545 }
1546 }
1547}
1548
1549static int __cpuinit uncore_cpu_starting(int cpu)
1550{
1551 struct intel_uncore_type *type;
1552 struct intel_uncore_pmu *pmu;
1553 struct intel_uncore_box *box, *exist;
1554 int i, j, k, phys_id;
1555
1556 phys_id = topology_physical_package_id(cpu);
1557
1558 for (i = 0; msr_uncores[i]; i++) {
1559 type = msr_uncores[i];
1560 for (j = 0; j < type->num_boxes; j++) {
1561 pmu = &type->pmus[j];
1562 box = *per_cpu_ptr(pmu->box, cpu);
1563 /* called by uncore_cpu_init? */
1564 if (box && box->phys_id >= 0) {
1565 uncore_box_init(box);
1566 continue;
1567 }
1568
1569 for_each_online_cpu(k) {
1570 exist = *per_cpu_ptr(pmu->box, k);
1571 if (exist && exist->phys_id == phys_id) {
1572 atomic_inc(&exist->refcnt);
1573 *per_cpu_ptr(pmu->box, cpu) = exist;
1574 kfree(box);
1575 box = NULL;
1576 break;
1577 }
1578 }
1579
1580 if (box) {
1581 box->phys_id = phys_id;
1582 uncore_box_init(box);
1583 }
1584 }
1585 }
1586 return 0;
1587}
1588
1589static int __cpuinit uncore_cpu_prepare(int cpu, int phys_id)
1590{
1591 struct intel_uncore_type *type;
1592 struct intel_uncore_pmu *pmu;
1593 struct intel_uncore_box *box;
1594 int i, j;
1595
1596 for (i = 0; msr_uncores[i]; i++) {
1597 type = msr_uncores[i];
1598 for (j = 0; j < type->num_boxes; j++) {
1599 pmu = &type->pmus[j];
1600 if (pmu->func_id < 0)
1601 pmu->func_id = j;
1602
1603 box = uncore_alloc_box(type, cpu);
1604 if (!box)
1605 return -ENOMEM;
1606
1607 box->pmu = pmu;
1608 box->phys_id = phys_id;
1609 *per_cpu_ptr(pmu->box, cpu) = box;
1610 }
1611 }
1612 return 0;
1613}
1614
1615static void __cpuinit uncore_change_context(struct intel_uncore_type **uncores,
1616 int old_cpu, int new_cpu)
1617{
1618 struct intel_uncore_type *type;
1619 struct intel_uncore_pmu *pmu;
1620 struct intel_uncore_box *box;
1621 int i, j;
1622
1623 for (i = 0; uncores[i]; i++) {
1624 type = uncores[i];
1625 for (j = 0; j < type->num_boxes; j++) {
1626 pmu = &type->pmus[j];
1627 if (old_cpu < 0)
1628 box = uncore_pmu_to_box(pmu, new_cpu);
1629 else
1630 box = uncore_pmu_to_box(pmu, old_cpu);
1631 if (!box)
1632 continue;
1633
1634 if (old_cpu < 0) {
1635 WARN_ON_ONCE(box->cpu != -1);
1636 box->cpu = new_cpu;
1637 continue;
1638 }
1639
1640 WARN_ON_ONCE(box->cpu != old_cpu);
1641 if (new_cpu >= 0) {
1642 uncore_pmu_cancel_hrtimer(box);
1643 perf_pmu_migrate_context(&pmu->pmu,
1644 old_cpu, new_cpu);
1645 box->cpu = new_cpu;
1646 } else {
1647 box->cpu = -1;
1648 }
1649 }
1650 }
1651}
1652
1653static void __cpuinit uncore_event_exit_cpu(int cpu)
1654{
1655 int i, phys_id, target;
1656
1657 /* if exiting cpu is used for collecting uncore events */
1658 if (!cpumask_test_and_clear_cpu(cpu, &uncore_cpu_mask))
1659 return;
1660
1661 /* find a new cpu to collect uncore events */
1662 phys_id = topology_physical_package_id(cpu);
1663 target = -1;
1664 for_each_online_cpu(i) {
1665 if (i == cpu)
1666 continue;
1667 if (phys_id == topology_physical_package_id(i)) {
1668 target = i;
1669 break;
1670 }
1671 }
1672
1673 /* migrate uncore events to the new cpu */
1674 if (target >= 0)
1675 cpumask_set_cpu(target, &uncore_cpu_mask);
1676
1677 uncore_change_context(msr_uncores, cpu, target);
1678 uncore_change_context(pci_uncores, cpu, target);
1679}
1680
1681static void __cpuinit uncore_event_init_cpu(int cpu)
1682{
1683 int i, phys_id;
1684
1685 phys_id = topology_physical_package_id(cpu);
1686 for_each_cpu(i, &uncore_cpu_mask) {
1687 if (phys_id == topology_physical_package_id(i))
1688 return;
1689 }
1690
1691 cpumask_set_cpu(cpu, &uncore_cpu_mask);
1692
1693 uncore_change_context(msr_uncores, -1, cpu);
1694 uncore_change_context(pci_uncores, -1, cpu);
1695}
1696
1697static int __cpuinit uncore_cpu_notifier(struct notifier_block *self,
1698 unsigned long action, void *hcpu)
1699{
1700 unsigned int cpu = (long)hcpu;
1701
1702 /* allocate/free data structure for uncore box */
1703 switch (action & ~CPU_TASKS_FROZEN) {
1704 case CPU_UP_PREPARE:
1705 uncore_cpu_prepare(cpu, -1);
1706 break;
1707 case CPU_STARTING:
1708 uncore_cpu_starting(cpu);
1709 break;
1710 case CPU_UP_CANCELED:
1711 case CPU_DYING:
1712 uncore_cpu_dying(cpu);
1713 break;
1714 default:
1715 break;
1716 }
1717
1718 /* select the cpu that collects uncore events */
1719 switch (action & ~CPU_TASKS_FROZEN) {
1720 case CPU_DOWN_FAILED:
1721 case CPU_STARTING:
1722 uncore_event_init_cpu(cpu);
1723 break;
1724 case CPU_DOWN_PREPARE:
1725 uncore_event_exit_cpu(cpu);
1726 break;
1727 default:
1728 break;
1729 }
1730
1731 return NOTIFY_OK;
1732}
1733
1734static struct notifier_block uncore_cpu_nb __cpuinitdata = {
1735 .notifier_call = uncore_cpu_notifier,
1736 /*
1737 * to migrate uncore events, our notifier should be executed
1738 * before perf core's notifier.
1739 */
1740 .priority = CPU_PRI_PERF + 1,
1741};
1742
1743static void __init uncore_cpu_setup(void *dummy)
1744{
1745 uncore_cpu_starting(smp_processor_id());
1746}
1747
1748static int __init uncore_cpu_init(void)
1749{
1750 int ret, cpu, max_cores;
1751
1752 max_cores = boot_cpu_data.x86_max_cores;
1753 switch (boot_cpu_data.x86_model) {
1754 case 26: /* Nehalem */
1755 case 30:
1756 case 37: /* Westmere */
1757 case 44:
1758 msr_uncores = nhm_msr_uncores;
1759 break;
1760 case 42: /* Sandy Bridge */
1761 if (snb_uncore_cbox.num_boxes > max_cores)
1762 snb_uncore_cbox.num_boxes = max_cores;
1763 msr_uncores = snb_msr_uncores;
1764 break;
1765 case 45: /* Sandy Birdge-EP */
1766 if (snbep_uncore_cbox.num_boxes > max_cores)
1767 snbep_uncore_cbox.num_boxes = max_cores;
1768 msr_uncores = snbep_msr_uncores;
1769 break;
1770 default:
1771 return 0;
1772 }
1773
1774 ret = uncore_types_init(msr_uncores);
1775 if (ret)
1776 return ret;
1777
1778 get_online_cpus();
1779
1780 for_each_online_cpu(cpu) {
1781 int i, phys_id = topology_physical_package_id(cpu);
1782
1783 for_each_cpu(i, &uncore_cpu_mask) {
1784 if (phys_id == topology_physical_package_id(i)) {
1785 phys_id = -1;
1786 break;
1787 }
1788 }
1789 if (phys_id < 0)
1790 continue;
1791
1792 uncore_cpu_prepare(cpu, phys_id);
1793 uncore_event_init_cpu(cpu);
1794 }
1795 on_each_cpu(uncore_cpu_setup, NULL, 1);
1796
1797 register_cpu_notifier(&uncore_cpu_nb);
1798
1799 put_online_cpus();
1800
1801 return 0;
1802}
1803
1804static int __init uncore_pmus_register(void)
1805{
1806 struct intel_uncore_pmu *pmu;
1807 struct intel_uncore_type *type;
1808 int i, j;
1809
1810 for (i = 0; msr_uncores[i]; i++) {
1811 type = msr_uncores[i];
1812 for (j = 0; j < type->num_boxes; j++) {
1813 pmu = &type->pmus[j];
1814 uncore_pmu_register(pmu);
1815 }
1816 }
1817
1818 for (i = 0; pci_uncores[i]; i++) {
1819 type = pci_uncores[i];
1820 for (j = 0; j < type->num_boxes; j++) {
1821 pmu = &type->pmus[j];
1822 uncore_pmu_register(pmu);
1823 }
1824 }
1825
1826 return 0;
1827}
1828
1829static int __init intel_uncore_init(void)
1830{
1831 int ret;
1832
1833 if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
1834 return -ENODEV;
1835
1836 ret = uncore_pci_init();
1837 if (ret)
1838 goto fail;
1839 ret = uncore_cpu_init();
1840 if (ret) {
1841 uncore_pci_exit();
1842 goto fail;
1843 }
1844
1845 uncore_pmus_register();
1846 return 0;
1847fail:
1848 return ret;
1849}
1850device_initcall(intel_uncore_init);
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h
new file mode 100644
index 000000000000..b13e9ea81def
--- /dev/null
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h
@@ -0,0 +1,424 @@
1#include <linux/module.h>
2#include <linux/slab.h>
3#include <linux/pci.h>
4#include <linux/perf_event.h>
5#include "perf_event.h"
6
7#define UNCORE_PMU_NAME_LEN 32
8#define UNCORE_BOX_HASH_SIZE 8
9
10#define UNCORE_PMU_HRTIMER_INTERVAL (60 * NSEC_PER_SEC)
11
12#define UNCORE_FIXED_EVENT 0xff
13#define UNCORE_PMC_IDX_MAX_GENERIC 8
14#define UNCORE_PMC_IDX_FIXED UNCORE_PMC_IDX_MAX_GENERIC
15#define UNCORE_PMC_IDX_MAX (UNCORE_PMC_IDX_FIXED + 1)
16
17#define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff)
18
19/* SNB event control */
20#define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff
21#define SNB_UNC_CTL_UMASK_MASK 0x0000ff00
22#define SNB_UNC_CTL_EDGE_DET (1 << 18)
23#define SNB_UNC_CTL_EN (1 << 22)
24#define SNB_UNC_CTL_INVERT (1 << 23)
25#define SNB_UNC_CTL_CMASK_MASK 0x1f000000
26#define NHM_UNC_CTL_CMASK_MASK 0xff000000
27#define NHM_UNC_FIXED_CTR_CTL_EN (1 << 0)
28
29#define SNB_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \
30 SNB_UNC_CTL_UMASK_MASK | \
31 SNB_UNC_CTL_EDGE_DET | \
32 SNB_UNC_CTL_INVERT | \
33 SNB_UNC_CTL_CMASK_MASK)
34
35#define NHM_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \
36 SNB_UNC_CTL_UMASK_MASK | \
37 SNB_UNC_CTL_EDGE_DET | \
38 SNB_UNC_CTL_INVERT | \
39 NHM_UNC_CTL_CMASK_MASK)
40
41/* SNB global control register */
42#define SNB_UNC_PERF_GLOBAL_CTL 0x391
43#define SNB_UNC_FIXED_CTR_CTRL 0x394
44#define SNB_UNC_FIXED_CTR 0x395
45
46/* SNB uncore global control */
47#define SNB_UNC_GLOBAL_CTL_CORE_ALL ((1 << 4) - 1)
48#define SNB_UNC_GLOBAL_CTL_EN (1 << 29)
49
50/* SNB Cbo register */
51#define SNB_UNC_CBO_0_PERFEVTSEL0 0x700
52#define SNB_UNC_CBO_0_PER_CTR0 0x706
53#define SNB_UNC_CBO_MSR_OFFSET 0x10
54
55/* NHM global control register */
56#define NHM_UNC_PERF_GLOBAL_CTL 0x391
57#define NHM_UNC_FIXED_CTR 0x394
58#define NHM_UNC_FIXED_CTR_CTRL 0x395
59
60/* NHM uncore global control */
61#define NHM_UNC_GLOBAL_CTL_EN_PC_ALL ((1ULL << 8) - 1)
62#define NHM_UNC_GLOBAL_CTL_EN_FC (1ULL << 32)
63
64/* NHM uncore register */
65#define NHM_UNC_PERFEVTSEL0 0x3c0
66#define NHM_UNC_UNCORE_PMC0 0x3b0
67
68/* SNB-EP Box level control */
69#define SNBEP_PMON_BOX_CTL_RST_CTRL (1 << 0)
70#define SNBEP_PMON_BOX_CTL_RST_CTRS (1 << 1)
71#define SNBEP_PMON_BOX_CTL_FRZ (1 << 8)
72#define SNBEP_PMON_BOX_CTL_FRZ_EN (1 << 16)
73#define SNBEP_PMON_BOX_CTL_INT (SNBEP_PMON_BOX_CTL_RST_CTRL | \
74 SNBEP_PMON_BOX_CTL_RST_CTRS | \
75 SNBEP_PMON_BOX_CTL_FRZ_EN)
76/* SNB-EP event control */
77#define SNBEP_PMON_CTL_EV_SEL_MASK 0x000000ff
78#define SNBEP_PMON_CTL_UMASK_MASK 0x0000ff00
79#define SNBEP_PMON_CTL_RST (1 << 17)
80#define SNBEP_PMON_CTL_EDGE_DET (1 << 18)
81#define SNBEP_PMON_CTL_EV_SEL_EXT (1 << 21) /* only for QPI */
82#define SNBEP_PMON_CTL_EN (1 << 22)
83#define SNBEP_PMON_CTL_INVERT (1 << 23)
84#define SNBEP_PMON_CTL_TRESH_MASK 0xff000000
85#define SNBEP_PMON_RAW_EVENT_MASK (SNBEP_PMON_CTL_EV_SEL_MASK | \
86 SNBEP_PMON_CTL_UMASK_MASK | \
87 SNBEP_PMON_CTL_EDGE_DET | \
88 SNBEP_PMON_CTL_INVERT | \
89 SNBEP_PMON_CTL_TRESH_MASK)
90
91/* SNB-EP Ubox event control */
92#define SNBEP_U_MSR_PMON_CTL_TRESH_MASK 0x1f000000
93#define SNBEP_U_MSR_PMON_RAW_EVENT_MASK \
94 (SNBEP_PMON_CTL_EV_SEL_MASK | \
95 SNBEP_PMON_CTL_UMASK_MASK | \
96 SNBEP_PMON_CTL_EDGE_DET | \
97 SNBEP_PMON_CTL_INVERT | \
98 SNBEP_U_MSR_PMON_CTL_TRESH_MASK)
99
100#define SNBEP_CBO_PMON_CTL_TID_EN (1 << 19)
101#define SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK (SNBEP_PMON_RAW_EVENT_MASK | \
102 SNBEP_CBO_PMON_CTL_TID_EN)
103
104/* SNB-EP PCU event control */
105#define SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK 0x0000c000
106#define SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK 0x1f000000
107#define SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT (1 << 30)
108#define SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET (1 << 31)
109#define SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK \
110 (SNBEP_PMON_CTL_EV_SEL_MASK | \
111 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \
112 SNBEP_PMON_CTL_EDGE_DET | \
113 SNBEP_PMON_CTL_INVERT | \
114 SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \
115 SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \
116 SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET)
117
118/* SNB-EP pci control register */
119#define SNBEP_PCI_PMON_BOX_CTL 0xf4
120#define SNBEP_PCI_PMON_CTL0 0xd8
121/* SNB-EP pci counter register */
122#define SNBEP_PCI_PMON_CTR0 0xa0
123
124/* SNB-EP home agent register */
125#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH0 0x40
126#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH1 0x44
127#define SNBEP_HA_PCI_PMON_BOX_OPCODEMATCH 0x48
128/* SNB-EP memory controller register */
129#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTL 0xf0
130#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTR 0xd0
131/* SNB-EP QPI register */
132#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH0 0x228
133#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH1 0x22c
134#define SNBEP_Q_Py_PCI_PMON_PKT_MASK0 0x238
135#define SNBEP_Q_Py_PCI_PMON_PKT_MASK1 0x23c
136
137/* SNB-EP Ubox register */
138#define SNBEP_U_MSR_PMON_CTR0 0xc16
139#define SNBEP_U_MSR_PMON_CTL0 0xc10
140
141#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTL 0xc08
142#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTR 0xc09
143
144/* SNB-EP Cbo register */
145#define SNBEP_C0_MSR_PMON_CTR0 0xd16
146#define SNBEP_C0_MSR_PMON_CTL0 0xd10
147#define SNBEP_C0_MSR_PMON_BOX_CTL 0xd04
148#define SNBEP_C0_MSR_PMON_BOX_FILTER 0xd14
149#define SNBEP_CB0_MSR_PMON_BOX_FILTER_MASK 0xfffffc1f
150#define SNBEP_CBO_MSR_OFFSET 0x20
151
152/* SNB-EP PCU register */
153#define SNBEP_PCU_MSR_PMON_CTR0 0xc36
154#define SNBEP_PCU_MSR_PMON_CTL0 0xc30
155#define SNBEP_PCU_MSR_PMON_BOX_CTL 0xc24
156#define SNBEP_PCU_MSR_PMON_BOX_FILTER 0xc34
157#define SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK 0xffffffff
158#define SNBEP_PCU_MSR_CORE_C3_CTR 0x3fc
159#define SNBEP_PCU_MSR_CORE_C6_CTR 0x3fd
160
161struct intel_uncore_ops;
162struct intel_uncore_pmu;
163struct intel_uncore_box;
164struct uncore_event_desc;
165
166struct intel_uncore_type {
167 const char *name;
168 int num_counters;
169 int num_boxes;
170 int perf_ctr_bits;
171 int fixed_ctr_bits;
172 unsigned perf_ctr;
173 unsigned event_ctl;
174 unsigned event_mask;
175 unsigned fixed_ctr;
176 unsigned fixed_ctl;
177 unsigned box_ctl;
178 unsigned msr_offset;
179 unsigned num_shared_regs:8;
180 unsigned single_fixed:1;
181 struct event_constraint unconstrainted;
182 struct event_constraint *constraints;
183 struct intel_uncore_pmu *pmus;
184 struct intel_uncore_ops *ops;
185 struct uncore_event_desc *event_descs;
186 const struct attribute_group *attr_groups[3];
187};
188
189#define format_group attr_groups[0]
190
191struct intel_uncore_ops {
192 void (*init_box)(struct intel_uncore_box *);
193 void (*disable_box)(struct intel_uncore_box *);
194 void (*enable_box)(struct intel_uncore_box *);
195 void (*disable_event)(struct intel_uncore_box *, struct perf_event *);
196 void (*enable_event)(struct intel_uncore_box *, struct perf_event *);
197 u64 (*read_counter)(struct intel_uncore_box *, struct perf_event *);
198 int (*hw_config)(struct intel_uncore_box *, struct perf_event *);
199 struct event_constraint *(*get_constraint)(struct intel_uncore_box *,
200 struct perf_event *);
201 void (*put_constraint)(struct intel_uncore_box *, struct perf_event *);
202};
203
204struct intel_uncore_pmu {
205 struct pmu pmu;
206 char name[UNCORE_PMU_NAME_LEN];
207 int pmu_idx;
208 int func_id;
209 struct intel_uncore_type *type;
210 struct intel_uncore_box ** __percpu box;
211 struct list_head box_list;
212};
213
214struct intel_uncore_extra_reg {
215 raw_spinlock_t lock;
216 u64 config1;
217 atomic_t ref;
218};
219
220struct intel_uncore_box {
221 int phys_id;
222 int n_active; /* number of active events */
223 int n_events;
224 int cpu; /* cpu to collect events */
225 unsigned long flags;
226 atomic_t refcnt;
227 struct perf_event *events[UNCORE_PMC_IDX_MAX];
228 struct perf_event *event_list[UNCORE_PMC_IDX_MAX];
229 unsigned long active_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)];
230 u64 tags[UNCORE_PMC_IDX_MAX];
231 struct pci_dev *pci_dev;
232 struct intel_uncore_pmu *pmu;
233 struct hrtimer hrtimer;
234 struct list_head list;
235 struct intel_uncore_extra_reg shared_regs[0];
236};
237
238#define UNCORE_BOX_FLAG_INITIATED 0
239
240struct uncore_event_desc {
241 struct kobj_attribute attr;
242 const char *config;
243};
244
245#define INTEL_UNCORE_EVENT_DESC(_name, _config) \
246{ \
247 .attr = __ATTR(_name, 0444, uncore_event_show, NULL), \
248 .config = _config, \
249}
250
251#define DEFINE_UNCORE_FORMAT_ATTR(_var, _name, _format) \
252static ssize_t __uncore_##_var##_show(struct kobject *kobj, \
253 struct kobj_attribute *attr, \
254 char *page) \
255{ \
256 BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \
257 return sprintf(page, _format "\n"); \
258} \
259static struct kobj_attribute format_attr_##_var = \
260 __ATTR(_name, 0444, __uncore_##_var##_show, NULL)
261
262
263static ssize_t uncore_event_show(struct kobject *kobj,
264 struct kobj_attribute *attr, char *buf)
265{
266 struct uncore_event_desc *event =
267 container_of(attr, struct uncore_event_desc, attr);
268 return sprintf(buf, "%s", event->config);
269}
270
271static inline unsigned uncore_pci_box_ctl(struct intel_uncore_box *box)
272{
273 return box->pmu->type->box_ctl;
274}
275
276static inline unsigned uncore_pci_fixed_ctl(struct intel_uncore_box *box)
277{
278 return box->pmu->type->fixed_ctl;
279}
280
281static inline unsigned uncore_pci_fixed_ctr(struct intel_uncore_box *box)
282{
283 return box->pmu->type->fixed_ctr;
284}
285
286static inline
287unsigned uncore_pci_event_ctl(struct intel_uncore_box *box, int idx)
288{
289 return idx * 4 + box->pmu->type->event_ctl;
290}
291
292static inline
293unsigned uncore_pci_perf_ctr(struct intel_uncore_box *box, int idx)
294{
295 return idx * 8 + box->pmu->type->perf_ctr;
296}
297
298static inline
299unsigned uncore_msr_box_ctl(struct intel_uncore_box *box)
300{
301 if (!box->pmu->type->box_ctl)
302 return 0;
303 return box->pmu->type->box_ctl +
304 box->pmu->type->msr_offset * box->pmu->pmu_idx;
305}
306
307static inline
308unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box)
309{
310 if (!box->pmu->type->fixed_ctl)
311 return 0;
312 return box->pmu->type->fixed_ctl +
313 box->pmu->type->msr_offset * box->pmu->pmu_idx;
314}
315
316static inline
317unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box)
318{
319 return box->pmu->type->fixed_ctr +
320 box->pmu->type->msr_offset * box->pmu->pmu_idx;
321}
322
323static inline
324unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx)
325{
326 return idx + box->pmu->type->event_ctl +
327 box->pmu->type->msr_offset * box->pmu->pmu_idx;
328}
329
330static inline
331unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx)
332{
333 return idx + box->pmu->type->perf_ctr +
334 box->pmu->type->msr_offset * box->pmu->pmu_idx;
335}
336
337static inline
338unsigned uncore_fixed_ctl(struct intel_uncore_box *box)
339{
340 if (box->pci_dev)
341 return uncore_pci_fixed_ctl(box);
342 else
343 return uncore_msr_fixed_ctl(box);
344}
345
346static inline
347unsigned uncore_fixed_ctr(struct intel_uncore_box *box)
348{
349 if (box->pci_dev)
350 return uncore_pci_fixed_ctr(box);
351 else
352 return uncore_msr_fixed_ctr(box);
353}
354
355static inline
356unsigned uncore_event_ctl(struct intel_uncore_box *box, int idx)
357{
358 if (box->pci_dev)
359 return uncore_pci_event_ctl(box, idx);
360 else
361 return uncore_msr_event_ctl(box, idx);
362}
363
364static inline
365unsigned uncore_perf_ctr(struct intel_uncore_box *box, int idx)
366{
367 if (box->pci_dev)
368 return uncore_pci_perf_ctr(box, idx);
369 else
370 return uncore_msr_perf_ctr(box, idx);
371}
372
373static inline int uncore_perf_ctr_bits(struct intel_uncore_box *box)
374{
375 return box->pmu->type->perf_ctr_bits;
376}
377
378static inline int uncore_fixed_ctr_bits(struct intel_uncore_box *box)
379{
380 return box->pmu->type->fixed_ctr_bits;
381}
382
383static inline int uncore_num_counters(struct intel_uncore_box *box)
384{
385 return box->pmu->type->num_counters;
386}
387
388static inline void uncore_disable_box(struct intel_uncore_box *box)
389{
390 if (box->pmu->type->ops->disable_box)
391 box->pmu->type->ops->disable_box(box);
392}
393
394static inline void uncore_enable_box(struct intel_uncore_box *box)
395{
396 if (box->pmu->type->ops->enable_box)
397 box->pmu->type->ops->enable_box(box);
398}
399
400static inline void uncore_disable_event(struct intel_uncore_box *box,
401 struct perf_event *event)
402{
403 box->pmu->type->ops->disable_event(box, event);
404}
405
406static inline void uncore_enable_event(struct intel_uncore_box *box,
407 struct perf_event *event)
408{
409 box->pmu->type->ops->enable_event(box, event);
410}
411
412static inline u64 uncore_read_counter(struct intel_uncore_box *box,
413 struct perf_event *event)
414{
415 return box->pmu->type->ops->read_counter(box, event);
416}
417
418static inline void uncore_box_init(struct intel_uncore_box *box)
419{
420 if (!test_and_set_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) {
421 if (box->pmu->type->ops->init_box)
422 box->pmu->type->ops->init_box(box);
423 }
424}
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c
index 47124a73dd73..92c7e39a079f 100644
--- a/arch/x86/kernel/cpu/perf_event_p4.c
+++ b/arch/x86/kernel/cpu/perf_event_p4.c
@@ -895,8 +895,8 @@ static void p4_pmu_disable_pebs(void)
895 * So at moment let leave metrics turned on forever -- it's 895 * So at moment let leave metrics turned on forever -- it's
896 * ok for now but need to be revisited! 896 * ok for now but need to be revisited!
897 * 897 *
898 * (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)0); 898 * (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, (u64)0);
899 * (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)0); 899 * (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, (u64)0);
900 */ 900 */
901} 901}
902 902
@@ -909,7 +909,7 @@ static inline void p4_pmu_disable_event(struct perf_event *event)
909 * state we need to clear P4_CCCR_OVF, otherwise interrupt get 909 * state we need to clear P4_CCCR_OVF, otherwise interrupt get
910 * asserted again and again 910 * asserted again and again
911 */ 911 */
912 (void)checking_wrmsrl(hwc->config_base, 912 (void)wrmsrl_safe(hwc->config_base,
913 (u64)(p4_config_unpack_cccr(hwc->config)) & 913 (u64)(p4_config_unpack_cccr(hwc->config)) &
914 ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED); 914 ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED);
915} 915}
@@ -943,8 +943,8 @@ static void p4_pmu_enable_pebs(u64 config)
943 943
944 bind = &p4_pebs_bind_map[idx]; 944 bind = &p4_pebs_bind_map[idx];
945 945
946 (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)bind->metric_pebs); 946 (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, (u64)bind->metric_pebs);
947 (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)bind->metric_vert); 947 (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, (u64)bind->metric_vert);
948} 948}
949 949
950static void p4_pmu_enable_event(struct perf_event *event) 950static void p4_pmu_enable_event(struct perf_event *event)
@@ -978,8 +978,8 @@ static void p4_pmu_enable_event(struct perf_event *event)
978 */ 978 */
979 p4_pmu_enable_pebs(hwc->config); 979 p4_pmu_enable_pebs(hwc->config);
980 980
981 (void)checking_wrmsrl(escr_addr, escr_conf); 981 (void)wrmsrl_safe(escr_addr, escr_conf);
982 (void)checking_wrmsrl(hwc->config_base, 982 (void)wrmsrl_safe(hwc->config_base,
983 (cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE); 983 (cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE);
984} 984}
985 985
@@ -1325,7 +1325,7 @@ __init int p4_pmu_init(void)
1325 unsigned int low, high; 1325 unsigned int low, high;
1326 1326
1327 /* If we get stripped -- indexing fails */ 1327 /* If we get stripped -- indexing fails */
1328 BUILD_BUG_ON(ARCH_P4_MAX_CCCR > X86_PMC_MAX_GENERIC); 1328 BUILD_BUG_ON(ARCH_P4_MAX_CCCR > INTEL_PMC_MAX_GENERIC);
1329 1329
1330 rdmsr(MSR_IA32_MISC_ENABLE, low, high); 1330 rdmsr(MSR_IA32_MISC_ENABLE, low, high);
1331 if (!(low & (1 << 7))) { 1331 if (!(low & (1 << 7))) {
diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c
index 32bcfc7dd230..e4dd0f7a0453 100644
--- a/arch/x86/kernel/cpu/perf_event_p6.c
+++ b/arch/x86/kernel/cpu/perf_event_p6.c
@@ -71,7 +71,7 @@ p6_pmu_disable_event(struct perf_event *event)
71 if (cpuc->enabled) 71 if (cpuc->enabled)
72 val |= ARCH_PERFMON_EVENTSEL_ENABLE; 72 val |= ARCH_PERFMON_EVENTSEL_ENABLE;
73 73
74 (void)checking_wrmsrl(hwc->config_base, val); 74 (void)wrmsrl_safe(hwc->config_base, val);
75} 75}
76 76
77static void p6_pmu_enable_event(struct perf_event *event) 77static void p6_pmu_enable_event(struct perf_event *event)
@@ -84,7 +84,7 @@ static void p6_pmu_enable_event(struct perf_event *event)
84 if (cpuc->enabled) 84 if (cpuc->enabled)
85 val |= ARCH_PERFMON_EVENTSEL_ENABLE; 85 val |= ARCH_PERFMON_EVENTSEL_ENABLE;
86 86
87 (void)checking_wrmsrl(hwc->config_base, val); 87 (void)wrmsrl_safe(hwc->config_base, val);
88} 88}
89 89
90PMU_FORMAT_ATTR(event, "config:0-7" ); 90PMU_FORMAT_ATTR(event, "config:0-7" );
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c
index fbdfc6917180..1649cf899ad6 100644
--- a/arch/x86/kernel/microcode_core.c
+++ b/arch/x86/kernel/microcode_core.c
@@ -87,6 +87,7 @@
87#include <asm/microcode.h> 87#include <asm/microcode.h>
88#include <asm/processor.h> 88#include <asm/processor.h>
89#include <asm/cpu_device_id.h> 89#include <asm/cpu_device_id.h>
90#include <asm/perf_event.h>
90 91
91MODULE_DESCRIPTION("Microcode Update Driver"); 92MODULE_DESCRIPTION("Microcode Update Driver");
92MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); 93MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
@@ -277,7 +278,6 @@ static int reload_for_cpu(int cpu)
277 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 278 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
278 int err = 0; 279 int err = 0;
279 280
280 mutex_lock(&microcode_mutex);
281 if (uci->valid) { 281 if (uci->valid) {
282 enum ucode_state ustate; 282 enum ucode_state ustate;
283 283
@@ -288,7 +288,6 @@ static int reload_for_cpu(int cpu)
288 if (ustate == UCODE_ERROR) 288 if (ustate == UCODE_ERROR)
289 err = -EINVAL; 289 err = -EINVAL;
290 } 290 }
291 mutex_unlock(&microcode_mutex);
292 291
293 return err; 292 return err;
294} 293}
@@ -298,19 +297,31 @@ static ssize_t reload_store(struct device *dev,
298 const char *buf, size_t size) 297 const char *buf, size_t size)
299{ 298{
300 unsigned long val; 299 unsigned long val;
301 int cpu = dev->id; 300 int cpu;
302 ssize_t ret = 0; 301 ssize_t ret = 0, tmp_ret;
303 302
304 ret = kstrtoul(buf, 0, &val); 303 ret = kstrtoul(buf, 0, &val);
305 if (ret) 304 if (ret)
306 return ret; 305 return ret;
307 306
308 if (val == 1) { 307 if (val != 1)
309 get_online_cpus(); 308 return size;
310 if (cpu_online(cpu)) 309
311 ret = reload_for_cpu(cpu); 310 get_online_cpus();
312 put_online_cpus(); 311 mutex_lock(&microcode_mutex);
312 for_each_online_cpu(cpu) {
313 tmp_ret = reload_for_cpu(cpu);
314 if (tmp_ret != 0)
315 pr_warn("Error reloading microcode on CPU %d\n", cpu);
316
317 /* save retval of the first encountered reload error */
318 if (!ret)
319 ret = tmp_ret;
313 } 320 }
321 if (!ret)
322 perf_check_microcode();
323 mutex_unlock(&microcode_mutex);
324 put_online_cpus();
314 325
315 if (!ret) 326 if (!ret)
316 ret = size; 327 ret = size;
@@ -339,7 +350,6 @@ static DEVICE_ATTR(version, 0400, version_show, NULL);
339static DEVICE_ATTR(processor_flags, 0400, pf_show, NULL); 350static DEVICE_ATTR(processor_flags, 0400, pf_show, NULL);
340 351
341static struct attribute *mc_default_attrs[] = { 352static struct attribute *mc_default_attrs[] = {
342 &dev_attr_reload.attr,
343 &dev_attr_version.attr, 353 &dev_attr_version.attr,
344 &dev_attr_processor_flags.attr, 354 &dev_attr_processor_flags.attr,
345 NULL 355 NULL
@@ -516,6 +526,16 @@ static const struct x86_cpu_id microcode_id[] = {
516MODULE_DEVICE_TABLE(x86cpu, microcode_id); 526MODULE_DEVICE_TABLE(x86cpu, microcode_id);
517#endif 527#endif
518 528
529static struct attribute *cpu_root_microcode_attrs[] = {
530 &dev_attr_reload.attr,
531 NULL
532};
533
534static struct attribute_group cpu_root_microcode_group = {
535 .name = "microcode",
536 .attrs = cpu_root_microcode_attrs,
537};
538
519static int __init microcode_init(void) 539static int __init microcode_init(void)
520{ 540{
521 struct cpuinfo_x86 *c = &cpu_data(0); 541 struct cpuinfo_x86 *c = &cpu_data(0);
@@ -540,16 +560,25 @@ static int __init microcode_init(void)
540 mutex_lock(&microcode_mutex); 560 mutex_lock(&microcode_mutex);
541 561
542 error = subsys_interface_register(&mc_cpu_interface); 562 error = subsys_interface_register(&mc_cpu_interface);
543 563 if (!error)
564 perf_check_microcode();
544 mutex_unlock(&microcode_mutex); 565 mutex_unlock(&microcode_mutex);
545 put_online_cpus(); 566 put_online_cpus();
546 567
547 if (error) 568 if (error)
548 goto out_pdev; 569 goto out_pdev;
549 570
571 error = sysfs_create_group(&cpu_subsys.dev_root->kobj,
572 &cpu_root_microcode_group);
573
574 if (error) {
575 pr_err("Error creating microcode group!\n");
576 goto out_driver;
577 }
578
550 error = microcode_dev_init(); 579 error = microcode_dev_init();
551 if (error) 580 if (error)
552 goto out_driver; 581 goto out_ucode_group;
553 582
554 register_syscore_ops(&mc_syscore_ops); 583 register_syscore_ops(&mc_syscore_ops);
555 register_hotcpu_notifier(&mc_cpu_notifier); 584 register_hotcpu_notifier(&mc_cpu_notifier);
@@ -559,7 +588,11 @@ static int __init microcode_init(void)
559 588
560 return 0; 589 return 0;
561 590
562out_driver: 591 out_ucode_group:
592 sysfs_remove_group(&cpu_subsys.dev_root->kobj,
593 &cpu_root_microcode_group);
594
595 out_driver:
563 get_online_cpus(); 596 get_online_cpus();
564 mutex_lock(&microcode_mutex); 597 mutex_lock(&microcode_mutex);
565 598
@@ -568,7 +601,7 @@ out_driver:
568 mutex_unlock(&microcode_mutex); 601 mutex_unlock(&microcode_mutex);
569 put_online_cpus(); 602 put_online_cpus();
570 603
571out_pdev: 604 out_pdev:
572 platform_device_unregister(microcode_pdev); 605 platform_device_unregister(microcode_pdev);
573 return error; 606 return error;
574 607
@@ -584,6 +617,9 @@ static void __exit microcode_exit(void)
584 unregister_hotcpu_notifier(&mc_cpu_notifier); 617 unregister_hotcpu_notifier(&mc_cpu_notifier);
585 unregister_syscore_ops(&mc_syscore_ops); 618 unregister_syscore_ops(&mc_syscore_ops);
586 619
620 sysfs_remove_group(&cpu_subsys.dev_root->kobj,
621 &cpu_root_microcode_group);
622
587 get_online_cpus(); 623 get_online_cpus();
588 mutex_lock(&microcode_mutex); 624 mutex_lock(&microcode_mutex);
589 625
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 9ce885996fd7..17fff18a1031 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -352,9 +352,7 @@ struct pv_cpu_ops pv_cpu_ops = {
352#endif 352#endif
353 .wbinvd = native_wbinvd, 353 .wbinvd = native_wbinvd,
354 .read_msr = native_read_msr_safe, 354 .read_msr = native_read_msr_safe,
355 .rdmsr_regs = native_rdmsr_safe_regs,
356 .write_msr = native_write_msr_safe, 355 .write_msr = native_write_msr_safe,
357 .wrmsr_regs = native_wrmsr_safe_regs,
358 .read_tsc = native_read_tsc, 356 .read_tsc = native_read_tsc,
359 .read_pmc = native_read_pmc, 357 .read_pmc = native_read_pmc,
360 .read_tscp = native_read_tscp, 358 .read_tscp = native_read_tscp,
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 61cdf7fdf099..3e215ba68766 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -466,7 +466,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
466 task->thread.gs = addr; 466 task->thread.gs = addr;
467 if (doit) { 467 if (doit) {
468 load_gs_index(0); 468 load_gs_index(0);
469 ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr); 469 ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, addr);
470 } 470 }
471 } 471 }
472 put_cpu(); 472 put_cpu();
@@ -494,7 +494,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
494 /* set the selector to 0 to not confuse 494 /* set the selector to 0 to not confuse
495 __switch_to */ 495 __switch_to */
496 loadsegment(fs, 0); 496 loadsegment(fs, 0);
497 ret = checking_wrmsrl(MSR_FS_BASE, addr); 497 ret = wrmsrl_safe(MSR_FS_BASE, addr);
498 } 498 }
499 } 499 }
500 put_cpu(); 500 put_cpu();
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index dc4e910a7d96..36fd42091fa7 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -409,9 +409,10 @@ static int validate_insn_bits(struct arch_uprobe *auprobe, struct mm_struct *mm,
409 * arch_uprobe_analyze_insn - instruction analysis including validity and fixups. 409 * arch_uprobe_analyze_insn - instruction analysis including validity and fixups.
410 * @mm: the probed address space. 410 * @mm: the probed address space.
411 * @arch_uprobe: the probepoint information. 411 * @arch_uprobe: the probepoint information.
412 * @addr: virtual address at which to install the probepoint
412 * Return 0 on success or a -ve number on error. 413 * Return 0 on success or a -ve number on error.
413 */ 414 */
414int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm) 415int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long addr)
415{ 416{
416 int ret; 417 int ret;
417 struct insn insn; 418 struct insn insn;
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 2e88438ffd83..9b7ec1150ab0 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -80,10 +80,10 @@ static inline struct kvm_pmc *get_fixed_pmc_idx(struct kvm_pmu *pmu, int idx)
80 80
81static struct kvm_pmc *global_idx_to_pmc(struct kvm_pmu *pmu, int idx) 81static struct kvm_pmc *global_idx_to_pmc(struct kvm_pmu *pmu, int idx)
82{ 82{
83 if (idx < X86_PMC_IDX_FIXED) 83 if (idx < INTEL_PMC_IDX_FIXED)
84 return get_gp_pmc(pmu, MSR_P6_EVNTSEL0 + idx, MSR_P6_EVNTSEL0); 84 return get_gp_pmc(pmu, MSR_P6_EVNTSEL0 + idx, MSR_P6_EVNTSEL0);
85 else 85 else
86 return get_fixed_pmc_idx(pmu, idx - X86_PMC_IDX_FIXED); 86 return get_fixed_pmc_idx(pmu, idx - INTEL_PMC_IDX_FIXED);
87} 87}
88 88
89void kvm_deliver_pmi(struct kvm_vcpu *vcpu) 89void kvm_deliver_pmi(struct kvm_vcpu *vcpu)
@@ -291,7 +291,7 @@ static void reprogram_idx(struct kvm_pmu *pmu, int idx)
291 if (pmc_is_gp(pmc)) 291 if (pmc_is_gp(pmc))
292 reprogram_gp_counter(pmc, pmc->eventsel); 292 reprogram_gp_counter(pmc, pmc->eventsel);
293 else { 293 else {
294 int fidx = idx - X86_PMC_IDX_FIXED; 294 int fidx = idx - INTEL_PMC_IDX_FIXED;
295 reprogram_fixed_counter(pmc, 295 reprogram_fixed_counter(pmc,
296 fixed_en_pmi(pmu->fixed_ctr_ctrl, fidx), fidx); 296 fixed_en_pmi(pmu->fixed_ctr_ctrl, fidx), fidx);
297 } 297 }
@@ -452,7 +452,7 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu)
452 return; 452 return;
453 453
454 pmu->nr_arch_gp_counters = min((int)(entry->eax >> 8) & 0xff, 454 pmu->nr_arch_gp_counters = min((int)(entry->eax >> 8) & 0xff,
455 X86_PMC_MAX_GENERIC); 455 INTEL_PMC_MAX_GENERIC);
456 pmu->counter_bitmask[KVM_PMC_GP] = 456 pmu->counter_bitmask[KVM_PMC_GP] =
457 ((u64)1 << ((entry->eax >> 16) & 0xff)) - 1; 457 ((u64)1 << ((entry->eax >> 16) & 0xff)) - 1;
458 bitmap_len = (entry->eax >> 24) & 0xff; 458 bitmap_len = (entry->eax >> 24) & 0xff;
@@ -462,13 +462,13 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu)
462 pmu->nr_arch_fixed_counters = 0; 462 pmu->nr_arch_fixed_counters = 0;
463 } else { 463 } else {
464 pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f), 464 pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f),
465 X86_PMC_MAX_FIXED); 465 INTEL_PMC_MAX_FIXED);
466 pmu->counter_bitmask[KVM_PMC_FIXED] = 466 pmu->counter_bitmask[KVM_PMC_FIXED] =
467 ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1; 467 ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1;
468 } 468 }
469 469
470 pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) | 470 pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) |
471 (((1ull << pmu->nr_arch_fixed_counters) - 1) << X86_PMC_IDX_FIXED); 471 (((1ull << pmu->nr_arch_fixed_counters) - 1) << INTEL_PMC_IDX_FIXED);
472 pmu->global_ctrl_mask = ~pmu->global_ctrl; 472 pmu->global_ctrl_mask = ~pmu->global_ctrl;
473} 473}
474 474
@@ -478,15 +478,15 @@ void kvm_pmu_init(struct kvm_vcpu *vcpu)
478 struct kvm_pmu *pmu = &vcpu->arch.pmu; 478 struct kvm_pmu *pmu = &vcpu->arch.pmu;
479 479
480 memset(pmu, 0, sizeof(*pmu)); 480 memset(pmu, 0, sizeof(*pmu));
481 for (i = 0; i < X86_PMC_MAX_GENERIC; i++) { 481 for (i = 0; i < INTEL_PMC_MAX_GENERIC; i++) {
482 pmu->gp_counters[i].type = KVM_PMC_GP; 482 pmu->gp_counters[i].type = KVM_PMC_GP;
483 pmu->gp_counters[i].vcpu = vcpu; 483 pmu->gp_counters[i].vcpu = vcpu;
484 pmu->gp_counters[i].idx = i; 484 pmu->gp_counters[i].idx = i;
485 } 485 }
486 for (i = 0; i < X86_PMC_MAX_FIXED; i++) { 486 for (i = 0; i < INTEL_PMC_MAX_FIXED; i++) {
487 pmu->fixed_counters[i].type = KVM_PMC_FIXED; 487 pmu->fixed_counters[i].type = KVM_PMC_FIXED;
488 pmu->fixed_counters[i].vcpu = vcpu; 488 pmu->fixed_counters[i].vcpu = vcpu;
489 pmu->fixed_counters[i].idx = i + X86_PMC_IDX_FIXED; 489 pmu->fixed_counters[i].idx = i + INTEL_PMC_IDX_FIXED;
490 } 490 }
491 init_irq_work(&pmu->irq_work, trigger_pmi); 491 init_irq_work(&pmu->irq_work, trigger_pmi);
492 kvm_pmu_cpuid_update(vcpu); 492 kvm_pmu_cpuid_update(vcpu);
@@ -498,13 +498,13 @@ void kvm_pmu_reset(struct kvm_vcpu *vcpu)
498 int i; 498 int i;
499 499
500 irq_work_sync(&pmu->irq_work); 500 irq_work_sync(&pmu->irq_work);
501 for (i = 0; i < X86_PMC_MAX_GENERIC; i++) { 501 for (i = 0; i < INTEL_PMC_MAX_GENERIC; i++) {
502 struct kvm_pmc *pmc = &pmu->gp_counters[i]; 502 struct kvm_pmc *pmc = &pmu->gp_counters[i];
503 stop_counter(pmc); 503 stop_counter(pmc);
504 pmc->counter = pmc->eventsel = 0; 504 pmc->counter = pmc->eventsel = 0;
505 } 505 }
506 506
507 for (i = 0; i < X86_PMC_MAX_FIXED; i++) 507 for (i = 0; i < INTEL_PMC_MAX_FIXED; i++)
508 stop_counter(&pmu->fixed_counters[i]); 508 stop_counter(&pmu->fixed_counters[i]);
509 509
510 pmu->fixed_ctr_ctrl = pmu->global_ctrl = pmu->global_status = 510 pmu->fixed_ctr_ctrl = pmu->global_ctrl = pmu->global_status =
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
index 911d2641f14c..62d02e3c3ed6 100644
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -710,16 +710,6 @@ TRACE_EVENT(kvm_skinit,
710 __entry->rip, __entry->slb) 710 __entry->rip, __entry->slb)
711); 711);
712 712
713#define __print_insn(insn, ilen) ({ \
714 int i; \
715 const char *ret = p->buffer + p->len; \
716 \
717 for (i = 0; i < ilen; ++i) \
718 trace_seq_printf(p, " %02x", insn[i]); \
719 trace_seq_printf(p, "%c", 0); \
720 ret; \
721 })
722
723#define KVM_EMUL_INSN_F_CR0_PE (1 << 0) 713#define KVM_EMUL_INSN_F_CR0_PE (1 << 0)
724#define KVM_EMUL_INSN_F_EFL_VM (1 << 1) 714#define KVM_EMUL_INSN_F_EFL_VM (1 << 1)
725#define KVM_EMUL_INSN_F_CS_D (1 << 2) 715#define KVM_EMUL_INSN_F_CS_D (1 << 2)
@@ -786,7 +776,7 @@ TRACE_EVENT(kvm_emulate_insn,
786 776
787 TP_printk("%x:%llx:%s (%s)%s", 777 TP_printk("%x:%llx:%s (%s)%s",
788 __entry->csbase, __entry->rip, 778 __entry->csbase, __entry->rip,
789 __print_insn(__entry->insn, __entry->len), 779 __print_hex(__entry->insn, __entry->len),
790 __print_symbolic(__entry->flags, 780 __print_symbolic(__entry->flags,
791 kvm_trace_symbol_emul_flags), 781 kvm_trace_symbol_emul_flags),
792 __entry->failed ? " failed" : "" 782 __entry->failed ? " failed" : ""
diff --git a/arch/x86/lib/msr-reg-export.c b/arch/x86/lib/msr-reg-export.c
index a311cc59b65d..8d6ef78b5d01 100644
--- a/arch/x86/lib/msr-reg-export.c
+++ b/arch/x86/lib/msr-reg-export.c
@@ -1,5 +1,5 @@
1#include <linux/module.h> 1#include <linux/module.h>
2#include <asm/msr.h> 2#include <asm/msr.h>
3 3
4EXPORT_SYMBOL(native_rdmsr_safe_regs); 4EXPORT_SYMBOL(rdmsr_safe_regs);
5EXPORT_SYMBOL(native_wrmsr_safe_regs); 5EXPORT_SYMBOL(wrmsr_safe_regs);
diff --git a/arch/x86/lib/msr-reg.S b/arch/x86/lib/msr-reg.S
index 69fa10623f21..f6d13eefad10 100644
--- a/arch/x86/lib/msr-reg.S
+++ b/arch/x86/lib/msr-reg.S
@@ -6,13 +6,13 @@
6 6
7#ifdef CONFIG_X86_64 7#ifdef CONFIG_X86_64
8/* 8/*
9 * int native_{rdmsr,wrmsr}_safe_regs(u32 gprs[8]); 9 * int {rdmsr,wrmsr}_safe_regs(u32 gprs[8]);
10 * 10 *
11 * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi] 11 * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi]
12 * 12 *
13 */ 13 */
14.macro op_safe_regs op 14.macro op_safe_regs op
15ENTRY(native_\op\()_safe_regs) 15ENTRY(\op\()_safe_regs)
16 CFI_STARTPROC 16 CFI_STARTPROC
17 pushq_cfi %rbx 17 pushq_cfi %rbx
18 pushq_cfi %rbp 18 pushq_cfi %rbp
@@ -45,13 +45,13 @@ ENTRY(native_\op\()_safe_regs)
45 45
46 _ASM_EXTABLE(1b, 3b) 46 _ASM_EXTABLE(1b, 3b)
47 CFI_ENDPROC 47 CFI_ENDPROC
48ENDPROC(native_\op\()_safe_regs) 48ENDPROC(\op\()_safe_regs)
49.endm 49.endm
50 50
51#else /* X86_32 */ 51#else /* X86_32 */
52 52
53.macro op_safe_regs op 53.macro op_safe_regs op
54ENTRY(native_\op\()_safe_regs) 54ENTRY(\op\()_safe_regs)
55 CFI_STARTPROC 55 CFI_STARTPROC
56 pushl_cfi %ebx 56 pushl_cfi %ebx
57 pushl_cfi %ebp 57 pushl_cfi %ebp
@@ -92,7 +92,7 @@ ENTRY(native_\op\()_safe_regs)
92 92
93 _ASM_EXTABLE(1b, 3b) 93 _ASM_EXTABLE(1b, 3b)
94 CFI_ENDPROC 94 CFI_ENDPROC
95ENDPROC(native_\op\()_safe_regs) 95ENDPROC(\op\()_safe_regs)
96.endm 96.endm
97 97
98#endif 98#endif
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
index 303f08637826..b2b94438ff05 100644
--- a/arch/x86/oprofile/op_model_amd.c
+++ b/arch/x86/oprofile/op_model_amd.c
@@ -312,7 +312,7 @@ static int op_amd_fill_in_addresses(struct op_msrs * const msrs)
312 goto fail; 312 goto fail;
313 } 313 }
314 /* both registers must be reserved */ 314 /* both registers must be reserved */
315 if (num_counters == AMD64_NUM_COUNTERS_F15H) { 315 if (num_counters == AMD64_NUM_COUNTERS_CORE) {
316 msrs->counters[i].addr = MSR_F15H_PERF_CTR + (i << 1); 316 msrs->counters[i].addr = MSR_F15H_PERF_CTR + (i << 1);
317 msrs->controls[i].addr = MSR_F15H_PERF_CTL + (i << 1); 317 msrs->controls[i].addr = MSR_F15H_PERF_CTL + (i << 1);
318 } else { 318 } else {
@@ -514,7 +514,7 @@ static int op_amd_init(struct oprofile_operations *ops)
514 ops->create_files = setup_ibs_files; 514 ops->create_files = setup_ibs_files;
515 515
516 if (boot_cpu_data.x86 == 0x15) { 516 if (boot_cpu_data.x86 == 0x15) {
517 num_counters = AMD64_NUM_COUNTERS_F15H; 517 num_counters = AMD64_NUM_COUNTERS_CORE;
518 } else { 518 } else {
519 num_counters = AMD64_NUM_COUNTERS; 519 num_counters = AMD64_NUM_COUNTERS;
520 } 520 }
diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c
index 66e6d9359826..0faad646f5fd 100644
--- a/arch/x86/vdso/vdso32-setup.c
+++ b/arch/x86/vdso/vdso32-setup.c
@@ -205,9 +205,9 @@ void syscall32_cpu_init(void)
205{ 205{
206 /* Load these always in case some future AMD CPU supports 206 /* Load these always in case some future AMD CPU supports
207 SYSENTER from compat mode too. */ 207 SYSENTER from compat mode too. */
208 checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); 208 wrmsrl_safe(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS);
209 checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL); 209 wrmsrl_safe(MSR_IA32_SYSENTER_ESP, 0ULL);
210 checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target); 210 wrmsrl_safe(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target);
211 211
212 wrmsrl(MSR_CSTAR, ia32_cstar_target); 212 wrmsrl(MSR_CSTAR, ia32_cstar_target);
213} 213}
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index ff962d4b821e..ed7d54985d0c 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1124,9 +1124,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = {
1124 .wbinvd = native_wbinvd, 1124 .wbinvd = native_wbinvd,
1125 1125
1126 .read_msr = native_read_msr_safe, 1126 .read_msr = native_read_msr_safe,
1127 .rdmsr_regs = native_rdmsr_safe_regs,
1128 .write_msr = xen_write_msr_safe, 1127 .write_msr = xen_write_msr_safe,
1129 .wrmsr_regs = native_wrmsr_safe_regs,
1130 1128
1131 .read_tsc = native_read_tsc, 1129 .read_tsc = native_read_tsc,
1132 .read_pmc = native_read_pmc, 1130 .read_pmc = native_read_pmc,
diff --git a/drivers/oprofile/oprofile_perf.c b/drivers/oprofile/oprofile_perf.c
index efc4b7f308cf..f3cfa0b9adfa 100644
--- a/drivers/oprofile/oprofile_perf.c
+++ b/drivers/oprofile/oprofile_perf.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright 2010 ARM Ltd. 2 * Copyright 2010 ARM Ltd.
3 * Copyright 2012 Advanced Micro Devices, Inc., Robert Richter
3 * 4 *
4 * Perf-events backend for OProfile. 5 * Perf-events backend for OProfile.
5 */ 6 */
@@ -25,7 +26,7 @@ static int oprofile_perf_enabled;
25static DEFINE_MUTEX(oprofile_perf_mutex); 26static DEFINE_MUTEX(oprofile_perf_mutex);
26 27
27static struct op_counter_config *counter_config; 28static struct op_counter_config *counter_config;
28static struct perf_event **perf_events[NR_CPUS]; 29static DEFINE_PER_CPU(struct perf_event **, perf_events);
29static int num_counters; 30static int num_counters;
30 31
31/* 32/*
@@ -38,7 +39,7 @@ static void op_overflow_handler(struct perf_event *event,
38 u32 cpu = smp_processor_id(); 39 u32 cpu = smp_processor_id();
39 40
40 for (id = 0; id < num_counters; ++id) 41 for (id = 0; id < num_counters; ++id)
41 if (perf_events[cpu][id] == event) 42 if (per_cpu(perf_events, cpu)[id] == event)
42 break; 43 break;
43 44
44 if (id != num_counters) 45 if (id != num_counters)
@@ -74,7 +75,7 @@ static int op_create_counter(int cpu, int event)
74{ 75{
75 struct perf_event *pevent; 76 struct perf_event *pevent;
76 77
77 if (!counter_config[event].enabled || perf_events[cpu][event]) 78 if (!counter_config[event].enabled || per_cpu(perf_events, cpu)[event])
78 return 0; 79 return 0;
79 80
80 pevent = perf_event_create_kernel_counter(&counter_config[event].attr, 81 pevent = perf_event_create_kernel_counter(&counter_config[event].attr,
@@ -91,18 +92,18 @@ static int op_create_counter(int cpu, int event)
91 return -EBUSY; 92 return -EBUSY;
92 } 93 }
93 94
94 perf_events[cpu][event] = pevent; 95 per_cpu(perf_events, cpu)[event] = pevent;
95 96
96 return 0; 97 return 0;
97} 98}
98 99
99static void op_destroy_counter(int cpu, int event) 100static void op_destroy_counter(int cpu, int event)
100{ 101{
101 struct perf_event *pevent = perf_events[cpu][event]; 102 struct perf_event *pevent = per_cpu(perf_events, cpu)[event];
102 103
103 if (pevent) { 104 if (pevent) {
104 perf_event_release_kernel(pevent); 105 perf_event_release_kernel(pevent);
105 perf_events[cpu][event] = NULL; 106 per_cpu(perf_events, cpu)[event] = NULL;
106 } 107 }
107} 108}
108 109
@@ -257,12 +258,12 @@ void oprofile_perf_exit(void)
257 258
258 for_each_possible_cpu(cpu) { 259 for_each_possible_cpu(cpu) {
259 for (id = 0; id < num_counters; ++id) { 260 for (id = 0; id < num_counters; ++id) {
260 event = perf_events[cpu][id]; 261 event = per_cpu(perf_events, cpu)[id];
261 if (event) 262 if (event)
262 perf_event_release_kernel(event); 263 perf_event_release_kernel(event);
263 } 264 }
264 265
265 kfree(perf_events[cpu]); 266 kfree(per_cpu(perf_events, cpu));
266 } 267 }
267 268
268 kfree(counter_config); 269 kfree(counter_config);
@@ -277,8 +278,6 @@ int __init oprofile_perf_init(struct oprofile_operations *ops)
277 if (ret) 278 if (ret)
278 return ret; 279 return ret;
279 280
280 memset(&perf_events, 0, sizeof(perf_events));
281
282 num_counters = perf_num_counters(); 281 num_counters = perf_num_counters();
283 if (num_counters <= 0) { 282 if (num_counters <= 0) {
284 pr_info("oprofile: no performance counters\n"); 283 pr_info("oprofile: no performance counters\n");
@@ -298,9 +297,9 @@ int __init oprofile_perf_init(struct oprofile_operations *ops)
298 } 297 }
299 298
300 for_each_possible_cpu(cpu) { 299 for_each_possible_cpu(cpu) {
301 perf_events[cpu] = kcalloc(num_counters, 300 per_cpu(perf_events, cpu) = kcalloc(num_counters,
302 sizeof(struct perf_event *), GFP_KERNEL); 301 sizeof(struct perf_event *), GFP_KERNEL);
303 if (!perf_events[cpu]) { 302 if (!per_cpu(perf_events, cpu)) {
304 pr_info("oprofile: failed to allocate %d perf events " 303 pr_info("oprofile: failed to allocate %d perf events "
305 "for cpu %d\n", num_counters, cpu); 304 "for cpu %d\n", num_counters, cpu);
306 ret = -ENOMEM; 305 ret = -ENOMEM;
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index 176a939d1547..af961d6f7ab1 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -65,7 +65,7 @@ struct trace_iterator {
65 void *private; 65 void *private;
66 int cpu_file; 66 int cpu_file;
67 struct mutex mutex; 67 struct mutex mutex;
68 struct ring_buffer_iter *buffer_iter[NR_CPUS]; 68 struct ring_buffer_iter **buffer_iter;
69 unsigned long iter_flags; 69 unsigned long iter_flags;
70 70
71 /* trace_seq for __print_flags() and __print_symbolic() etc. */ 71 /* trace_seq for __print_flags() and __print_symbolic() etc. */
@@ -207,6 +207,9 @@ struct ftrace_event_call {
207 * bit 1: enabled 207 * bit 1: enabled
208 * bit 2: filter_active 208 * bit 2: filter_active
209 * bit 3: enabled cmd record 209 * bit 3: enabled cmd record
210 * bit 4: allow trace by non root (cap any)
211 * bit 5: failed to apply filter
212 * bit 6: ftrace internal event (do not enable)
210 * 213 *
211 * Changes to flags must hold the event_mutex. 214 * Changes to flags must hold the event_mutex.
212 * 215 *
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
index c513a40510f5..0976fc46d1e0 100644
--- a/include/linux/jump_label.h
+++ b/include/linux/jump_label.h
@@ -42,8 +42,7 @@
42 * allowed. 42 * allowed.
43 * 43 *
44 * Not initializing the key (static data is initialized to 0s anyway) is the 44 * Not initializing the key (static data is initialized to 0s anyway) is the
45 * same as using STATIC_KEY_INIT_FALSE and static_key_false() is 45 * same as using STATIC_KEY_INIT_FALSE.
46 * equivalent with static_branch().
47 * 46 *
48*/ 47*/
49 48
@@ -107,12 +106,6 @@ static __always_inline bool static_key_true(struct static_key *key)
107 return !static_key_false(key); 106 return !static_key_false(key);
108} 107}
109 108
110/* Deprecated. Please use 'static_key_false() instead. */
111static __always_inline bool static_branch(struct static_key *key)
112{
113 return arch_static_branch(key);
114}
115
116extern struct jump_entry __start___jump_table[]; 109extern struct jump_entry __start___jump_table[];
117extern struct jump_entry __stop___jump_table[]; 110extern struct jump_entry __stop___jump_table[];
118 111
@@ -166,14 +159,6 @@ static __always_inline bool static_key_true(struct static_key *key)
166 return false; 159 return false;
167} 160}
168 161
169/* Deprecated. Please use 'static_key_false() instead. */
170static __always_inline bool static_branch(struct static_key *key)
171{
172 if (unlikely(atomic_read(&key->enabled)) > 0)
173 return true;
174 return false;
175}
176
177static inline void static_key_slow_inc(struct static_key *key) 162static inline void static_key_slow_inc(struct static_key *key)
178{ 163{
179 atomic_inc(&key->enabled); 164 atomic_inc(&key->enabled);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index ab741b0d0074..5f187026b812 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2755,6 +2755,17 @@
2755#define PCI_DEVICE_ID_INTEL_IOAT_SNB7 0x3c27 2755#define PCI_DEVICE_ID_INTEL_IOAT_SNB7 0x3c27
2756#define PCI_DEVICE_ID_INTEL_IOAT_SNB8 0x3c2e 2756#define PCI_DEVICE_ID_INTEL_IOAT_SNB8 0x3c2e
2757#define PCI_DEVICE_ID_INTEL_IOAT_SNB9 0x3c2f 2757#define PCI_DEVICE_ID_INTEL_IOAT_SNB9 0x3c2f
2758#define PCI_DEVICE_ID_INTEL_UNC_HA 0x3c46
2759#define PCI_DEVICE_ID_INTEL_UNC_IMC0 0x3cb0
2760#define PCI_DEVICE_ID_INTEL_UNC_IMC1 0x3cb1
2761#define PCI_DEVICE_ID_INTEL_UNC_IMC2 0x3cb4
2762#define PCI_DEVICE_ID_INTEL_UNC_IMC3 0x3cb5
2763#define PCI_DEVICE_ID_INTEL_UNC_QPI0 0x3c41
2764#define PCI_DEVICE_ID_INTEL_UNC_QPI1 0x3c42
2765#define PCI_DEVICE_ID_INTEL_UNC_R2PCIE 0x3c43
2766#define PCI_DEVICE_ID_INTEL_UNC_R3QPI0 0x3c44
2767#define PCI_DEVICE_ID_INTEL_UNC_R3QPI1 0x3c45
2768#define PCI_DEVICE_ID_INTEL_JAKETOWN_UBOX 0x3ce0
2758#define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f 2769#define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f
2759#define PCI_DEVICE_ID_INTEL_5100_16 0x65f0 2770#define PCI_DEVICE_ID_INTEL_5100_16 0x65f0
2760#define PCI_DEVICE_ID_INTEL_5100_21 0x65f5 2771#define PCI_DEVICE_ID_INTEL_5100_21 0x65f5
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 45db49f64bb4..76c5c8b724a7 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -677,6 +677,7 @@ struct hw_perf_event {
677 u64 last_tag; 677 u64 last_tag;
678 unsigned long config_base; 678 unsigned long config_base;
679 unsigned long event_base; 679 unsigned long event_base;
680 int event_base_rdpmc;
680 int idx; 681 int idx;
681 int last_cpu; 682 int last_cpu;
682 683
@@ -1106,6 +1107,8 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr,
1106 struct task_struct *task, 1107 struct task_struct *task,
1107 perf_overflow_handler_t callback, 1108 perf_overflow_handler_t callback,
1108 void *context); 1109 void *context);
1110extern void perf_pmu_migrate_context(struct pmu *pmu,
1111 int src_cpu, int dst_cpu);
1109extern u64 perf_event_read_value(struct perf_event *event, 1112extern u64 perf_event_read_value(struct perf_event *event,
1110 u64 *enabled, u64 *running); 1113 u64 *enabled, u64 *running);
1111 1114
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 4a1f493e0fef..64d9df5c3a49 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1581,7 +1581,6 @@ struct task_struct {
1581#endif 1581#endif
1582#ifdef CONFIG_UPROBES 1582#ifdef CONFIG_UPROBES
1583 struct uprobe_task *utask; 1583 struct uprobe_task *utask;
1584 int uprobe_srcu_id;
1585#endif 1584#endif
1586}; 1585};
1587 1586
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index bd96ecd0e05c..802de56c41e8 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -153,7 +153,7 @@ static inline void tracepoint_synchronize_unregister(void)
153 } \ 153 } \
154 static inline void trace_##name##_rcuidle(proto) \ 154 static inline void trace_##name##_rcuidle(proto) \
155 { \ 155 { \
156 if (static_branch(&__tracepoint_##name.key)) \ 156 if (static_key_false(&__tracepoint_##name.key)) \
157 __DO_TRACE(&__tracepoint_##name, \ 157 __DO_TRACE(&__tracepoint_##name, \
158 TP_PROTO(data_proto), \ 158 TP_PROTO(data_proto), \
159 TP_ARGS(data_args), \ 159 TP_ARGS(data_args), \
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index 769724944fc6..c6bc2faaf261 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -571,6 +571,7 @@ static inline void ftrace_test_probe_##call(void) \
571 571
572#undef __print_flags 572#undef __print_flags
573#undef __print_symbolic 573#undef __print_symbolic
574#undef __print_hex
574#undef __get_dynamic_array 575#undef __get_dynamic_array
575#undef __get_str 576#undef __get_str
576 577
diff --git a/kernel/events/core.c b/kernel/events/core.c
index d7d71d6ec972..f1cf0edeb39a 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -1645,6 +1645,8 @@ perf_install_in_context(struct perf_event_context *ctx,
1645 lockdep_assert_held(&ctx->mutex); 1645 lockdep_assert_held(&ctx->mutex);
1646 1646
1647 event->ctx = ctx; 1647 event->ctx = ctx;
1648 if (event->cpu != -1)
1649 event->cpu = cpu;
1648 1650
1649 if (!task) { 1651 if (!task) {
1650 /* 1652 /*
@@ -6252,6 +6254,8 @@ SYSCALL_DEFINE5(perf_event_open,
6252 } 6254 }
6253 } 6255 }
6254 6256
6257 get_online_cpus();
6258
6255 event = perf_event_alloc(&attr, cpu, task, group_leader, NULL, 6259 event = perf_event_alloc(&attr, cpu, task, group_leader, NULL,
6256 NULL, NULL); 6260 NULL, NULL);
6257 if (IS_ERR(event)) { 6261 if (IS_ERR(event)) {
@@ -6304,7 +6308,7 @@ SYSCALL_DEFINE5(perf_event_open,
6304 /* 6308 /*
6305 * Get the target context (task or percpu): 6309 * Get the target context (task or percpu):
6306 */ 6310 */
6307 ctx = find_get_context(pmu, task, cpu); 6311 ctx = find_get_context(pmu, task, event->cpu);
6308 if (IS_ERR(ctx)) { 6312 if (IS_ERR(ctx)) {
6309 err = PTR_ERR(ctx); 6313 err = PTR_ERR(ctx);
6310 goto err_alloc; 6314 goto err_alloc;
@@ -6377,20 +6381,23 @@ SYSCALL_DEFINE5(perf_event_open,
6377 mutex_lock(&ctx->mutex); 6381 mutex_lock(&ctx->mutex);
6378 6382
6379 if (move_group) { 6383 if (move_group) {
6380 perf_install_in_context(ctx, group_leader, cpu); 6384 synchronize_rcu();
6385 perf_install_in_context(ctx, group_leader, event->cpu);
6381 get_ctx(ctx); 6386 get_ctx(ctx);
6382 list_for_each_entry(sibling, &group_leader->sibling_list, 6387 list_for_each_entry(sibling, &group_leader->sibling_list,
6383 group_entry) { 6388 group_entry) {
6384 perf_install_in_context(ctx, sibling, cpu); 6389 perf_install_in_context(ctx, sibling, event->cpu);
6385 get_ctx(ctx); 6390 get_ctx(ctx);
6386 } 6391 }
6387 } 6392 }
6388 6393
6389 perf_install_in_context(ctx, event, cpu); 6394 perf_install_in_context(ctx, event, event->cpu);
6390 ++ctx->generation; 6395 ++ctx->generation;
6391 perf_unpin_context(ctx); 6396 perf_unpin_context(ctx);
6392 mutex_unlock(&ctx->mutex); 6397 mutex_unlock(&ctx->mutex);
6393 6398
6399 put_online_cpus();
6400
6394 event->owner = current; 6401 event->owner = current;
6395 6402
6396 mutex_lock(&current->perf_event_mutex); 6403 mutex_lock(&current->perf_event_mutex);
@@ -6419,6 +6426,7 @@ err_context:
6419err_alloc: 6426err_alloc:
6420 free_event(event); 6427 free_event(event);
6421err_task: 6428err_task:
6429 put_online_cpus();
6422 if (task) 6430 if (task)
6423 put_task_struct(task); 6431 put_task_struct(task);
6424err_group_fd: 6432err_group_fd:
@@ -6479,6 +6487,39 @@ err:
6479} 6487}
6480EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter); 6488EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter);
6481 6489
6490void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu)
6491{
6492 struct perf_event_context *src_ctx;
6493 struct perf_event_context *dst_ctx;
6494 struct perf_event *event, *tmp;
6495 LIST_HEAD(events);
6496
6497 src_ctx = &per_cpu_ptr(pmu->pmu_cpu_context, src_cpu)->ctx;
6498 dst_ctx = &per_cpu_ptr(pmu->pmu_cpu_context, dst_cpu)->ctx;
6499
6500 mutex_lock(&src_ctx->mutex);
6501 list_for_each_entry_safe(event, tmp, &src_ctx->event_list,
6502 event_entry) {
6503 perf_remove_from_context(event);
6504 put_ctx(src_ctx);
6505 list_add(&event->event_entry, &events);
6506 }
6507 mutex_unlock(&src_ctx->mutex);
6508
6509 synchronize_rcu();
6510
6511 mutex_lock(&dst_ctx->mutex);
6512 list_for_each_entry_safe(event, tmp, &events, event_entry) {
6513 list_del(&event->event_entry);
6514 if (event->state >= PERF_EVENT_STATE_OFF)
6515 event->state = PERF_EVENT_STATE_INACTIVE;
6516 perf_install_in_context(dst_ctx, event, dst_cpu);
6517 get_ctx(dst_ctx);
6518 }
6519 mutex_unlock(&dst_ctx->mutex);
6520}
6521EXPORT_SYMBOL_GPL(perf_pmu_migrate_context);
6522
6482static void sync_child_event(struct perf_event *child_event, 6523static void sync_child_event(struct perf_event *child_event,
6483 struct task_struct *child) 6524 struct task_struct *child)
6484{ 6525{
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 985be4d80fe8..f93532748bca 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -38,13 +38,29 @@
38#define UINSNS_PER_PAGE (PAGE_SIZE/UPROBE_XOL_SLOT_BYTES) 38#define UINSNS_PER_PAGE (PAGE_SIZE/UPROBE_XOL_SLOT_BYTES)
39#define MAX_UPROBE_XOL_SLOTS UINSNS_PER_PAGE 39#define MAX_UPROBE_XOL_SLOTS UINSNS_PER_PAGE
40 40
41static struct srcu_struct uprobes_srcu;
42static struct rb_root uprobes_tree = RB_ROOT; 41static struct rb_root uprobes_tree = RB_ROOT;
43 42
44static DEFINE_SPINLOCK(uprobes_treelock); /* serialize rbtree access */ 43static DEFINE_SPINLOCK(uprobes_treelock); /* serialize rbtree access */
45 44
46#define UPROBES_HASH_SZ 13 45#define UPROBES_HASH_SZ 13
47 46
47/*
48 * We need separate register/unregister and mmap/munmap lock hashes because
49 * of mmap_sem nesting.
50 *
51 * uprobe_register() needs to install probes on (potentially) all processes
52 * and thus needs to acquire multiple mmap_sems (consequtively, not
53 * concurrently), whereas uprobe_mmap() is called while holding mmap_sem
54 * for the particular process doing the mmap.
55 *
56 * uprobe_register()->register_for_each_vma() needs to drop/acquire mmap_sem
57 * because of lock order against i_mmap_mutex. This means there's a hole in
58 * the register vma iteration where a mmap() can happen.
59 *
60 * Thus uprobe_register() can race with uprobe_mmap() and we can try and
61 * install a probe where one is already installed.
62 */
63
48/* serialize (un)register */ 64/* serialize (un)register */
49static struct mutex uprobes_mutex[UPROBES_HASH_SZ]; 65static struct mutex uprobes_mutex[UPROBES_HASH_SZ];
50 66
@@ -61,17 +77,6 @@ static struct mutex uprobes_mmap_mutex[UPROBES_HASH_SZ];
61 */ 77 */
62static atomic_t uprobe_events = ATOMIC_INIT(0); 78static atomic_t uprobe_events = ATOMIC_INIT(0);
63 79
64/*
65 * Maintain a temporary per vma info that can be used to search if a vma
66 * has already been handled. This structure is introduced since extending
67 * vm_area_struct wasnt recommended.
68 */
69struct vma_info {
70 struct list_head probe_list;
71 struct mm_struct *mm;
72 loff_t vaddr;
73};
74
75struct uprobe { 80struct uprobe {
76 struct rb_node rb_node; /* node in the rb tree */ 81 struct rb_node rb_node; /* node in the rb tree */
77 atomic_t ref; 82 atomic_t ref;
@@ -100,7 +105,8 @@ static bool valid_vma(struct vm_area_struct *vma, bool is_register)
100 if (!is_register) 105 if (!is_register)
101 return true; 106 return true;
102 107
103 if ((vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)) == (VM_READ|VM_EXEC)) 108 if ((vma->vm_flags & (VM_HUGETLB|VM_READ|VM_WRITE|VM_EXEC|VM_SHARED))
109 == (VM_READ|VM_EXEC))
104 return true; 110 return true;
105 111
106 return false; 112 return false;
@@ -129,33 +135,17 @@ static loff_t vma_address(struct vm_area_struct *vma, loff_t offset)
129static int __replace_page(struct vm_area_struct *vma, struct page *page, struct page *kpage) 135static int __replace_page(struct vm_area_struct *vma, struct page *page, struct page *kpage)
130{ 136{
131 struct mm_struct *mm = vma->vm_mm; 137 struct mm_struct *mm = vma->vm_mm;
132 pgd_t *pgd;
133 pud_t *pud;
134 pmd_t *pmd;
135 pte_t *ptep;
136 spinlock_t *ptl;
137 unsigned long addr; 138 unsigned long addr;
138 int err = -EFAULT; 139 spinlock_t *ptl;
140 pte_t *ptep;
139 141
140 addr = page_address_in_vma(page, vma); 142 addr = page_address_in_vma(page, vma);
141 if (addr == -EFAULT) 143 if (addr == -EFAULT)
142 goto out; 144 return -EFAULT;
143
144 pgd = pgd_offset(mm, addr);
145 if (!pgd_present(*pgd))
146 goto out;
147
148 pud = pud_offset(pgd, addr);
149 if (!pud_present(*pud))
150 goto out;
151
152 pmd = pmd_offset(pud, addr);
153 if (!pmd_present(*pmd))
154 goto out;
155 145
156 ptep = pte_offset_map_lock(mm, pmd, addr, &ptl); 146 ptep = page_check_address(page, mm, addr, &ptl, 0);
157 if (!ptep) 147 if (!ptep)
158 goto out; 148 return -EAGAIN;
159 149
160 get_page(kpage); 150 get_page(kpage);
161 page_add_new_anon_rmap(kpage, vma, addr); 151 page_add_new_anon_rmap(kpage, vma, addr);
@@ -174,10 +164,8 @@ static int __replace_page(struct vm_area_struct *vma, struct page *page, struct
174 try_to_free_swap(page); 164 try_to_free_swap(page);
175 put_page(page); 165 put_page(page);
176 pte_unmap_unlock(ptep, ptl); 166 pte_unmap_unlock(ptep, ptl);
177 err = 0;
178 167
179out: 168 return 0;
180 return err;
181} 169}
182 170
183/** 171/**
@@ -222,9 +210,8 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
222 void *vaddr_old, *vaddr_new; 210 void *vaddr_old, *vaddr_new;
223 struct vm_area_struct *vma; 211 struct vm_area_struct *vma;
224 struct uprobe *uprobe; 212 struct uprobe *uprobe;
225 loff_t addr;
226 int ret; 213 int ret;
227 214retry:
228 /* Read the page with vaddr into memory */ 215 /* Read the page with vaddr into memory */
229 ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &old_page, &vma); 216 ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &old_page, &vma);
230 if (ret <= 0) 217 if (ret <= 0)
@@ -246,10 +233,6 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
246 if (mapping != vma->vm_file->f_mapping) 233 if (mapping != vma->vm_file->f_mapping)
247 goto put_out; 234 goto put_out;
248 235
249 addr = vma_address(vma, uprobe->offset);
250 if (vaddr != (unsigned long)addr)
251 goto put_out;
252
253 ret = -ENOMEM; 236 ret = -ENOMEM;
254 new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr); 237 new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr);
255 if (!new_page) 238 if (!new_page)
@@ -267,11 +250,7 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
267 vaddr_new = kmap_atomic(new_page); 250 vaddr_new = kmap_atomic(new_page);
268 251
269 memcpy(vaddr_new, vaddr_old, PAGE_SIZE); 252 memcpy(vaddr_new, vaddr_old, PAGE_SIZE);
270 253 memcpy(vaddr_new + (vaddr & ~PAGE_MASK), &opcode, UPROBE_SWBP_INSN_SIZE);
271 /* poke the new insn in, ASSUMES we don't cross page boundary */
272 vaddr &= ~PAGE_MASK;
273 BUG_ON(vaddr + UPROBE_SWBP_INSN_SIZE > PAGE_SIZE);
274 memcpy(vaddr_new + vaddr, &opcode, UPROBE_SWBP_INSN_SIZE);
275 254
276 kunmap_atomic(vaddr_new); 255 kunmap_atomic(vaddr_new);
277 kunmap_atomic(vaddr_old); 256 kunmap_atomic(vaddr_old);
@@ -291,6 +270,8 @@ unlock_out:
291put_out: 270put_out:
292 put_page(old_page); 271 put_page(old_page);
293 272
273 if (unlikely(ret == -EAGAIN))
274 goto retry;
294 return ret; 275 return ret;
295} 276}
296 277
@@ -312,7 +293,7 @@ static int read_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_
312 void *vaddr_new; 293 void *vaddr_new;
313 int ret; 294 int ret;
314 295
315 ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &page, NULL); 296 ret = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &page, NULL);
316 if (ret <= 0) 297 if (ret <= 0)
317 return ret; 298 return ret;
318 299
@@ -333,10 +314,20 @@ static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr)
333 uprobe_opcode_t opcode; 314 uprobe_opcode_t opcode;
334 int result; 315 int result;
335 316
317 if (current->mm == mm) {
318 pagefault_disable();
319 result = __copy_from_user_inatomic(&opcode, (void __user*)vaddr,
320 sizeof(opcode));
321 pagefault_enable();
322
323 if (likely(result == 0))
324 goto out;
325 }
326
336 result = read_opcode(mm, vaddr, &opcode); 327 result = read_opcode(mm, vaddr, &opcode);
337 if (result) 328 if (result)
338 return result; 329 return result;
339 330out:
340 if (is_swbp_insn(&opcode)) 331 if (is_swbp_insn(&opcode))
341 return 1; 332 return 1;
342 333
@@ -355,7 +346,9 @@ static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr)
355int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr) 346int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr)
356{ 347{
357 int result; 348 int result;
358 349 /*
350 * See the comment near uprobes_hash().
351 */
359 result = is_swbp_at_addr(mm, vaddr); 352 result = is_swbp_at_addr(mm, vaddr);
360 if (result == 1) 353 if (result == 1)
361 return -EEXIST; 354 return -EEXIST;
@@ -520,7 +513,6 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
520 uprobe->inode = igrab(inode); 513 uprobe->inode = igrab(inode);
521 uprobe->offset = offset; 514 uprobe->offset = offset;
522 init_rwsem(&uprobe->consumer_rwsem); 515 init_rwsem(&uprobe->consumer_rwsem);
523 INIT_LIST_HEAD(&uprobe->pending_list);
524 516
525 /* add to uprobes_tree, sorted on inode:offset */ 517 /* add to uprobes_tree, sorted on inode:offset */
526 cur_uprobe = insert_uprobe(uprobe); 518 cur_uprobe = insert_uprobe(uprobe);
@@ -588,20 +580,22 @@ static bool consumer_del(struct uprobe *uprobe, struct uprobe_consumer *uc)
588} 580}
589 581
590static int 582static int
591__copy_insn(struct address_space *mapping, struct vm_area_struct *vma, char *insn, 583__copy_insn(struct address_space *mapping, struct file *filp, char *insn,
592 unsigned long nbytes, unsigned long offset) 584 unsigned long nbytes, loff_t offset)
593{ 585{
594 struct file *filp = vma->vm_file;
595 struct page *page; 586 struct page *page;
596 void *vaddr; 587 void *vaddr;
597 unsigned long off1; 588 unsigned long off;
598 unsigned long idx; 589 pgoff_t idx;
599 590
600 if (!filp) 591 if (!filp)
601 return -EINVAL; 592 return -EINVAL;
602 593
603 idx = (unsigned long)(offset >> PAGE_CACHE_SHIFT); 594 if (!mapping->a_ops->readpage)
604 off1 = offset &= ~PAGE_MASK; 595 return -EIO;
596
597 idx = offset >> PAGE_CACHE_SHIFT;
598 off = offset & ~PAGE_MASK;
605 599
606 /* 600 /*
607 * Ensure that the page that has the original instruction is 601 * Ensure that the page that has the original instruction is
@@ -612,22 +606,20 @@ __copy_insn(struct address_space *mapping, struct vm_area_struct *vma, char *ins
612 return PTR_ERR(page); 606 return PTR_ERR(page);
613 607
614 vaddr = kmap_atomic(page); 608 vaddr = kmap_atomic(page);
615 memcpy(insn, vaddr + off1, nbytes); 609 memcpy(insn, vaddr + off, nbytes);
616 kunmap_atomic(vaddr); 610 kunmap_atomic(vaddr);
617 page_cache_release(page); 611 page_cache_release(page);
618 612
619 return 0; 613 return 0;
620} 614}
621 615
622static int 616static int copy_insn(struct uprobe *uprobe, struct file *filp)
623copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned long addr)
624{ 617{
625 struct address_space *mapping; 618 struct address_space *mapping;
626 unsigned long nbytes; 619 unsigned long nbytes;
627 int bytes; 620 int bytes;
628 621
629 addr &= ~PAGE_MASK; 622 nbytes = PAGE_SIZE - (uprobe->offset & ~PAGE_MASK);
630 nbytes = PAGE_SIZE - addr;
631 mapping = uprobe->inode->i_mapping; 623 mapping = uprobe->inode->i_mapping;
632 624
633 /* Instruction at end of binary; copy only available bytes */ 625 /* Instruction at end of binary; copy only available bytes */
@@ -638,13 +630,13 @@ copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned long addr)
638 630
639 /* Instruction at the page-boundary; copy bytes in second page */ 631 /* Instruction at the page-boundary; copy bytes in second page */
640 if (nbytes < bytes) { 632 if (nbytes < bytes) {
641 if (__copy_insn(mapping, vma, uprobe->arch.insn + nbytes, 633 int err = __copy_insn(mapping, filp, uprobe->arch.insn + nbytes,
642 bytes - nbytes, uprobe->offset + nbytes)) 634 bytes - nbytes, uprobe->offset + nbytes);
643 return -ENOMEM; 635 if (err)
644 636 return err;
645 bytes = nbytes; 637 bytes = nbytes;
646 } 638 }
647 return __copy_insn(mapping, vma, uprobe->arch.insn, bytes, uprobe->offset); 639 return __copy_insn(mapping, filp, uprobe->arch.insn, bytes, uprobe->offset);
648} 640}
649 641
650/* 642/*
@@ -672,9 +664,8 @@ copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned long addr)
672 */ 664 */
673static int 665static int
674install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, 666install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
675 struct vm_area_struct *vma, loff_t vaddr) 667 struct vm_area_struct *vma, unsigned long vaddr)
676{ 668{
677 unsigned long addr;
678 int ret; 669 int ret;
679 670
680 /* 671 /*
@@ -687,20 +678,22 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
687 if (!uprobe->consumers) 678 if (!uprobe->consumers)
688 return -EEXIST; 679 return -EEXIST;
689 680
690 addr = (unsigned long)vaddr;
691
692 if (!(uprobe->flags & UPROBE_COPY_INSN)) { 681 if (!(uprobe->flags & UPROBE_COPY_INSN)) {
693 ret = copy_insn(uprobe, vma, addr); 682 ret = copy_insn(uprobe, vma->vm_file);
694 if (ret) 683 if (ret)
695 return ret; 684 return ret;
696 685
697 if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn)) 686 if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn))
698 return -EEXIST; 687 return -ENOTSUPP;
699 688
700 ret = arch_uprobe_analyze_insn(&uprobe->arch, mm); 689 ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, vaddr);
701 if (ret) 690 if (ret)
702 return ret; 691 return ret;
703 692
693 /* write_opcode() assumes we don't cross page boundary */
694 BUG_ON((uprobe->offset & ~PAGE_MASK) +
695 UPROBE_SWBP_INSN_SIZE > PAGE_SIZE);
696
704 uprobe->flags |= UPROBE_COPY_INSN; 697 uprobe->flags |= UPROBE_COPY_INSN;
705 } 698 }
706 699
@@ -713,7 +706,7 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
713 * Hence increment before and decrement on failure. 706 * Hence increment before and decrement on failure.
714 */ 707 */
715 atomic_inc(&mm->uprobes_state.count); 708 atomic_inc(&mm->uprobes_state.count);
716 ret = set_swbp(&uprobe->arch, mm, addr); 709 ret = set_swbp(&uprobe->arch, mm, vaddr);
717 if (ret) 710 if (ret)
718 atomic_dec(&mm->uprobes_state.count); 711 atomic_dec(&mm->uprobes_state.count);
719 712
@@ -721,27 +714,21 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
721} 714}
722 715
723static void 716static void
724remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, loff_t vaddr) 717remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, unsigned long vaddr)
725{ 718{
726 if (!set_orig_insn(&uprobe->arch, mm, (unsigned long)vaddr, true)) 719 if (!set_orig_insn(&uprobe->arch, mm, vaddr, true))
727 atomic_dec(&mm->uprobes_state.count); 720 atomic_dec(&mm->uprobes_state.count);
728} 721}
729 722
730/* 723/*
731 * There could be threads that have hit the breakpoint and are entering the 724 * There could be threads that have already hit the breakpoint. They
732 * notifier code and trying to acquire the uprobes_treelock. The thread 725 * will recheck the current insn and restart if find_uprobe() fails.
733 * calling delete_uprobe() that is removing the uprobe from the rb_tree can 726 * See find_active_uprobe().
734 * race with these threads and might acquire the uprobes_treelock compared
735 * to some of the breakpoint hit threads. In such a case, the breakpoint
736 * hit threads will not find the uprobe. The current unregistering thread
737 * waits till all other threads have hit a breakpoint, to acquire the
738 * uprobes_treelock before the uprobe is removed from the rbtree.
739 */ 727 */
740static void delete_uprobe(struct uprobe *uprobe) 728static void delete_uprobe(struct uprobe *uprobe)
741{ 729{
742 unsigned long flags; 730 unsigned long flags;
743 731
744 synchronize_srcu(&uprobes_srcu);
745 spin_lock_irqsave(&uprobes_treelock, flags); 732 spin_lock_irqsave(&uprobes_treelock, flags);
746 rb_erase(&uprobe->rb_node, &uprobes_tree); 733 rb_erase(&uprobe->rb_node, &uprobes_tree);
747 spin_unlock_irqrestore(&uprobes_treelock, flags); 734 spin_unlock_irqrestore(&uprobes_treelock, flags);
@@ -750,139 +737,135 @@ static void delete_uprobe(struct uprobe *uprobe)
750 atomic_dec(&uprobe_events); 737 atomic_dec(&uprobe_events);
751} 738}
752 739
753static struct vma_info * 740struct map_info {
754__find_next_vma_info(struct address_space *mapping, struct list_head *head, 741 struct map_info *next;
755 struct vma_info *vi, loff_t offset, bool is_register) 742 struct mm_struct *mm;
743 unsigned long vaddr;
744};
745
746static inline struct map_info *free_map_info(struct map_info *info)
747{
748 struct map_info *next = info->next;
749 kfree(info);
750 return next;
751}
752
753static struct map_info *
754build_map_info(struct address_space *mapping, loff_t offset, bool is_register)
756{ 755{
756 unsigned long pgoff = offset >> PAGE_SHIFT;
757 struct prio_tree_iter iter; 757 struct prio_tree_iter iter;
758 struct vm_area_struct *vma; 758 struct vm_area_struct *vma;
759 struct vma_info *tmpvi; 759 struct map_info *curr = NULL;
760 unsigned long pgoff; 760 struct map_info *prev = NULL;
761 int existing_vma; 761 struct map_info *info;
762 loff_t vaddr; 762 int more = 0;
763
764 pgoff = offset >> PAGE_SHIFT;
765 763
764 again:
765 mutex_lock(&mapping->i_mmap_mutex);
766 vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { 766 vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
767 if (!valid_vma(vma, is_register)) 767 if (!valid_vma(vma, is_register))
768 continue; 768 continue;
769 769
770 existing_vma = 0; 770 if (!prev && !more) {
771 vaddr = vma_address(vma, offset); 771 /*
772 772 * Needs GFP_NOWAIT to avoid i_mmap_mutex recursion through
773 list_for_each_entry(tmpvi, head, probe_list) { 773 * reclaim. This is optimistic, no harm done if it fails.
774 if (tmpvi->mm == vma->vm_mm && tmpvi->vaddr == vaddr) { 774 */
775 existing_vma = 1; 775 prev = kmalloc(sizeof(struct map_info),
776 break; 776 GFP_NOWAIT | __GFP_NOMEMALLOC | __GFP_NOWARN);
777 } 777 if (prev)
778 prev->next = NULL;
778 } 779 }
779 780 if (!prev) {
780 /* 781 more++;
781 * Another vma needs a probe to be installed. However skip 782 continue;
782 * installing the probe if the vma is about to be unlinked.
783 */
784 if (!existing_vma && atomic_inc_not_zero(&vma->vm_mm->mm_users)) {
785 vi->mm = vma->vm_mm;
786 vi->vaddr = vaddr;
787 list_add(&vi->probe_list, head);
788
789 return vi;
790 } 783 }
791 }
792 784
793 return NULL; 785 if (!atomic_inc_not_zero(&vma->vm_mm->mm_users))
794} 786 continue;
795
796/*
797 * Iterate in the rmap prio tree and find a vma where a probe has not
798 * yet been inserted.
799 */
800static struct vma_info *
801find_next_vma_info(struct address_space *mapping, struct list_head *head,
802 loff_t offset, bool is_register)
803{
804 struct vma_info *vi, *retvi;
805 787
806 vi = kzalloc(sizeof(struct vma_info), GFP_KERNEL); 788 info = prev;
807 if (!vi) 789 prev = prev->next;
808 return ERR_PTR(-ENOMEM); 790 info->next = curr;
791 curr = info;
809 792
810 mutex_lock(&mapping->i_mmap_mutex); 793 info->mm = vma->vm_mm;
811 retvi = __find_next_vma_info(mapping, head, vi, offset, is_register); 794 info->vaddr = vma_address(vma, offset);
795 }
812 mutex_unlock(&mapping->i_mmap_mutex); 796 mutex_unlock(&mapping->i_mmap_mutex);
813 797
814 if (!retvi) 798 if (!more)
815 kfree(vi); 799 goto out;
800
801 prev = curr;
802 while (curr) {
803 mmput(curr->mm);
804 curr = curr->next;
805 }
816 806
817 return retvi; 807 do {
808 info = kmalloc(sizeof(struct map_info), GFP_KERNEL);
809 if (!info) {
810 curr = ERR_PTR(-ENOMEM);
811 goto out;
812 }
813 info->next = prev;
814 prev = info;
815 } while (--more);
816
817 goto again;
818 out:
819 while (prev)
820 prev = free_map_info(prev);
821 return curr;
818} 822}
819 823
820static int register_for_each_vma(struct uprobe *uprobe, bool is_register) 824static int register_for_each_vma(struct uprobe *uprobe, bool is_register)
821{ 825{
822 struct list_head try_list; 826 struct map_info *info;
823 struct vm_area_struct *vma; 827 int err = 0;
824 struct address_space *mapping;
825 struct vma_info *vi, *tmpvi;
826 struct mm_struct *mm;
827 loff_t vaddr;
828 int ret;
829 828
830 mapping = uprobe->inode->i_mapping; 829 info = build_map_info(uprobe->inode->i_mapping,
831 INIT_LIST_HEAD(&try_list); 830 uprobe->offset, is_register);
831 if (IS_ERR(info))
832 return PTR_ERR(info);
832 833
833 ret = 0; 834 while (info) {
835 struct mm_struct *mm = info->mm;
836 struct vm_area_struct *vma;
834 837
835 for (;;) { 838 if (err)
836 vi = find_next_vma_info(mapping, &try_list, uprobe->offset, is_register); 839 goto free;
837 if (!vi)
838 break;
839 840
840 if (IS_ERR(vi)) { 841 down_write(&mm->mmap_sem);
841 ret = PTR_ERR(vi); 842 vma = find_vma(mm, (unsigned long)info->vaddr);
842 break; 843 if (!vma || !valid_vma(vma, is_register))
843 } 844 goto unlock;
844 845
845 mm = vi->mm;
846 down_read(&mm->mmap_sem);
847 vma = find_vma(mm, (unsigned long)vi->vaddr);
848 if (!vma || !valid_vma(vma, is_register)) {
849 list_del(&vi->probe_list);
850 kfree(vi);
851 up_read(&mm->mmap_sem);
852 mmput(mm);
853 continue;
854 }
855 vaddr = vma_address(vma, uprobe->offset);
856 if (vma->vm_file->f_mapping->host != uprobe->inode || 846 if (vma->vm_file->f_mapping->host != uprobe->inode ||
857 vaddr != vi->vaddr) { 847 vma_address(vma, uprobe->offset) != info->vaddr)
858 list_del(&vi->probe_list); 848 goto unlock;
859 kfree(vi);
860 up_read(&mm->mmap_sem);
861 mmput(mm);
862 continue;
863 }
864
865 if (is_register)
866 ret = install_breakpoint(uprobe, mm, vma, vi->vaddr);
867 else
868 remove_breakpoint(uprobe, mm, vi->vaddr);
869 849
870 up_read(&mm->mmap_sem);
871 mmput(mm);
872 if (is_register) { 850 if (is_register) {
873 if (ret && ret == -EEXIST) 851 err = install_breakpoint(uprobe, mm, vma, info->vaddr);
874 ret = 0; 852 /*
875 if (ret) 853 * We can race against uprobe_mmap(), see the
876 break; 854 * comment near uprobe_hash().
855 */
856 if (err == -EEXIST)
857 err = 0;
858 } else {
859 remove_breakpoint(uprobe, mm, info->vaddr);
877 } 860 }
861 unlock:
862 up_write(&mm->mmap_sem);
863 free:
864 mmput(mm);
865 info = free_map_info(info);
878 } 866 }
879 867
880 list_for_each_entry_safe(vi, tmpvi, &try_list, probe_list) { 868 return err;
881 list_del(&vi->probe_list);
882 kfree(vi);
883 }
884
885 return ret;
886} 869}
887 870
888static int __uprobe_register(struct uprobe *uprobe) 871static int __uprobe_register(struct uprobe *uprobe)
@@ -1048,7 +1031,7 @@ static void build_probe_list(struct inode *inode, struct list_head *head)
1048int uprobe_mmap(struct vm_area_struct *vma) 1031int uprobe_mmap(struct vm_area_struct *vma)
1049{ 1032{
1050 struct list_head tmp_list; 1033 struct list_head tmp_list;
1051 struct uprobe *uprobe, *u; 1034 struct uprobe *uprobe;
1052 struct inode *inode; 1035 struct inode *inode;
1053 int ret, count; 1036 int ret, count;
1054 1037
@@ -1066,12 +1049,9 @@ int uprobe_mmap(struct vm_area_struct *vma)
1066 ret = 0; 1049 ret = 0;
1067 count = 0; 1050 count = 0;
1068 1051
1069 list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) { 1052 list_for_each_entry(uprobe, &tmp_list, pending_list) {
1070 loff_t vaddr;
1071
1072 list_del(&uprobe->pending_list);
1073 if (!ret) { 1053 if (!ret) {
1074 vaddr = vma_address(vma, uprobe->offset); 1054 loff_t vaddr = vma_address(vma, uprobe->offset);
1075 1055
1076 if (vaddr < vma->vm_start || vaddr >= vma->vm_end) { 1056 if (vaddr < vma->vm_start || vaddr >= vma->vm_end) {
1077 put_uprobe(uprobe); 1057 put_uprobe(uprobe);
@@ -1079,8 +1059,10 @@ int uprobe_mmap(struct vm_area_struct *vma)
1079 } 1059 }
1080 1060
1081 ret = install_breakpoint(uprobe, vma->vm_mm, vma, vaddr); 1061 ret = install_breakpoint(uprobe, vma->vm_mm, vma, vaddr);
1082 1062 /*
1083 /* Ignore double add: */ 1063 * We can race against uprobe_register(), see the
1064 * comment near uprobe_hash().
1065 */
1084 if (ret == -EEXIST) { 1066 if (ret == -EEXIST) {
1085 ret = 0; 1067 ret = 0;
1086 1068
@@ -1115,7 +1097,7 @@ int uprobe_mmap(struct vm_area_struct *vma)
1115void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end) 1097void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end)
1116{ 1098{
1117 struct list_head tmp_list; 1099 struct list_head tmp_list;
1118 struct uprobe *uprobe, *u; 1100 struct uprobe *uprobe;
1119 struct inode *inode; 1101 struct inode *inode;
1120 1102
1121 if (!atomic_read(&uprobe_events) || !valid_vma(vma, false)) 1103 if (!atomic_read(&uprobe_events) || !valid_vma(vma, false))
@@ -1132,11 +1114,8 @@ void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned lon
1132 mutex_lock(uprobes_mmap_hash(inode)); 1114 mutex_lock(uprobes_mmap_hash(inode));
1133 build_probe_list(inode, &tmp_list); 1115 build_probe_list(inode, &tmp_list);
1134 1116
1135 list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) { 1117 list_for_each_entry(uprobe, &tmp_list, pending_list) {
1136 loff_t vaddr; 1118 loff_t vaddr = vma_address(vma, uprobe->offset);
1137
1138 list_del(&uprobe->pending_list);
1139 vaddr = vma_address(vma, uprobe->offset);
1140 1119
1141 if (vaddr >= start && vaddr < end) { 1120 if (vaddr >= start && vaddr < end) {
1142 /* 1121 /*
@@ -1378,9 +1357,6 @@ void uprobe_free_utask(struct task_struct *t)
1378{ 1357{
1379 struct uprobe_task *utask = t->utask; 1358 struct uprobe_task *utask = t->utask;
1380 1359
1381 if (t->uprobe_srcu_id != -1)
1382 srcu_read_unlock_raw(&uprobes_srcu, t->uprobe_srcu_id);
1383
1384 if (!utask) 1360 if (!utask)
1385 return; 1361 return;
1386 1362
@@ -1398,7 +1374,6 @@ void uprobe_free_utask(struct task_struct *t)
1398void uprobe_copy_process(struct task_struct *t) 1374void uprobe_copy_process(struct task_struct *t)
1399{ 1375{
1400 t->utask = NULL; 1376 t->utask = NULL;
1401 t->uprobe_srcu_id = -1;
1402} 1377}
1403 1378
1404/* 1379/*
@@ -1417,7 +1392,6 @@ static struct uprobe_task *add_utask(void)
1417 if (unlikely(!utask)) 1392 if (unlikely(!utask))
1418 return NULL; 1393 return NULL;
1419 1394
1420 utask->active_uprobe = NULL;
1421 current->utask = utask; 1395 current->utask = utask;
1422 return utask; 1396 return utask;
1423} 1397}
@@ -1479,41 +1453,64 @@ static bool can_skip_sstep(struct uprobe *uprobe, struct pt_regs *regs)
1479 return false; 1453 return false;
1480} 1454}
1481 1455
1456static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp)
1457{
1458 struct mm_struct *mm = current->mm;
1459 struct uprobe *uprobe = NULL;
1460 struct vm_area_struct *vma;
1461
1462 down_read(&mm->mmap_sem);
1463 vma = find_vma(mm, bp_vaddr);
1464 if (vma && vma->vm_start <= bp_vaddr) {
1465 if (valid_vma(vma, false)) {
1466 struct inode *inode;
1467 loff_t offset;
1468
1469 inode = vma->vm_file->f_mapping->host;
1470 offset = bp_vaddr - vma->vm_start;
1471 offset += (vma->vm_pgoff << PAGE_SHIFT);
1472 uprobe = find_uprobe(inode, offset);
1473 }
1474
1475 if (!uprobe)
1476 *is_swbp = is_swbp_at_addr(mm, bp_vaddr);
1477 } else {
1478 *is_swbp = -EFAULT;
1479 }
1480 up_read(&mm->mmap_sem);
1481
1482 return uprobe;
1483}
1484
1482/* 1485/*
1483 * Run handler and ask thread to singlestep. 1486 * Run handler and ask thread to singlestep.
1484 * Ensure all non-fatal signals cannot interrupt thread while it singlesteps. 1487 * Ensure all non-fatal signals cannot interrupt thread while it singlesteps.
1485 */ 1488 */
1486static void handle_swbp(struct pt_regs *regs) 1489static void handle_swbp(struct pt_regs *regs)
1487{ 1490{
1488 struct vm_area_struct *vma;
1489 struct uprobe_task *utask; 1491 struct uprobe_task *utask;
1490 struct uprobe *uprobe; 1492 struct uprobe *uprobe;
1491 struct mm_struct *mm;
1492 unsigned long bp_vaddr; 1493 unsigned long bp_vaddr;
1494 int uninitialized_var(is_swbp);
1493 1495
1494 uprobe = NULL;
1495 bp_vaddr = uprobe_get_swbp_addr(regs); 1496 bp_vaddr = uprobe_get_swbp_addr(regs);
1496 mm = current->mm; 1497 uprobe = find_active_uprobe(bp_vaddr, &is_swbp);
1497 down_read(&mm->mmap_sem);
1498 vma = find_vma(mm, bp_vaddr);
1499
1500 if (vma && vma->vm_start <= bp_vaddr && valid_vma(vma, false)) {
1501 struct inode *inode;
1502 loff_t offset;
1503
1504 inode = vma->vm_file->f_mapping->host;
1505 offset = bp_vaddr - vma->vm_start;
1506 offset += (vma->vm_pgoff << PAGE_SHIFT);
1507 uprobe = find_uprobe(inode, offset);
1508 }
1509
1510 srcu_read_unlock_raw(&uprobes_srcu, current->uprobe_srcu_id);
1511 current->uprobe_srcu_id = -1;
1512 up_read(&mm->mmap_sem);
1513 1498
1514 if (!uprobe) { 1499 if (!uprobe) {
1515 /* No matching uprobe; signal SIGTRAP. */ 1500 if (is_swbp > 0) {
1516 send_sig(SIGTRAP, current, 0); 1501 /* No matching uprobe; signal SIGTRAP. */
1502 send_sig(SIGTRAP, current, 0);
1503 } else {
1504 /*
1505 * Either we raced with uprobe_unregister() or we can't
1506 * access this memory. The latter is only possible if
1507 * another thread plays with our ->mm. In both cases
1508 * we can simply restart. If this vma was unmapped we
1509 * can pretend this insn was not executed yet and get
1510 * the (correct) SIGSEGV after restart.
1511 */
1512 instruction_pointer_set(regs, bp_vaddr);
1513 }
1517 return; 1514 return;
1518 } 1515 }
1519 1516
@@ -1620,7 +1617,6 @@ int uprobe_pre_sstep_notifier(struct pt_regs *regs)
1620 utask->state = UTASK_BP_HIT; 1617 utask->state = UTASK_BP_HIT;
1621 1618
1622 set_thread_flag(TIF_UPROBE); 1619 set_thread_flag(TIF_UPROBE);
1623 current->uprobe_srcu_id = srcu_read_lock_raw(&uprobes_srcu);
1624 1620
1625 return 1; 1621 return 1;
1626} 1622}
@@ -1655,7 +1651,6 @@ static int __init init_uprobes(void)
1655 mutex_init(&uprobes_mutex[i]); 1651 mutex_init(&uprobes_mutex[i]);
1656 mutex_init(&uprobes_mmap_mutex[i]); 1652 mutex_init(&uprobes_mmap_mutex[i]);
1657 } 1653 }
1658 init_srcu_struct(&uprobes_srcu);
1659 1654
1660 return register_die_notifier(&uprobe_exception_nb); 1655 return register_die_notifier(&uprobe_exception_nb);
1661} 1656}
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index a008663d86c8..b4f20fba09fc 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -312,7 +312,7 @@ static int remove_ftrace_list_ops(struct ftrace_ops **list,
312 312
313static int __register_ftrace_function(struct ftrace_ops *ops) 313static int __register_ftrace_function(struct ftrace_ops *ops)
314{ 314{
315 if (ftrace_disabled) 315 if (unlikely(ftrace_disabled))
316 return -ENODEV; 316 return -ENODEV;
317 317
318 if (FTRACE_WARN_ON(ops == &global_ops)) 318 if (FTRACE_WARN_ON(ops == &global_ops))
@@ -4299,16 +4299,12 @@ int register_ftrace_function(struct ftrace_ops *ops)
4299 4299
4300 mutex_lock(&ftrace_lock); 4300 mutex_lock(&ftrace_lock);
4301 4301
4302 if (unlikely(ftrace_disabled))
4303 goto out_unlock;
4304
4305 ret = __register_ftrace_function(ops); 4302 ret = __register_ftrace_function(ops);
4306 if (!ret) 4303 if (!ret)
4307 ret = ftrace_startup(ops, 0); 4304 ret = ftrace_startup(ops, 0);
4308 4305
4309
4310 out_unlock:
4311 mutex_unlock(&ftrace_lock); 4306 mutex_unlock(&ftrace_lock);
4307
4312 return ret; 4308 return ret;
4313} 4309}
4314EXPORT_SYMBOL_GPL(register_ftrace_function); 4310EXPORT_SYMBOL_GPL(register_ftrace_function);
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index f765465bffe4..49491fa7daa2 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -3239,6 +3239,10 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
3239 if (cpu_buffer->commit_page == cpu_buffer->reader_page) 3239 if (cpu_buffer->commit_page == cpu_buffer->reader_page)
3240 goto out; 3240 goto out;
3241 3241
3242 /* Don't bother swapping if the ring buffer is empty */
3243 if (rb_num_of_entries(cpu_buffer) == 0)
3244 goto out;
3245
3242 /* 3246 /*
3243 * Reset the reader page to size zero. 3247 * Reset the reader page to size zero.
3244 */ 3248 */
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index a7fa0702be1c..a120f98c4112 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -830,6 +830,8 @@ int register_tracer(struct tracer *type)
830 current_trace = saved_tracer; 830 current_trace = saved_tracer;
831 if (ret) { 831 if (ret) {
832 printk(KERN_CONT "FAILED!\n"); 832 printk(KERN_CONT "FAILED!\n");
833 /* Add the warning after printing 'FAILED' */
834 WARN_ON(1);
833 goto out; 835 goto out;
834 } 836 }
835 /* Only reset on passing, to avoid touching corrupted buffers */ 837 /* Only reset on passing, to avoid touching corrupted buffers */
@@ -1708,9 +1710,11 @@ EXPORT_SYMBOL_GPL(trace_vprintk);
1708 1710
1709static void trace_iterator_increment(struct trace_iterator *iter) 1711static void trace_iterator_increment(struct trace_iterator *iter)
1710{ 1712{
1713 struct ring_buffer_iter *buf_iter = trace_buffer_iter(iter, iter->cpu);
1714
1711 iter->idx++; 1715 iter->idx++;
1712 if (iter->buffer_iter[iter->cpu]) 1716 if (buf_iter)
1713 ring_buffer_read(iter->buffer_iter[iter->cpu], NULL); 1717 ring_buffer_read(buf_iter, NULL);
1714} 1718}
1715 1719
1716static struct trace_entry * 1720static struct trace_entry *
@@ -1718,7 +1722,7 @@ peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts,
1718 unsigned long *lost_events) 1722 unsigned long *lost_events)
1719{ 1723{
1720 struct ring_buffer_event *event; 1724 struct ring_buffer_event *event;
1721 struct ring_buffer_iter *buf_iter = iter->buffer_iter[cpu]; 1725 struct ring_buffer_iter *buf_iter = trace_buffer_iter(iter, cpu);
1722 1726
1723 if (buf_iter) 1727 if (buf_iter)
1724 event = ring_buffer_iter_peek(buf_iter, ts); 1728 event = ring_buffer_iter_peek(buf_iter, ts);
@@ -1856,10 +1860,10 @@ void tracing_iter_reset(struct trace_iterator *iter, int cpu)
1856 1860
1857 tr->data[cpu]->skipped_entries = 0; 1861 tr->data[cpu]->skipped_entries = 0;
1858 1862
1859 if (!iter->buffer_iter[cpu]) 1863 buf_iter = trace_buffer_iter(iter, cpu);
1864 if (!buf_iter)
1860 return; 1865 return;
1861 1866
1862 buf_iter = iter->buffer_iter[cpu];
1863 ring_buffer_iter_reset(buf_iter); 1867 ring_buffer_iter_reset(buf_iter);
1864 1868
1865 /* 1869 /*
@@ -2205,13 +2209,15 @@ static enum print_line_t print_bin_fmt(struct trace_iterator *iter)
2205 2209
2206int trace_empty(struct trace_iterator *iter) 2210int trace_empty(struct trace_iterator *iter)
2207{ 2211{
2212 struct ring_buffer_iter *buf_iter;
2208 int cpu; 2213 int cpu;
2209 2214
2210 /* If we are looking at one CPU buffer, only check that one */ 2215 /* If we are looking at one CPU buffer, only check that one */
2211 if (iter->cpu_file != TRACE_PIPE_ALL_CPU) { 2216 if (iter->cpu_file != TRACE_PIPE_ALL_CPU) {
2212 cpu = iter->cpu_file; 2217 cpu = iter->cpu_file;
2213 if (iter->buffer_iter[cpu]) { 2218 buf_iter = trace_buffer_iter(iter, cpu);
2214 if (!ring_buffer_iter_empty(iter->buffer_iter[cpu])) 2219 if (buf_iter) {
2220 if (!ring_buffer_iter_empty(buf_iter))
2215 return 0; 2221 return 0;
2216 } else { 2222 } else {
2217 if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu)) 2223 if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu))
@@ -2221,8 +2227,9 @@ int trace_empty(struct trace_iterator *iter)
2221 } 2227 }
2222 2228
2223 for_each_tracing_cpu(cpu) { 2229 for_each_tracing_cpu(cpu) {
2224 if (iter->buffer_iter[cpu]) { 2230 buf_iter = trace_buffer_iter(iter, cpu);
2225 if (!ring_buffer_iter_empty(iter->buffer_iter[cpu])) 2231 if (buf_iter) {
2232 if (!ring_buffer_iter_empty(buf_iter))
2226 return 0; 2233 return 0;
2227 } else { 2234 } else {
2228 if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu)) 2235 if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu))
@@ -2381,6 +2388,11 @@ __tracing_open(struct inode *inode, struct file *file)
2381 if (!iter) 2388 if (!iter)
2382 return ERR_PTR(-ENOMEM); 2389 return ERR_PTR(-ENOMEM);
2383 2390
2391 iter->buffer_iter = kzalloc(sizeof(*iter->buffer_iter) * num_possible_cpus(),
2392 GFP_KERNEL);
2393 if (!iter->buffer_iter)
2394 goto release;
2395
2384 /* 2396 /*
2385 * We make a copy of the current tracer to avoid concurrent 2397 * We make a copy of the current tracer to avoid concurrent
2386 * changes on it while we are reading. 2398 * changes on it while we are reading.
@@ -2441,6 +2453,8 @@ __tracing_open(struct inode *inode, struct file *file)
2441 fail: 2453 fail:
2442 mutex_unlock(&trace_types_lock); 2454 mutex_unlock(&trace_types_lock);
2443 kfree(iter->trace); 2455 kfree(iter->trace);
2456 kfree(iter->buffer_iter);
2457release:
2444 seq_release_private(inode, file); 2458 seq_release_private(inode, file);
2445 return ERR_PTR(-ENOMEM); 2459 return ERR_PTR(-ENOMEM);
2446} 2460}
@@ -2481,6 +2495,7 @@ static int tracing_release(struct inode *inode, struct file *file)
2481 mutex_destroy(&iter->mutex); 2495 mutex_destroy(&iter->mutex);
2482 free_cpumask_var(iter->started); 2496 free_cpumask_var(iter->started);
2483 kfree(iter->trace); 2497 kfree(iter->trace);
2498 kfree(iter->buffer_iter);
2484 seq_release_private(inode, file); 2499 seq_release_private(inode, file);
2485 return 0; 2500 return 0;
2486} 2501}
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 5aec220d2de0..55e1f7f0db12 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -317,6 +317,14 @@ struct tracer {
317 317
318#define TRACE_PIPE_ALL_CPU -1 318#define TRACE_PIPE_ALL_CPU -1
319 319
320static inline struct ring_buffer_iter *
321trace_buffer_iter(struct trace_iterator *iter, int cpu)
322{
323 if (iter->buffer_iter && iter->buffer_iter[cpu])
324 return iter->buffer_iter[cpu];
325 return NULL;
326}
327
320int tracer_init(struct tracer *t, struct trace_array *tr); 328int tracer_init(struct tracer *t, struct trace_array *tr);
321int tracing_is_enabled(void); 329int tracing_is_enabled(void);
322void trace_wake_up(void); 330void trace_wake_up(void);
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index a7d2a4c653d8..ce27c8ba8d31 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -538,7 +538,7 @@ get_return_for_leaf(struct trace_iterator *iter,
538 next = &data->ret; 538 next = &data->ret;
539 } else { 539 } else {
540 540
541 ring_iter = iter->buffer_iter[iter->cpu]; 541 ring_iter = trace_buffer_iter(iter, iter->cpu);
542 542
543 /* First peek to compare current entry and the next one */ 543 /* First peek to compare current entry and the next one */
544 if (ring_iter) 544 if (ring_iter)
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index df611a0e76c5..123b189c732c 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -1325,4 +1325,4 @@ __init static int init_events(void)
1325 1325
1326 return 0; 1326 return 0;
1327} 1327}
1328device_initcall(init_events); 1328early_initcall(init_events);
diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 3d69aa9ff51e..46c2f6b7b123 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -250,8 +250,12 @@ endef
250all_objs := $(sort $(ALL_OBJS)) 250all_objs := $(sort $(ALL_OBJS))
251all_deps := $(all_objs:%.o=.%.d) 251all_deps := $(all_objs:%.o=.%.d)
252 252
253# let .d file also depends on the source and header files
253define check_deps 254define check_deps
254 $(CC) -M $(CFLAGS) $< > $@; 255 @set -e; $(RM) $@; \
256 $(CC) -M $(CFLAGS) $< > $@.$$$$; \
257 sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
258 $(RM) $@.$$$$
255endef 259endef
256 260
257$(gui_deps): ks_version.h 261$(gui_deps): ks_version.h
@@ -270,11 +274,13 @@ endif
270 274
271tags: force 275tags: force
272 $(RM) tags 276 $(RM) tags
273 find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px 277 find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \
278 --regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/'
274 279
275TAGS: force 280TAGS: force
276 $(RM) TAGS 281 $(RM) TAGS
277 find . -name '*.[ch]' | xargs etags 282 find . -name '*.[ch]' | xargs etags \
283 --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/'
278 284
279define do_install 285define do_install
280 $(print_install) \ 286 $(print_install) \
@@ -290,7 +296,7 @@ install_lib: all_cmd install_plugins install_python
290install: install_lib 296install: install_lib
291 297
292clean: 298clean:
293 $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES).*.d 299 $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d
294 $(RM) tags TAGS 300 $(RM) tags TAGS
295 301
296endif # skip-makefile 302endif # skip-makefile
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 554828219c33..5f34aa371b56 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -467,8 +467,10 @@ int pevent_register_function(struct pevent *pevent, char *func,
467 item->mod = NULL; 467 item->mod = NULL;
468 item->addr = addr; 468 item->addr = addr;
469 469
470 pevent->funclist = item; 470 if (!item->func || (mod && !item->mod))
471 die("malloc func");
471 472
473 pevent->funclist = item;
472 pevent->func_count++; 474 pevent->func_count++;
473 475
474 return 0; 476 return 0;
@@ -511,12 +513,12 @@ struct printk_list {
511 513
512static int printk_cmp(const void *a, const void *b) 514static int printk_cmp(const void *a, const void *b)
513{ 515{
514 const struct func_map *fa = a; 516 const struct printk_map *pa = a;
515 const struct func_map *fb = b; 517 const struct printk_map *pb = b;
516 518
517 if (fa->addr < fb->addr) 519 if (pa->addr < pb->addr)
518 return -1; 520 return -1;
519 if (fa->addr > fb->addr) 521 if (pa->addr > pb->addr)
520 return 1; 522 return 1;
521 523
522 return 0; 524 return 0;
@@ -583,10 +585,13 @@ int pevent_register_print_string(struct pevent *pevent, char *fmt,
583 item = malloc_or_die(sizeof(*item)); 585 item = malloc_or_die(sizeof(*item));
584 586
585 item->next = pevent->printklist; 587 item->next = pevent->printklist;
586 pevent->printklist = item;
587 item->printk = strdup(fmt); 588 item->printk = strdup(fmt);
588 item->addr = addr; 589 item->addr = addr;
589 590
591 if (!item->printk)
592 die("malloc fmt");
593
594 pevent->printklist = item;
590 pevent->printk_count++; 595 pevent->printk_count++;
591 596
592 return 0; 597 return 0;
@@ -616,7 +621,9 @@ static struct event_format *alloc_event(void)
616{ 621{
617 struct event_format *event; 622 struct event_format *event;
618 623
619 event = malloc_or_die(sizeof(*event)); 624 event = malloc(sizeof(*event));
625 if (!event)
626 return NULL;
620 memset(event, 0, sizeof(*event)); 627 memset(event, 0, sizeof(*event));
621 628
622 return event; 629 return event;
@@ -626,12 +633,8 @@ static void add_event(struct pevent *pevent, struct event_format *event)
626{ 633{
627 int i; 634 int i;
628 635
629 if (!pevent->events) 636 pevent->events = realloc(pevent->events, sizeof(event) *
630 pevent->events = malloc_or_die(sizeof(event)); 637 (pevent->nr_events + 1));
631 else
632 pevent->events =
633 realloc(pevent->events, sizeof(event) *
634 (pevent->nr_events + 1));
635 if (!pevent->events) 638 if (!pevent->events)
636 die("Can not allocate events"); 639 die("Can not allocate events");
637 640
@@ -697,6 +700,10 @@ static void free_arg(struct print_arg *arg)
697 free_arg(arg->symbol.field); 700 free_arg(arg->symbol.field);
698 free_flag_sym(arg->symbol.symbols); 701 free_flag_sym(arg->symbol.symbols);
699 break; 702 break;
703 case PRINT_HEX:
704 free_arg(arg->hex.field);
705 free_arg(arg->hex.size);
706 break;
700 case PRINT_TYPE: 707 case PRINT_TYPE:
701 free(arg->typecast.type); 708 free(arg->typecast.type);
702 free_arg(arg->typecast.item); 709 free_arg(arg->typecast.item);
@@ -775,6 +782,25 @@ int pevent_peek_char(void)
775 return __peek_char(); 782 return __peek_char();
776} 783}
777 784
785static int extend_token(char **tok, char *buf, int size)
786{
787 char *newtok = realloc(*tok, size);
788
789 if (!newtok) {
790 free(*tok);
791 *tok = NULL;
792 return -1;
793 }
794
795 if (!*tok)
796 strcpy(newtok, buf);
797 else
798 strcat(newtok, buf);
799 *tok = newtok;
800
801 return 0;
802}
803
778static enum event_type force_token(const char *str, char **tok); 804static enum event_type force_token(const char *str, char **tok);
779 805
780static enum event_type __read_token(char **tok) 806static enum event_type __read_token(char **tok)
@@ -859,17 +885,10 @@ static enum event_type __read_token(char **tok)
859 do { 885 do {
860 if (i == (BUFSIZ - 1)) { 886 if (i == (BUFSIZ - 1)) {
861 buf[i] = 0; 887 buf[i] = 0;
862 if (*tok) { 888 tok_size += BUFSIZ;
863 *tok = realloc(*tok, tok_size + BUFSIZ);
864 if (!*tok)
865 return EVENT_NONE;
866 strcat(*tok, buf);
867 } else
868 *tok = strdup(buf);
869 889
870 if (!*tok) 890 if (extend_token(tok, buf, tok_size) < 0)
871 return EVENT_NONE; 891 return EVENT_NONE;
872 tok_size += BUFSIZ;
873 i = 0; 892 i = 0;
874 } 893 }
875 last_ch = ch; 894 last_ch = ch;
@@ -908,17 +927,10 @@ static enum event_type __read_token(char **tok)
908 while (get_type(__peek_char()) == type) { 927 while (get_type(__peek_char()) == type) {
909 if (i == (BUFSIZ - 1)) { 928 if (i == (BUFSIZ - 1)) {
910 buf[i] = 0; 929 buf[i] = 0;
911 if (*tok) { 930 tok_size += BUFSIZ;
912 *tok = realloc(*tok, tok_size + BUFSIZ);
913 if (!*tok)
914 return EVENT_NONE;
915 strcat(*tok, buf);
916 } else
917 *tok = strdup(buf);
918 931
919 if (!*tok) 932 if (extend_token(tok, buf, tok_size) < 0)
920 return EVENT_NONE; 933 return EVENT_NONE;
921 tok_size += BUFSIZ;
922 i = 0; 934 i = 0;
923 } 935 }
924 ch = __read_char(); 936 ch = __read_char();
@@ -927,14 +939,7 @@ static enum event_type __read_token(char **tok)
927 939
928 out: 940 out:
929 buf[i] = 0; 941 buf[i] = 0;
930 if (*tok) { 942 if (extend_token(tok, buf, tok_size + i + 1) < 0)
931 *tok = realloc(*tok, tok_size + i);
932 if (!*tok)
933 return EVENT_NONE;
934 strcat(*tok, buf);
935 } else
936 *tok = strdup(buf);
937 if (!*tok)
938 return EVENT_NONE; 943 return EVENT_NONE;
939 944
940 if (type == EVENT_ITEM) { 945 if (type == EVENT_ITEM) {
@@ -1255,9 +1260,15 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1255 field->flags |= FIELD_IS_POINTER; 1260 field->flags |= FIELD_IS_POINTER;
1256 1261
1257 if (field->type) { 1262 if (field->type) {
1258 field->type = realloc(field->type, 1263 char *new_type;
1259 strlen(field->type) + 1264 new_type = realloc(field->type,
1260 strlen(last_token) + 2); 1265 strlen(field->type) +
1266 strlen(last_token) + 2);
1267 if (!new_type) {
1268 free(last_token);
1269 goto fail;
1270 }
1271 field->type = new_type;
1261 strcat(field->type, " "); 1272 strcat(field->type, " ");
1262 strcat(field->type, last_token); 1273 strcat(field->type, last_token);
1263 free(last_token); 1274 free(last_token);
@@ -1282,6 +1293,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1282 if (strcmp(token, "[") == 0) { 1293 if (strcmp(token, "[") == 0) {
1283 enum event_type last_type = type; 1294 enum event_type last_type = type;
1284 char *brackets = token; 1295 char *brackets = token;
1296 char *new_brackets;
1285 int len; 1297 int len;
1286 1298
1287 field->flags |= FIELD_IS_ARRAY; 1299 field->flags |= FIELD_IS_ARRAY;
@@ -1301,9 +1313,14 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1301 len = 1; 1313 len = 1;
1302 last_type = type; 1314 last_type = type;
1303 1315
1304 brackets = realloc(brackets, 1316 new_brackets = realloc(brackets,
1305 strlen(brackets) + 1317 strlen(brackets) +
1306 strlen(token) + len); 1318 strlen(token) + len);
1319 if (!new_brackets) {
1320 free(brackets);
1321 goto fail;
1322 }
1323 brackets = new_brackets;
1307 if (len == 2) 1324 if (len == 2)
1308 strcat(brackets, " "); 1325 strcat(brackets, " ");
1309 strcat(brackets, token); 1326 strcat(brackets, token);
@@ -1319,7 +1336,12 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1319 1336
1320 free_token(token); 1337 free_token(token);
1321 1338
1322 brackets = realloc(brackets, strlen(brackets) + 2); 1339 new_brackets = realloc(brackets, strlen(brackets) + 2);
1340 if (!new_brackets) {
1341 free(brackets);
1342 goto fail;
1343 }
1344 brackets = new_brackets;
1323 strcat(brackets, "]"); 1345 strcat(brackets, "]");
1324 1346
1325 /* add brackets to type */ 1347 /* add brackets to type */
@@ -1330,10 +1352,16 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1330 * the format: type [] item; 1352 * the format: type [] item;
1331 */ 1353 */
1332 if (type == EVENT_ITEM) { 1354 if (type == EVENT_ITEM) {
1333 field->type = realloc(field->type, 1355 char *new_type;
1334 strlen(field->type) + 1356 new_type = realloc(field->type,
1335 strlen(field->name) + 1357 strlen(field->type) +
1336 strlen(brackets) + 2); 1358 strlen(field->name) +
1359 strlen(brackets) + 2);
1360 if (!new_type) {
1361 free(brackets);
1362 goto fail;
1363 }
1364 field->type = new_type;
1337 strcat(field->type, " "); 1365 strcat(field->type, " ");
1338 strcat(field->type, field->name); 1366 strcat(field->type, field->name);
1339 free_token(field->name); 1367 free_token(field->name);
@@ -1341,9 +1369,15 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1341 field->name = token; 1369 field->name = token;
1342 type = read_token(&token); 1370 type = read_token(&token);
1343 } else { 1371 } else {
1344 field->type = realloc(field->type, 1372 char *new_type;
1345 strlen(field->type) + 1373 new_type = realloc(field->type,
1346 strlen(brackets) + 1); 1374 strlen(field->type) +
1375 strlen(brackets) + 1);
1376 if (!new_type) {
1377 free(brackets);
1378 goto fail;
1379 }
1380 field->type = new_type;
1347 strcat(field->type, brackets); 1381 strcat(field->type, brackets);
1348 } 1382 }
1349 free(brackets); 1383 free(brackets);
@@ -1726,10 +1760,16 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
1726 /* could just be a type pointer */ 1760 /* could just be a type pointer */
1727 if ((strcmp(arg->op.op, "*") == 0) && 1761 if ((strcmp(arg->op.op, "*") == 0) &&
1728 type == EVENT_DELIM && (strcmp(token, ")") == 0)) { 1762 type == EVENT_DELIM && (strcmp(token, ")") == 0)) {
1763 char *new_atom;
1764
1729 if (left->type != PRINT_ATOM) 1765 if (left->type != PRINT_ATOM)
1730 die("bad pointer type"); 1766 die("bad pointer type");
1731 left->atom.atom = realloc(left->atom.atom, 1767 new_atom = realloc(left->atom.atom,
1732 strlen(left->atom.atom) + 3); 1768 strlen(left->atom.atom) + 3);
1769 if (!new_atom)
1770 goto out_free;
1771
1772 left->atom.atom = new_atom;
1733 strcat(left->atom.atom, " *"); 1773 strcat(left->atom.atom, " *");
1734 free(arg->op.op); 1774 free(arg->op.op);
1735 *arg = *left; 1775 *arg = *left;
@@ -2146,6 +2186,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
2146 if (value == NULL) 2186 if (value == NULL)
2147 goto out_free; 2187 goto out_free;
2148 field->value = strdup(value); 2188 field->value = strdup(value);
2189 if (field->value == NULL)
2190 goto out_free;
2149 2191
2150 free_arg(arg); 2192 free_arg(arg);
2151 arg = alloc_arg(); 2193 arg = alloc_arg();
@@ -2159,6 +2201,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
2159 if (value == NULL) 2201 if (value == NULL)
2160 goto out_free; 2202 goto out_free;
2161 field->str = strdup(value); 2203 field->str = strdup(value);
2204 if (field->str == NULL)
2205 goto out_free;
2162 free_arg(arg); 2206 free_arg(arg);
2163 arg = NULL; 2207 arg = NULL;
2164 2208
@@ -2260,6 +2304,45 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok)
2260} 2304}
2261 2305
2262static enum event_type 2306static enum event_type
2307process_hex(struct event_format *event, struct print_arg *arg, char **tok)
2308{
2309 struct print_arg *field;
2310 enum event_type type;
2311 char *token;
2312
2313 memset(arg, 0, sizeof(*arg));
2314 arg->type = PRINT_HEX;
2315
2316 field = alloc_arg();
2317 type = process_arg(event, field, &token);
2318
2319 if (test_type_token(type, token, EVENT_DELIM, ","))
2320 goto out_free;
2321
2322 arg->hex.field = field;
2323
2324 free_token(token);
2325
2326 field = alloc_arg();
2327 type = process_arg(event, field, &token);
2328
2329 if (test_type_token(type, token, EVENT_DELIM, ")"))
2330 goto out_free;
2331
2332 arg->hex.size = field;
2333
2334 free_token(token);
2335 type = read_token_item(tok);
2336 return type;
2337
2338 out_free:
2339 free_arg(field);
2340 free_token(token);
2341 *tok = NULL;
2342 return EVENT_ERROR;
2343}
2344
2345static enum event_type
2263process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok) 2346process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok)
2264{ 2347{
2265 struct format_field *field; 2348 struct format_field *field;
@@ -2488,6 +2571,10 @@ process_function(struct event_format *event, struct print_arg *arg,
2488 is_symbolic_field = 1; 2571 is_symbolic_field = 1;
2489 return process_symbols(event, arg, tok); 2572 return process_symbols(event, arg, tok);
2490 } 2573 }
2574 if (strcmp(token, "__print_hex") == 0) {
2575 free_token(token);
2576 return process_hex(event, arg, tok);
2577 }
2491 if (strcmp(token, "__get_str") == 0) { 2578 if (strcmp(token, "__get_str") == 0) {
2492 free_token(token); 2579 free_token(token);
2493 return process_str(event, arg, tok); 2580 return process_str(event, arg, tok);
@@ -2541,7 +2628,16 @@ process_arg_token(struct event_format *event, struct print_arg *arg,
2541 } 2628 }
2542 /* atoms can be more than one token long */ 2629 /* atoms can be more than one token long */
2543 while (type == EVENT_ITEM) { 2630 while (type == EVENT_ITEM) {
2544 atom = realloc(atom, strlen(atom) + strlen(token) + 2); 2631 char *new_atom;
2632 new_atom = realloc(atom,
2633 strlen(atom) + strlen(token) + 2);
2634 if (!new_atom) {
2635 free(atom);
2636 *tok = NULL;
2637 free_token(token);
2638 return EVENT_ERROR;
2639 }
2640 atom = new_atom;
2545 strcat(atom, " "); 2641 strcat(atom, " ");
2546 strcat(atom, token); 2642 strcat(atom, token);
2547 free_token(token); 2643 free_token(token);
@@ -2835,7 +2931,7 @@ static int get_common_info(struct pevent *pevent,
2835 event = pevent->events[0]; 2931 event = pevent->events[0];
2836 field = pevent_find_common_field(event, type); 2932 field = pevent_find_common_field(event, type);
2837 if (!field) 2933 if (!field)
2838 die("field '%s' not found", type); 2934 return -1;
2839 2935
2840 *offset = field->offset; 2936 *offset = field->offset;
2841 *size = field->size; 2937 *size = field->size;
@@ -2886,15 +2982,16 @@ static int parse_common_flags(struct pevent *pevent, void *data)
2886 2982
2887static int parse_common_lock_depth(struct pevent *pevent, void *data) 2983static int parse_common_lock_depth(struct pevent *pevent, void *data)
2888{ 2984{
2889 int ret; 2985 return __parse_common(pevent, data,
2890 2986 &pevent->ld_size, &pevent->ld_offset,
2891 ret = __parse_common(pevent, data, 2987 "common_lock_depth");
2892 &pevent->ld_size, &pevent->ld_offset, 2988}
2893 "common_lock_depth");
2894 if (ret < 0)
2895 return -1;
2896 2989
2897 return ret; 2990static int parse_common_migrate_disable(struct pevent *pevent, void *data)
2991{
2992 return __parse_common(pevent, data,
2993 &pevent->ld_size, &pevent->ld_offset,
2994 "common_migrate_disable");
2898} 2995}
2899 2996
2900static int events_id_cmp(const void *a, const void *b); 2997static int events_id_cmp(const void *a, const void *b);
@@ -2995,6 +3092,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
2995 break; 3092 break;
2996 case PRINT_FLAGS: 3093 case PRINT_FLAGS:
2997 case PRINT_SYMBOL: 3094 case PRINT_SYMBOL:
3095 case PRINT_HEX:
2998 break; 3096 break;
2999 case PRINT_TYPE: 3097 case PRINT_TYPE:
3000 val = eval_num_arg(data, size, event, arg->typecast.item); 3098 val = eval_num_arg(data, size, event, arg->typecast.item);
@@ -3214,11 +3312,13 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3214{ 3312{
3215 struct pevent *pevent = event->pevent; 3313 struct pevent *pevent = event->pevent;
3216 struct print_flag_sym *flag; 3314 struct print_flag_sym *flag;
3315 struct format_field *field;
3217 unsigned long long val, fval; 3316 unsigned long long val, fval;
3218 unsigned long addr; 3317 unsigned long addr;
3219 char *str; 3318 char *str;
3319 unsigned char *hex;
3220 int print; 3320 int print;
3221 int len; 3321 int i, len;
3222 3322
3223 switch (arg->type) { 3323 switch (arg->type) {
3224 case PRINT_NULL: 3324 case PRINT_NULL:
@@ -3228,27 +3328,29 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3228 print_str_to_seq(s, format, len_arg, arg->atom.atom); 3328 print_str_to_seq(s, format, len_arg, arg->atom.atom);
3229 return; 3329 return;
3230 case PRINT_FIELD: 3330 case PRINT_FIELD:
3231 if (!arg->field.field) { 3331 field = arg->field.field;
3232 arg->field.field = pevent_find_any_field(event, arg->field.name); 3332 if (!field) {
3233 if (!arg->field.field) 3333 field = pevent_find_any_field(event, arg->field.name);
3334 if (!field)
3234 die("field %s not found", arg->field.name); 3335 die("field %s not found", arg->field.name);
3336 arg->field.field = field;
3235 } 3337 }
3236 /* Zero sized fields, mean the rest of the data */ 3338 /* Zero sized fields, mean the rest of the data */
3237 len = arg->field.field->size ? : size - arg->field.field->offset; 3339 len = field->size ? : size - field->offset;
3238 3340
3239 /* 3341 /*
3240 * Some events pass in pointers. If this is not an array 3342 * Some events pass in pointers. If this is not an array
3241 * and the size is the same as long_size, assume that it 3343 * and the size is the same as long_size, assume that it
3242 * is a pointer. 3344 * is a pointer.
3243 */ 3345 */
3244 if (!(arg->field.field->flags & FIELD_IS_ARRAY) && 3346 if (!(field->flags & FIELD_IS_ARRAY) &&
3245 arg->field.field->size == pevent->long_size) { 3347 field->size == pevent->long_size) {
3246 addr = *(unsigned long *)(data + arg->field.field->offset); 3348 addr = *(unsigned long *)(data + field->offset);
3247 trace_seq_printf(s, "%lx", addr); 3349 trace_seq_printf(s, "%lx", addr);
3248 break; 3350 break;
3249 } 3351 }
3250 str = malloc_or_die(len + 1); 3352 str = malloc_or_die(len + 1);
3251 memcpy(str, data + arg->field.field->offset, len); 3353 memcpy(str, data + field->offset, len);
3252 str[len] = 0; 3354 str[len] = 0;
3253 print_str_to_seq(s, format, len_arg, str); 3355 print_str_to_seq(s, format, len_arg, str);
3254 free(str); 3356 free(str);
@@ -3281,6 +3383,23 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3281 } 3383 }
3282 } 3384 }
3283 break; 3385 break;
3386 case PRINT_HEX:
3387 field = arg->hex.field->field.field;
3388 if (!field) {
3389 str = arg->hex.field->field.name;
3390 field = pevent_find_any_field(event, str);
3391 if (!field)
3392 die("field %s not found", str);
3393 arg->hex.field->field.field = field;
3394 }
3395 hex = data + field->offset;
3396 len = eval_num_arg(data, size, event, arg->hex.size);
3397 for (i = 0; i < len; i++) {
3398 if (i)
3399 trace_seq_putc(s, ' ');
3400 trace_seq_printf(s, "%02x", hex[i]);
3401 }
3402 break;
3284 3403
3285 case PRINT_TYPE: 3404 case PRINT_TYPE:
3286 break; 3405 break;
@@ -3299,7 +3418,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3299 break; 3418 break;
3300 } 3419 }
3301 case PRINT_BSTRING: 3420 case PRINT_BSTRING:
3302 trace_seq_printf(s, format, arg->string.string); 3421 print_str_to_seq(s, format, len_arg, arg->string.string);
3303 break; 3422 break;
3304 case PRINT_OP: 3423 case PRINT_OP:
3305 /* 3424 /*
@@ -3363,6 +3482,10 @@ process_defined_func(struct trace_seq *s, void *data, int size,
3363 string = malloc_or_die(sizeof(*string)); 3482 string = malloc_or_die(sizeof(*string));
3364 string->next = strings; 3483 string->next = strings;
3365 string->str = strdup(str.buffer); 3484 string->str = strdup(str.buffer);
3485 if (!string->str)
3486 die("malloc str");
3487
3488 args[i] = (unsigned long long)string->str;
3366 strings = string; 3489 strings = string;
3367 trace_seq_destroy(&str); 3490 trace_seq_destroy(&str);
3368 break; 3491 break;
@@ -3400,6 +3523,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3400 unsigned long long ip, val; 3523 unsigned long long ip, val;
3401 char *ptr; 3524 char *ptr;
3402 void *bptr; 3525 void *bptr;
3526 int vsize;
3403 3527
3404 field = pevent->bprint_buf_field; 3528 field = pevent->bprint_buf_field;
3405 ip_field = pevent->bprint_ip_field; 3529 ip_field = pevent->bprint_ip_field;
@@ -3448,6 +3572,8 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3448 goto process_again; 3572 goto process_again;
3449 case '0' ... '9': 3573 case '0' ... '9':
3450 goto process_again; 3574 goto process_again;
3575 case '.':
3576 goto process_again;
3451 case 'p': 3577 case 'p':
3452 ls = 1; 3578 ls = 1;
3453 /* fall through */ 3579 /* fall through */
@@ -3455,23 +3581,30 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3455 case 'u': 3581 case 'u':
3456 case 'x': 3582 case 'x':
3457 case 'i': 3583 case 'i':
3458 /* the pointers are always 4 bytes aligned */
3459 bptr = (void *)(((unsigned long)bptr + 3) &
3460 ~3);
3461 switch (ls) { 3584 switch (ls) {
3462 case 0: 3585 case 0:
3463 ls = 4; 3586 vsize = 4;
3464 break; 3587 break;
3465 case 1: 3588 case 1:
3466 ls = pevent->long_size; 3589 vsize = pevent->long_size;
3467 break; 3590 break;
3468 case 2: 3591 case 2:
3469 ls = 8; 3592 vsize = 8;
3593 break;
3470 default: 3594 default:
3595 vsize = ls; /* ? */
3471 break; 3596 break;
3472 } 3597 }
3473 val = pevent_read_number(pevent, bptr, ls); 3598 /* fall through */
3474 bptr += ls; 3599 case '*':
3600 if (*ptr == '*')
3601 vsize = 4;
3602
3603 /* the pointers are always 4 bytes aligned */
3604 bptr = (void *)(((unsigned long)bptr + 3) &
3605 ~3);
3606 val = pevent_read_number(pevent, bptr, vsize);
3607 bptr += vsize;
3475 arg = alloc_arg(); 3608 arg = alloc_arg();
3476 arg->next = NULL; 3609 arg->next = NULL;
3477 arg->type = PRINT_ATOM; 3610 arg->type = PRINT_ATOM;
@@ -3479,12 +3612,21 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
3479 sprintf(arg->atom.atom, "%lld", val); 3612 sprintf(arg->atom.atom, "%lld", val);
3480 *next = arg; 3613 *next = arg;
3481 next = &arg->next; 3614 next = &arg->next;
3615 /*
3616 * The '*' case means that an arg is used as the length.
3617 * We need to continue to figure out for what.
3618 */
3619 if (*ptr == '*')
3620 goto process_again;
3621
3482 break; 3622 break;
3483 case 's': 3623 case 's':
3484 arg = alloc_arg(); 3624 arg = alloc_arg();
3485 arg->next = NULL; 3625 arg->next = NULL;
3486 arg->type = PRINT_BSTRING; 3626 arg->type = PRINT_BSTRING;
3487 arg->string.string = strdup(bptr); 3627 arg->string.string = strdup(bptr);
3628 if (!arg->string.string)
3629 break;
3488 bptr += strlen(bptr) + 1; 3630 bptr += strlen(bptr) + 1;
3489 *next = arg; 3631 *next = arg;
3490 next = &arg->next; 3632 next = &arg->next;
@@ -3589,6 +3731,16 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
3589 trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); 3731 trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
3590} 3732}
3591 3733
3734static int is_printable_array(char *p, unsigned int len)
3735{
3736 unsigned int i;
3737
3738 for (i = 0; i < len && p[i]; i++)
3739 if (!isprint(p[i]))
3740 return 0;
3741 return 1;
3742}
3743
3592static void print_event_fields(struct trace_seq *s, void *data, int size, 3744static void print_event_fields(struct trace_seq *s, void *data, int size,
3593 struct event_format *event) 3745 struct event_format *event)
3594{ 3746{
@@ -3608,7 +3760,8 @@ static void print_event_fields(struct trace_seq *s, void *data, int size,
3608 len = offset >> 16; 3760 len = offset >> 16;
3609 offset &= 0xffff; 3761 offset &= 0xffff;
3610 } 3762 }
3611 if (field->flags & FIELD_IS_STRING) { 3763 if (field->flags & FIELD_IS_STRING &&
3764 is_printable_array(data + offset, len)) {
3612 trace_seq_printf(s, "%s", (char *)data + offset); 3765 trace_seq_printf(s, "%s", (char *)data + offset);
3613 } else { 3766 } else {
3614 trace_seq_puts(s, "ARRAY["); 3767 trace_seq_puts(s, "ARRAY[");
@@ -3619,6 +3772,7 @@ static void print_event_fields(struct trace_seq *s, void *data, int size,
3619 *((unsigned char *)data + offset + i)); 3772 *((unsigned char *)data + offset + i));
3620 } 3773 }
3621 trace_seq_putc(s, ']'); 3774 trace_seq_putc(s, ']');
3775 field->flags &= ~FIELD_IS_STRING;
3622 } 3776 }
3623 } else { 3777 } else {
3624 val = pevent_read_number(event->pevent, data + field->offset, 3778 val = pevent_read_number(event->pevent, data + field->offset,
@@ -3758,6 +3912,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
3758 } else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') { 3912 } else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') {
3759 print_mac_arg(s, *(ptr+1), data, size, event, arg); 3913 print_mac_arg(s, *(ptr+1), data, size, event, arg);
3760 ptr++; 3914 ptr++;
3915 arg = arg->next;
3761 break; 3916 break;
3762 } 3917 }
3763 3918
@@ -3794,14 +3949,15 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
3794 break; 3949 break;
3795 } 3950 }
3796 } 3951 }
3797 if (pevent->long_size == 8 && ls) { 3952 if (pevent->long_size == 8 && ls &&
3953 sizeof(long) != 8) {
3798 char *p; 3954 char *p;
3799 3955
3800 ls = 2; 3956 ls = 2;
3801 /* make %l into %ll */ 3957 /* make %l into %ll */
3802 p = strchr(format, 'l'); 3958 p = strchr(format, 'l');
3803 if (p) 3959 if (p)
3804 memmove(p, p+1, strlen(p)+1); 3960 memmove(p+1, p, strlen(p)+1);
3805 else if (strcmp(format, "%p") == 0) 3961 else if (strcmp(format, "%p") == 0)
3806 strcpy(format, "0x%llx"); 3962 strcpy(format, "0x%llx");
3807 } 3963 }
@@ -3878,8 +4034,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
3878 * pevent_data_lat_fmt - parse the data for the latency format 4034 * pevent_data_lat_fmt - parse the data for the latency format
3879 * @pevent: a handle to the pevent 4035 * @pevent: a handle to the pevent
3880 * @s: the trace_seq to write to 4036 * @s: the trace_seq to write to
3881 * @data: the raw data to read from 4037 * @record: the record to read from
3882 * @size: currently unused.
3883 * 4038 *
3884 * This parses out the Latency format (interrupts disabled, 4039 * This parses out the Latency format (interrupts disabled,
3885 * need rescheduling, in hard/soft interrupt, preempt count 4040 * need rescheduling, in hard/soft interrupt, preempt count
@@ -3889,10 +4044,13 @@ void pevent_data_lat_fmt(struct pevent *pevent,
3889 struct trace_seq *s, struct pevent_record *record) 4044 struct trace_seq *s, struct pevent_record *record)
3890{ 4045{
3891 static int check_lock_depth = 1; 4046 static int check_lock_depth = 1;
4047 static int check_migrate_disable = 1;
3892 static int lock_depth_exists; 4048 static int lock_depth_exists;
4049 static int migrate_disable_exists;
3893 unsigned int lat_flags; 4050 unsigned int lat_flags;
3894 unsigned int pc; 4051 unsigned int pc;
3895 int lock_depth; 4052 int lock_depth;
4053 int migrate_disable;
3896 int hardirq; 4054 int hardirq;
3897 int softirq; 4055 int softirq;
3898 void *data = record->data; 4056 void *data = record->data;
@@ -3900,18 +4058,26 @@ void pevent_data_lat_fmt(struct pevent *pevent,
3900 lat_flags = parse_common_flags(pevent, data); 4058 lat_flags = parse_common_flags(pevent, data);
3901 pc = parse_common_pc(pevent, data); 4059 pc = parse_common_pc(pevent, data);
3902 /* lock_depth may not always exist */ 4060 /* lock_depth may not always exist */
3903 if (check_lock_depth) {
3904 struct format_field *field;
3905 struct event_format *event;
3906
3907 check_lock_depth = 0;
3908 event = pevent->events[0];
3909 field = pevent_find_common_field(event, "common_lock_depth");
3910 if (field)
3911 lock_depth_exists = 1;
3912 }
3913 if (lock_depth_exists) 4061 if (lock_depth_exists)
3914 lock_depth = parse_common_lock_depth(pevent, data); 4062 lock_depth = parse_common_lock_depth(pevent, data);
4063 else if (check_lock_depth) {
4064 lock_depth = parse_common_lock_depth(pevent, data);
4065 if (lock_depth < 0)
4066 check_lock_depth = 0;
4067 else
4068 lock_depth_exists = 1;
4069 }
4070
4071 /* migrate_disable may not always exist */
4072 if (migrate_disable_exists)
4073 migrate_disable = parse_common_migrate_disable(pevent, data);
4074 else if (check_migrate_disable) {
4075 migrate_disable = parse_common_migrate_disable(pevent, data);
4076 if (migrate_disable < 0)
4077 check_migrate_disable = 0;
4078 else
4079 migrate_disable_exists = 1;
4080 }
3915 4081
3916 hardirq = lat_flags & TRACE_FLAG_HARDIRQ; 4082 hardirq = lat_flags & TRACE_FLAG_HARDIRQ;
3917 softirq = lat_flags & TRACE_FLAG_SOFTIRQ; 4083 softirq = lat_flags & TRACE_FLAG_SOFTIRQ;
@@ -3930,6 +4096,13 @@ void pevent_data_lat_fmt(struct pevent *pevent,
3930 else 4096 else
3931 trace_seq_putc(s, '.'); 4097 trace_seq_putc(s, '.');
3932 4098
4099 if (migrate_disable_exists) {
4100 if (migrate_disable < 0)
4101 trace_seq_putc(s, '.');
4102 else
4103 trace_seq_printf(s, "%d", migrate_disable);
4104 }
4105
3933 if (lock_depth_exists) { 4106 if (lock_depth_exists) {
3934 if (lock_depth < 0) 4107 if (lock_depth < 0)
3935 trace_seq_putc(s, '.'); 4108 trace_seq_putc(s, '.');
@@ -3996,10 +4169,7 @@ const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid)
3996 * pevent_data_comm_from_pid - parse the data into the print format 4169 * pevent_data_comm_from_pid - parse the data into the print format
3997 * @s: the trace_seq to write to 4170 * @s: the trace_seq to write to
3998 * @event: the handle to the event 4171 * @event: the handle to the event
3999 * @cpu: the cpu the event was recorded on 4172 * @record: the record to read from
4000 * @data: the raw data
4001 * @size: the size of the raw data
4002 * @nsecs: the timestamp of the event
4003 * 4173 *
4004 * This parses the raw @data using the given @event information and 4174 * This parses the raw @data using the given @event information and
4005 * writes the print format into the trace_seq. 4175 * writes the print format into the trace_seq.
@@ -4279,6 +4449,13 @@ static void print_args(struct print_arg *args)
4279 trace_seq_destroy(&s); 4449 trace_seq_destroy(&s);
4280 printf(")"); 4450 printf(")");
4281 break; 4451 break;
4452 case PRINT_HEX:
4453 printf("__print_hex(");
4454 print_args(args->hex.field);
4455 printf(", ");
4456 print_args(args->hex.size);
4457 printf(")");
4458 break;
4282 case PRINT_STRING: 4459 case PRINT_STRING:
4283 case PRINT_BSTRING: 4460 case PRINT_BSTRING:
4284 printf("__get_str(%s)", args->string.string); 4461 printf("__get_str(%s)", args->string.string);
@@ -4541,6 +4718,8 @@ int pevent_parse_event(struct pevent *pevent,
4541 die("failed to read event id"); 4718 die("failed to read event id");
4542 4719
4543 event->system = strdup(sys); 4720 event->system = strdup(sys);
4721 if (!event->system)
4722 die("failed to allocate system");
4544 4723
4545 /* Add pevent to event so that it can be referenced */ 4724 /* Add pevent to event so that it can be referenced */
4546 event->pevent = pevent; 4725 event->pevent = pevent;
@@ -4582,6 +4761,11 @@ int pevent_parse_event(struct pevent *pevent,
4582 list = &arg->next; 4761 list = &arg->next;
4583 arg->type = PRINT_FIELD; 4762 arg->type = PRINT_FIELD;
4584 arg->field.name = strdup(field->name); 4763 arg->field.name = strdup(field->name);
4764 if (!arg->field.name) {
4765 do_warning("failed to allocate field name");
4766 event->flags |= EVENT_FL_FAILED;
4767 return -1;
4768 }
4585 arg->field.field = field; 4769 arg->field.field = field;
4586 } 4770 }
4587 return 0; 4771 return 0;
@@ -4753,7 +4937,7 @@ int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event,
4753 * @record: The record with the field name. 4937 * @record: The record with the field name.
4754 * @err: print default error if failed. 4938 * @err: print default error if failed.
4755 * 4939 *
4756 * Returns: 0 on success, -1 field not fould, or 1 if buffer is full. 4940 * Returns: 0 on success, -1 field not found, or 1 if buffer is full.
4757 */ 4941 */
4758int pevent_print_num_field(struct trace_seq *s, const char *fmt, 4942int pevent_print_num_field(struct trace_seq *s, const char *fmt,
4759 struct event_format *event, const char *name, 4943 struct event_format *event, const char *name,
@@ -4795,11 +4979,12 @@ static void free_func_handle(struct pevent_function_handler *func)
4795 * pevent_register_print_function - register a helper function 4979 * pevent_register_print_function - register a helper function
4796 * @pevent: the handle to the pevent 4980 * @pevent: the handle to the pevent
4797 * @func: the function to process the helper function 4981 * @func: the function to process the helper function
4982 * @ret_type: the return type of the helper function
4798 * @name: the name of the helper function 4983 * @name: the name of the helper function
4799 * @parameters: A list of enum pevent_func_arg_type 4984 * @parameters: A list of enum pevent_func_arg_type
4800 * 4985 *
4801 * Some events may have helper functions in the print format arguments. 4986 * Some events may have helper functions in the print format arguments.
4802 * This allows a plugin to dynmically create a way to process one 4987 * This allows a plugin to dynamically create a way to process one
4803 * of these functions. 4988 * of these functions.
4804 * 4989 *
4805 * The @parameters is a variable list of pevent_func_arg_type enums that 4990 * The @parameters is a variable list of pevent_func_arg_type enums that
@@ -4870,12 +5055,13 @@ int pevent_register_print_function(struct pevent *pevent,
4870} 5055}
4871 5056
4872/** 5057/**
4873 * pevent_register_event_handle - register a way to parse an event 5058 * pevent_register_event_handler - register a way to parse an event
4874 * @pevent: the handle to the pevent 5059 * @pevent: the handle to the pevent
4875 * @id: the id of the event to register 5060 * @id: the id of the event to register
4876 * @sys_name: the system name the event belongs to 5061 * @sys_name: the system name the event belongs to
4877 * @event_name: the name of the event 5062 * @event_name: the name of the event
4878 * @func: the function to call to parse the event information 5063 * @func: the function to call to parse the event information
5064 * @context: the data to be passed to @func
4879 * 5065 *
4880 * This function allows a developer to override the parsing of 5066 * This function allows a developer to override the parsing of
4881 * a given event. If for some reason the default print format 5067 * a given event. If for some reason the default print format
@@ -4925,6 +5111,11 @@ int pevent_register_event_handler(struct pevent *pevent,
4925 if (sys_name) 5111 if (sys_name)
4926 handle->sys_name = strdup(sys_name); 5112 handle->sys_name = strdup(sys_name);
4927 5113
5114 if ((event_name && !handle->event_name) ||
5115 (sys_name && !handle->sys_name)) {
5116 die("Failed to allocate event/sys name");
5117 }
5118
4928 handle->func = func; 5119 handle->func = func;
4929 handle->next = pevent->handlers; 5120 handle->next = pevent->handlers;
4930 pevent->handlers = handle; 5121 pevent->handlers = handle;
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index ac997bc7b592..5772ad8cb386 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -226,6 +226,11 @@ struct print_arg_symbol {
226 struct print_flag_sym *symbols; 226 struct print_flag_sym *symbols;
227}; 227};
228 228
229struct print_arg_hex {
230 struct print_arg *field;
231 struct print_arg *size;
232};
233
229struct print_arg_dynarray { 234struct print_arg_dynarray {
230 struct format_field *field; 235 struct format_field *field;
231 struct print_arg *index; 236 struct print_arg *index;
@@ -253,6 +258,7 @@ enum print_arg_type {
253 PRINT_FIELD, 258 PRINT_FIELD,
254 PRINT_FLAGS, 259 PRINT_FLAGS,
255 PRINT_SYMBOL, 260 PRINT_SYMBOL,
261 PRINT_HEX,
256 PRINT_TYPE, 262 PRINT_TYPE,
257 PRINT_STRING, 263 PRINT_STRING,
258 PRINT_BSTRING, 264 PRINT_BSTRING,
@@ -270,6 +276,7 @@ struct print_arg {
270 struct print_arg_typecast typecast; 276 struct print_arg_typecast typecast;
271 struct print_arg_flags flags; 277 struct print_arg_flags flags;
272 struct print_arg_symbol symbol; 278 struct print_arg_symbol symbol;
279 struct print_arg_hex hex;
273 struct print_arg_func func; 280 struct print_arg_func func;
274 struct print_arg_string string; 281 struct print_arg_string string;
275 struct print_arg_op op; 282 struct print_arg_op op;
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index dfcfe2c131de..ad17855528f9 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -96,7 +96,7 @@ static enum event_type read_token(char **tok)
96 (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) && 96 (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) &&
97 pevent_peek_char() == '~') { 97 pevent_peek_char() == '~') {
98 /* append it */ 98 /* append it */
99 *tok = malloc(3); 99 *tok = malloc_or_die(3);
100 sprintf(*tok, "%c%c", *token, '~'); 100 sprintf(*tok, "%c%c", *token, '~');
101 free_token(token); 101 free_token(token);
102 /* Now remove the '~' from the buffer */ 102 /* Now remove the '~' from the buffer */
@@ -148,17 +148,11 @@ add_filter_type(struct event_filter *filter, int id)
148 if (filter_type) 148 if (filter_type)
149 return filter_type; 149 return filter_type;
150 150
151 if (!filter->filters) 151 filter->event_filters = realloc(filter->event_filters,
152 filter->event_filters = 152 sizeof(*filter->event_filters) *
153 malloc_or_die(sizeof(*filter->event_filters)); 153 (filter->filters + 1));
154 else { 154 if (!filter->event_filters)
155 filter->event_filters = 155 die("Could not allocate filter");
156 realloc(filter->event_filters,
157 sizeof(*filter->event_filters) *
158 (filter->filters + 1));
159 if (!filter->event_filters)
160 die("Could not allocate filter");
161 }
162 156
163 for (i = 0; i < filter->filters; i++) { 157 for (i = 0; i < filter->filters; i++) {
164 if (filter->event_filters[i].event_id > id) 158 if (filter->event_filters[i].event_id > id)
@@ -1480,7 +1474,7 @@ void pevent_filter_clear_trivial(struct event_filter *filter,
1480{ 1474{
1481 struct filter_type *filter_type; 1475 struct filter_type *filter_type;
1482 int count = 0; 1476 int count = 0;
1483 int *ids; 1477 int *ids = NULL;
1484 int i; 1478 int i;
1485 1479
1486 if (!filter->filters) 1480 if (!filter->filters)
@@ -1504,10 +1498,8 @@ void pevent_filter_clear_trivial(struct event_filter *filter,
1504 default: 1498 default:
1505 break; 1499 break;
1506 } 1500 }
1507 if (count) 1501
1508 ids = realloc(ids, sizeof(*ids) * (count + 1)); 1502 ids = realloc(ids, sizeof(*ids) * (count + 1));
1509 else
1510 ids = malloc(sizeof(*ids));
1511 if (!ids) 1503 if (!ids)
1512 die("Can't allocate ids"); 1504 die("Can't allocate ids");
1513 ids[count++] = filter_type->event_id; 1505 ids[count++] = filter_type->event_id;
@@ -1710,18 +1702,43 @@ static int test_num(struct event_format *event,
1710 1702
1711static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record) 1703static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record)
1712{ 1704{
1713 const char *val = record->data + arg->str.field->offset; 1705 struct event_format *event;
1706 struct pevent *pevent;
1707 unsigned long long addr;
1708 const char *val = NULL;
1709 char hex[64];
1714 1710
1715 /* 1711 /* If the field is not a string convert it */
1716 * We need to copy the data since we can't be sure the field 1712 if (arg->str.field->flags & FIELD_IS_STRING) {
1717 * is null terminated. 1713 val = record->data + arg->str.field->offset;
1718 */ 1714
1719 if (*(val + arg->str.field->size - 1)) { 1715 /*
1720 /* copy it */ 1716 * We need to copy the data since we can't be sure the field
1721 memcpy(arg->str.buffer, val, arg->str.field->size); 1717 * is null terminated.
1722 /* the buffer is already NULL terminated */ 1718 */
1723 val = arg->str.buffer; 1719 if (*(val + arg->str.field->size - 1)) {
1720 /* copy it */
1721 memcpy(arg->str.buffer, val, arg->str.field->size);
1722 /* the buffer is already NULL terminated */
1723 val = arg->str.buffer;
1724 }
1725
1726 } else {
1727 event = arg->str.field->event;
1728 pevent = event->pevent;
1729 addr = get_value(event, arg->str.field, record);
1730
1731 if (arg->str.field->flags & (FIELD_IS_POINTER | FIELD_IS_LONG))
1732 /* convert to a kernel symbol */
1733 val = pevent_find_function(pevent, addr);
1734
1735 if (val == NULL) {
1736 /* just use the hex of the string name */
1737 snprintf(hex, 64, "0x%llx", addr);
1738 val = hex;
1739 }
1724 } 1740 }
1741
1725 return val; 1742 return val;
1726} 1743}
1727 1744
@@ -2001,11 +2018,13 @@ static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg)
2001 char *lstr; 2018 char *lstr;
2002 char *rstr; 2019 char *rstr;
2003 char *op; 2020 char *op;
2004 char *str; 2021 char *str = NULL;
2005 int len; 2022 int len;
2006 2023
2007 lstr = arg_to_str(filter, arg->exp.left); 2024 lstr = arg_to_str(filter, arg->exp.left);
2008 rstr = arg_to_str(filter, arg->exp.right); 2025 rstr = arg_to_str(filter, arg->exp.right);
2026 if (!lstr || !rstr)
2027 goto out;
2009 2028
2010 switch (arg->exp.type) { 2029 switch (arg->exp.type) {
2011 case FILTER_EXP_ADD: 2030 case FILTER_EXP_ADD:
@@ -2045,6 +2064,7 @@ static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg)
2045 len = strlen(op) + strlen(lstr) + strlen(rstr) + 4; 2064 len = strlen(op) + strlen(lstr) + strlen(rstr) + 4;
2046 str = malloc_or_die(len); 2065 str = malloc_or_die(len);
2047 snprintf(str, len, "%s %s %s", lstr, op, rstr); 2066 snprintf(str, len, "%s %s %s", lstr, op, rstr);
2067out:
2048 free(lstr); 2068 free(lstr);
2049 free(rstr); 2069 free(rstr);
2050 2070
@@ -2061,6 +2081,8 @@ static char *num_to_str(struct event_filter *filter, struct filter_arg *arg)
2061 2081
2062 lstr = arg_to_str(filter, arg->num.left); 2082 lstr = arg_to_str(filter, arg->num.left);
2063 rstr = arg_to_str(filter, arg->num.right); 2083 rstr = arg_to_str(filter, arg->num.right);
2084 if (!lstr || !rstr)
2085 goto out;
2064 2086
2065 switch (arg->num.type) { 2087 switch (arg->num.type) {
2066 case FILTER_CMP_EQ: 2088 case FILTER_CMP_EQ:
@@ -2097,6 +2119,7 @@ static char *num_to_str(struct event_filter *filter, struct filter_arg *arg)
2097 break; 2119 break;
2098 } 2120 }
2099 2121
2122out:
2100 free(lstr); 2123 free(lstr);
2101 free(rstr); 2124 free(rstr);
2102 return str; 2125 return str;
@@ -2247,7 +2270,12 @@ int pevent_filter_compare(struct event_filter *filter1, struct event_filter *fil
2247 /* The best way to compare complex filters is with strings */ 2270 /* The best way to compare complex filters is with strings */
2248 str1 = arg_to_str(filter1, filter_type1->filter); 2271 str1 = arg_to_str(filter1, filter_type1->filter);
2249 str2 = arg_to_str(filter2, filter_type2->filter); 2272 str2 = arg_to_str(filter2, filter_type2->filter);
2250 result = strcmp(str1, str2) != 0; 2273 if (str1 && str2)
2274 result = strcmp(str1, str2) != 0;
2275 else
2276 /* bail out if allocation fails */
2277 result = 1;
2278
2251 free(str1); 2279 free(str1);
2252 free(str2); 2280 free(str2);
2253 if (result) 2281 if (result)
diff --git a/tools/perf/Documentation/perf-bench.txt b/tools/perf/Documentation/perf-bench.txt
index a3dbadb26ef5..7065cd6fbdfc 100644
--- a/tools/perf/Documentation/perf-bench.txt
+++ b/tools/perf/Documentation/perf-bench.txt
@@ -12,7 +12,7 @@ SYNOPSIS
12 12
13DESCRIPTION 13DESCRIPTION
14----------- 14-----------
15This 'perf bench' command is general framework for benchmark suites. 15This 'perf bench' command is a general framework for benchmark suites.
16 16
17COMMON OPTIONS 17COMMON OPTIONS
18-------------- 18--------------
@@ -45,14 +45,20 @@ SUBSYSTEM
45'sched':: 45'sched'::
46 Scheduler and IPC mechanisms. 46 Scheduler and IPC mechanisms.
47 47
48'mem'::
49 Memory access performance.
50
51'all'::
52 All benchmark subsystems.
53
48SUITES FOR 'sched' 54SUITES FOR 'sched'
49~~~~~~~~~~~~~~~~~~ 55~~~~~~~~~~~~~~~~~~
50*messaging*:: 56*messaging*::
51Suite for evaluating performance of scheduler and IPC mechanisms. 57Suite for evaluating performance of scheduler and IPC mechanisms.
52Based on hackbench by Rusty Russell. 58Based on hackbench by Rusty Russell.
53 59
54Options of *pipe* 60Options of *messaging*
55^^^^^^^^^^^^^^^^^ 61^^^^^^^^^^^^^^^^^^^^^^
56-p:: 62-p::
57--pipe:: 63--pipe::
58Use pipe() instead of socketpair() 64Use pipe() instead of socketpair()
@@ -115,6 +121,72 @@ Example of *pipe*
115 59004 ops/sec 121 59004 ops/sec
116--------------------- 122---------------------
117 123
124SUITES FOR 'mem'
125~~~~~~~~~~~~~~~~
126*memcpy*::
127Suite for evaluating performance of simple memory copy in various ways.
128
129Options of *memcpy*
130^^^^^^^^^^^^^^^^^^^
131-l::
132--length::
133Specify length of memory to copy (default: 1MB).
134Available units are B, KB, MB, GB and TB (case insensitive).
135
136-r::
137--routine::
138Specify routine to copy (default: default).
139Available routines are depend on the architecture.
140On x86-64, x86-64-unrolled, x86-64-movsq and x86-64-movsb are supported.
141
142-i::
143--iterations::
144Repeat memcpy invocation this number of times.
145
146-c::
147--cycle::
148Use perf's cpu-cycles event instead of gettimeofday syscall.
149
150-o::
151--only-prefault::
152Show only the result with page faults before memcpy.
153
154-n::
155--no-prefault::
156Show only the result without page faults before memcpy.
157
158*memset*::
159Suite for evaluating performance of simple memory set in various ways.
160
161Options of *memset*
162^^^^^^^^^^^^^^^^^^^
163-l::
164--length::
165Specify length of memory to set (default: 1MB).
166Available units are B, KB, MB, GB and TB (case insensitive).
167
168-r::
169--routine::
170Specify routine to set (default: default).
171Available routines are depend on the architecture.
172On x86-64, x86-64-unrolled, x86-64-stosq and x86-64-stosb are supported.
173
174-i::
175--iterations::
176Repeat memset invocation this number of times.
177
178-c::
179--cycle::
180Use perf's cpu-cycles event instead of gettimeofday syscall.
181
182-o::
183--only-prefault::
184Show only the result with page faults before memset.
185
186-n::
187--no-prefault::
188Show only the result without page faults before memset.
189
118SEE ALSO 190SEE ALSO
119-------- 191--------
120linkperf:perf[1] 192linkperf:perf[1]
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 2d89f02719b5..495210a612c4 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -57,7 +57,7 @@ OPTIONS
57 57
58-s:: 58-s::
59--sort=:: 59--sort=::
60 Sort by key(s): pid, comm, dso, symbol, parent. 60 Sort by key(s): pid, comm, dso, symbol, parent, srcline.
61 61
62-p:: 62-p::
63--parent=<regex>:: 63--parent=<regex>::
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index 4a5680cb242e..5b80d84d6b4a 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -112,7 +112,7 @@ Default is to monitor all CPUS.
112 112
113-s:: 113-s::
114--sort:: 114--sort::
115 Sort by key(s): pid, comm, dso, symbol, parent 115 Sort by key(s): pid, comm, dso, symbol, parent, srcline.
116 116
117-n:: 117-n::
118--show-nr-samples:: 118--show-nr-samples::
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 0eee64cfe9a0..75d74e5db8d5 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -155,7 +155,7 @@ endif
155 155
156### --- END CONFIGURATION SECTION --- 156### --- END CONFIGURATION SECTION ---
157 157
158BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)/util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE 158BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
159BASIC_LDFLAGS = 159BASIC_LDFLAGS =
160 160
161# Guard against environment variables 161# Guard against environment variables
@@ -503,6 +503,7 @@ else
503 LIB_OBJS += $(OUTPUT)ui/progress.o 503 LIB_OBJS += $(OUTPUT)ui/progress.o
504 LIB_OBJS += $(OUTPUT)ui/util.o 504 LIB_OBJS += $(OUTPUT)ui/util.o
505 LIB_OBJS += $(OUTPUT)ui/tui/setup.o 505 LIB_OBJS += $(OUTPUT)ui/tui/setup.o
506 LIB_OBJS += $(OUTPUT)ui/tui/util.o
506 LIB_H += ui/browser.h 507 LIB_H += ui/browser.h
507 LIB_H += ui/browsers/map.h 508 LIB_H += ui/browsers/map.h
508 LIB_H += ui/helpline.h 509 LIB_H += ui/helpline.h
@@ -522,13 +523,18 @@ else
522 msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev); 523 msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
523 BASIC_CFLAGS += -DNO_GTK2_SUPPORT 524 BASIC_CFLAGS += -DNO_GTK2_SUPPORT
524 else 525 else
526 ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2)),y)
527 BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR
528 endif
525 BASIC_CFLAGS += $(shell pkg-config --cflags gtk+-2.0) 529 BASIC_CFLAGS += $(shell pkg-config --cflags gtk+-2.0)
526 EXTLIBS += $(shell pkg-config --libs gtk+-2.0) 530 EXTLIBS += $(shell pkg-config --libs gtk+-2.0)
527 LIB_OBJS += $(OUTPUT)ui/gtk/browser.o 531 LIB_OBJS += $(OUTPUT)ui/gtk/browser.o
528 LIB_OBJS += $(OUTPUT)ui/gtk/setup.o 532 LIB_OBJS += $(OUTPUT)ui/gtk/setup.o
533 LIB_OBJS += $(OUTPUT)ui/gtk/util.o
529 # Make sure that it'd be included only once. 534 # Make sure that it'd be included only once.
530 ifneq ($(findstring -DNO_NEWT_SUPPORT,$(BASIC_CFLAGS)),) 535 ifneq ($(findstring -DNO_NEWT_SUPPORT,$(BASIC_CFLAGS)),)
531 LIB_OBJS += $(OUTPUT)ui/setup.o 536 LIB_OBJS += $(OUTPUT)ui/setup.o
537 LIB_OBJS += $(OUTPUT)ui/util.o
532 endif 538 endif
533 endif 539 endif
534endif 540endif
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
index 71557225bf92..02dad5d3359b 100644
--- a/tools/perf/bench/mem-memcpy.c
+++ b/tools/perf/bench/mem-memcpy.c
@@ -24,21 +24,21 @@
24static const char *length_str = "1MB"; 24static const char *length_str = "1MB";
25static const char *routine = "default"; 25static const char *routine = "default";
26static int iterations = 1; 26static int iterations = 1;
27static bool use_clock; 27static bool use_cycle;
28static int clock_fd; 28static int cycle_fd;
29static bool only_prefault; 29static bool only_prefault;
30static bool no_prefault; 30static bool no_prefault;
31 31
32static const struct option options[] = { 32static const struct option options[] = {
33 OPT_STRING('l', "length", &length_str, "1MB", 33 OPT_STRING('l', "length", &length_str, "1MB",
34 "Specify length of memory to copy. " 34 "Specify length of memory to copy. "
35 "available unit: B, MB, GB (upper and lower)"), 35 "Available units: B, KB, MB, GB and TB (upper and lower)"),
36 OPT_STRING('r', "routine", &routine, "default", 36 OPT_STRING('r', "routine", &routine, "default",
37 "Specify routine to copy"), 37 "Specify routine to copy"),
38 OPT_INTEGER('i', "iterations", &iterations, 38 OPT_INTEGER('i', "iterations", &iterations,
39 "repeat memcpy() invocation this number of times"), 39 "repeat memcpy() invocation this number of times"),
40 OPT_BOOLEAN('c', "clock", &use_clock, 40 OPT_BOOLEAN('c', "cycle", &use_cycle,
41 "Use CPU clock for measuring"), 41 "Use cycles event instead of gettimeofday() for measuring"),
42 OPT_BOOLEAN('o', "only-prefault", &only_prefault, 42 OPT_BOOLEAN('o', "only-prefault", &only_prefault,
43 "Show only the result with page faults before memcpy()"), 43 "Show only the result with page faults before memcpy()"),
44 OPT_BOOLEAN('n', "no-prefault", &no_prefault, 44 OPT_BOOLEAN('n', "no-prefault", &no_prefault,
@@ -76,27 +76,27 @@ static const char * const bench_mem_memcpy_usage[] = {
76 NULL 76 NULL
77}; 77};
78 78
79static struct perf_event_attr clock_attr = { 79static struct perf_event_attr cycle_attr = {
80 .type = PERF_TYPE_HARDWARE, 80 .type = PERF_TYPE_HARDWARE,
81 .config = PERF_COUNT_HW_CPU_CYCLES 81 .config = PERF_COUNT_HW_CPU_CYCLES
82}; 82};
83 83
84static void init_clock(void) 84static void init_cycle(void)
85{ 85{
86 clock_fd = sys_perf_event_open(&clock_attr, getpid(), -1, -1, 0); 86 cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, 0);
87 87
88 if (clock_fd < 0 && errno == ENOSYS) 88 if (cycle_fd < 0 && errno == ENOSYS)
89 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); 89 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
90 else 90 else
91 BUG_ON(clock_fd < 0); 91 BUG_ON(cycle_fd < 0);
92} 92}
93 93
94static u64 get_clock(void) 94static u64 get_cycle(void)
95{ 95{
96 int ret; 96 int ret;
97 u64 clk; 97 u64 clk;
98 98
99 ret = read(clock_fd, &clk, sizeof(u64)); 99 ret = read(cycle_fd, &clk, sizeof(u64));
100 BUG_ON(ret != sizeof(u64)); 100 BUG_ON(ret != sizeof(u64));
101 101
102 return clk; 102 return clk;
@@ -119,9 +119,9 @@ static void alloc_mem(void **dst, void **src, size_t length)
119 die("memory allocation failed - maybe length is too large?\n"); 119 die("memory allocation failed - maybe length is too large?\n");
120} 120}
121 121
122static u64 do_memcpy_clock(memcpy_t fn, size_t len, bool prefault) 122static u64 do_memcpy_cycle(memcpy_t fn, size_t len, bool prefault)
123{ 123{
124 u64 clock_start = 0ULL, clock_end = 0ULL; 124 u64 cycle_start = 0ULL, cycle_end = 0ULL;
125 void *src = NULL, *dst = NULL; 125 void *src = NULL, *dst = NULL;
126 int i; 126 int i;
127 127
@@ -130,14 +130,14 @@ static u64 do_memcpy_clock(memcpy_t fn, size_t len, bool prefault)
130 if (prefault) 130 if (prefault)
131 fn(dst, src, len); 131 fn(dst, src, len);
132 132
133 clock_start = get_clock(); 133 cycle_start = get_cycle();
134 for (i = 0; i < iterations; ++i) 134 for (i = 0; i < iterations; ++i)
135 fn(dst, src, len); 135 fn(dst, src, len);
136 clock_end = get_clock(); 136 cycle_end = get_cycle();
137 137
138 free(src); 138 free(src);
139 free(dst); 139 free(dst);
140 return clock_end - clock_start; 140 return cycle_end - cycle_start;
141} 141}
142 142
143static double do_memcpy_gettimeofday(memcpy_t fn, size_t len, bool prefault) 143static double do_memcpy_gettimeofday(memcpy_t fn, size_t len, bool prefault)
@@ -182,17 +182,17 @@ int bench_mem_memcpy(int argc, const char **argv,
182 int i; 182 int i;
183 size_t len; 183 size_t len;
184 double result_bps[2]; 184 double result_bps[2];
185 u64 result_clock[2]; 185 u64 result_cycle[2];
186 186
187 argc = parse_options(argc, argv, options, 187 argc = parse_options(argc, argv, options,
188 bench_mem_memcpy_usage, 0); 188 bench_mem_memcpy_usage, 0);
189 189
190 if (use_clock) 190 if (use_cycle)
191 init_clock(); 191 init_cycle();
192 192
193 len = (size_t)perf_atoll((char *)length_str); 193 len = (size_t)perf_atoll((char *)length_str);
194 194
195 result_clock[0] = result_clock[1] = 0ULL; 195 result_cycle[0] = result_cycle[1] = 0ULL;
196 result_bps[0] = result_bps[1] = 0.0; 196 result_bps[0] = result_bps[1] = 0.0;
197 197
198 if ((s64)len <= 0) { 198 if ((s64)len <= 0) {
@@ -223,11 +223,11 @@ int bench_mem_memcpy(int argc, const char **argv,
223 223
224 if (!only_prefault && !no_prefault) { 224 if (!only_prefault && !no_prefault) {
225 /* show both of results */ 225 /* show both of results */
226 if (use_clock) { 226 if (use_cycle) {
227 result_clock[0] = 227 result_cycle[0] =
228 do_memcpy_clock(routines[i].fn, len, false); 228 do_memcpy_cycle(routines[i].fn, len, false);
229 result_clock[1] = 229 result_cycle[1] =
230 do_memcpy_clock(routines[i].fn, len, true); 230 do_memcpy_cycle(routines[i].fn, len, true);
231 } else { 231 } else {
232 result_bps[0] = 232 result_bps[0] =
233 do_memcpy_gettimeofday(routines[i].fn, 233 do_memcpy_gettimeofday(routines[i].fn,
@@ -237,9 +237,9 @@ int bench_mem_memcpy(int argc, const char **argv,
237 len, true); 237 len, true);
238 } 238 }
239 } else { 239 } else {
240 if (use_clock) { 240 if (use_cycle) {
241 result_clock[pf] = 241 result_cycle[pf] =
242 do_memcpy_clock(routines[i].fn, 242 do_memcpy_cycle(routines[i].fn,
243 len, only_prefault); 243 len, only_prefault);
244 } else { 244 } else {
245 result_bps[pf] = 245 result_bps[pf] =
@@ -251,12 +251,12 @@ int bench_mem_memcpy(int argc, const char **argv,
251 switch (bench_format) { 251 switch (bench_format) {
252 case BENCH_FORMAT_DEFAULT: 252 case BENCH_FORMAT_DEFAULT:
253 if (!only_prefault && !no_prefault) { 253 if (!only_prefault && !no_prefault) {
254 if (use_clock) { 254 if (use_cycle) {
255 printf(" %14lf Clock/Byte\n", 255 printf(" %14lf Cycle/Byte\n",
256 (double)result_clock[0] 256 (double)result_cycle[0]
257 / (double)len); 257 / (double)len);
258 printf(" %14lf Clock/Byte (with prefault)\n", 258 printf(" %14lf Cycle/Byte (with prefault)\n",
259 (double)result_clock[1] 259 (double)result_cycle[1]
260 / (double)len); 260 / (double)len);
261 } else { 261 } else {
262 print_bps(result_bps[0]); 262 print_bps(result_bps[0]);
@@ -265,9 +265,9 @@ int bench_mem_memcpy(int argc, const char **argv,
265 printf(" (with prefault)\n"); 265 printf(" (with prefault)\n");
266 } 266 }
267 } else { 267 } else {
268 if (use_clock) { 268 if (use_cycle) {
269 printf(" %14lf Clock/Byte", 269 printf(" %14lf Cycle/Byte",
270 (double)result_clock[pf] 270 (double)result_cycle[pf]
271 / (double)len); 271 / (double)len);
272 } else 272 } else
273 print_bps(result_bps[pf]); 273 print_bps(result_bps[pf]);
@@ -277,17 +277,17 @@ int bench_mem_memcpy(int argc, const char **argv,
277 break; 277 break;
278 case BENCH_FORMAT_SIMPLE: 278 case BENCH_FORMAT_SIMPLE:
279 if (!only_prefault && !no_prefault) { 279 if (!only_prefault && !no_prefault) {
280 if (use_clock) { 280 if (use_cycle) {
281 printf("%lf %lf\n", 281 printf("%lf %lf\n",
282 (double)result_clock[0] / (double)len, 282 (double)result_cycle[0] / (double)len,
283 (double)result_clock[1] / (double)len); 283 (double)result_cycle[1] / (double)len);
284 } else { 284 } else {
285 printf("%lf %lf\n", 285 printf("%lf %lf\n",
286 result_bps[0], result_bps[1]); 286 result_bps[0], result_bps[1]);
287 } 287 }
288 } else { 288 } else {
289 if (use_clock) { 289 if (use_cycle) {
290 printf("%lf\n", (double)result_clock[pf] 290 printf("%lf\n", (double)result_cycle[pf]
291 / (double)len); 291 / (double)len);
292 } else 292 } else
293 printf("%lf\n", result_bps[pf]); 293 printf("%lf\n", result_bps[pf]);
diff --git a/tools/perf/bench/mem-memset.c b/tools/perf/bench/mem-memset.c
index e9079185bd72..350cc9557265 100644
--- a/tools/perf/bench/mem-memset.c
+++ b/tools/perf/bench/mem-memset.c
@@ -24,21 +24,21 @@
24static const char *length_str = "1MB"; 24static const char *length_str = "1MB";
25static const char *routine = "default"; 25static const char *routine = "default";
26static int iterations = 1; 26static int iterations = 1;
27static bool use_clock; 27static bool use_cycle;
28static int clock_fd; 28static int cycle_fd;
29static bool only_prefault; 29static bool only_prefault;
30static bool no_prefault; 30static bool no_prefault;
31 31
32static const struct option options[] = { 32static const struct option options[] = {
33 OPT_STRING('l', "length", &length_str, "1MB", 33 OPT_STRING('l', "length", &length_str, "1MB",
34 "Specify length of memory to copy. " 34 "Specify length of memory to set. "
35 "available unit: B, MB, GB (upper and lower)"), 35 "Available units: B, KB, MB, GB and TB (upper and lower)"),
36 OPT_STRING('r', "routine", &routine, "default", 36 OPT_STRING('r', "routine", &routine, "default",
37 "Specify routine to copy"), 37 "Specify routine to set"),
38 OPT_INTEGER('i', "iterations", &iterations, 38 OPT_INTEGER('i', "iterations", &iterations,
39 "repeat memset() invocation this number of times"), 39 "repeat memset() invocation this number of times"),
40 OPT_BOOLEAN('c', "clock", &use_clock, 40 OPT_BOOLEAN('c', "cycle", &use_cycle,
41 "Use CPU clock for measuring"), 41 "Use cycles event instead of gettimeofday() for measuring"),
42 OPT_BOOLEAN('o', "only-prefault", &only_prefault, 42 OPT_BOOLEAN('o', "only-prefault", &only_prefault,
43 "Show only the result with page faults before memset()"), 43 "Show only the result with page faults before memset()"),
44 OPT_BOOLEAN('n', "no-prefault", &no_prefault, 44 OPT_BOOLEAN('n', "no-prefault", &no_prefault,
@@ -76,27 +76,27 @@ static const char * const bench_mem_memset_usage[] = {
76 NULL 76 NULL
77}; 77};
78 78
79static struct perf_event_attr clock_attr = { 79static struct perf_event_attr cycle_attr = {
80 .type = PERF_TYPE_HARDWARE, 80 .type = PERF_TYPE_HARDWARE,
81 .config = PERF_COUNT_HW_CPU_CYCLES 81 .config = PERF_COUNT_HW_CPU_CYCLES
82}; 82};
83 83
84static void init_clock(void) 84static void init_cycle(void)
85{ 85{
86 clock_fd = sys_perf_event_open(&clock_attr, getpid(), -1, -1, 0); 86 cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, 0);
87 87
88 if (clock_fd < 0 && errno == ENOSYS) 88 if (cycle_fd < 0 && errno == ENOSYS)
89 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); 89 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
90 else 90 else
91 BUG_ON(clock_fd < 0); 91 BUG_ON(cycle_fd < 0);
92} 92}
93 93
94static u64 get_clock(void) 94static u64 get_cycle(void)
95{ 95{
96 int ret; 96 int ret;
97 u64 clk; 97 u64 clk;
98 98
99 ret = read(clock_fd, &clk, sizeof(u64)); 99 ret = read(cycle_fd, &clk, sizeof(u64));
100 BUG_ON(ret != sizeof(u64)); 100 BUG_ON(ret != sizeof(u64));
101 101
102 return clk; 102 return clk;
@@ -115,9 +115,9 @@ static void alloc_mem(void **dst, size_t length)
115 die("memory allocation failed - maybe length is too large?\n"); 115 die("memory allocation failed - maybe length is too large?\n");
116} 116}
117 117
118static u64 do_memset_clock(memset_t fn, size_t len, bool prefault) 118static u64 do_memset_cycle(memset_t fn, size_t len, bool prefault)
119{ 119{
120 u64 clock_start = 0ULL, clock_end = 0ULL; 120 u64 cycle_start = 0ULL, cycle_end = 0ULL;
121 void *dst = NULL; 121 void *dst = NULL;
122 int i; 122 int i;
123 123
@@ -126,13 +126,13 @@ static u64 do_memset_clock(memset_t fn, size_t len, bool prefault)
126 if (prefault) 126 if (prefault)
127 fn(dst, -1, len); 127 fn(dst, -1, len);
128 128
129 clock_start = get_clock(); 129 cycle_start = get_cycle();
130 for (i = 0; i < iterations; ++i) 130 for (i = 0; i < iterations; ++i)
131 fn(dst, i, len); 131 fn(dst, i, len);
132 clock_end = get_clock(); 132 cycle_end = get_cycle();
133 133
134 free(dst); 134 free(dst);
135 return clock_end - clock_start; 135 return cycle_end - cycle_start;
136} 136}
137 137
138static double do_memset_gettimeofday(memset_t fn, size_t len, bool prefault) 138static double do_memset_gettimeofday(memset_t fn, size_t len, bool prefault)
@@ -176,17 +176,17 @@ int bench_mem_memset(int argc, const char **argv,
176 int i; 176 int i;
177 size_t len; 177 size_t len;
178 double result_bps[2]; 178 double result_bps[2];
179 u64 result_clock[2]; 179 u64 result_cycle[2];
180 180
181 argc = parse_options(argc, argv, options, 181 argc = parse_options(argc, argv, options,
182 bench_mem_memset_usage, 0); 182 bench_mem_memset_usage, 0);
183 183
184 if (use_clock) 184 if (use_cycle)
185 init_clock(); 185 init_cycle();
186 186
187 len = (size_t)perf_atoll((char *)length_str); 187 len = (size_t)perf_atoll((char *)length_str);
188 188
189 result_clock[0] = result_clock[1] = 0ULL; 189 result_cycle[0] = result_cycle[1] = 0ULL;
190 result_bps[0] = result_bps[1] = 0.0; 190 result_bps[0] = result_bps[1] = 0.0;
191 191
192 if ((s64)len <= 0) { 192 if ((s64)len <= 0) {
@@ -217,11 +217,11 @@ int bench_mem_memset(int argc, const char **argv,
217 217
218 if (!only_prefault && !no_prefault) { 218 if (!only_prefault && !no_prefault) {
219 /* show both of results */ 219 /* show both of results */
220 if (use_clock) { 220 if (use_cycle) {
221 result_clock[0] = 221 result_cycle[0] =
222 do_memset_clock(routines[i].fn, len, false); 222 do_memset_cycle(routines[i].fn, len, false);
223 result_clock[1] = 223 result_cycle[1] =
224 do_memset_clock(routines[i].fn, len, true); 224 do_memset_cycle(routines[i].fn, len, true);
225 } else { 225 } else {
226 result_bps[0] = 226 result_bps[0] =
227 do_memset_gettimeofday(routines[i].fn, 227 do_memset_gettimeofday(routines[i].fn,
@@ -231,9 +231,9 @@ int bench_mem_memset(int argc, const char **argv,
231 len, true); 231 len, true);
232 } 232 }
233 } else { 233 } else {
234 if (use_clock) { 234 if (use_cycle) {
235 result_clock[pf] = 235 result_cycle[pf] =
236 do_memset_clock(routines[i].fn, 236 do_memset_cycle(routines[i].fn,
237 len, only_prefault); 237 len, only_prefault);
238 } else { 238 } else {
239 result_bps[pf] = 239 result_bps[pf] =
@@ -245,12 +245,12 @@ int bench_mem_memset(int argc, const char **argv,
245 switch (bench_format) { 245 switch (bench_format) {
246 case BENCH_FORMAT_DEFAULT: 246 case BENCH_FORMAT_DEFAULT:
247 if (!only_prefault && !no_prefault) { 247 if (!only_prefault && !no_prefault) {
248 if (use_clock) { 248 if (use_cycle) {
249 printf(" %14lf Clock/Byte\n", 249 printf(" %14lf Cycle/Byte\n",
250 (double)result_clock[0] 250 (double)result_cycle[0]
251 / (double)len); 251 / (double)len);
252 printf(" %14lf Clock/Byte (with prefault)\n ", 252 printf(" %14lf Cycle/Byte (with prefault)\n ",
253 (double)result_clock[1] 253 (double)result_cycle[1]
254 / (double)len); 254 / (double)len);
255 } else { 255 } else {
256 print_bps(result_bps[0]); 256 print_bps(result_bps[0]);
@@ -259,9 +259,9 @@ int bench_mem_memset(int argc, const char **argv,
259 printf(" (with prefault)\n"); 259 printf(" (with prefault)\n");
260 } 260 }
261 } else { 261 } else {
262 if (use_clock) { 262 if (use_cycle) {
263 printf(" %14lf Clock/Byte", 263 printf(" %14lf Cycle/Byte",
264 (double)result_clock[pf] 264 (double)result_cycle[pf]
265 / (double)len); 265 / (double)len);
266 } else 266 } else
267 print_bps(result_bps[pf]); 267 print_bps(result_bps[pf]);
@@ -271,17 +271,17 @@ int bench_mem_memset(int argc, const char **argv,
271 break; 271 break;
272 case BENCH_FORMAT_SIMPLE: 272 case BENCH_FORMAT_SIMPLE:
273 if (!only_prefault && !no_prefault) { 273 if (!only_prefault && !no_prefault) {
274 if (use_clock) { 274 if (use_cycle) {
275 printf("%lf %lf\n", 275 printf("%lf %lf\n",
276 (double)result_clock[0] / (double)len, 276 (double)result_cycle[0] / (double)len,
277 (double)result_clock[1] / (double)len); 277 (double)result_cycle[1] / (double)len);
278 } else { 278 } else {
279 printf("%lf %lf\n", 279 printf("%lf %lf\n",
280 result_bps[0], result_bps[1]); 280 result_bps[0], result_bps[1]);
281 } 281 }
282 } else { 282 } else {
283 if (use_clock) { 283 if (use_cycle) {
284 printf("%lf\n", (double)result_clock[pf] 284 printf("%lf\n", (double)result_cycle[pf]
285 / (double)len); 285 / (double)len);
286 } else 286 } else
287 printf("%lf\n", result_bps[pf]); 287 printf("%lf\n", result_bps[pf]);
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
index b0e74ab2d7a2..1f3100216448 100644
--- a/tools/perf/builtin-bench.c
+++ b/tools/perf/builtin-bench.c
@@ -33,7 +33,7 @@ struct bench_suite {
33}; 33};
34 \ 34 \
35/* sentinel: easy for help */ 35/* sentinel: easy for help */
36#define suite_all { "all", "test all suite (pseudo suite)", NULL } 36#define suite_all { "all", "Test all benchmark suites", NULL }
37 37
38static struct bench_suite sched_suites[] = { 38static struct bench_suite sched_suites[] = {
39 { "messaging", 39 { "messaging",
@@ -75,7 +75,7 @@ static struct bench_subsys subsystems[] = {
75 "memory access performance", 75 "memory access performance",
76 mem_suites }, 76 mem_suites },
77 { "all", /* sentinel: easy for help */ 77 { "all", /* sentinel: easy for help */
78 "test all subsystem (pseudo subsystem)", 78 "all benchmark subsystem",
79 NULL }, 79 NULL },
80 { NULL, 80 { NULL,
81 NULL, 81 NULL,
diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c
index acd78dc28341..0dd5a058f766 100644
--- a/tools/perf/builtin-evlist.c
+++ b/tools/perf/builtin-evlist.c
@@ -60,7 +60,7 @@ static int __cmd_evlist(const char *input_name, struct perf_attr_details *detail
60 list_for_each_entry(pos, &session->evlist->entries, node) { 60 list_for_each_entry(pos, &session->evlist->entries, node) {
61 bool first = true; 61 bool first = true;
62 62
63 printf("%s", event_name(pos)); 63 printf("%s", perf_evsel__name(pos));
64 64
65 if (details->verbose || details->freq) { 65 if (details->verbose || details->freq) {
66 comma_printf(&first, " sample_freq=%" PRIu64, 66 comma_printf(&first, " sample_freq=%" PRIu64,
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 547af48deb4f..ce35015f2dc6 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -57,6 +57,11 @@ static unsigned long nr_allocs, nr_cross_allocs;
57 57
58#define PATH_SYS_NODE "/sys/devices/system/node" 58#define PATH_SYS_NODE "/sys/devices/system/node"
59 59
60struct perf_kmem {
61 struct perf_tool tool;
62 struct perf_session *session;
63};
64
60static void init_cpunode_map(void) 65static void init_cpunode_map(void)
61{ 66{
62 FILE *fp; 67 FILE *fp;
@@ -278,14 +283,16 @@ static void process_free_event(void *data,
278 s_alloc->alloc_cpu = -1; 283 s_alloc->alloc_cpu = -1;
279} 284}
280 285
281static void process_raw_event(union perf_event *raw_event __used, void *data, 286static void process_raw_event(struct perf_tool *tool,
287 union perf_event *raw_event __used, void *data,
282 int cpu, u64 timestamp, struct thread *thread) 288 int cpu, u64 timestamp, struct thread *thread)
283{ 289{
290 struct perf_kmem *kmem = container_of(tool, struct perf_kmem, tool);
284 struct event_format *event; 291 struct event_format *event;
285 int type; 292 int type;
286 293
287 type = trace_parse_common_type(data); 294 type = trace_parse_common_type(kmem->session->pevent, data);
288 event = trace_find_event(type); 295 event = pevent_find_event(kmem->session->pevent, type);
289 296
290 if (!strcmp(event->name, "kmalloc") || 297 if (!strcmp(event->name, "kmalloc") ||
291 !strcmp(event->name, "kmem_cache_alloc")) { 298 !strcmp(event->name, "kmem_cache_alloc")) {
@@ -306,7 +313,7 @@ static void process_raw_event(union perf_event *raw_event __used, void *data,
306 } 313 }
307} 314}
308 315
309static int process_sample_event(struct perf_tool *tool __used, 316static int process_sample_event(struct perf_tool *tool,
310 union perf_event *event, 317 union perf_event *event,
311 struct perf_sample *sample, 318 struct perf_sample *sample,
312 struct perf_evsel *evsel __used, 319 struct perf_evsel *evsel __used,
@@ -322,16 +329,18 @@ static int process_sample_event(struct perf_tool *tool __used,
322 329
323 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); 330 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
324 331
325 process_raw_event(event, sample->raw_data, sample->cpu, 332 process_raw_event(tool, event, sample->raw_data, sample->cpu,
326 sample->time, thread); 333 sample->time, thread);
327 334
328 return 0; 335 return 0;
329} 336}
330 337
331static struct perf_tool perf_kmem = { 338static struct perf_kmem perf_kmem = {
332 .sample = process_sample_event, 339 .tool = {
333 .comm = perf_event__process_comm, 340 .sample = process_sample_event,
334 .ordered_samples = true, 341 .comm = perf_event__process_comm,
342 .ordered_samples = true,
343 },
335}; 344};
336 345
337static double fragmentation(unsigned long n_req, unsigned long n_alloc) 346static double fragmentation(unsigned long n_req, unsigned long n_alloc)
@@ -486,11 +495,15 @@ static void sort_result(void)
486static int __cmd_kmem(void) 495static int __cmd_kmem(void)
487{ 496{
488 int err = -EINVAL; 497 int err = -EINVAL;
489 struct perf_session *session = perf_session__new(input_name, O_RDONLY, 498 struct perf_session *session;
490 0, false, &perf_kmem); 499
500 session = perf_session__new(input_name, O_RDONLY, 0, false,
501 &perf_kmem.tool);
491 if (session == NULL) 502 if (session == NULL)
492 return -ENOMEM; 503 return -ENOMEM;
493 504
505 perf_kmem.session = session;
506
494 if (perf_session__create_kernel_maps(session) < 0) 507 if (perf_session__create_kernel_maps(session) < 0)
495 goto out_delete; 508 goto out_delete;
496 509
@@ -498,7 +511,7 @@ static int __cmd_kmem(void)
498 goto out_delete; 511 goto out_delete;
499 512
500 setup_pager(); 513 setup_pager();
501 err = perf_session__process_events(session, &perf_kmem); 514 err = perf_session__process_events(session, &perf_kmem.tool);
502 if (err != 0) 515 if (err != 0)
503 goto out_delete; 516 goto out_delete;
504 sort_result(); 517 sort_result();
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index fd53319de20d..b3c428548868 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -724,8 +724,8 @@ process_raw_event(void *data, int cpu, u64 timestamp, struct thread *thread)
724 struct event_format *event; 724 struct event_format *event;
725 int type; 725 int type;
726 726
727 type = trace_parse_common_type(data); 727 type = trace_parse_common_type(session->pevent, data);
728 event = trace_find_event(type); 728 event = pevent_find_event(session->pevent, type);
729 729
730 if (!strcmp(event->name, "lock_acquire")) 730 if (!strcmp(event->name, "lock_acquire"))
731 process_lock_acquire_event(data, event, cpu, timestamp, thread); 731 process_lock_acquire_event(data, event, cpu, timestamp, thread);
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index f95840d04e4c..f5a6452931e6 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -265,7 +265,7 @@ try_again:
265 265
266 if (err == ENOENT) { 266 if (err == ENOENT) {
267 ui__error("The %s event is not supported.\n", 267 ui__error("The %s event is not supported.\n",
268 event_name(pos)); 268 perf_evsel__name(pos));
269 exit(EXIT_FAILURE); 269 exit(EXIT_FAILURE);
270 } 270 }
271 271
@@ -916,7 +916,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
916 usage_with_options(record_usage, record_options); 916 usage_with_options(record_usage, record_options);
917 917
918 list_for_each_entry(pos, &evsel_list->entries, node) { 918 list_for_each_entry(pos, &evsel_list->entries, node) {
919 if (perf_header__push_event(pos->attr.config, event_name(pos))) 919 if (perf_header__push_event(pos->attr.config, perf_evsel__name(pos)))
920 goto out_free_fd; 920 goto out_free_fd;
921 } 921 }
922 922
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 25249f76329d..69b1c1185159 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -69,7 +69,7 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
69 69
70 if ((sort__has_parent || symbol_conf.use_callchain) 70 if ((sort__has_parent || symbol_conf.use_callchain)
71 && sample->callchain) { 71 && sample->callchain) {
72 err = machine__resolve_callchain(machine, evsel, al->thread, 72 err = machine__resolve_callchain(machine, al->thread,
73 sample->callchain, &parent); 73 sample->callchain, &parent);
74 if (err) 74 if (err)
75 return err; 75 return err;
@@ -140,7 +140,7 @@ static int perf_evsel__add_hist_entry(struct perf_evsel *evsel,
140 struct hist_entry *he; 140 struct hist_entry *he;
141 141
142 if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { 142 if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) {
143 err = machine__resolve_callchain(machine, evsel, al->thread, 143 err = machine__resolve_callchain(machine, al->thread,
144 sample->callchain, &parent); 144 sample->callchain, &parent);
145 if (err) 145 if (err)
146 return err; 146 return err;
@@ -230,7 +230,7 @@ static int process_read_event(struct perf_tool *tool,
230 struct perf_report *rep = container_of(tool, struct perf_report, tool); 230 struct perf_report *rep = container_of(tool, struct perf_report, tool);
231 231
232 if (rep->show_threads) { 232 if (rep->show_threads) {
233 const char *name = evsel ? event_name(evsel) : "unknown"; 233 const char *name = evsel ? perf_evsel__name(evsel) : "unknown";
234 perf_read_values_add_value(&rep->show_threads_values, 234 perf_read_values_add_value(&rep->show_threads_values,
235 event->read.pid, event->read.tid, 235 event->read.pid, event->read.tid,
236 event->read.id, 236 event->read.id,
@@ -239,17 +239,18 @@ static int process_read_event(struct perf_tool *tool,
239 } 239 }
240 240
241 dump_printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, 241 dump_printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid,
242 evsel ? event_name(evsel) : "FAIL", 242 evsel ? perf_evsel__name(evsel) : "FAIL",
243 event->read.value); 243 event->read.value);
244 244
245 return 0; 245 return 0;
246} 246}
247 247
248/* For pipe mode, sample_type is not currently set */
248static int perf_report__setup_sample_type(struct perf_report *rep) 249static int perf_report__setup_sample_type(struct perf_report *rep)
249{ 250{
250 struct perf_session *self = rep->session; 251 struct perf_session *self = rep->session;
251 252
252 if (!(self->sample_type & PERF_SAMPLE_CALLCHAIN)) { 253 if (!self->fd_pipe && !(self->sample_type & PERF_SAMPLE_CALLCHAIN)) {
253 if (sort__has_parent) { 254 if (sort__has_parent) {
254 ui__error("Selected --sort parent, but no " 255 ui__error("Selected --sort parent, but no "
255 "callchain data. Did you call " 256 "callchain data. Did you call "
@@ -272,7 +273,8 @@ static int perf_report__setup_sample_type(struct perf_report *rep)
272 } 273 }
273 274
274 if (sort__branch_mode == 1) { 275 if (sort__branch_mode == 1) {
275 if (!(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) { 276 if (!self->fd_pipe &&
277 !(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) {
276 ui__error("Selected -b but no branch data. " 278 ui__error("Selected -b but no branch data. "
277 "Did you call perf record without -b?\n"); 279 "Did you call perf record without -b?\n");
278 return -1; 280 return -1;
@@ -314,7 +316,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
314 316
315 list_for_each_entry(pos, &evlist->entries, node) { 317 list_for_each_entry(pos, &evlist->entries, node) {
316 struct hists *hists = &pos->hists; 318 struct hists *hists = &pos->hists;
317 const char *evname = event_name(pos); 319 const char *evname = perf_evsel__name(pos);
318 320
319 hists__fprintf_nr_sample_events(hists, evname, stdout); 321 hists__fprintf_nr_sample_events(hists, evname, stdout);
320 hists__fprintf(hists, NULL, false, true, 0, 0, stdout); 322 hists__fprintf(hists, NULL, false, true, 0, 0, stdout);
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index b125e07eb399..7a9ad2b1ee76 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -43,6 +43,11 @@ static u64 sleep_measurement_overhead;
43 43
44static unsigned long nr_tasks; 44static unsigned long nr_tasks;
45 45
46struct perf_sched {
47 struct perf_tool tool;
48 struct perf_session *session;
49};
50
46struct sched_atom; 51struct sched_atom;
47 52
48struct task_desc { 53struct task_desc {
@@ -1597,11 +1602,13 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool,
1597 struct perf_evsel *evsel, 1602 struct perf_evsel *evsel,
1598 struct machine *machine) 1603 struct machine *machine)
1599{ 1604{
1605 struct perf_sched *sched = container_of(tool, struct perf_sched, tool);
1606 struct pevent *pevent = sched->session->pevent;
1600 struct thread *thread = machine__findnew_thread(machine, sample->pid); 1607 struct thread *thread = machine__findnew_thread(machine, sample->pid);
1601 1608
1602 if (thread == NULL) { 1609 if (thread == NULL) {
1603 pr_debug("problem processing %s event, skipping it.\n", 1610 pr_debug("problem processing %s event, skipping it.\n",
1604 evsel->name); 1611 perf_evsel__name(evsel));
1605 return -1; 1612 return -1;
1606 } 1613 }
1607 1614
@@ -1612,7 +1619,8 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool,
1612 tracepoint_handler f = evsel->handler.func; 1619 tracepoint_handler f = evsel->handler.func;
1613 1620
1614 if (evsel->handler.data == NULL) 1621 if (evsel->handler.data == NULL)
1615 evsel->handler.data = trace_find_event(evsel->attr.config); 1622 evsel->handler.data = pevent_find_event(pevent,
1623 evsel->attr.config);
1616 1624
1617 f(tool, evsel->handler.data, sample, machine, thread); 1625 f(tool, evsel->handler.data, sample, machine, thread);
1618 } 1626 }
@@ -1620,12 +1628,14 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool,
1620 return 0; 1628 return 0;
1621} 1629}
1622 1630
1623static struct perf_tool perf_sched = { 1631static struct perf_sched perf_sched = {
1624 .sample = perf_sched__process_tracepoint_sample, 1632 .tool = {
1625 .comm = perf_event__process_comm, 1633 .sample = perf_sched__process_tracepoint_sample,
1626 .lost = perf_event__process_lost, 1634 .comm = perf_event__process_comm,
1627 .fork = perf_event__process_task, 1635 .lost = perf_event__process_lost,
1628 .ordered_samples = true, 1636 .fork = perf_event__process_task,
1637 .ordered_samples = true,
1638 },
1629}; 1639};
1630 1640
1631static void read_events(bool destroy, struct perf_session **psession) 1641static void read_events(bool destroy, struct perf_session **psession)
@@ -1640,16 +1650,20 @@ static void read_events(bool destroy, struct perf_session **psession)
1640 { "sched:sched_process_exit", process_sched_exit_event, }, 1650 { "sched:sched_process_exit", process_sched_exit_event, },
1641 { "sched:sched_migrate_task", process_sched_migrate_task_event, }, 1651 { "sched:sched_migrate_task", process_sched_migrate_task_event, },
1642 }; 1652 };
1643 struct perf_session *session = perf_session__new(input_name, O_RDONLY, 1653 struct perf_session *session;
1644 0, false, &perf_sched); 1654
1655 session = perf_session__new(input_name, O_RDONLY, 0, false,
1656 &perf_sched.tool);
1645 if (session == NULL) 1657 if (session == NULL)
1646 die("No Memory"); 1658 die("No Memory");
1647 1659
1648 err = perf_evlist__set_tracepoints_handlers_array(session->evlist, handlers); 1660 perf_sched.session = session;
1661
1662 err = perf_session__set_tracepoints_handlers(session, handlers);
1649 assert(err == 0); 1663 assert(err == 0);
1650 1664
1651 if (perf_session__has_traces(session, "record -R")) { 1665 if (perf_session__has_traces(session, "record -R")) {
1652 err = perf_session__process_events(session, &perf_sched); 1666 err = perf_session__process_events(session, &perf_sched.tool);
1653 if (err) 1667 if (err)
1654 die("Failed to process events, error %d", err); 1668 die("Failed to process events, error %d", err);
1655 1669
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 8e395a538eb9..1e60ab70b2b1 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -28,6 +28,11 @@ static bool system_wide;
28static const char *cpu_list; 28static const char *cpu_list;
29static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 29static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
30 30
31struct perf_script {
32 struct perf_tool tool;
33 struct perf_session *session;
34};
35
31enum perf_output_field { 36enum perf_output_field {
32 PERF_OUTPUT_COMM = 1U << 0, 37 PERF_OUTPUT_COMM = 1U << 0,
33 PERF_OUTPUT_TID = 1U << 1, 38 PERF_OUTPUT_TID = 1U << 1,
@@ -137,10 +142,11 @@ static const char *output_field2str(enum perf_output_field field)
137 142
138#define PRINT_FIELD(x) (output[attr->type].fields & PERF_OUTPUT_##x) 143#define PRINT_FIELD(x) (output[attr->type].fields & PERF_OUTPUT_##x)
139 144
140static int perf_event_attr__check_stype(struct perf_event_attr *attr, 145static int perf_evsel__check_stype(struct perf_evsel *evsel,
141 u64 sample_type, const char *sample_msg, 146 u64 sample_type, const char *sample_msg,
142 enum perf_output_field field) 147 enum perf_output_field field)
143{ 148{
149 struct perf_event_attr *attr = &evsel->attr;
144 int type = attr->type; 150 int type = attr->type;
145 const char *evname; 151 const char *evname;
146 152
@@ -148,7 +154,7 @@ static int perf_event_attr__check_stype(struct perf_event_attr *attr,
148 return 0; 154 return 0;
149 155
150 if (output[type].user_set) { 156 if (output[type].user_set) {
151 evname = __event_name(attr->type, attr->config); 157 evname = perf_evsel__name(evsel);
152 pr_err("Samples for '%s' event do not have %s attribute set. " 158 pr_err("Samples for '%s' event do not have %s attribute set. "
153 "Cannot print '%s' field.\n", 159 "Cannot print '%s' field.\n",
154 evname, sample_msg, output_field2str(field)); 160 evname, sample_msg, output_field2str(field));
@@ -157,7 +163,7 @@ static int perf_event_attr__check_stype(struct perf_event_attr *attr,
157 163
158 /* user did not ask for it explicitly so remove from the default list */ 164 /* user did not ask for it explicitly so remove from the default list */
159 output[type].fields &= ~field; 165 output[type].fields &= ~field;
160 evname = __event_name(attr->type, attr->config); 166 evname = perf_evsel__name(evsel);
161 pr_debug("Samples for '%s' event do not have %s attribute set. " 167 pr_debug("Samples for '%s' event do not have %s attribute set. "
162 "Skipping '%s' field.\n", 168 "Skipping '%s' field.\n",
163 evname, sample_msg, output_field2str(field)); 169 evname, sample_msg, output_field2str(field));
@@ -175,8 +181,8 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
175 return -EINVAL; 181 return -EINVAL;
176 182
177 if (PRINT_FIELD(IP)) { 183 if (PRINT_FIELD(IP)) {
178 if (perf_event_attr__check_stype(attr, PERF_SAMPLE_IP, "IP", 184 if (perf_evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP",
179 PERF_OUTPUT_IP)) 185 PERF_OUTPUT_IP))
180 return -EINVAL; 186 return -EINVAL;
181 187
182 if (!no_callchain && 188 if (!no_callchain &&
@@ -185,8 +191,8 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
185 } 191 }
186 192
187 if (PRINT_FIELD(ADDR) && 193 if (PRINT_FIELD(ADDR) &&
188 perf_event_attr__check_stype(attr, PERF_SAMPLE_ADDR, "ADDR", 194 perf_evsel__check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR",
189 PERF_OUTPUT_ADDR)) 195 PERF_OUTPUT_ADDR))
190 return -EINVAL; 196 return -EINVAL;
191 197
192 if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) { 198 if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
@@ -208,18 +214,18 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
208 } 214 }
209 215
210 if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) && 216 if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
211 perf_event_attr__check_stype(attr, PERF_SAMPLE_TID, "TID", 217 perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID",
212 PERF_OUTPUT_TID|PERF_OUTPUT_PID)) 218 PERF_OUTPUT_TID|PERF_OUTPUT_PID))
213 return -EINVAL; 219 return -EINVAL;
214 220
215 if (PRINT_FIELD(TIME) && 221 if (PRINT_FIELD(TIME) &&
216 perf_event_attr__check_stype(attr, PERF_SAMPLE_TIME, "TIME", 222 perf_evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME",
217 PERF_OUTPUT_TIME)) 223 PERF_OUTPUT_TIME))
218 return -EINVAL; 224 return -EINVAL;
219 225
220 if (PRINT_FIELD(CPU) && 226 if (PRINT_FIELD(CPU) &&
221 perf_event_attr__check_stype(attr, PERF_SAMPLE_CPU, "CPU", 227 perf_evsel__check_stype(evsel, PERF_SAMPLE_CPU, "CPU",
222 PERF_OUTPUT_CPU)) 228 PERF_OUTPUT_CPU))
223 return -EINVAL; 229 return -EINVAL;
224 230
225 return 0; 231 return 0;
@@ -256,11 +262,13 @@ static int perf_session__check_output_opt(struct perf_session *session)
256 return 0; 262 return 0;
257} 263}
258 264
259static void print_sample_start(struct perf_sample *sample, 265static void print_sample_start(struct pevent *pevent,
266 struct perf_sample *sample,
260 struct thread *thread, 267 struct thread *thread,
261 struct perf_event_attr *attr) 268 struct perf_evsel *evsel)
262{ 269{
263 int type; 270 int type;
271 struct perf_event_attr *attr = &evsel->attr;
264 struct event_format *event; 272 struct event_format *event;
265 const char *evname = NULL; 273 const char *evname = NULL;
266 unsigned long secs; 274 unsigned long secs;
@@ -300,12 +308,18 @@ static void print_sample_start(struct perf_sample *sample,
300 308
301 if (PRINT_FIELD(EVNAME)) { 309 if (PRINT_FIELD(EVNAME)) {
302 if (attr->type == PERF_TYPE_TRACEPOINT) { 310 if (attr->type == PERF_TYPE_TRACEPOINT) {
303 type = trace_parse_common_type(sample->raw_data); 311 /*
304 event = trace_find_event(type); 312 * XXX Do we really need this here?
313 * perf_evlist__set_tracepoint_names should have done
314 * this already
315 */
316 type = trace_parse_common_type(pevent,
317 sample->raw_data);
318 event = pevent_find_event(pevent, type);
305 if (event) 319 if (event)
306 evname = event->name; 320 evname = event->name;
307 } else 321 } else
308 evname = __event_name(attr->type, attr->config); 322 evname = perf_evsel__name(evsel);
309 323
310 printf("%s: ", evname ? evname : "[unknown]"); 324 printf("%s: ", evname ? evname : "[unknown]");
311 } 325 }
@@ -387,7 +401,7 @@ static void print_sample_bts(union perf_event *event,
387 printf(" "); 401 printf(" ");
388 else 402 else
389 printf("\n"); 403 printf("\n");
390 perf_event__print_ip(event, sample, machine, evsel, 404 perf_event__print_ip(event, sample, machine,
391 PRINT_FIELD(SYM), PRINT_FIELD(DSO), 405 PRINT_FIELD(SYM), PRINT_FIELD(DSO),
392 PRINT_FIELD(SYMOFFSET)); 406 PRINT_FIELD(SYMOFFSET));
393 } 407 }
@@ -402,6 +416,7 @@ static void print_sample_bts(union perf_event *event,
402} 416}
403 417
404static void process_event(union perf_event *event __unused, 418static void process_event(union perf_event *event __unused,
419 struct pevent *pevent,
405 struct perf_sample *sample, 420 struct perf_sample *sample,
406 struct perf_evsel *evsel, 421 struct perf_evsel *evsel,
407 struct machine *machine, 422 struct machine *machine,
@@ -412,7 +427,7 @@ static void process_event(union perf_event *event __unused,
412 if (output[attr->type].fields == 0) 427 if (output[attr->type].fields == 0)
413 return; 428 return;
414 429
415 print_sample_start(sample, thread, attr); 430 print_sample_start(pevent, sample, thread, evsel);
416 431
417 if (is_bts_event(attr)) { 432 if (is_bts_event(attr)) {
418 print_sample_bts(event, sample, evsel, machine, thread); 433 print_sample_bts(event, sample, evsel, machine, thread);
@@ -420,7 +435,7 @@ static void process_event(union perf_event *event __unused,
420 } 435 }
421 436
422 if (PRINT_FIELD(TRACE)) 437 if (PRINT_FIELD(TRACE))
423 print_trace_event(sample->cpu, sample->raw_data, 438 print_trace_event(pevent, sample->cpu, sample->raw_data,
424 sample->raw_size); 439 sample->raw_size);
425 440
426 if (PRINT_FIELD(ADDR)) 441 if (PRINT_FIELD(ADDR))
@@ -431,7 +446,7 @@ static void process_event(union perf_event *event __unused,
431 printf(" "); 446 printf(" ");
432 else 447 else
433 printf("\n"); 448 printf("\n");
434 perf_event__print_ip(event, sample, machine, evsel, 449 perf_event__print_ip(event, sample, machine,
435 PRINT_FIELD(SYM), PRINT_FIELD(DSO), 450 PRINT_FIELD(SYM), PRINT_FIELD(DSO),
436 PRINT_FIELD(SYMOFFSET)); 451 PRINT_FIELD(SYMOFFSET));
437 } 452 }
@@ -451,7 +466,8 @@ static int default_stop_script(void)
451 return 0; 466 return 0;
452} 467}
453 468
454static int default_generate_script(const char *outfile __unused) 469static int default_generate_script(struct pevent *pevent __unused,
470 const char *outfile __unused)
455{ 471{
456 return 0; 472 return 0;
457} 473}
@@ -489,6 +505,7 @@ static int process_sample_event(struct perf_tool *tool __used,
489 struct machine *machine) 505 struct machine *machine)
490{ 506{
491 struct addr_location al; 507 struct addr_location al;
508 struct perf_script *scr = container_of(tool, struct perf_script, tool);
492 struct thread *thread = machine__findnew_thread(machine, event->ip.tid); 509 struct thread *thread = machine__findnew_thread(machine, event->ip.tid);
493 510
494 if (thread == NULL) { 511 if (thread == NULL) {
@@ -520,24 +537,27 @@ static int process_sample_event(struct perf_tool *tool __used,
520 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) 537 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
521 return 0; 538 return 0;
522 539
523 scripting_ops->process_event(event, sample, evsel, machine, thread); 540 scripting_ops->process_event(event, scr->session->pevent,
541 sample, evsel, machine, thread);
524 542
525 evsel->hists.stats.total_period += sample->period; 543 evsel->hists.stats.total_period += sample->period;
526 return 0; 544 return 0;
527} 545}
528 546
529static struct perf_tool perf_script = { 547static struct perf_script perf_script = {
530 .sample = process_sample_event, 548 .tool = {
531 .mmap = perf_event__process_mmap, 549 .sample = process_sample_event,
532 .comm = perf_event__process_comm, 550 .mmap = perf_event__process_mmap,
533 .exit = perf_event__process_task, 551 .comm = perf_event__process_comm,
534 .fork = perf_event__process_task, 552 .exit = perf_event__process_task,
535 .attr = perf_event__process_attr, 553 .fork = perf_event__process_task,
536 .event_type = perf_event__process_event_type, 554 .attr = perf_event__process_attr,
537 .tracing_data = perf_event__process_tracing_data, 555 .event_type = perf_event__process_event_type,
538 .build_id = perf_event__process_build_id, 556 .tracing_data = perf_event__process_tracing_data,
539 .ordered_samples = true, 557 .build_id = perf_event__process_build_id,
540 .ordering_requires_timestamps = true, 558 .ordered_samples = true,
559 .ordering_requires_timestamps = true,
560 },
541}; 561};
542 562
543extern volatile int session_done; 563extern volatile int session_done;
@@ -553,7 +573,7 @@ static int __cmd_script(struct perf_session *session)
553 573
554 signal(SIGINT, sig_handler); 574 signal(SIGINT, sig_handler);
555 575
556 ret = perf_session__process_events(session, &perf_script); 576 ret = perf_session__process_events(session, &perf_script.tool);
557 577
558 if (debug_mode) 578 if (debug_mode)
559 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); 579 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
@@ -1335,10 +1355,13 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1335 if (!script_name) 1355 if (!script_name)
1336 setup_pager(); 1356 setup_pager();
1337 1357
1338 session = perf_session__new(input_name, O_RDONLY, 0, false, &perf_script); 1358 session = perf_session__new(input_name, O_RDONLY, 0, false,
1359 &perf_script.tool);
1339 if (session == NULL) 1360 if (session == NULL)
1340 return -ENOMEM; 1361 return -ENOMEM;
1341 1362
1363 perf_script.session = session;
1364
1342 if (cpu_list) { 1365 if (cpu_list) {
1343 if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap)) 1366 if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap))
1344 return -1; 1367 return -1;
@@ -1384,7 +1407,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1384 return -1; 1407 return -1;
1385 } 1408 }
1386 1409
1387 err = scripting_ops->generate_script("perf-script"); 1410 err = scripting_ops->generate_script(session->pevent,
1411 "perf-script");
1388 goto out; 1412 goto out;
1389 } 1413 }
1390 1414
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 07b5c7703dd1..861f0aec77ae 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -391,7 +391,7 @@ static int read_counter_aggr(struct perf_evsel *counter)
391 391
392 if (verbose) { 392 if (verbose) {
393 fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", 393 fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
394 event_name(counter), count[0], count[1], count[2]); 394 perf_evsel__name(counter), count[0], count[1], count[2]);
395 } 395 }
396 396
397 /* 397 /*
@@ -496,7 +496,7 @@ static int run_perf_stat(int argc __used, const char **argv)
496 errno == ENXIO) { 496 errno == ENXIO) {
497 if (verbose) 497 if (verbose)
498 ui__warning("%s event is not supported by the kernel.\n", 498 ui__warning("%s event is not supported by the kernel.\n",
499 event_name(counter)); 499 perf_evsel__name(counter));
500 counter->supported = false; 500 counter->supported = false;
501 continue; 501 continue;
502 } 502 }
@@ -594,7 +594,7 @@ static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg)
594 csv_output ? 0 : -4, 594 csv_output ? 0 : -4,
595 evsel_list->cpus->map[cpu], csv_sep); 595 evsel_list->cpus->map[cpu], csv_sep);
596 596
597 fprintf(output, fmt, cpustr, msecs, csv_sep, event_name(evsel)); 597 fprintf(output, fmt, cpustr, msecs, csv_sep, perf_evsel__name(evsel));
598 598
599 if (evsel->cgrp) 599 if (evsel->cgrp)
600 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); 600 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
@@ -792,7 +792,7 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
792 else 792 else
793 cpu = 0; 793 cpu = 0;
794 794
795 fprintf(output, fmt, cpustr, avg, csv_sep, event_name(evsel)); 795 fprintf(output, fmt, cpustr, avg, csv_sep, perf_evsel__name(evsel));
796 796
797 if (evsel->cgrp) 797 if (evsel->cgrp)
798 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); 798 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
@@ -908,7 +908,7 @@ static void print_counter_aggr(struct perf_evsel *counter)
908 counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 908 counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
909 csv_sep, 909 csv_sep,
910 csv_output ? 0 : -24, 910 csv_output ? 0 : -24,
911 event_name(counter)); 911 perf_evsel__name(counter));
912 912
913 if (counter->cgrp) 913 if (counter->cgrp)
914 fprintf(output, "%s%s", csv_sep, counter->cgrp->name); 914 fprintf(output, "%s%s", csv_sep, counter->cgrp->name);
@@ -961,7 +961,7 @@ static void print_counter(struct perf_evsel *counter)
961 counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 961 counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
962 csv_sep, 962 csv_sep,
963 csv_output ? 0 : -24, 963 csv_output ? 0 : -24,
964 event_name(counter)); 964 perf_evsel__name(counter));
965 965
966 if (counter->cgrp) 966 if (counter->cgrp)
967 fprintf(output, "%s%s", 967 fprintf(output, "%s%s",
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index 5a8727c08757..5ce30305462b 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -583,7 +583,7 @@ static int test__basic_mmap(void)
583 if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) { 583 if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) {
584 pr_debug("expected %d %s events, got %d\n", 584 pr_debug("expected %d %s events, got %d\n",
585 expected_nr_events[evsel->idx], 585 expected_nr_events[evsel->idx],
586 event_name(evsel), nr_events[evsel->idx]); 586 perf_evsel__name(evsel), nr_events[evsel->idx]);
587 goto out_munmap; 587 goto out_munmap;
588 } 588 }
589 } 589 }
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 6bb0277b7dfe..e3cab5f088f8 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -245,7 +245,7 @@ static void perf_top__show_details(struct perf_top *top)
245 if (notes->src == NULL) 245 if (notes->src == NULL)
246 goto out_unlock; 246 goto out_unlock;
247 247
248 printf("Showing %s for %s\n", event_name(top->sym_evsel), symbol->name); 248 printf("Showing %s for %s\n", perf_evsel__name(top->sym_evsel), symbol->name);
249 printf(" Events Pcnt (>=%d%%)\n", top->sym_pcnt_filter); 249 printf(" Events Pcnt (>=%d%%)\n", top->sym_pcnt_filter);
250 250
251 more = symbol__annotate_printf(symbol, he->ms.map, top->sym_evsel->idx, 251 more = symbol__annotate_printf(symbol, he->ms.map, top->sym_evsel->idx,
@@ -408,7 +408,7 @@ static void perf_top__print_mapped_keys(struct perf_top *top)
408 fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", top->print_entries); 408 fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", top->print_entries);
409 409
410 if (top->evlist->nr_entries > 1) 410 if (top->evlist->nr_entries > 1)
411 fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(top->sym_evsel)); 411 fprintf(stdout, "\t[E] active event counter. \t(%s)\n", perf_evsel__name(top->sym_evsel));
412 412
413 fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", top->count_filter); 413 fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", top->count_filter);
414 414
@@ -503,13 +503,13 @@ static void perf_top__handle_keypress(struct perf_top *top, int c)
503 fprintf(stderr, "\nAvailable events:"); 503 fprintf(stderr, "\nAvailable events:");
504 504
505 list_for_each_entry(top->sym_evsel, &top->evlist->entries, node) 505 list_for_each_entry(top->sym_evsel, &top->evlist->entries, node)
506 fprintf(stderr, "\n\t%d %s", top->sym_evsel->idx, event_name(top->sym_evsel)); 506 fprintf(stderr, "\n\t%d %s", top->sym_evsel->idx, perf_evsel__name(top->sym_evsel));
507 507
508 prompt_integer(&counter, "Enter details event counter"); 508 prompt_integer(&counter, "Enter details event counter");
509 509
510 if (counter >= top->evlist->nr_entries) { 510 if (counter >= top->evlist->nr_entries) {
511 top->sym_evsel = list_entry(top->evlist->entries.next, struct perf_evsel, node); 511 top->sym_evsel = list_entry(top->evlist->entries.next, struct perf_evsel, node);
512 fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(top->sym_evsel)); 512 fprintf(stderr, "Sorry, no such event, using %s.\n", perf_evsel__name(top->sym_evsel));
513 sleep(1); 513 sleep(1);
514 break; 514 break;
515 } 515 }
@@ -774,7 +774,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
774 774
775 if ((sort__has_parent || symbol_conf.use_callchain) && 775 if ((sort__has_parent || symbol_conf.use_callchain) &&
776 sample->callchain) { 776 sample->callchain) {
777 err = machine__resolve_callchain(machine, evsel, al.thread, 777 err = machine__resolve_callchain(machine, al.thread,
778 sample->callchain, &parent); 778 sample->callchain, &parent);
779 if (err) 779 if (err)
780 return; 780 return;
@@ -960,7 +960,7 @@ try_again:
960 960
961 if (err == ENOENT) { 961 if (err == ENOENT) {
962 ui__error("The %s event is not supported.\n", 962 ui__error("The %s event is not supported.\n",
963 event_name(counter)); 963 perf_evsel__name(counter));
964 goto out_err; 964 goto out_err;
965 } else if (err == EMFILE) { 965 } else if (err == EMFILE) {
966 ui__error("Too many events are opened.\n" 966 ui__error("Too many events are opened.\n"
diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak
index d9084e03ce56..6c18785a6417 100644
--- a/tools/perf/config/feature-tests.mak
+++ b/tools/perf/config/feature-tests.mak
@@ -78,6 +78,19 @@ int main(int argc, char *argv[])
78 return 0; 78 return 0;
79} 79}
80endef 80endef
81
82define SOURCE_GTK2_INFOBAR
83#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
84#include <gtk/gtk.h>
85#pragma GCC diagnostic error \"-Wstrict-prototypes\"
86
87int main(void)
88{
89 gtk_info_bar_new();
90
91 return 0;
92}
93endef
81endif 94endif
82 95
83ifndef NO_LIBPERL 96ifndef NO_LIBPERL
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index 34b1c46eaf42..67a2703e666a 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -814,7 +814,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
814{ 814{
815 struct disasm_line *pos, *n; 815 struct disasm_line *pos, *n;
816 struct annotation *notes; 816 struct annotation *notes;
817 const size_t size = symbol__size(sym); 817 size_t size;
818 struct map_symbol ms = { 818 struct map_symbol ms = {
819 .map = map, 819 .map = map,
820 .sym = sym, 820 .sym = sym,
@@ -834,6 +834,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
834 if (sym == NULL) 834 if (sym == NULL)
835 return -1; 835 return -1;
836 836
837 size = symbol__size(sym);
838
837 if (map->dso->annotate_warned) 839 if (map->dso->annotate_warned)
838 return -1; 840 return -1;
839 841
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 53f6697d014e..482f0517b61e 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -23,6 +23,7 @@ struct hist_browser {
23 struct hists *hists; 23 struct hists *hists;
24 struct hist_entry *he_selection; 24 struct hist_entry *he_selection;
25 struct map_symbol *selection; 25 struct map_symbol *selection;
26 int print_seq;
26 bool has_symbols; 27 bool has_symbols;
27}; 28};
28 29
@@ -800,6 +801,196 @@ do_offset:
800 } 801 }
801} 802}
802 803
804static int hist_browser__fprintf_callchain_node_rb_tree(struct hist_browser *browser,
805 struct callchain_node *chain_node,
806 u64 total, int level,
807 FILE *fp)
808{
809 struct rb_node *node;
810 int offset = level * LEVEL_OFFSET_STEP;
811 u64 new_total, remaining;
812 int printed = 0;
813
814 if (callchain_param.mode == CHAIN_GRAPH_REL)
815 new_total = chain_node->children_hit;
816 else
817 new_total = total;
818
819 remaining = new_total;
820 node = rb_first(&chain_node->rb_root);
821 while (node) {
822 struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
823 struct rb_node *next = rb_next(node);
824 u64 cumul = callchain_cumul_hits(child);
825 struct callchain_list *chain;
826 char folded_sign = ' ';
827 int first = true;
828 int extra_offset = 0;
829
830 remaining -= cumul;
831
832 list_for_each_entry(chain, &child->val, list) {
833 char ipstr[BITS_PER_LONG / 4 + 1], *alloc_str;
834 const char *str;
835 bool was_first = first;
836
837 if (first)
838 first = false;
839 else
840 extra_offset = LEVEL_OFFSET_STEP;
841
842 folded_sign = callchain_list__folded(chain);
843
844 alloc_str = NULL;
845 str = callchain_list__sym_name(chain, ipstr, sizeof(ipstr));
846 if (was_first) {
847 double percent = cumul * 100.0 / new_total;
848
849 if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0)
850 str = "Not enough memory!";
851 else
852 str = alloc_str;
853 }
854
855 printed += fprintf(fp, "%*s%c %s\n", offset + extra_offset, " ", folded_sign, str);
856 free(alloc_str);
857 if (folded_sign == '+')
858 break;
859 }
860
861 if (folded_sign == '-') {
862 const int new_level = level + (extra_offset ? 2 : 1);
863 printed += hist_browser__fprintf_callchain_node_rb_tree(browser, child, new_total,
864 new_level, fp);
865 }
866
867 node = next;
868 }
869
870 return printed;
871}
872
873static int hist_browser__fprintf_callchain_node(struct hist_browser *browser,
874 struct callchain_node *node,
875 int level, FILE *fp)
876{
877 struct callchain_list *chain;
878 int offset = level * LEVEL_OFFSET_STEP;
879 char folded_sign = ' ';
880 int printed = 0;
881
882 list_for_each_entry(chain, &node->val, list) {
883 char ipstr[BITS_PER_LONG / 4 + 1], *s;
884
885 folded_sign = callchain_list__folded(chain);
886 s = callchain_list__sym_name(chain, ipstr, sizeof(ipstr));
887 printed += fprintf(fp, "%*s%c %s\n", offset, " ", folded_sign, s);
888 }
889
890 if (folded_sign == '-')
891 printed += hist_browser__fprintf_callchain_node_rb_tree(browser, node,
892 browser->hists->stats.total_period,
893 level + 1, fp);
894 return printed;
895}
896
897static int hist_browser__fprintf_callchain(struct hist_browser *browser,
898 struct rb_root *chain, int level, FILE *fp)
899{
900 struct rb_node *nd;
901 int printed = 0;
902
903 for (nd = rb_first(chain); nd; nd = rb_next(nd)) {
904 struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node);
905
906 printed += hist_browser__fprintf_callchain_node(browser, node, level, fp);
907 }
908
909 return printed;
910}
911
912static int hist_browser__fprintf_entry(struct hist_browser *browser,
913 struct hist_entry *he, FILE *fp)
914{
915 char s[8192];
916 double percent;
917 int printed = 0;
918 char folded_sign = ' ';
919
920 if (symbol_conf.use_callchain)
921 folded_sign = hist_entry__folded(he);
922
923 hist_entry__snprintf(he, s, sizeof(s), browser->hists);
924 percent = (he->period * 100.0) / browser->hists->stats.total_period;
925
926 if (symbol_conf.use_callchain)
927 printed += fprintf(fp, "%c ", folded_sign);
928
929 printed += fprintf(fp, " %5.2f%%", percent);
930
931 if (symbol_conf.show_nr_samples)
932 printed += fprintf(fp, " %11u", he->nr_events);
933
934 if (symbol_conf.show_total_period)
935 printed += fprintf(fp, " %12" PRIu64, he->period);
936
937 printed += fprintf(fp, "%s\n", rtrim(s));
938
939 if (folded_sign == '-')
940 printed += hist_browser__fprintf_callchain(browser, &he->sorted_chain, 1, fp);
941
942 return printed;
943}
944
945static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp)
946{
947 struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries));
948 int printed = 0;
949
950 while (nd) {
951 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
952
953 printed += hist_browser__fprintf_entry(browser, h, fp);
954 nd = hists__filter_entries(rb_next(nd));
955 }
956
957 return printed;
958}
959
960static int hist_browser__dump(struct hist_browser *browser)
961{
962 char filename[64];
963 FILE *fp;
964
965 while (1) {
966 scnprintf(filename, sizeof(filename), "perf.hist.%d", browser->print_seq);
967 if (access(filename, F_OK))
968 break;
969 /*
970 * XXX: Just an arbitrary lazy upper limit
971 */
972 if (++browser->print_seq == 8192) {
973 ui_helpline__fpush("Too many perf.hist.N files, nothing written!");
974 return -1;
975 }
976 }
977
978 fp = fopen(filename, "w");
979 if (fp == NULL) {
980 char bf[64];
981 strerror_r(errno, bf, sizeof(bf));
982 ui_helpline__fpush("Couldn't write to %s: %s", filename, bf);
983 return -1;
984 }
985
986 ++browser->print_seq;
987 hist_browser__fprintf(browser, fp);
988 fclose(fp);
989 ui_helpline__fpush("%s written!", filename);
990
991 return 0;
992}
993
803static struct hist_browser *hist_browser__new(struct hists *hists) 994static struct hist_browser *hist_browser__new(struct hists *hists)
804{ 995{
805 struct hist_browser *browser = zalloc(sizeof(*browser)); 996 struct hist_browser *browser = zalloc(sizeof(*browser));
@@ -937,6 +1128,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
937 browser->selection->map->dso->annotate_warned) 1128 browser->selection->map->dso->annotate_warned)
938 continue; 1129 continue;
939 goto do_annotate; 1130 goto do_annotate;
1131 case 'P':
1132 hist_browser__dump(browser);
1133 continue;
940 case 'd': 1134 case 'd':
941 goto zoom_dso; 1135 goto zoom_dso;
942 case 't': 1136 case 't':
@@ -969,6 +1163,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
969 "E Expand all callchains\n" 1163 "E Expand all callchains\n"
970 "d Zoom into current DSO\n" 1164 "d Zoom into current DSO\n"
971 "t Zoom into current Thread\n" 1165 "t Zoom into current Thread\n"
1166 "P Print histograms to perf.hist.N\n"
972 "/ Filter symbol by name"); 1167 "/ Filter symbol by name");
973 continue; 1168 continue;
974 case K_ENTER: 1169 case K_ENTER:
@@ -1172,7 +1367,7 @@ static void perf_evsel_menu__write(struct ui_browser *browser,
1172 struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node); 1367 struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node);
1173 bool current_entry = ui_browser__is_current_entry(browser, row); 1368 bool current_entry = ui_browser__is_current_entry(browser, row);
1174 unsigned long nr_events = evsel->hists.stats.nr_events[PERF_RECORD_SAMPLE]; 1369 unsigned long nr_events = evsel->hists.stats.nr_events[PERF_RECORD_SAMPLE];
1175 const char *ev_name = event_name(evsel); 1370 const char *ev_name = perf_evsel__name(evsel);
1176 char bf[256], unit; 1371 char bf[256], unit;
1177 const char *warn = " "; 1372 const char *warn = " ";
1178 size_t printed; 1373 size_t printed;
@@ -1240,7 +1435,7 @@ browse_hists:
1240 */ 1435 */
1241 if (timer) 1436 if (timer)
1242 timer(arg); 1437 timer(arg);
1243 ev_name = event_name(pos); 1438 ev_name = perf_evsel__name(pos);
1244 key = perf_evsel__hists_browse(pos, nr_events, help, 1439 key = perf_evsel__hists_browse(pos, nr_events, help,
1245 ev_name, true, timer, 1440 ev_name, true, timer,
1246 arg, delay_secs); 1441 arg, delay_secs);
@@ -1309,17 +1504,11 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
1309 ui_helpline__push("Press ESC to exit"); 1504 ui_helpline__push("Press ESC to exit");
1310 1505
1311 list_for_each_entry(pos, &evlist->entries, node) { 1506 list_for_each_entry(pos, &evlist->entries, node) {
1312 const char *ev_name = event_name(pos); 1507 const char *ev_name = perf_evsel__name(pos);
1313 size_t line_len = strlen(ev_name) + 7; 1508 size_t line_len = strlen(ev_name) + 7;
1314 1509
1315 if (menu.b.width < line_len) 1510 if (menu.b.width < line_len)
1316 menu.b.width = line_len; 1511 menu.b.width = line_len;
1317 /*
1318 * Cache the evsel name, tracepoints have a _high_ cost per
1319 * event_name() call.
1320 */
1321 if (pos->name == NULL)
1322 pos->name = strdup(ev_name);
1323 } 1512 }
1324 1513
1325 return perf_evsel_menu__run(&menu, evlist->nr_entries, help, timer, 1514 return perf_evsel_menu__run(&menu, evlist->nr_entries, help, timer,
@@ -1330,11 +1519,10 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
1330 void(*timer)(void *arg), void *arg, 1519 void(*timer)(void *arg), void *arg,
1331 int delay_secs) 1520 int delay_secs)
1332{ 1521{
1333
1334 if (evlist->nr_entries == 1) { 1522 if (evlist->nr_entries == 1) {
1335 struct perf_evsel *first = list_entry(evlist->entries.next, 1523 struct perf_evsel *first = list_entry(evlist->entries.next,
1336 struct perf_evsel, node); 1524 struct perf_evsel, node);
1337 const char *ev_name = event_name(first); 1525 const char *ev_name = perf_evsel__name(first);
1338 return perf_evsel__hists_browse(first, evlist->nr_entries, help, 1526 return perf_evsel__hists_browse(first, evlist->nr_entries, help,
1339 ev_name, false, timer, arg, 1527 ev_name, false, timer, arg,
1340 delay_secs); 1528 delay_secs);
diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c
index 0656c381a89c..ec12e0b4ded6 100644
--- a/tools/perf/ui/gtk/browser.c
+++ b/tools/perf/ui/gtk/browser.c
@@ -11,8 +11,8 @@
11 11
12static void perf_gtk__signal(int sig) 12static void perf_gtk__signal(int sig)
13{ 13{
14 perf_gtk__exit(false);
14 psignal(sig, "perf"); 15 psignal(sig, "perf");
15 gtk_main_quit();
16} 16}
17 17
18static void perf_gtk__resize_window(GtkWidget *window) 18static void perf_gtk__resize_window(GtkWidget *window)
@@ -122,13 +122,59 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists)
122 gtk_container_add(GTK_CONTAINER(window), view); 122 gtk_container_add(GTK_CONTAINER(window), view);
123} 123}
124 124
125#ifdef HAVE_GTK_INFO_BAR
126static GtkWidget *perf_gtk__setup_info_bar(void)
127{
128 GtkWidget *info_bar;
129 GtkWidget *label;
130 GtkWidget *content_area;
131
132 info_bar = gtk_info_bar_new();
133 gtk_widget_set_no_show_all(info_bar, TRUE);
134
135 label = gtk_label_new("");
136 gtk_widget_show(label);
137
138 content_area = gtk_info_bar_get_content_area(GTK_INFO_BAR(info_bar));
139 gtk_container_add(GTK_CONTAINER(content_area), label);
140
141 gtk_info_bar_add_button(GTK_INFO_BAR(info_bar), GTK_STOCK_OK,
142 GTK_RESPONSE_OK);
143 g_signal_connect(info_bar, "response",
144 G_CALLBACK(gtk_widget_hide), NULL);
145
146 pgctx->info_bar = info_bar;
147 pgctx->message_label = label;
148
149 return info_bar;
150}
151#endif
152
153static GtkWidget *perf_gtk__setup_statusbar(void)
154{
155 GtkWidget *stbar;
156 unsigned ctxid;
157
158 stbar = gtk_statusbar_new();
159
160 ctxid = gtk_statusbar_get_context_id(GTK_STATUSBAR(stbar),
161 "perf report");
162 pgctx->statbar = stbar;
163 pgctx->statbar_ctx_id = ctxid;
164
165 return stbar;
166}
167
125int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, 168int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
126 const char *help __used, 169 const char *help __used,
127 void (*timer) (void *arg)__used, 170 void (*timer) (void *arg)__used,
128 void *arg __used, int delay_secs __used) 171 void *arg __used, int delay_secs __used)
129{ 172{
130 struct perf_evsel *pos; 173 struct perf_evsel *pos;
174 GtkWidget *vbox;
131 GtkWidget *notebook; 175 GtkWidget *notebook;
176 GtkWidget *info_bar;
177 GtkWidget *statbar;
132 GtkWidget *window; 178 GtkWidget *window;
133 179
134 signal(SIGSEGV, perf_gtk__signal); 180 signal(SIGSEGV, perf_gtk__signal);
@@ -143,11 +189,17 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
143 189
144 g_signal_connect(window, "delete_event", gtk_main_quit, NULL); 190 g_signal_connect(window, "delete_event", gtk_main_quit, NULL);
145 191
192 pgctx = perf_gtk__activate_context(window);
193 if (!pgctx)
194 return -1;
195
196 vbox = gtk_vbox_new(FALSE, 0);
197
146 notebook = gtk_notebook_new(); 198 notebook = gtk_notebook_new();
147 199
148 list_for_each_entry(pos, &evlist->entries, node) { 200 list_for_each_entry(pos, &evlist->entries, node) {
149 struct hists *hists = &pos->hists; 201 struct hists *hists = &pos->hists;
150 const char *evname = event_name(pos); 202 const char *evname = perf_evsel__name(pos);
151 GtkWidget *scrolled_window; 203 GtkWidget *scrolled_window;
152 GtkWidget *tab_label; 204 GtkWidget *tab_label;
153 205
@@ -164,7 +216,16 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
164 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_window, tab_label); 216 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_window, tab_label);
165 } 217 }
166 218
167 gtk_container_add(GTK_CONTAINER(window), notebook); 219 gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
220
221 info_bar = perf_gtk__setup_info_bar();
222 if (info_bar)
223 gtk_box_pack_start(GTK_BOX(vbox), info_bar, FALSE, FALSE, 0);
224
225 statbar = perf_gtk__setup_statusbar();
226 gtk_box_pack_start(GTK_BOX(vbox), statbar, FALSE, FALSE, 0);
227
228 gtk_container_add(GTK_CONTAINER(window), vbox);
168 229
169 gtk_widget_show_all(window); 230 gtk_widget_show_all(window);
170 231
@@ -174,5 +235,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
174 235
175 gtk_main(); 236 gtk_main();
176 237
238 perf_gtk__deactivate_context(&pgctx);
239
177 return 0; 240 return 0;
178} 241}
diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h
index 75177ee04032..a4d0f2b4a2dc 100644
--- a/tools/perf/ui/gtk/gtk.h
+++ b/tools/perf/ui/gtk/gtk.h
@@ -1,8 +1,39 @@
1#ifndef _PERF_GTK_H_ 1#ifndef _PERF_GTK_H_
2#define _PERF_GTK_H_ 1 2#define _PERF_GTK_H_ 1
3 3
4#include <stdbool.h>
5
4#pragma GCC diagnostic ignored "-Wstrict-prototypes" 6#pragma GCC diagnostic ignored "-Wstrict-prototypes"
5#include <gtk/gtk.h> 7#include <gtk/gtk.h>
6#pragma GCC diagnostic error "-Wstrict-prototypes" 8#pragma GCC diagnostic error "-Wstrict-prototypes"
7 9
10
11struct perf_gtk_context {
12 GtkWidget *main_window;
13
14#ifdef HAVE_GTK_INFO_BAR
15 GtkWidget *info_bar;
16 GtkWidget *message_label;
17#endif
18 GtkWidget *statbar;
19 guint statbar_ctx_id;
20};
21
22extern struct perf_gtk_context *pgctx;
23
24static inline bool perf_gtk__is_active_context(struct perf_gtk_context *ctx)
25{
26 return ctx && ctx->main_window;
27}
28
29struct perf_gtk_context *perf_gtk__activate_context(GtkWidget *window);
30int perf_gtk__deactivate_context(struct perf_gtk_context **ctx);
31
32#ifndef HAVE_GTK_INFO_BAR
33static inline GtkWidget *perf_gtk__setup_info_bar(void)
34{
35 return NULL;
36}
37#endif
38
8#endif /* _PERF_GTK_H_ */ 39#endif /* _PERF_GTK_H_ */
diff --git a/tools/perf/ui/gtk/setup.c b/tools/perf/ui/gtk/setup.c
index 829529957766..92879ce61e2f 100644
--- a/tools/perf/ui/gtk/setup.c
+++ b/tools/perf/ui/gtk/setup.c
@@ -1,12 +1,17 @@
1#include "gtk.h" 1#include "gtk.h"
2#include "../../util/cache.h" 2#include "../../util/cache.h"
3#include "../../util/debug.h"
4
5extern struct perf_error_ops perf_gtk_eops;
3 6
4int perf_gtk__init(void) 7int perf_gtk__init(void)
5{ 8{
9 perf_error__register(&perf_gtk_eops);
6 return gtk_init_check(NULL, NULL) ? 0 : -1; 10 return gtk_init_check(NULL, NULL) ? 0 : -1;
7} 11}
8 12
9void perf_gtk__exit(bool wait_for_ok __used) 13void perf_gtk__exit(bool wait_for_ok __used)
10{ 14{
15 perf_error__unregister(&perf_gtk_eops);
11 gtk_main_quit(); 16 gtk_main_quit();
12} 17}
diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c
new file mode 100644
index 000000000000..0ead373c0dfb
--- /dev/null
+++ b/tools/perf/ui/gtk/util.c
@@ -0,0 +1,129 @@
1#include "../util.h"
2#include "../../util/debug.h"
3#include "gtk.h"
4
5#include <string.h>
6
7
8struct perf_gtk_context *pgctx;
9
10struct perf_gtk_context *perf_gtk__activate_context(GtkWidget *window)
11{
12 struct perf_gtk_context *ctx;
13
14 ctx = malloc(sizeof(*pgctx));
15 if (ctx)
16 ctx->main_window = window;
17
18 return ctx;
19}
20
21int perf_gtk__deactivate_context(struct perf_gtk_context **ctx)
22{
23 if (!perf_gtk__is_active_context(*ctx))
24 return -1;
25
26 free(*ctx);
27 *ctx = NULL;
28 return 0;
29}
30
31static int perf_gtk__error(const char *format, va_list args)
32{
33 char *msg;
34 GtkWidget *dialog;
35
36 if (!perf_gtk__is_active_context(pgctx) ||
37 vasprintf(&msg, format, args) < 0) {
38 fprintf(stderr, "Error:\n");
39 vfprintf(stderr, format, args);
40 fprintf(stderr, "\n");
41 return -1;
42 }
43
44 dialog = gtk_message_dialog_new_with_markup(GTK_WINDOW(pgctx->main_window),
45 GTK_DIALOG_DESTROY_WITH_PARENT,
46 GTK_MESSAGE_ERROR,
47 GTK_BUTTONS_CLOSE,
48 "<b>Error</b>\n\n%s", msg);
49 gtk_dialog_run(GTK_DIALOG(dialog));
50
51 gtk_widget_destroy(dialog);
52 free(msg);
53 return 0;
54}
55
56#ifdef HAVE_GTK_INFO_BAR
57static int perf_gtk__warning_info_bar(const char *format, va_list args)
58{
59 char *msg;
60
61 if (!perf_gtk__is_active_context(pgctx) ||
62 vasprintf(&msg, format, args) < 0) {
63 fprintf(stderr, "Warning:\n");
64 vfprintf(stderr, format, args);
65 fprintf(stderr, "\n");
66 return -1;
67 }
68
69 gtk_label_set_text(GTK_LABEL(pgctx->message_label), msg);
70 gtk_info_bar_set_message_type(GTK_INFO_BAR(pgctx->info_bar),
71 GTK_MESSAGE_WARNING);
72 gtk_widget_show(pgctx->info_bar);
73
74 free(msg);
75 return 0;
76}
77#else
78static int perf_gtk__warning_statusbar(const char *format, va_list args)
79{
80 char *msg, *p;
81
82 if (!perf_gtk__is_active_context(pgctx) ||
83 vasprintf(&msg, format, args) < 0) {
84 fprintf(stderr, "Warning:\n");
85 vfprintf(stderr, format, args);
86 fprintf(stderr, "\n");
87 return -1;
88 }
89
90 gtk_statusbar_pop(GTK_STATUSBAR(pgctx->statbar),
91 pgctx->statbar_ctx_id);
92
93 /* Only first line can be displayed */
94 p = strchr(msg, '\n');
95 if (p)
96 *p = '\0';
97
98 gtk_statusbar_push(GTK_STATUSBAR(pgctx->statbar),
99 pgctx->statbar_ctx_id, msg);
100
101 free(msg);
102 return 0;
103}
104#endif
105
106struct perf_error_ops perf_gtk_eops = {
107 .error = perf_gtk__error,
108#ifdef HAVE_GTK_INFO_BAR
109 .warning = perf_gtk__warning_info_bar,
110#else
111 .warning = perf_gtk__warning_statusbar,
112#endif
113};
114
115/*
116 * FIXME: Functions below should be implemented properly.
117 * For now, just add stubs for NO_NEWT=1 build.
118 */
119#ifdef NO_NEWT_SUPPORT
120int ui_helpline__show_help(const char *format __used, va_list ap __used)
121{
122 return 0;
123}
124
125void ui_progress__update(u64 curr __used, u64 total __used,
126 const char *title __used)
127{
128}
129#endif
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c
index d33e943ac434..e813c1d17346 100644
--- a/tools/perf/ui/tui/setup.c
+++ b/tools/perf/ui/tui/setup.c
@@ -15,6 +15,8 @@ pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;
15 15
16static volatile int ui__need_resize; 16static volatile int ui__need_resize;
17 17
18extern struct perf_error_ops perf_tui_eops;
19
18void ui__refresh_dimensions(bool force) 20void ui__refresh_dimensions(bool force)
19{ 21{
20 if (force || ui__need_resize) { 22 if (force || ui__need_resize) {
@@ -122,6 +124,8 @@ int ui__init(void)
122 signal(SIGINT, ui__signal); 124 signal(SIGINT, ui__signal);
123 signal(SIGQUIT, ui__signal); 125 signal(SIGQUIT, ui__signal);
124 signal(SIGTERM, ui__signal); 126 signal(SIGTERM, ui__signal);
127
128 perf_error__register(&perf_tui_eops);
125out: 129out:
126 return err; 130 return err;
127} 131}
@@ -137,4 +141,6 @@ void ui__exit(bool wait_for_ok)
137 SLsmg_refresh(); 141 SLsmg_refresh();
138 SLsmg_reset_smg(); 142 SLsmg_reset_smg();
139 SLang_reset_tty(); 143 SLang_reset_tty();
144
145 perf_error__unregister(&perf_tui_eops);
140} 146}
diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c
new file mode 100644
index 000000000000..092902e30cee
--- /dev/null
+++ b/tools/perf/ui/tui/util.c
@@ -0,0 +1,243 @@
1#include "../../util/util.h"
2#include <signal.h>
3#include <stdbool.h>
4#include <string.h>
5#include <sys/ttydefaults.h>
6
7#include "../../util/cache.h"
8#include "../../util/debug.h"
9#include "../browser.h"
10#include "../keysyms.h"
11#include "../helpline.h"
12#include "../ui.h"
13#include "../util.h"
14#include "../libslang.h"
15
16static void ui_browser__argv_write(struct ui_browser *browser,
17 void *entry, int row)
18{
19 char **arg = entry;
20 bool current_entry = ui_browser__is_current_entry(browser, row);
21
22 ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
23 HE_COLORSET_NORMAL);
24 slsmg_write_nstring(*arg, browser->width);
25}
26
27static int popup_menu__run(struct ui_browser *menu)
28{
29 int key;
30
31 if (ui_browser__show(menu, " ", "ESC: exit, ENTER|->: Select option") < 0)
32 return -1;
33
34 while (1) {
35 key = ui_browser__run(menu, 0);
36
37 switch (key) {
38 case K_RIGHT:
39 case K_ENTER:
40 key = menu->index;
41 break;
42 case K_LEFT:
43 case K_ESC:
44 case 'q':
45 case CTRL('c'):
46 key = -1;
47 break;
48 default:
49 continue;
50 }
51
52 break;
53 }
54
55 ui_browser__hide(menu);
56 return key;
57}
58
59int ui__popup_menu(int argc, char * const argv[])
60{
61 struct ui_browser menu = {
62 .entries = (void *)argv,
63 .refresh = ui_browser__argv_refresh,
64 .seek = ui_browser__argv_seek,
65 .write = ui_browser__argv_write,
66 .nr_entries = argc,
67 };
68
69 return popup_menu__run(&menu);
70}
71
72int ui_browser__input_window(const char *title, const char *text, char *input,
73 const char *exit_msg, int delay_secs)
74{
75 int x, y, len, key;
76 int max_len = 60, nr_lines = 0;
77 static char buf[50];
78 const char *t;
79
80 t = text;
81 while (1) {
82 const char *sep = strchr(t, '\n');
83
84 if (sep == NULL)
85 sep = strchr(t, '\0');
86 len = sep - t;
87 if (max_len < len)
88 max_len = len;
89 ++nr_lines;
90 if (*sep == '\0')
91 break;
92 t = sep + 1;
93 }
94
95 max_len += 2;
96 nr_lines += 8;
97 y = SLtt_Screen_Rows / 2 - nr_lines / 2;
98 x = SLtt_Screen_Cols / 2 - max_len / 2;
99
100 SLsmg_set_color(0);
101 SLsmg_draw_box(y, x++, nr_lines, max_len);
102 if (title) {
103 SLsmg_gotorc(y, x + 1);
104 SLsmg_write_string((char *)title);
105 }
106 SLsmg_gotorc(++y, x);
107 nr_lines -= 7;
108 max_len -= 2;
109 SLsmg_write_wrapped_string((unsigned char *)text, y, x,
110 nr_lines, max_len, 1);
111 y += nr_lines;
112 len = 5;
113 while (len--) {
114 SLsmg_gotorc(y + len - 1, x);
115 SLsmg_write_nstring((char *)" ", max_len);
116 }
117 SLsmg_draw_box(y++, x + 1, 3, max_len - 2);
118
119 SLsmg_gotorc(y + 3, x);
120 SLsmg_write_nstring((char *)exit_msg, max_len);
121 SLsmg_refresh();
122
123 x += 2;
124 len = 0;
125 key = ui__getch(delay_secs);
126 while (key != K_TIMER && key != K_ENTER && key != K_ESC) {
127 if (key == K_BKSPC) {
128 if (len == 0)
129 goto next_key;
130 SLsmg_gotorc(y, x + --len);
131 SLsmg_write_char(' ');
132 } else {
133 buf[len] = key;
134 SLsmg_gotorc(y, x + len++);
135 SLsmg_write_char(key);
136 }
137 SLsmg_refresh();
138
139 /* XXX more graceful overflow handling needed */
140 if (len == sizeof(buf) - 1) {
141 ui_helpline__push("maximum size of symbol name reached!");
142 key = K_ENTER;
143 break;
144 }
145next_key:
146 key = ui__getch(delay_secs);
147 }
148
149 buf[len] = '\0';
150 strncpy(input, buf, len+1);
151 return key;
152}
153
154int ui__question_window(const char *title, const char *text,
155 const char *exit_msg, int delay_secs)
156{
157 int x, y;
158 int max_len = 0, nr_lines = 0;
159 const char *t;
160
161 t = text;
162 while (1) {
163 const char *sep = strchr(t, '\n');
164 int len;
165
166 if (sep == NULL)
167 sep = strchr(t, '\0');
168 len = sep - t;
169 if (max_len < len)
170 max_len = len;
171 ++nr_lines;
172 if (*sep == '\0')
173 break;
174 t = sep + 1;
175 }
176
177 max_len += 2;
178 nr_lines += 4;
179 y = SLtt_Screen_Rows / 2 - nr_lines / 2,
180 x = SLtt_Screen_Cols / 2 - max_len / 2;
181
182 SLsmg_set_color(0);
183 SLsmg_draw_box(y, x++, nr_lines, max_len);
184 if (title) {
185 SLsmg_gotorc(y, x + 1);
186 SLsmg_write_string((char *)title);
187 }
188 SLsmg_gotorc(++y, x);
189 nr_lines -= 2;
190 max_len -= 2;
191 SLsmg_write_wrapped_string((unsigned char *)text, y, x,
192 nr_lines, max_len, 1);
193 SLsmg_gotorc(y + nr_lines - 2, x);
194 SLsmg_write_nstring((char *)" ", max_len);
195 SLsmg_gotorc(y + nr_lines - 1, x);
196 SLsmg_write_nstring((char *)exit_msg, max_len);
197 SLsmg_refresh();
198 return ui__getch(delay_secs);
199}
200
201int ui__help_window(const char *text)
202{
203 return ui__question_window("Help", text, "Press any key...", 0);
204}
205
206int ui__dialog_yesno(const char *msg)
207{
208 return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0);
209}
210
211static int __ui__warning(const char *title, const char *format, va_list args)
212{
213 char *s;
214
215 if (vasprintf(&s, format, args) > 0) {
216 int key;
217
218 pthread_mutex_lock(&ui__lock);
219 key = ui__question_window(title, s, "Press any key...", 0);
220 pthread_mutex_unlock(&ui__lock);
221 free(s);
222 return key;
223 }
224
225 fprintf(stderr, "%s\n", title);
226 vfprintf(stderr, format, args);
227 return K_ESC;
228}
229
230static int perf_tui__error(const char *format, va_list args)
231{
232 return __ui__warning("Error:", format, args);
233}
234
235static int perf_tui__warning(const char *format, va_list args)
236{
237 return __ui__warning("Warning:", format, args);
238}
239
240struct perf_error_ops perf_tui_eops = {
241 .error = perf_tui__error,
242 .warning = perf_tui__warning,
243};
diff --git a/tools/perf/ui/util.c b/tools/perf/ui/util.c
index ad4374a16bb0..4f989774c8c6 100644
--- a/tools/perf/ui/util.c
+++ b/tools/perf/ui/util.c
@@ -1,250 +1,85 @@
1#include "../util.h"
2#include <signal.h>
3#include <stdbool.h>
4#include <string.h>
5#include <sys/ttydefaults.h>
6
7#include "../cache.h"
8#include "../debug.h"
9#include "browser.h"
10#include "keysyms.h"
11#include "helpline.h"
12#include "ui.h"
13#include "util.h" 1#include "util.h"
14#include "libslang.h" 2#include "../debug.h"
15
16static void ui_browser__argv_write(struct ui_browser *browser,
17 void *entry, int row)
18{
19 char **arg = entry;
20 bool current_entry = ui_browser__is_current_entry(browser, row);
21
22 ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
23 HE_COLORSET_NORMAL);
24 slsmg_write_nstring(*arg, browser->width);
25}
26
27static int popup_menu__run(struct ui_browser *menu)
28{
29 int key;
30
31 if (ui_browser__show(menu, " ", "ESC: exit, ENTER|->: Select option") < 0)
32 return -1;
33 3
34 while (1) {
35 key = ui_browser__run(menu, 0);
36
37 switch (key) {
38 case K_RIGHT:
39 case K_ENTER:
40 key = menu->index;
41 break;
42 case K_LEFT:
43 case K_ESC:
44 case 'q':
45 case CTRL('c'):
46 key = -1;
47 break;
48 default:
49 continue;
50 }
51
52 break;
53 }
54
55 ui_browser__hide(menu);
56 return key;
57}
58 4
59int ui__popup_menu(int argc, char * const argv[]) 5/*
6 * Default error logging functions
7 */
8static int perf_stdio__error(const char *format, va_list args)
60{ 9{
61 struct ui_browser menu = { 10 fprintf(stderr, "Error:\n");
62 .entries = (void *)argv, 11 vfprintf(stderr, format, args);
63 .refresh = ui_browser__argv_refresh, 12 return 0;
64 .seek = ui_browser__argv_seek,
65 .write = ui_browser__argv_write,
66 .nr_entries = argc,
67 };
68
69 return popup_menu__run(&menu);
70} 13}
71 14
72int ui_browser__input_window(const char *title, const char *text, char *input, 15static int perf_stdio__warning(const char *format, va_list args)
73 const char *exit_msg, int delay_secs)
74{ 16{
75 int x, y, len, key; 17 fprintf(stderr, "Warning:\n");
76 int max_len = 60, nr_lines = 0; 18 vfprintf(stderr, format, args);
77 static char buf[50]; 19 return 0;
78 const char *t;
79
80 t = text;
81 while (1) {
82 const char *sep = strchr(t, '\n');
83
84 if (sep == NULL)
85 sep = strchr(t, '\0');
86 len = sep - t;
87 if (max_len < len)
88 max_len = len;
89 ++nr_lines;
90 if (*sep == '\0')
91 break;
92 t = sep + 1;
93 }
94
95 max_len += 2;
96 nr_lines += 8;
97 y = SLtt_Screen_Rows / 2 - nr_lines / 2;
98 x = SLtt_Screen_Cols / 2 - max_len / 2;
99
100 SLsmg_set_color(0);
101 SLsmg_draw_box(y, x++, nr_lines, max_len);
102 if (title) {
103 SLsmg_gotorc(y, x + 1);
104 SLsmg_write_string((char *)title);
105 }
106 SLsmg_gotorc(++y, x);
107 nr_lines -= 7;
108 max_len -= 2;
109 SLsmg_write_wrapped_string((unsigned char *)text, y, x,
110 nr_lines, max_len, 1);
111 y += nr_lines;
112 len = 5;
113 while (len--) {
114 SLsmg_gotorc(y + len - 1, x);
115 SLsmg_write_nstring((char *)" ", max_len);
116 }
117 SLsmg_draw_box(y++, x + 1, 3, max_len - 2);
118
119 SLsmg_gotorc(y + 3, x);
120 SLsmg_write_nstring((char *)exit_msg, max_len);
121 SLsmg_refresh();
122
123 x += 2;
124 len = 0;
125 key = ui__getch(delay_secs);
126 while (key != K_TIMER && key != K_ENTER && key != K_ESC) {
127 if (key == K_BKSPC) {
128 if (len == 0)
129 goto next_key;
130 SLsmg_gotorc(y, x + --len);
131 SLsmg_write_char(' ');
132 } else {
133 buf[len] = key;
134 SLsmg_gotorc(y, x + len++);
135 SLsmg_write_char(key);
136 }
137 SLsmg_refresh();
138
139 /* XXX more graceful overflow handling needed */
140 if (len == sizeof(buf) - 1) {
141 ui_helpline__push("maximum size of symbol name reached!");
142 key = K_ENTER;
143 break;
144 }
145next_key:
146 key = ui__getch(delay_secs);
147 }
148
149 buf[len] = '\0';
150 strncpy(input, buf, len+1);
151 return key;
152} 20}
153 21
154int ui__question_window(const char *title, const char *text, 22static struct perf_error_ops default_eops =
155 const char *exit_msg, int delay_secs)
156{ 23{
157 int x, y; 24 .error = perf_stdio__error,
158 int max_len = 0, nr_lines = 0; 25 .warning = perf_stdio__warning,
159 const char *t; 26};
160
161 t = text;
162 while (1) {
163 const char *sep = strchr(t, '\n');
164 int len;
165
166 if (sep == NULL)
167 sep = strchr(t, '\0');
168 len = sep - t;
169 if (max_len < len)
170 max_len = len;
171 ++nr_lines;
172 if (*sep == '\0')
173 break;
174 t = sep + 1;
175 }
176
177 max_len += 2;
178 nr_lines += 4;
179 y = SLtt_Screen_Rows / 2 - nr_lines / 2,
180 x = SLtt_Screen_Cols / 2 - max_len / 2;
181
182 SLsmg_set_color(0);
183 SLsmg_draw_box(y, x++, nr_lines, max_len);
184 if (title) {
185 SLsmg_gotorc(y, x + 1);
186 SLsmg_write_string((char *)title);
187 }
188 SLsmg_gotorc(++y, x);
189 nr_lines -= 2;
190 max_len -= 2;
191 SLsmg_write_wrapped_string((unsigned char *)text, y, x,
192 nr_lines, max_len, 1);
193 SLsmg_gotorc(y + nr_lines - 2, x);
194 SLsmg_write_nstring((char *)" ", max_len);
195 SLsmg_gotorc(y + nr_lines - 1, x);
196 SLsmg_write_nstring((char *)exit_msg, max_len);
197 SLsmg_refresh();
198 return ui__getch(delay_secs);
199}
200 27
201int ui__help_window(const char *text) 28static struct perf_error_ops *perf_eops = &default_eops;
202{
203 return ui__question_window("Help", text, "Press any key...", 0);
204}
205 29
206int ui__dialog_yesno(const char *msg)
207{
208 return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0);
209}
210 30
211int __ui__warning(const char *title, const char *format, va_list args) 31int ui__error(const char *format, ...)
212{ 32{
213 char *s; 33 int ret;
214 34 va_list args;
215 if (use_browser > 0 && vasprintf(&s, format, args) > 0) {
216 int key;
217 35
218 pthread_mutex_lock(&ui__lock); 36 va_start(args, format);
219 key = ui__question_window(title, s, "Press any key...", 0); 37 ret = perf_eops->error(format, args);
220 pthread_mutex_unlock(&ui__lock); 38 va_end(args);
221 free(s);
222 return key;
223 }
224 39
225 fprintf(stderr, "%s:\n", title); 40 return ret;
226 vfprintf(stderr, format, args);
227 return K_ESC;
228} 41}
229 42
230int ui__warning(const char *format, ...) 43int ui__warning(const char *format, ...)
231{ 44{
232 int key; 45 int ret;
233 va_list args; 46 va_list args;
234 47
235 va_start(args, format); 48 va_start(args, format);
236 key = __ui__warning("Warning", format, args); 49 ret = perf_eops->warning(format, args);
237 va_end(args); 50 va_end(args);
238 return key; 51
52 return ret;
239} 53}
240 54
241int ui__error(const char *format, ...) 55
56/**
57 * perf_error__register - Register error logging functions
58 * @eops: The pointer to error logging function struct
59 *
60 * Register UI-specific error logging functions. Before calling this,
61 * other logging functions should be unregistered, if any.
62 */
63int perf_error__register(struct perf_error_ops *eops)
242{ 64{
243 int key; 65 if (perf_eops != &default_eops)
244 va_list args; 66 return -1;
245 67
246 va_start(args, format); 68 perf_eops = eops;
247 key = __ui__warning("Error", format, args); 69 return 0;
248 va_end(args); 70}
249 return key; 71
72/**
73 * perf_error__unregister - Unregister error logging functions
74 * @eops: The pointer to error logging function struct
75 *
76 * Unregister already registered error logging functions.
77 */
78int perf_error__unregister(struct perf_error_ops *eops)
79{
80 if (perf_eops != eops)
81 return -1;
82
83 perf_eops = &default_eops;
84 return 0;
250} 85}
diff --git a/tools/perf/ui/util.h b/tools/perf/ui/util.h
index 2d1738bd71c8..361f08c52d37 100644
--- a/tools/perf/ui/util.h
+++ b/tools/perf/ui/util.h
@@ -9,6 +9,13 @@ int ui__help_window(const char *text);
9int ui__dialog_yesno(const char *msg); 9int ui__dialog_yesno(const char *msg);
10int ui__question_window(const char *title, const char *text, 10int ui__question_window(const char *title, const char *text,
11 const char *exit_msg, int delay_secs); 11 const char *exit_msg, int delay_secs);
12int __ui__warning(const char *title, const char *format, va_list args); 12
13struct perf_error_ops {
14 int (*error)(const char *format, va_list args);
15 int (*warning)(const char *format, va_list args);
16};
17
18int perf_error__register(struct perf_error_ops *eops);
19int perf_error__unregister(struct perf_error_ops *eops);
13 20
14#endif /* _PERF_UI_UTIL_H_ */ 21#endif /* _PERF_UI_UTIL_H_ */
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
index efb1fce259a4..4dfe0bb3c322 100644
--- a/tools/perf/util/debug.c
+++ b/tools/perf/util/debug.c
@@ -47,7 +47,7 @@ int dump_printf(const char *fmt, ...)
47 return ret; 47 return ret;
48} 48}
49 49
50#ifdef NO_NEWT_SUPPORT 50#if defined(NO_NEWT_SUPPORT) && defined(NO_GTK2_SUPPORT)
51int ui__warning(const char *format, ...) 51int ui__warning(const char *format, ...)
52{ 52{
53 va_list args; 53 va_list args;
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
index 6bebe7f0a20c..015c91dbc096 100644
--- a/tools/perf/util/debug.h
+++ b/tools/perf/util/debug.h
@@ -12,8 +12,9 @@ int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
12void trace_event(union perf_event *event); 12void trace_event(union perf_event *event);
13 13
14struct ui_progress; 14struct ui_progress;
15struct perf_error_ops;
15 16
16#ifdef NO_NEWT_SUPPORT 17#if defined(NO_NEWT_SUPPORT) && defined(NO_GTK2_SUPPORT)
17static inline int ui_helpline__show_help(const char *format __used, va_list ap __used) 18static inline int ui_helpline__show_help(const char *format __used, va_list ap __used)
18{ 19{
19 return 0; 20 return 0;
@@ -23,12 +24,28 @@ static inline void ui_progress__update(u64 curr __used, u64 total __used,
23 const char *title __used) {} 24 const char *title __used) {}
24 25
25#define ui__error(format, arg...) ui__warning(format, ##arg) 26#define ui__error(format, arg...) ui__warning(format, ##arg)
26#else 27
28static inline int
29perf_error__register(struct perf_error_ops *eops __used)
30{
31 return 0;
32}
33
34static inline int
35perf_error__unregister(struct perf_error_ops *eops __used)
36{
37 return 0;
38}
39
40#else /* NO_NEWT_SUPPORT && NO_GTK2_SUPPORT */
41
27extern char ui_helpline__last_msg[]; 42extern char ui_helpline__last_msg[];
28int ui_helpline__show_help(const char *format, va_list ap); 43int ui_helpline__show_help(const char *format, va_list ap);
29#include "../ui/progress.h" 44#include "../ui/progress.h"
30int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2))); 45int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2)));
31#endif 46#include "../ui/util.h"
47
48#endif /* NO_NEWT_SUPPORT && NO_GTK2_SUPPORT */
32 49
33int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); 50int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2)));
34int ui__error_paranoid(void); 51int ui__error_paranoid(void);
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 7400fb3fc50c..f74e9560350e 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -224,8 +224,8 @@ out_free_attrs:
224 return err; 224 return err;
225} 225}
226 226
227static struct perf_evsel * 227struct perf_evsel *
228 perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id) 228perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id)
229{ 229{
230 struct perf_evsel *evsel; 230 struct perf_evsel *evsel;
231 231
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 989bee9624c2..40d4d3cdced0 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -73,6 +73,9 @@ int perf_evlist__set_tracepoints_handlers(struct perf_evlist *evlist,
73#define perf_evlist__set_tracepoints_handlers_array(evlist, array) \ 73#define perf_evlist__set_tracepoints_handlers_array(evlist, array) \
74 perf_evlist__set_tracepoints_handlers(evlist, array, ARRAY_SIZE(array)) 74 perf_evlist__set_tracepoints_handlers(evlist, array, ARRAY_SIZE(array))
75 75
76struct perf_evsel *
77perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id);
78
76void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel, 79void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel,
77 int cpu, int thread, u64 id); 80 int cpu, int thread, u64 id);
78 81
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 9f6cebd798ee..e81771364867 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -15,7 +15,7 @@
15#include "cpumap.h" 15#include "cpumap.h"
16#include "thread_map.h" 16#include "thread_map.h"
17#include "target.h" 17#include "target.h"
18#include "../../include/linux/perf_event.h" 18#include "../../../include/linux/hw_breakpoint.h"
19 19
20#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 20#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
21#define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) 21#define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0))
@@ -78,7 +78,7 @@ static const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = {
78 "ref-cycles", 78 "ref-cycles",
79}; 79};
80 80
81const char *__perf_evsel__hw_name(u64 config) 81static const char *__perf_evsel__hw_name(u64 config)
82{ 82{
83 if (config < PERF_COUNT_HW_MAX && perf_evsel__hw_names[config]) 83 if (config < PERF_COUNT_HW_MAX && perf_evsel__hw_names[config])
84 return perf_evsel__hw_names[config]; 84 return perf_evsel__hw_names[config];
@@ -86,16 +86,15 @@ const char *__perf_evsel__hw_name(u64 config)
86 return "unknown-hardware"; 86 return "unknown-hardware";
87} 87}
88 88
89static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) 89static int perf_evsel__add_modifiers(struct perf_evsel *evsel, char *bf, size_t size)
90{ 90{
91 int colon = 0; 91 int colon = 0, r = 0;
92 struct perf_event_attr *attr = &evsel->attr; 92 struct perf_event_attr *attr = &evsel->attr;
93 int r = scnprintf(bf, size, "%s", __perf_evsel__hw_name(attr->config));
94 bool exclude_guest_default = false; 93 bool exclude_guest_default = false;
95 94
96#define MOD_PRINT(context, mod) do { \ 95#define MOD_PRINT(context, mod) do { \
97 if (!attr->exclude_##context) { \ 96 if (!attr->exclude_##context) { \
98 if (!colon) colon = r++; \ 97 if (!colon) colon = ++r; \
99 r += scnprintf(bf + r, size - r, "%c", mod); \ 98 r += scnprintf(bf + r, size - r, "%c", mod); \
100 } } while(0) 99 } } while(0)
101 100
@@ -108,7 +107,7 @@ static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size)
108 107
109 if (attr->precise_ip) { 108 if (attr->precise_ip) {
110 if (!colon) 109 if (!colon)
111 colon = r++; 110 colon = ++r;
112 r += scnprintf(bf + r, size - r, "%.*s", attr->precise_ip, "ppp"); 111 r += scnprintf(bf + r, size - r, "%.*s", attr->precise_ip, "ppp");
113 exclude_guest_default = true; 112 exclude_guest_default = true;
114 } 113 }
@@ -119,39 +118,211 @@ static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size)
119 } 118 }
120#undef MOD_PRINT 119#undef MOD_PRINT
121 if (colon) 120 if (colon)
122 bf[colon] = ':'; 121 bf[colon - 1] = ':';
123 return r; 122 return r;
124} 123}
125 124
126int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size) 125static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size)
126{
127 int r = scnprintf(bf, size, "%s", __perf_evsel__hw_name(evsel->attr.config));
128 return r + perf_evsel__add_modifiers(evsel, bf + r, size - r);
129}
130
131static const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX] = {
132 "cpu-clock",
133 "task-clock",
134 "page-faults",
135 "context-switches",
136 "CPU-migrations",
137 "minor-faults",
138 "major-faults",
139 "alignment-faults",
140 "emulation-faults",
141};
142
143static const char *__perf_evsel__sw_name(u64 config)
127{ 144{
128 int ret; 145 if (config < PERF_COUNT_SW_MAX && perf_evsel__sw_names[config])
146 return perf_evsel__sw_names[config];
147 return "unknown-software";
148}
149
150static int perf_evsel__sw_name(struct perf_evsel *evsel, char *bf, size_t size)
151{
152 int r = scnprintf(bf, size, "%s", __perf_evsel__sw_name(evsel->attr.config));
153 return r + perf_evsel__add_modifiers(evsel, bf + r, size - r);
154}
155
156static int __perf_evsel__bp_name(char *bf, size_t size, u64 addr, u64 type)
157{
158 int r;
159
160 r = scnprintf(bf, size, "mem:0x%" PRIx64 ":", addr);
161
162 if (type & HW_BREAKPOINT_R)
163 r += scnprintf(bf + r, size - r, "r");
164
165 if (type & HW_BREAKPOINT_W)
166 r += scnprintf(bf + r, size - r, "w");
167
168 if (type & HW_BREAKPOINT_X)
169 r += scnprintf(bf + r, size - r, "x");
170
171 return r;
172}
173
174static int perf_evsel__bp_name(struct perf_evsel *evsel, char *bf, size_t size)
175{
176 struct perf_event_attr *attr = &evsel->attr;
177 int r = __perf_evsel__bp_name(bf, size, attr->bp_addr, attr->bp_type);
178 return r + perf_evsel__add_modifiers(evsel, bf + r, size - r);
179}
180
181const char *perf_evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX]
182 [PERF_EVSEL__MAX_ALIASES] = {
183 { "L1-dcache", "l1-d", "l1d", "L1-data", },
184 { "L1-icache", "l1-i", "l1i", "L1-instruction", },
185 { "LLC", "L2", },
186 { "dTLB", "d-tlb", "Data-TLB", },
187 { "iTLB", "i-tlb", "Instruction-TLB", },
188 { "branch", "branches", "bpu", "btb", "bpc", },
189 { "node", },
190};
191
192const char *perf_evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX]
193 [PERF_EVSEL__MAX_ALIASES] = {
194 { "load", "loads", "read", },
195 { "store", "stores", "write", },
196 { "prefetch", "prefetches", "speculative-read", "speculative-load", },
197};
198
199const char *perf_evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX]
200 [PERF_EVSEL__MAX_ALIASES] = {
201 { "refs", "Reference", "ops", "access", },
202 { "misses", "miss", },
203};
204
205#define C(x) PERF_COUNT_HW_CACHE_##x
206#define CACHE_READ (1 << C(OP_READ))
207#define CACHE_WRITE (1 << C(OP_WRITE))
208#define CACHE_PREFETCH (1 << C(OP_PREFETCH))
209#define COP(x) (1 << x)
210
211/*
212 * cache operartion stat
213 * L1I : Read and prefetch only
214 * ITLB and BPU : Read-only
215 */
216static unsigned long perf_evsel__hw_cache_stat[C(MAX)] = {
217 [C(L1D)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
218 [C(L1I)] = (CACHE_READ | CACHE_PREFETCH),
219 [C(LL)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
220 [C(DTLB)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
221 [C(ITLB)] = (CACHE_READ),
222 [C(BPU)] = (CACHE_READ),
223 [C(NODE)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
224};
225
226bool perf_evsel__is_cache_op_valid(u8 type, u8 op)
227{
228 if (perf_evsel__hw_cache_stat[type] & COP(op))
229 return true; /* valid */
230 else
231 return false; /* invalid */
232}
233
234int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result,
235 char *bf, size_t size)
236{
237 if (result) {
238 return scnprintf(bf, size, "%s-%s-%s", perf_evsel__hw_cache[type][0],
239 perf_evsel__hw_cache_op[op][0],
240 perf_evsel__hw_cache_result[result][0]);
241 }
242
243 return scnprintf(bf, size, "%s-%s", perf_evsel__hw_cache[type][0],
244 perf_evsel__hw_cache_op[op][1]);
245}
246
247static int __perf_evsel__hw_cache_name(u64 config, char *bf, size_t size)
248{
249 u8 op, result, type = (config >> 0) & 0xff;
250 const char *err = "unknown-ext-hardware-cache-type";
251
252 if (type > PERF_COUNT_HW_CACHE_MAX)
253 goto out_err;
254
255 op = (config >> 8) & 0xff;
256 err = "unknown-ext-hardware-cache-op";
257 if (op > PERF_COUNT_HW_CACHE_OP_MAX)
258 goto out_err;
259
260 result = (config >> 16) & 0xff;
261 err = "unknown-ext-hardware-cache-result";
262 if (result > PERF_COUNT_HW_CACHE_RESULT_MAX)
263 goto out_err;
264
265 err = "invalid-cache";
266 if (!perf_evsel__is_cache_op_valid(type, op))
267 goto out_err;
268
269 return __perf_evsel__hw_cache_type_op_res_name(type, op, result, bf, size);
270out_err:
271 return scnprintf(bf, size, "%s", err);
272}
273
274static int perf_evsel__hw_cache_name(struct perf_evsel *evsel, char *bf, size_t size)
275{
276 int ret = __perf_evsel__hw_cache_name(evsel->attr.config, bf, size);
277 return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret);
278}
279
280static int perf_evsel__raw_name(struct perf_evsel *evsel, char *bf, size_t size)
281{
282 int ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->attr.config);
283 return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret);
284}
285
286const char *perf_evsel__name(struct perf_evsel *evsel)
287{
288 char bf[128];
289
290 if (evsel->name)
291 return evsel->name;
129 292
130 switch (evsel->attr.type) { 293 switch (evsel->attr.type) {
131 case PERF_TYPE_RAW: 294 case PERF_TYPE_RAW:
132 ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->attr.config); 295 perf_evsel__raw_name(evsel, bf, sizeof(bf));
133 break; 296 break;
134 297
135 case PERF_TYPE_HARDWARE: 298 case PERF_TYPE_HARDWARE:
136 ret = perf_evsel__hw_name(evsel, bf, size); 299 perf_evsel__hw_name(evsel, bf, sizeof(bf));
300 break;
301
302 case PERF_TYPE_HW_CACHE:
303 perf_evsel__hw_cache_name(evsel, bf, sizeof(bf));
304 break;
305
306 case PERF_TYPE_SOFTWARE:
307 perf_evsel__sw_name(evsel, bf, sizeof(bf));
137 break; 308 break;
309
310 case PERF_TYPE_TRACEPOINT:
311 scnprintf(bf, sizeof(bf), "%s", "unknown tracepoint");
312 break;
313
314 case PERF_TYPE_BREAKPOINT:
315 perf_evsel__bp_name(evsel, bf, sizeof(bf));
316 break;
317
138 default: 318 default:
139 /* 319 scnprintf(bf, sizeof(bf), "%s", "unknown attr type");
140 * FIXME 320 break;
141 * 321 }
142 * This is the minimal perf_evsel__name so that we can 322
143 * reconstruct event names taking into account event modifiers. 323 evsel->name = strdup(bf);
144 * 324
145 * The old event_name uses it now for raw anr hw events, so that 325 return evsel->name ?: "unknown";
146 * we don't drag all the parsing stuff into the python binding.
147 *
148 * On the next devel cycle the rest of the event naming will be
149 * brought here.
150 */
151 return 0;
152 }
153
154 return ret;
155} 326}
156 327
157void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, 328void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts,
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 4ba8b564e6f4..67cc5033d192 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -83,8 +83,19 @@ void perf_evsel__config(struct perf_evsel *evsel,
83 struct perf_record_opts *opts, 83 struct perf_record_opts *opts,
84 struct perf_evsel *first); 84 struct perf_evsel *first);
85 85
86const char* __perf_evsel__hw_name(u64 config); 86bool perf_evsel__is_cache_op_valid(u8 type, u8 op);
87int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size); 87
88#define PERF_EVSEL__MAX_ALIASES 8
89
90extern const char *perf_evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX]
91 [PERF_EVSEL__MAX_ALIASES];
92extern const char *perf_evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX]
93 [PERF_EVSEL__MAX_ALIASES];
94const char *perf_evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX]
95 [PERF_EVSEL__MAX_ALIASES];
96int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result,
97 char *bf, size_t size);
98const char *perf_evsel__name(struct perf_evsel *evsel);
88 99
89int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); 100int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
90int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads); 101int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index e909d43cf542..5a47aba46759 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -641,7 +641,7 @@ static int write_event_desc(int fd, struct perf_header *h __used,
641 /* 641 /*
642 * write event string as passed on cmdline 642 * write event string as passed on cmdline
643 */ 643 */
644 ret = do_write_string(fd, event_name(attr)); 644 ret = do_write_string(fd, perf_evsel__name(attr));
645 if (ret < 0) 645 if (ret < 0)
646 return ret; 646 return ret;
647 /* 647 /*
@@ -1474,15 +1474,15 @@ out:
1474 1474
1475static int process_tracing_data(struct perf_file_section *section __unused, 1475static int process_tracing_data(struct perf_file_section *section __unused,
1476 struct perf_header *ph __unused, 1476 struct perf_header *ph __unused,
1477 int feat __unused, int fd) 1477 int feat __unused, int fd, void *data)
1478{ 1478{
1479 trace_report(fd, false); 1479 trace_report(fd, data, false);
1480 return 0; 1480 return 0;
1481} 1481}
1482 1482
1483static int process_build_id(struct perf_file_section *section, 1483static int process_build_id(struct perf_file_section *section,
1484 struct perf_header *ph, 1484 struct perf_header *ph,
1485 int feat __unused, int fd) 1485 int feat __unused, int fd, void *data __used)
1486{ 1486{
1487 if (perf_header__read_build_ids(ph, fd, section->offset, section->size)) 1487 if (perf_header__read_build_ids(ph, fd, section->offset, section->size))
1488 pr_debug("Failed to read buildids, continuing...\n"); 1488 pr_debug("Failed to read buildids, continuing...\n");
@@ -1493,7 +1493,7 @@ struct feature_ops {
1493 int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist); 1493 int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist);
1494 void (*print)(struct perf_header *h, int fd, FILE *fp); 1494 void (*print)(struct perf_header *h, int fd, FILE *fp);
1495 int (*process)(struct perf_file_section *section, 1495 int (*process)(struct perf_file_section *section,
1496 struct perf_header *h, int feat, int fd); 1496 struct perf_header *h, int feat, int fd, void *data);
1497 const char *name; 1497 const char *name;
1498 bool full_only; 1498 bool full_only;
1499}; 1499};
@@ -1988,7 +1988,7 @@ int perf_file_header__read(struct perf_file_header *header,
1988 1988
1989static int perf_file_section__process(struct perf_file_section *section, 1989static int perf_file_section__process(struct perf_file_section *section,
1990 struct perf_header *ph, 1990 struct perf_header *ph,
1991 int feat, int fd, void *data __used) 1991 int feat, int fd, void *data)
1992{ 1992{
1993 if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) { 1993 if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) {
1994 pr_debug("Failed to lseek to %" PRIu64 " offset for feature " 1994 pr_debug("Failed to lseek to %" PRIu64 " offset for feature "
@@ -2004,7 +2004,7 @@ static int perf_file_section__process(struct perf_file_section *section,
2004 if (!feat_ops[feat].process) 2004 if (!feat_ops[feat].process)
2005 return 0; 2005 return 0;
2006 2006
2007 return feat_ops[feat].process(section, ph, feat, fd); 2007 return feat_ops[feat].process(section, ph, feat, fd, data);
2008} 2008}
2009 2009
2010static int perf_file_header__read_pipe(struct perf_pipe_file_header *header, 2010static int perf_file_header__read_pipe(struct perf_pipe_file_header *header,
@@ -2093,9 +2093,11 @@ static int read_attr(int fd, struct perf_header *ph,
2093 return ret <= 0 ? -1 : 0; 2093 return ret <= 0 ? -1 : 0;
2094} 2094}
2095 2095
2096static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel) 2096static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel,
2097 struct pevent *pevent)
2097{ 2098{
2098 struct event_format *event = trace_find_event(evsel->attr.config); 2099 struct event_format *event = pevent_find_event(pevent,
2100 evsel->attr.config);
2099 char bf[128]; 2101 char bf[128];
2100 2102
2101 if (event == NULL) 2103 if (event == NULL)
@@ -2109,13 +2111,14 @@ static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel)
2109 return 0; 2111 return 0;
2110} 2112}
2111 2113
2112static int perf_evlist__set_tracepoint_names(struct perf_evlist *evlist) 2114static int perf_evlist__set_tracepoint_names(struct perf_evlist *evlist,
2115 struct pevent *pevent)
2113{ 2116{
2114 struct perf_evsel *pos; 2117 struct perf_evsel *pos;
2115 2118
2116 list_for_each_entry(pos, &evlist->entries, node) { 2119 list_for_each_entry(pos, &evlist->entries, node) {
2117 if (pos->attr.type == PERF_TYPE_TRACEPOINT && 2120 if (pos->attr.type == PERF_TYPE_TRACEPOINT &&
2118 perf_evsel__set_tracepoint_name(pos)) 2121 perf_evsel__set_tracepoint_name(pos, pevent))
2119 return -1; 2122 return -1;
2120 } 2123 }
2121 2124
@@ -2198,12 +2201,12 @@ int perf_session__read_header(struct perf_session *session, int fd)
2198 event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type); 2201 event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type);
2199 } 2202 }
2200 2203
2201 perf_header__process_sections(header, fd, NULL, 2204 perf_header__process_sections(header, fd, &session->pevent,
2202 perf_file_section__process); 2205 perf_file_section__process);
2203 2206
2204 lseek(fd, header->data_offset, SEEK_SET); 2207 lseek(fd, header->data_offset, SEEK_SET);
2205 2208
2206 if (perf_evlist__set_tracepoint_names(session->evlist)) 2209 if (perf_evlist__set_tracepoint_names(session->evlist, session->pevent))
2207 goto out_delete_evlist; 2210 goto out_delete_evlist;
2208 2211
2209 header->frozen = 1; 2212 header->frozen = 1;
@@ -2419,8 +2422,8 @@ int perf_event__process_tracing_data(union perf_event *event,
2419 lseek(session->fd, offset + sizeof(struct tracing_data_event), 2422 lseek(session->fd, offset + sizeof(struct tracing_data_event),
2420 SEEK_SET); 2423 SEEK_SET);
2421 2424
2422 size_read = trace_report(session->fd, session->repipe); 2425 size_read = trace_report(session->fd, &session->pevent,
2423 2426 session->repipe);
2424 padding = ALIGN(size_read, sizeof(u64)) - size_read; 2427 padding = ALIGN(size_read, sizeof(u64)) - size_read;
2425 2428
2426 if (read(session->fd, buf, padding) < 0) 2429 if (read(session->fd, buf, padding) < 0)
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 34bb556d6219..0b096c27a419 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -47,6 +47,7 @@ enum hist_column {
47 HISTC_SYMBOL_TO, 47 HISTC_SYMBOL_TO,
48 HISTC_DSO_FROM, 48 HISTC_DSO_FROM,
49 HISTC_DSO_TO, 49 HISTC_DSO_TO,
50 HISTC_SRCLINE,
50 HISTC_NR_COLS, /* Last entry */ 51 HISTC_NR_COLS, /* Last entry */
51}; 52};
52 53
diff --git a/tools/perf/util/include/linux/kernel.h b/tools/perf/util/include/linux/kernel.h
index 1eb804fd3fbf..b6842c1d02a8 100644
--- a/tools/perf/util/include/linux/kernel.h
+++ b/tools/perf/util/include/linux/kernel.h
@@ -108,4 +108,14 @@ int eprintf(int level,
108#define pr_debug3(fmt, ...) pr_debugN(3, pr_fmt(fmt), ##__VA_ARGS__) 108#define pr_debug3(fmt, ...) pr_debugN(3, pr_fmt(fmt), ##__VA_ARGS__)
109#define pr_debug4(fmt, ...) pr_debugN(4, pr_fmt(fmt), ##__VA_ARGS__) 109#define pr_debug4(fmt, ...) pr_debugN(4, pr_fmt(fmt), ##__VA_ARGS__)
110 110
111/*
112 * This looks more complex than it should be. But we need to
113 * get the type for the ~ right in round_down (it needs to be
114 * as wide as the result!), and we want to evaluate the macro
115 * arguments just once each.
116 */
117#define __round_mask(x, y) ((__typeof__(x))((y)-1))
118#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
119#define round_down(x, y) ((x) & ~__round_mask(x, y))
120
111#endif 121#endif
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 81371bad4ef0..c14c665d9a25 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -157,7 +157,7 @@ void machine__exit(struct machine *self);
157void machine__delete(struct machine *self); 157void machine__delete(struct machine *self);
158 158
159int machine__resolve_callchain(struct machine *machine, 159int machine__resolve_callchain(struct machine *machine,
160 struct perf_evsel *evsel, struct thread *thread, 160 struct thread *thread,
161 struct ip_callchain *chain, 161 struct ip_callchain *chain,
162 struct symbol **parent); 162 struct symbol **parent);
163int maps__set_kallsyms_ref_reloc_sym(struct map **maps, const char *symbol_name, 163int maps__set_kallsyms_ref_reloc_sym(struct map **maps, const char *symbol_name,
diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c
index 76b98e2a587d..1b997d2b89ce 100644
--- a/tools/perf/util/parse-events-test.c
+++ b/tools/perf/util/parse-events-test.c
@@ -181,6 +181,22 @@ static int test__checkevent_breakpoint_w(struct perf_evlist *evlist)
181 return 0; 181 return 0;
182} 182}
183 183
184static int test__checkevent_breakpoint_rw(struct perf_evlist *evlist)
185{
186 struct perf_evsel *evsel = list_entry(evlist->entries.next,
187 struct perf_evsel, node);
188
189 TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
190 TEST_ASSERT_VAL("wrong type",
191 PERF_TYPE_BREAKPOINT == evsel->attr.type);
192 TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
193 TEST_ASSERT_VAL("wrong bp_type",
194 (HW_BREAKPOINT_R|HW_BREAKPOINT_W) == evsel->attr.bp_type);
195 TEST_ASSERT_VAL("wrong bp_len",
196 HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len);
197 return 0;
198}
199
184static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist) 200static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist)
185{ 201{
186 struct perf_evsel *evsel = list_entry(evlist->entries.next, 202 struct perf_evsel *evsel = list_entry(evlist->entries.next,
@@ -309,6 +325,8 @@ static int test__checkevent_breakpoint_modifier(struct perf_evlist *evlist)
309 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); 325 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
310 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); 326 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
311 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); 327 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
328 TEST_ASSERT_VAL("wrong name",
329 !strcmp(perf_evsel__name(evsel), "mem:0x0:rw:u"));
312 330
313 return test__checkevent_breakpoint(evlist); 331 return test__checkevent_breakpoint(evlist);
314} 332}
@@ -322,6 +340,8 @@ static int test__checkevent_breakpoint_x_modifier(struct perf_evlist *evlist)
322 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); 340 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
323 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); 341 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
324 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); 342 TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
343 TEST_ASSERT_VAL("wrong name",
344 !strcmp(perf_evsel__name(evsel), "mem:0x0:x:k"));
325 345
326 return test__checkevent_breakpoint_x(evlist); 346 return test__checkevent_breakpoint_x(evlist);
327} 347}
@@ -335,6 +355,8 @@ static int test__checkevent_breakpoint_r_modifier(struct perf_evlist *evlist)
335 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); 355 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
336 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); 356 TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
337 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); 357 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
358 TEST_ASSERT_VAL("wrong name",
359 !strcmp(perf_evsel__name(evsel), "mem:0x0:r:hp"));
338 360
339 return test__checkevent_breakpoint_r(evlist); 361 return test__checkevent_breakpoint_r(evlist);
340} 362}
@@ -348,10 +370,27 @@ static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist)
348 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); 370 TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
349 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); 371 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
350 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); 372 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
373 TEST_ASSERT_VAL("wrong name",
374 !strcmp(perf_evsel__name(evsel), "mem:0x0:w:up"));
351 375
352 return test__checkevent_breakpoint_w(evlist); 376 return test__checkevent_breakpoint_w(evlist);
353} 377}
354 378
379static int test__checkevent_breakpoint_rw_modifier(struct perf_evlist *evlist)
380{
381 struct perf_evsel *evsel = list_entry(evlist->entries.next,
382 struct perf_evsel, node);
383
384 TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
385 TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
386 TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
387 TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
388 TEST_ASSERT_VAL("wrong name",
389 !strcmp(perf_evsel__name(evsel), "mem:0x0:rw:kp"));
390
391 return test__checkevent_breakpoint_rw(evlist);
392}
393
355static int test__checkevent_pmu(struct perf_evlist *evlist) 394static int test__checkevent_pmu(struct perf_evlist *evlist)
356{ 395{
357 396
@@ -413,19 +452,63 @@ static int test__checkevent_pmu_name(struct perf_evlist *evlist)
413{ 452{
414 struct perf_evsel *evsel; 453 struct perf_evsel *evsel;
415 454
416 /* cpu/config=1,name=krava1/u */ 455 /* cpu/config=1,name=krava/u */
417 evsel = list_entry(evlist->entries.next, struct perf_evsel, node); 456 evsel = list_entry(evlist->entries.next, struct perf_evsel, node);
418 TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); 457 TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries);
419 TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); 458 TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
420 TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); 459 TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config);
421 TEST_ASSERT_VAL("wrong name", !strcmp(evsel->name, "krava")); 460 TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "krava"));
422 461
423 /* cpu/config=2/" */ 462 /* cpu/config=2/u" */
424 evsel = list_entry(evsel->node.next, struct perf_evsel, node); 463 evsel = list_entry(evsel->node.next, struct perf_evsel, node);
425 TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); 464 TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries);
426 TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); 465 TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
427 TEST_ASSERT_VAL("wrong config", 2 == evsel->attr.config); 466 TEST_ASSERT_VAL("wrong config", 2 == evsel->attr.config);
428 TEST_ASSERT_VAL("wrong name", !strcmp(evsel->name, "raw 0x2")); 467 TEST_ASSERT_VAL("wrong name",
468 !strcmp(perf_evsel__name(evsel), "raw 0x2:u"));
469
470 return 0;
471}
472
473static int test__checkterms_simple(struct list_head *terms)
474{
475 struct parse_events__term *term;
476
477 /* config=10 */
478 term = list_entry(terms->next, struct parse_events__term, list);
479 TEST_ASSERT_VAL("wrong type term",
480 term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG);
481 TEST_ASSERT_VAL("wrong type val",
482 term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
483 TEST_ASSERT_VAL("wrong val", term->val.num == 10);
484 TEST_ASSERT_VAL("wrong config", !term->config);
485
486 /* config1 */
487 term = list_entry(term->list.next, struct parse_events__term, list);
488 TEST_ASSERT_VAL("wrong type term",
489 term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG1);
490 TEST_ASSERT_VAL("wrong type val",
491 term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
492 TEST_ASSERT_VAL("wrong val", term->val.num == 1);
493 TEST_ASSERT_VAL("wrong config", !term->config);
494
495 /* config2=3 */
496 term = list_entry(term->list.next, struct parse_events__term, list);
497 TEST_ASSERT_VAL("wrong type term",
498 term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG2);
499 TEST_ASSERT_VAL("wrong type val",
500 term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
501 TEST_ASSERT_VAL("wrong val", term->val.num == 3);
502 TEST_ASSERT_VAL("wrong config", !term->config);
503
504 /* umask=1*/
505 term = list_entry(term->list.next, struct parse_events__term, list);
506 TEST_ASSERT_VAL("wrong type term",
507 term->type_term == PARSE_EVENTS__TERM_TYPE_USER);
508 TEST_ASSERT_VAL("wrong type val",
509 term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
510 TEST_ASSERT_VAL("wrong val", term->val.num == 1);
511 TEST_ASSERT_VAL("wrong config", !strcmp(term->config, "umask"));
429 512
430 return 0; 513 return 0;
431} 514}
@@ -541,10 +624,16 @@ static struct test__event_st test__events[] = {
541 .name = "instructions:H", 624 .name = "instructions:H",
542 .check = test__checkevent_exclude_guest_modifier, 625 .check = test__checkevent_exclude_guest_modifier,
543 }, 626 },
627 [26] = {
628 .name = "mem:0:rw",
629 .check = test__checkevent_breakpoint_rw,
630 },
631 [27] = {
632 .name = "mem:0:rw:kp",
633 .check = test__checkevent_breakpoint_rw_modifier,
634 },
544}; 635};
545 636
546#define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st))
547
548static struct test__event_st test__events_pmu[] = { 637static struct test__event_st test__events_pmu[] = {
549 [0] = { 638 [0] = {
550 .name = "cpu/config=10,config1,config2=3,period=1000/u", 639 .name = "cpu/config=10,config1,config2=3,period=1000/u",
@@ -556,10 +645,23 @@ static struct test__event_st test__events_pmu[] = {
556 }, 645 },
557}; 646};
558 647
559#define TEST__EVENTS_PMU_CNT (sizeof(test__events_pmu) / \ 648struct test__term {
560 sizeof(struct test__event_st)) 649 const char *str;
650 __u32 type;
651 int (*check)(struct list_head *terms);
652};
653
654static struct test__term test__terms[] = {
655 [0] = {
656 .str = "config=10,config1,config2=3,umask=1",
657 .check = test__checkterms_simple,
658 },
659};
660
661#define TEST__TERMS_CNT (sizeof(test__terms) / \
662 sizeof(struct test__term))
561 663
562static int test(struct test__event_st *e) 664static int test_event(struct test__event_st *e)
563{ 665{
564 struct perf_evlist *evlist; 666 struct perf_evlist *evlist;
565 int ret; 667 int ret;
@@ -590,7 +692,48 @@ static int test_events(struct test__event_st *events, unsigned cnt)
590 struct test__event_st *e = &events[i]; 692 struct test__event_st *e = &events[i];
591 693
592 pr_debug("running test %d '%s'\n", i, e->name); 694 pr_debug("running test %d '%s'\n", i, e->name);
593 ret = test(e); 695 ret = test_event(e);
696 if (ret)
697 break;
698 }
699
700 return ret;
701}
702
703static int test_term(struct test__term *t)
704{
705 struct list_head *terms;
706 int ret;
707
708 terms = malloc(sizeof(*terms));
709 if (!terms)
710 return -ENOMEM;
711
712 INIT_LIST_HEAD(terms);
713
714 ret = parse_events_terms(terms, t->str);
715 if (ret) {
716 pr_debug("failed to parse terms '%s', err %d\n",
717 t->str , ret);
718 return ret;
719 }
720
721 ret = t->check(terms);
722 parse_events__free_terms(terms);
723
724 return ret;
725}
726
727static int test_terms(struct test__term *terms, unsigned cnt)
728{
729 int ret = 0;
730 unsigned i;
731
732 for (i = 0; i < cnt; i++) {
733 struct test__term *t = &terms[i];
734
735 pr_debug("running test %d '%s'\n", i, t->str);
736 ret = test_term(t);
594 if (ret) 737 if (ret)
595 break; 738 break;
596 } 739 }
@@ -617,9 +760,17 @@ int parse_events__test(void)
617{ 760{
618 int ret; 761 int ret;
619 762
620 ret = test_events(test__events, TEST__EVENTS_CNT); 763#define TEST_EVENTS(tests) \
621 if (!ret && test_pmu()) 764do { \
622 ret = test_events(test__events_pmu, TEST__EVENTS_PMU_CNT); 765 ret = test_events(tests, ARRAY_SIZE(tests)); \
766 if (ret) \
767 return ret; \
768} while (0)
623 769
624 return ret; 770 TEST_EVENTS(test__events);
771
772 if (test_pmu())
773 TEST_EVENTS(test__events_pmu);
774
775 return test_terms(test__terms, ARRAY_SIZE(test__terms));
625} 776}
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 05dbc8b3c767..1aa721d7c10f 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -11,14 +11,14 @@
11#include "cache.h" 11#include "cache.h"
12#include "header.h" 12#include "header.h"
13#include "debugfs.h" 13#include "debugfs.h"
14#include "parse-events-bison.h"
15#define YY_EXTRA_TYPE int
14#include "parse-events-flex.h" 16#include "parse-events-flex.h"
15#include "pmu.h" 17#include "pmu.h"
16 18
17#define MAX_NAME_LEN 100 19#define MAX_NAME_LEN 100
18 20
19struct event_symbol { 21struct event_symbol {
20 u8 type;
21 u64 config;
22 const char *symbol; 22 const char *symbol;
23 const char *alias; 23 const char *alias;
24}; 24};
@@ -26,32 +26,88 @@ struct event_symbol {
26#ifdef PARSER_DEBUG 26#ifdef PARSER_DEBUG
27extern int parse_events_debug; 27extern int parse_events_debug;
28#endif 28#endif
29int parse_events_parse(struct list_head *list, int *idx); 29int parse_events_parse(void *data, void *scanner);
30 30
31#define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x 31static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = {
32#define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x 32 [PERF_COUNT_HW_CPU_CYCLES] = {
33 33 .symbol = "cpu-cycles",
34static struct event_symbol event_symbols[] = { 34 .alias = "cycles",
35 { CHW(CPU_CYCLES), "cpu-cycles", "cycles" }, 35 },
36 { CHW(STALLED_CYCLES_FRONTEND), "stalled-cycles-frontend", "idle-cycles-frontend" }, 36 [PERF_COUNT_HW_INSTRUCTIONS] = {
37 { CHW(STALLED_CYCLES_BACKEND), "stalled-cycles-backend", "idle-cycles-backend" }, 37 .symbol = "instructions",
38 { CHW(INSTRUCTIONS), "instructions", "" }, 38 .alias = "",
39 { CHW(CACHE_REFERENCES), "cache-references", "" }, 39 },
40 { CHW(CACHE_MISSES), "cache-misses", "" }, 40 [PERF_COUNT_HW_CACHE_REFERENCES] = {
41 { CHW(BRANCH_INSTRUCTIONS), "branch-instructions", "branches" }, 41 .symbol = "cache-references",
42 { CHW(BRANCH_MISSES), "branch-misses", "" }, 42 .alias = "",
43 { CHW(BUS_CYCLES), "bus-cycles", "" }, 43 },
44 { CHW(REF_CPU_CYCLES), "ref-cycles", "" }, 44 [PERF_COUNT_HW_CACHE_MISSES] = {
45 45 .symbol = "cache-misses",
46 { CSW(CPU_CLOCK), "cpu-clock", "" }, 46 .alias = "",
47 { CSW(TASK_CLOCK), "task-clock", "" }, 47 },
48 { CSW(PAGE_FAULTS), "page-faults", "faults" }, 48 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = {
49 { CSW(PAGE_FAULTS_MIN), "minor-faults", "" }, 49 .symbol = "branch-instructions",
50 { CSW(PAGE_FAULTS_MAJ), "major-faults", "" }, 50 .alias = "branches",
51 { CSW(CONTEXT_SWITCHES), "context-switches", "cs" }, 51 },
52 { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" }, 52 [PERF_COUNT_HW_BRANCH_MISSES] = {
53 { CSW(ALIGNMENT_FAULTS), "alignment-faults", "" }, 53 .symbol = "branch-misses",
54 { CSW(EMULATION_FAULTS), "emulation-faults", "" }, 54 .alias = "",
55 },
56 [PERF_COUNT_HW_BUS_CYCLES] = {
57 .symbol = "bus-cycles",
58 .alias = "",
59 },
60 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = {
61 .symbol = "stalled-cycles-frontend",
62 .alias = "idle-cycles-frontend",
63 },
64 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = {
65 .symbol = "stalled-cycles-backend",
66 .alias = "idle-cycles-backend",
67 },
68 [PERF_COUNT_HW_REF_CPU_CYCLES] = {
69 .symbol = "ref-cycles",
70 .alias = "",
71 },
72};
73
74static struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = {
75 [PERF_COUNT_SW_CPU_CLOCK] = {
76 .symbol = "cpu-clock",
77 .alias = "",
78 },
79 [PERF_COUNT_SW_TASK_CLOCK] = {
80 .symbol = "task-clock",
81 .alias = "",
82 },
83 [PERF_COUNT_SW_PAGE_FAULTS] = {
84 .symbol = "page-faults",
85 .alias = "faults",
86 },
87 [PERF_COUNT_SW_CONTEXT_SWITCHES] = {
88 .symbol = "context-switches",
89 .alias = "cs",
90 },
91 [PERF_COUNT_SW_CPU_MIGRATIONS] = {
92 .symbol = "cpu-migrations",
93 .alias = "migrations",
94 },
95 [PERF_COUNT_SW_PAGE_FAULTS_MIN] = {
96 .symbol = "minor-faults",
97 .alias = "",
98 },
99 [PERF_COUNT_SW_PAGE_FAULTS_MAJ] = {
100 .symbol = "major-faults",
101 .alias = "",
102 },
103 [PERF_COUNT_SW_ALIGNMENT_FAULTS] = {
104 .symbol = "alignment-faults",
105 .alias = "",
106 },
107 [PERF_COUNT_SW_EMULATION_FAULTS] = {
108 .symbol = "emulation-faults",
109 .alias = "",
110 },
55}; 111};
56 112
57#define __PERF_EVENT_FIELD(config, name) \ 113#define __PERF_EVENT_FIELD(config, name) \
@@ -62,63 +118,6 @@ static struct event_symbol event_symbols[] = {
62#define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) 118#define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE)
63#define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) 119#define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT)
64 120
65static const char *sw_event_names[PERF_COUNT_SW_MAX] = {
66 "cpu-clock",
67 "task-clock",
68 "page-faults",
69 "context-switches",
70 "CPU-migrations",
71 "minor-faults",
72 "major-faults",
73 "alignment-faults",
74 "emulation-faults",
75};
76
77#define MAX_ALIASES 8
78
79static const char *hw_cache[PERF_COUNT_HW_CACHE_MAX][MAX_ALIASES] = {
80 { "L1-dcache", "l1-d", "l1d", "L1-data", },
81 { "L1-icache", "l1-i", "l1i", "L1-instruction", },
82 { "LLC", "L2", },
83 { "dTLB", "d-tlb", "Data-TLB", },
84 { "iTLB", "i-tlb", "Instruction-TLB", },
85 { "branch", "branches", "bpu", "btb", "bpc", },
86 { "node", },
87};
88
89static const char *hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX][MAX_ALIASES] = {
90 { "load", "loads", "read", },
91 { "store", "stores", "write", },
92 { "prefetch", "prefetches", "speculative-read", "speculative-load", },
93};
94
95static const char *hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX]
96 [MAX_ALIASES] = {
97 { "refs", "Reference", "ops", "access", },
98 { "misses", "miss", },
99};
100
101#define C(x) PERF_COUNT_HW_CACHE_##x
102#define CACHE_READ (1 << C(OP_READ))
103#define CACHE_WRITE (1 << C(OP_WRITE))
104#define CACHE_PREFETCH (1 << C(OP_PREFETCH))
105#define COP(x) (1 << x)
106
107/*
108 * cache operartion stat
109 * L1I : Read and prefetch only
110 * ITLB and BPU : Read-only
111 */
112static unsigned long hw_cache_stat[C(MAX)] = {
113 [C(L1D)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
114 [C(L1I)] = (CACHE_READ | CACHE_PREFETCH),
115 [C(LL)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
116 [C(DTLB)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
117 [C(ITLB)] = (CACHE_READ),
118 [C(BPU)] = (CACHE_READ),
119 [C(NODE)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
120};
121
122#define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ 121#define for_each_subsystem(sys_dir, sys_dirent, sys_next) \
123 while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ 122 while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \
124 if (sys_dirent.d_type == DT_DIR && \ 123 if (sys_dirent.d_type == DT_DIR && \
@@ -218,48 +217,6 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
218 return NULL; 217 return NULL;
219} 218}
220 219
221#define TP_PATH_LEN (MAX_EVENT_LENGTH * 2 + 1)
222static const char *tracepoint_id_to_name(u64 config)
223{
224 static char buf[TP_PATH_LEN];
225 struct tracepoint_path *path;
226
227 path = tracepoint_id_to_path(config);
228 if (path) {
229 snprintf(buf, TP_PATH_LEN, "%s:%s", path->system, path->name);
230 free(path->name);
231 free(path->system);
232 free(path);
233 } else
234 snprintf(buf, TP_PATH_LEN, "%s:%s", "unknown", "unknown");
235
236 return buf;
237}
238
239static int is_cache_op_valid(u8 cache_type, u8 cache_op)
240{
241 if (hw_cache_stat[cache_type] & COP(cache_op))
242 return 1; /* valid */
243 else
244 return 0; /* invalid */
245}
246
247static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result)
248{
249 static char name[50];
250
251 if (cache_result) {
252 sprintf(name, "%s-%s-%s", hw_cache[cache_type][0],
253 hw_cache_op[cache_op][0],
254 hw_cache_result[cache_result][0]);
255 } else {
256 sprintf(name, "%s-%s", hw_cache[cache_type][0],
257 hw_cache_op[cache_op][1]);
258 }
259
260 return name;
261}
262
263const char *event_type(int type) 220const char *event_type(int type)
264{ 221{
265 switch (type) { 222 switch (type) {
@@ -282,76 +239,6 @@ const char *event_type(int type)
282 return "unknown"; 239 return "unknown";
283} 240}
284 241
285const char *event_name(struct perf_evsel *evsel)
286{
287 u64 config = evsel->attr.config;
288 int type = evsel->attr.type;
289
290 if (type == PERF_TYPE_RAW || type == PERF_TYPE_HARDWARE) {
291 /*
292 * XXX minimal fix, see comment on perf_evsen__name, this static buffer
293 * will go away together with event_name in the next devel cycle.
294 */
295 static char bf[128];
296 perf_evsel__name(evsel, bf, sizeof(bf));
297 return bf;
298 }
299
300 if (evsel->name)
301 return evsel->name;
302
303 return __event_name(type, config);
304}
305
306const char *__event_name(int type, u64 config)
307{
308 static char buf[32];
309
310 if (type == PERF_TYPE_RAW) {
311 sprintf(buf, "raw 0x%" PRIx64, config);
312 return buf;
313 }
314
315 switch (type) {
316 case PERF_TYPE_HARDWARE:
317 return __perf_evsel__hw_name(config);
318
319 case PERF_TYPE_HW_CACHE: {
320 u8 cache_type, cache_op, cache_result;
321
322 cache_type = (config >> 0) & 0xff;
323 if (cache_type > PERF_COUNT_HW_CACHE_MAX)
324 return "unknown-ext-hardware-cache-type";
325
326 cache_op = (config >> 8) & 0xff;
327 if (cache_op > PERF_COUNT_HW_CACHE_OP_MAX)
328 return "unknown-ext-hardware-cache-op";
329
330 cache_result = (config >> 16) & 0xff;
331 if (cache_result > PERF_COUNT_HW_CACHE_RESULT_MAX)
332 return "unknown-ext-hardware-cache-result";
333
334 if (!is_cache_op_valid(cache_type, cache_op))
335 return "invalid-cache";
336
337 return event_cache_name(cache_type, cache_op, cache_result);
338 }
339
340 case PERF_TYPE_SOFTWARE:
341 if (config < PERF_COUNT_SW_MAX && sw_event_names[config])
342 return sw_event_names[config];
343 return "unknown-software";
344
345 case PERF_TYPE_TRACEPOINT:
346 return tracepoint_id_to_name(config);
347
348 default:
349 break;
350 }
351
352 return "unknown";
353}
354
355static int add_event(struct list_head **_list, int *idx, 242static int add_event(struct list_head **_list, int *idx,
356 struct perf_event_attr *attr, char *name) 243 struct perf_event_attr *attr, char *name)
357{ 244{
@@ -373,19 +260,20 @@ static int add_event(struct list_head **_list, int *idx,
373 return -ENOMEM; 260 return -ENOMEM;
374 } 261 }
375 262
376 evsel->name = strdup(name); 263 if (name)
264 evsel->name = strdup(name);
377 list_add_tail(&evsel->node, list); 265 list_add_tail(&evsel->node, list);
378 *_list = list; 266 *_list = list;
379 return 0; 267 return 0;
380} 268}
381 269
382static int parse_aliases(char *str, const char *names[][MAX_ALIASES], int size) 270static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size)
383{ 271{
384 int i, j; 272 int i, j;
385 int n, longest = -1; 273 int n, longest = -1;
386 274
387 for (i = 0; i < size; i++) { 275 for (i = 0; i < size; i++) {
388 for (j = 0; j < MAX_ALIASES && names[i][j]; j++) { 276 for (j = 0; j < PERF_EVSEL__MAX_ALIASES && names[i][j]; j++) {
389 n = strlen(names[i][j]); 277 n = strlen(names[i][j]);
390 if (n > longest && !strncasecmp(str, names[i][j], n)) 278 if (n > longest && !strncasecmp(str, names[i][j], n))
391 longest = n; 279 longest = n;
@@ -410,7 +298,7 @@ int parse_events_add_cache(struct list_head **list, int *idx,
410 * No fallback - if we cannot get a clear cache type 298 * No fallback - if we cannot get a clear cache type
411 * then bail out: 299 * then bail out:
412 */ 300 */
413 cache_type = parse_aliases(type, hw_cache, 301 cache_type = parse_aliases(type, perf_evsel__hw_cache,
414 PERF_COUNT_HW_CACHE_MAX); 302 PERF_COUNT_HW_CACHE_MAX);
415 if (cache_type == -1) 303 if (cache_type == -1)
416 return -EINVAL; 304 return -EINVAL;
@@ -423,18 +311,18 @@ int parse_events_add_cache(struct list_head **list, int *idx,
423 snprintf(name + n, MAX_NAME_LEN - n, "-%s\n", str); 311 snprintf(name + n, MAX_NAME_LEN - n, "-%s\n", str);
424 312
425 if (cache_op == -1) { 313 if (cache_op == -1) {
426 cache_op = parse_aliases(str, hw_cache_op, 314 cache_op = parse_aliases(str, perf_evsel__hw_cache_op,
427 PERF_COUNT_HW_CACHE_OP_MAX); 315 PERF_COUNT_HW_CACHE_OP_MAX);
428 if (cache_op >= 0) { 316 if (cache_op >= 0) {
429 if (!is_cache_op_valid(cache_type, cache_op)) 317 if (!perf_evsel__is_cache_op_valid(cache_type, cache_op))
430 return -EINVAL; 318 return -EINVAL;
431 continue; 319 continue;
432 } 320 }
433 } 321 }
434 322
435 if (cache_result == -1) { 323 if (cache_result == -1) {
436 cache_result = parse_aliases(str, hw_cache_result, 324 cache_result = parse_aliases(str, perf_evsel__hw_cache_result,
437 PERF_COUNT_HW_CACHE_RESULT_MAX); 325 PERF_COUNT_HW_CACHE_RESULT_MAX);
438 if (cache_result >= 0) 326 if (cache_result >= 0)
439 continue; 327 continue;
440 } 328 }
@@ -549,21 +437,31 @@ parse_breakpoint_type(const char *type, struct perf_event_attr *attr)
549 if (!type || !type[i]) 437 if (!type || !type[i])
550 break; 438 break;
551 439
440#define CHECK_SET_TYPE(bit) \
441do { \
442 if (attr->bp_type & bit) \
443 return -EINVAL; \
444 else \
445 attr->bp_type |= bit; \
446} while (0)
447
552 switch (type[i]) { 448 switch (type[i]) {
553 case 'r': 449 case 'r':
554 attr->bp_type |= HW_BREAKPOINT_R; 450 CHECK_SET_TYPE(HW_BREAKPOINT_R);
555 break; 451 break;
556 case 'w': 452 case 'w':
557 attr->bp_type |= HW_BREAKPOINT_W; 453 CHECK_SET_TYPE(HW_BREAKPOINT_W);
558 break; 454 break;
559 case 'x': 455 case 'x':
560 attr->bp_type |= HW_BREAKPOINT_X; 456 CHECK_SET_TYPE(HW_BREAKPOINT_X);
561 break; 457 break;
562 default: 458 default:
563 return -EINVAL; 459 return -EINVAL;
564 } 460 }
565 } 461 }
566 462
463#undef CHECK_SET_TYPE
464
567 if (!attr->bp_type) /* Default */ 465 if (!attr->bp_type) /* Default */
568 attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; 466 attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W;
569 467
@@ -574,7 +472,6 @@ int parse_events_add_breakpoint(struct list_head **list, int *idx,
574 void *ptr, char *type) 472 void *ptr, char *type)
575{ 473{
576 struct perf_event_attr attr; 474 struct perf_event_attr attr;
577 char name[MAX_NAME_LEN];
578 475
579 memset(&attr, 0, sizeof(attr)); 476 memset(&attr, 0, sizeof(attr));
580 attr.bp_addr = (unsigned long) ptr; 477 attr.bp_addr = (unsigned long) ptr;
@@ -593,8 +490,7 @@ int parse_events_add_breakpoint(struct list_head **list, int *idx,
593 490
594 attr.type = PERF_TYPE_BREAKPOINT; 491 attr.type = PERF_TYPE_BREAKPOINT;
595 492
596 snprintf(name, MAX_NAME_LEN, "mem:%p:%s", ptr, type ? type : "rw"); 493 return add_event(list, idx, &attr, NULL);
597 return add_event(list, idx, &attr, name);
598} 494}
599 495
600static int config_term(struct perf_event_attr *attr, 496static int config_term(struct perf_event_attr *attr,
@@ -666,8 +562,7 @@ int parse_events_add_numeric(struct list_head **list, int *idx,
666 config_attr(&attr, head_config, 1)) 562 config_attr(&attr, head_config, 1))
667 return -EINVAL; 563 return -EINVAL;
668 564
669 return add_event(list, idx, &attr, 565 return add_event(list, idx, &attr, NULL);
670 (char *) __event_name(type, config));
671} 566}
672 567
673static int parse_events__is_name_term(struct parse_events__term *term) 568static int parse_events__is_name_term(struct parse_events__term *term)
@@ -675,8 +570,7 @@ static int parse_events__is_name_term(struct parse_events__term *term)
675 return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME; 570 return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME;
676} 571}
677 572
678static char *pmu_event_name(struct perf_event_attr *attr, 573static char *pmu_event_name(struct list_head *head_terms)
679 struct list_head *head_terms)
680{ 574{
681 struct parse_events__term *term; 575 struct parse_events__term *term;
682 576
@@ -684,7 +578,7 @@ static char *pmu_event_name(struct perf_event_attr *attr,
684 if (parse_events__is_name_term(term)) 578 if (parse_events__is_name_term(term))
685 return term->val.str; 579 return term->val.str;
686 580
687 return (char *) __event_name(PERF_TYPE_RAW, attr->config); 581 return NULL;
688} 582}
689 583
690int parse_events_add_pmu(struct list_head **list, int *idx, 584int parse_events_add_pmu(struct list_head **list, int *idx,
@@ -699,6 +593,9 @@ int parse_events_add_pmu(struct list_head **list, int *idx,
699 593
700 memset(&attr, 0, sizeof(attr)); 594 memset(&attr, 0, sizeof(attr));
701 595
596 if (perf_pmu__check_alias(pmu, head_config))
597 return -EINVAL;
598
702 /* 599 /*
703 * Configure hardcoded terms first, no need to check 600 * Configure hardcoded terms first, no need to check
704 * return value when called with fail == 0 ;) 601 * return value when called with fail == 0 ;)
@@ -709,7 +606,7 @@ int parse_events_add_pmu(struct list_head **list, int *idx,
709 return -EINVAL; 606 return -EINVAL;
710 607
711 return add_event(list, idx, &attr, 608 return add_event(list, idx, &attr,
712 pmu_event_name(&attr, head_config)); 609 pmu_event_name(head_config));
713} 610}
714 611
715void parse_events_update_lists(struct list_head *list_event, 612void parse_events_update_lists(struct list_head *list_event,
@@ -787,27 +684,62 @@ int parse_events_modifier(struct list_head *list, char *str)
787 return 0; 684 return 0;
788} 685}
789 686
790int parse_events(struct perf_evlist *evlist, const char *str, int unset __used) 687static int parse_events__scanner(const char *str, void *data, int start_token)
791{ 688{
792 LIST_HEAD(list);
793 LIST_HEAD(list_tmp);
794 YY_BUFFER_STATE buffer; 689 YY_BUFFER_STATE buffer;
795 int ret, idx = evlist->nr_entries; 690 void *scanner;
691 int ret;
692
693 ret = parse_events_lex_init_extra(start_token, &scanner);
694 if (ret)
695 return ret;
796 696
797 buffer = parse_events__scan_string(str); 697 buffer = parse_events__scan_string(str, scanner);
798 698
799#ifdef PARSER_DEBUG 699#ifdef PARSER_DEBUG
800 parse_events_debug = 1; 700 parse_events_debug = 1;
801#endif 701#endif
802 ret = parse_events_parse(&list, &idx); 702 ret = parse_events_parse(data, scanner);
803 703
804 parse_events__flush_buffer(buffer); 704 parse_events__flush_buffer(buffer, scanner);
805 parse_events__delete_buffer(buffer); 705 parse_events__delete_buffer(buffer, scanner);
806 parse_events_lex_destroy(); 706 parse_events_lex_destroy(scanner);
707 return ret;
708}
709
710/*
711 * parse event config string, return a list of event terms.
712 */
713int parse_events_terms(struct list_head *terms, const char *str)
714{
715 struct parse_events_data__terms data = {
716 .terms = NULL,
717 };
718 int ret;
807 719
720 ret = parse_events__scanner(str, &data, PE_START_TERMS);
808 if (!ret) { 721 if (!ret) {
809 int entries = idx - evlist->nr_entries; 722 list_splice(data.terms, terms);
810 perf_evlist__splice_list_tail(evlist, &list, entries); 723 free(data.terms);
724 return 0;
725 }
726
727 parse_events__free_terms(data.terms);
728 return ret;
729}
730
731int parse_events(struct perf_evlist *evlist, const char *str, int unset __used)
732{
733 struct parse_events_data__events data = {
734 .list = LIST_HEAD_INIT(data.list),
735 .idx = evlist->nr_entries,
736 };
737 int ret;
738
739 ret = parse_events__scanner(str, &data, PE_START_EVENTS);
740 if (!ret) {
741 int entries = data.idx - evlist->nr_entries;
742 perf_evlist__splice_list_tail(evlist, &data.list, entries);
811 return 0; 743 return 0;
812 } 744 }
813 745
@@ -946,16 +878,13 @@ int is_valid_tracepoint(const char *event_string)
946 return 0; 878 return 0;
947} 879}
948 880
949void print_events_type(u8 type) 881static void __print_events_type(u8 type, struct event_symbol *syms,
882 unsigned max)
950{ 883{
951 struct event_symbol *syms = event_symbols;
952 unsigned int i;
953 char name[64]; 884 char name[64];
885 unsigned i;
954 886
955 for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { 887 for (i = 0; i < max ; i++, syms++) {
956 if (type != syms->type)
957 continue;
958
959 if (strlen(syms->alias)) 888 if (strlen(syms->alias))
960 snprintf(name, sizeof(name), "%s OR %s", 889 snprintf(name, sizeof(name), "%s OR %s",
961 syms->symbol, syms->alias); 890 syms->symbol, syms->alias);
@@ -967,19 +896,28 @@ void print_events_type(u8 type)
967 } 896 }
968} 897}
969 898
899void print_events_type(u8 type)
900{
901 if (type == PERF_TYPE_SOFTWARE)
902 __print_events_type(type, event_symbols_sw, PERF_COUNT_SW_MAX);
903 else
904 __print_events_type(type, event_symbols_hw, PERF_COUNT_HW_MAX);
905}
906
970int print_hwcache_events(const char *event_glob) 907int print_hwcache_events(const char *event_glob)
971{ 908{
972 unsigned int type, op, i, printed = 0; 909 unsigned int type, op, i, printed = 0;
910 char name[64];
973 911
974 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { 912 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
975 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { 913 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
976 /* skip invalid cache type */ 914 /* skip invalid cache type */
977 if (!is_cache_op_valid(type, op)) 915 if (!perf_evsel__is_cache_op_valid(type, op))
978 continue; 916 continue;
979 917
980 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { 918 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
981 char *name = event_cache_name(type, op, i); 919 __perf_evsel__hw_cache_type_op_res_name(type, op, i,
982 920 name, sizeof(name));
983 if (event_glob != NULL && !strglobmatch(name, event_glob)) 921 if (event_glob != NULL && !strglobmatch(name, event_glob))
984 continue; 922 continue;
985 923
@@ -993,26 +931,13 @@ int print_hwcache_events(const char *event_glob)
993 return printed; 931 return printed;
994} 932}
995 933
996/* 934static void print_symbol_events(const char *event_glob, unsigned type,
997 * Print the help text for the event symbols: 935 struct event_symbol *syms, unsigned max)
998 */
999void print_events(const char *event_glob)
1000{ 936{
1001 unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0; 937 unsigned i, printed = 0;
1002 struct event_symbol *syms = event_symbols;
1003 char name[MAX_NAME_LEN]; 938 char name[MAX_NAME_LEN];
1004 939
1005 printf("\n"); 940 for (i = 0; i < max; i++, syms++) {
1006 printf("List of pre-defined events (to be used in -e):\n");
1007
1008 for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
1009 type = syms->type;
1010
1011 if (type != prev_type && printed) {
1012 printf("\n");
1013 printed = 0;
1014 ntypes_printed++;
1015 }
1016 941
1017 if (event_glob != NULL && 942 if (event_glob != NULL &&
1018 !(strglobmatch(syms->symbol, event_glob) || 943 !(strglobmatch(syms->symbol, event_glob) ||
@@ -1023,17 +948,31 @@ void print_events(const char *event_glob)
1023 snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); 948 snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias);
1024 else 949 else
1025 strncpy(name, syms->symbol, MAX_NAME_LEN); 950 strncpy(name, syms->symbol, MAX_NAME_LEN);
1026 printf(" %-50s [%s]\n", name,
1027 event_type_descriptors[type]);
1028 951
1029 prev_type = type; 952 printf(" %-50s [%s]\n", name, event_type_descriptors[type]);
1030 ++printed; 953
954 printed++;
1031 } 955 }
1032 956
1033 if (ntypes_printed) { 957 if (printed)
1034 printed = 0;
1035 printf("\n"); 958 printf("\n");
1036 } 959}
960
961/*
962 * Print the help text for the event symbols:
963 */
964void print_events(const char *event_glob)
965{
966
967 printf("\n");
968 printf("List of pre-defined events (to be used in -e):\n");
969
970 print_symbol_events(event_glob, PERF_TYPE_HARDWARE,
971 event_symbols_hw, PERF_COUNT_HW_MAX);
972
973 print_symbol_events(event_glob, PERF_TYPE_SOFTWARE,
974 event_symbols_sw, PERF_COUNT_SW_MAX);
975
1037 print_hwcache_events(event_glob); 976 print_hwcache_events(event_glob);
1038 977
1039 if (event_glob != NULL) 978 if (event_glob != NULL)
@@ -1106,6 +1045,13 @@ int parse_events__term_str(struct parse_events__term **term,
1106 config, str, 0); 1045 config, str, 0);
1107} 1046}
1108 1047
1048int parse_events__term_clone(struct parse_events__term **new,
1049 struct parse_events__term *term)
1050{
1051 return new_term(new, term->type_val, term->type_term, term->config,
1052 term->val.str, term->val.num);
1053}
1054
1109void parse_events__free_terms(struct list_head *terms) 1055void parse_events__free_terms(struct list_head *terms)
1110{ 1056{
1111 struct parse_events__term *term, *h; 1057 struct parse_events__term *term, *h;
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 8cac57ab4ee6..ee9c218a193c 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -26,13 +26,12 @@ extern struct tracepoint_path *tracepoint_id_to_path(u64 config);
26extern bool have_tracepoints(struct list_head *evlist); 26extern bool have_tracepoints(struct list_head *evlist);
27 27
28const char *event_type(int type); 28const char *event_type(int type);
29const char *event_name(struct perf_evsel *event);
30extern const char *__event_name(int type, u64 config);
31 29
32extern int parse_events_option(const struct option *opt, const char *str, 30extern int parse_events_option(const struct option *opt, const char *str,
33 int unset); 31 int unset);
34extern int parse_events(struct perf_evlist *evlist, const char *str, 32extern int parse_events(struct perf_evlist *evlist, const char *str,
35 int unset); 33 int unset);
34extern int parse_events_terms(struct list_head *terms, const char *str);
36extern int parse_filter(const struct option *opt, const char *str, int unset); 35extern int parse_filter(const struct option *opt, const char *str, int unset);
37 36
38#define EVENTS_HELP_MAX (128*1024) 37#define EVENTS_HELP_MAX (128*1024)
@@ -63,11 +62,22 @@ struct parse_events__term {
63 struct list_head list; 62 struct list_head list;
64}; 63};
65 64
65struct parse_events_data__events {
66 struct list_head list;
67 int idx;
68};
69
70struct parse_events_data__terms {
71 struct list_head *terms;
72};
73
66int parse_events__is_hardcoded_term(struct parse_events__term *term); 74int parse_events__is_hardcoded_term(struct parse_events__term *term);
67int parse_events__term_num(struct parse_events__term **_term, 75int parse_events__term_num(struct parse_events__term **_term,
68 int type_term, char *config, long num); 76 int type_term, char *config, long num);
69int parse_events__term_str(struct parse_events__term **_term, 77int parse_events__term_str(struct parse_events__term **_term,
70 int type_term, char *config, char *str); 78 int type_term, char *config, char *str);
79int parse_events__term_clone(struct parse_events__term **new,
80 struct parse_events__term *term);
71void parse_events__free_terms(struct list_head *terms); 81void parse_events__free_terms(struct list_head *terms);
72int parse_events_modifier(struct list_head *list, char *str); 82int parse_events_modifier(struct list_head *list, char *str);
73int parse_events_add_tracepoint(struct list_head **list, int *idx, 83int parse_events_add_tracepoint(struct list_head **list, int *idx,
@@ -83,8 +93,7 @@ int parse_events_add_pmu(struct list_head **list, int *idx,
83 char *pmu , struct list_head *head_config); 93 char *pmu , struct list_head *head_config);
84void parse_events_update_lists(struct list_head *list_event, 94void parse_events_update_lists(struct list_head *list_event,
85 struct list_head *list_all); 95 struct list_head *list_all);
86void parse_events_error(struct list_head *list_all, 96void parse_events_error(void *data, void *scanner, char const *msg);
87 int *idx, char const *msg);
88int parse_events__test(void); 97int parse_events__test(void);
89 98
90void print_events(const char *event_glob); 99void print_events(const char *event_glob);
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 618a8e788399..384ca74c6b22 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -1,4 +1,6 @@
1 1
2%option reentrant
3%option bison-bridge
2%option prefix="parse_events_" 4%option prefix="parse_events_"
3%option stack 5%option stack
4 6
@@ -8,7 +10,10 @@
8#include "parse-events-bison.h" 10#include "parse-events-bison.h"
9#include "parse-events.h" 11#include "parse-events.h"
10 12
11static int __value(char *str, int base, int token) 13char *parse_events_get_text(yyscan_t yyscanner);
14YYSTYPE *parse_events_get_lval(yyscan_t yyscanner);
15
16static int __value(YYSTYPE *yylval, char *str, int base, int token)
12{ 17{
13 long num; 18 long num;
14 19
@@ -17,35 +22,48 @@ static int __value(char *str, int base, int token)
17 if (errno) 22 if (errno)
18 return PE_ERROR; 23 return PE_ERROR;
19 24
20 parse_events_lval.num = num; 25 yylval->num = num;
21 return token; 26 return token;
22} 27}
23 28
24static int value(int base) 29static int value(yyscan_t scanner, int base)
25{ 30{
26 return __value(parse_events_text, base, PE_VALUE); 31 YYSTYPE *yylval = parse_events_get_lval(scanner);
32 char *text = parse_events_get_text(scanner);
33
34 return __value(yylval, text, base, PE_VALUE);
27} 35}
28 36
29static int raw(void) 37static int raw(yyscan_t scanner)
30{ 38{
31 return __value(parse_events_text + 1, 16, PE_RAW); 39 YYSTYPE *yylval = parse_events_get_lval(scanner);
40 char *text = parse_events_get_text(scanner);
41
42 return __value(yylval, text + 1, 16, PE_RAW);
32} 43}
33 44
34static int str(int token) 45static int str(yyscan_t scanner, int token)
35{ 46{
36 parse_events_lval.str = strdup(parse_events_text); 47 YYSTYPE *yylval = parse_events_get_lval(scanner);
48 char *text = parse_events_get_text(scanner);
49
50 yylval->str = strdup(text);
37 return token; 51 return token;
38} 52}
39 53
40static int sym(int type, int config) 54static int sym(yyscan_t scanner, int type, int config)
41{ 55{
42 parse_events_lval.num = (type << 16) + config; 56 YYSTYPE *yylval = parse_events_get_lval(scanner);
43 return PE_VALUE_SYM; 57
58 yylval->num = (type << 16) + config;
59 return type == PERF_TYPE_HARDWARE ? PE_VALUE_SYM_HW : PE_VALUE_SYM_SW;
44} 60}
45 61
46static int term(int type) 62static int term(yyscan_t scanner, int type)
47{ 63{
48 parse_events_lval.num = type; 64 YYSTYPE *yylval = parse_events_get_lval(scanner);
65
66 yylval->num = type;
49 return PE_TERM; 67 return PE_TERM;
50} 68}
51 69
@@ -58,28 +76,41 @@ num_hex 0x[a-fA-F0-9]+
58num_raw_hex [a-fA-F0-9]+ 76num_raw_hex [a-fA-F0-9]+
59name [a-zA-Z_*?][a-zA-Z0-9_*?]* 77name [a-zA-Z_*?][a-zA-Z0-9_*?]*
60modifier_event [ukhpGH]{1,8} 78modifier_event [ukhpGH]{1,8}
61modifier_bp [rwx] 79modifier_bp [rwx]{1,3}
62 80
63%% 81%%
64cpu-cycles|cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); } 82
65stalled-cycles-frontend|idle-cycles-frontend { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } 83%{
66stalled-cycles-backend|idle-cycles-backend { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); } 84 {
67instructions { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS); } 85 int start_token;
68cache-references { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES); } 86
69cache-misses { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES); } 87 start_token = (int) parse_events_get_extra(yyscanner);
70branch-instructions|branches { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); } 88 if (start_token) {
71branch-misses { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES); } 89 parse_events_set_extra(NULL, yyscanner);
72bus-cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES); } 90 return start_token;
73ref-cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); } 91 }
74cpu-clock { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK); } 92 }
75task-clock { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK); } 93%}
76page-faults|faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS); } 94
77minor-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN); } 95cpu-cycles|cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); }
78major-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ); } 96stalled-cycles-frontend|idle-cycles-frontend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); }
79context-switches|cs { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES); } 97stalled-cycles-backend|idle-cycles-backend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); }
80cpu-migrations|migrations { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS); } 98instructions { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS); }
81alignment-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); } 99cache-references { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES); }
82emulation-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } 100cache-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES); }
101branch-instructions|branches { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); }
102branch-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES); }
103bus-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES); }
104ref-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); }
105cpu-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK); }
106task-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK); }
107page-faults|faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS); }
108minor-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN); }
109major-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ); }
110context-switches|cs { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES); }
111cpu-migrations|migrations { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS); }
112alignment-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); }
113emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); }
83 114
84L1-dcache|l1-d|l1d|L1-data | 115L1-dcache|l1-d|l1d|L1-data |
85L1-icache|l1-i|l1i|L1-instruction | 116L1-icache|l1-i|l1i|L1-instruction |
@@ -87,14 +118,14 @@ LLC|L2 |
87dTLB|d-tlb|Data-TLB | 118dTLB|d-tlb|Data-TLB |
88iTLB|i-tlb|Instruction-TLB | 119iTLB|i-tlb|Instruction-TLB |
89branch|branches|bpu|btb|bpc | 120branch|branches|bpu|btb|bpc |
90node { return str(PE_NAME_CACHE_TYPE); } 121node { return str(yyscanner, PE_NAME_CACHE_TYPE); }
91 122
92load|loads|read | 123load|loads|read |
93store|stores|write | 124store|stores|write |
94prefetch|prefetches | 125prefetch|prefetches |
95speculative-read|speculative-load | 126speculative-read|speculative-load |
96refs|Reference|ops|access | 127refs|Reference|ops|access |
97misses|miss { return str(PE_NAME_CACHE_OP_RESULT); } 128misses|miss { return str(yyscanner, PE_NAME_CACHE_OP_RESULT); }
98 129
99 /* 130 /*
100 * These are event config hardcoded term names to be specified 131 * These are event config hardcoded term names to be specified
@@ -102,38 +133,39 @@ misses|miss { return str(PE_NAME_CACHE_OP_RESULT); }
102 * so we can put them here directly. In case the we have a conflict 133 * so we can put them here directly. In case the we have a conflict
103 * in future, this needs to go into '//' condition block. 134 * in future, this needs to go into '//' condition block.
104 */ 135 */
105config { return term(PARSE_EVENTS__TERM_TYPE_CONFIG); } 136config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG); }
106config1 { return term(PARSE_EVENTS__TERM_TYPE_CONFIG1); } 137config1 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG1); }
107config2 { return term(PARSE_EVENTS__TERM_TYPE_CONFIG2); } 138config2 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG2); }
108name { return term(PARSE_EVENTS__TERM_TYPE_NAME); } 139name { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NAME); }
109period { return term(PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); } 140period { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); }
110branch_type { return term(PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); } 141branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); }
111 142
112mem: { BEGIN(mem); return PE_PREFIX_MEM; } 143mem: { BEGIN(mem); return PE_PREFIX_MEM; }
113r{num_raw_hex} { return raw(); } 144r{num_raw_hex} { return raw(yyscanner); }
114{num_dec} { return value(10); } 145{num_dec} { return value(yyscanner, 10); }
115{num_hex} { return value(16); } 146{num_hex} { return value(yyscanner, 16); }
116 147
117{modifier_event} { return str(PE_MODIFIER_EVENT); } 148{modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); }
118{name} { return str(PE_NAME); } 149{name} { return str(yyscanner, PE_NAME); }
119"/" { return '/'; } 150"/" { return '/'; }
120- { return '-'; } 151- { return '-'; }
121, { return ','; } 152, { return ','; }
122: { return ':'; } 153: { return ':'; }
123= { return '='; } 154= { return '='; }
155\n { }
124 156
125<mem>{ 157<mem>{
126{modifier_bp} { return str(PE_MODIFIER_BP); } 158{modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); }
127: { return ':'; } 159: { return ':'; }
128{num_dec} { return value(10); } 160{num_dec} { return value(yyscanner, 10); }
129{num_hex} { return value(16); } 161{num_hex} { return value(yyscanner, 16); }
130 /* 162 /*
131 * We need to separate 'mem:' scanner part, in order to get specific 163 * We need to separate 'mem:' scanner part, in order to get specific
132 * modifier bits parsed out. Otherwise we would need to handle PE_NAME 164 * modifier bits parsed out. Otherwise we would need to handle PE_NAME
133 * and we'd need to parse it manually. During the escape from <mem> 165 * and we'd need to parse it manually. During the escape from <mem>
134 * state we need to put the escaping char back, so we dont miss it. 166 * state we need to put the escaping char back, so we dont miss it.
135 */ 167 */
136. { unput(*parse_events_text); BEGIN(INITIAL); } 168. { unput(*yytext); BEGIN(INITIAL); }
137 /* 169 /*
138 * We destroy the scanner after reaching EOF, 170 * We destroy the scanner after reaching EOF,
139 * but anyway just to be sure get back to INIT state. 171 * but anyway just to be sure get back to INIT state.
@@ -143,7 +175,7 @@ r{num_raw_hex} { return raw(); }
143 175
144%% 176%%
145 177
146int parse_events_wrap(void) 178int parse_events_wrap(void *scanner __used)
147{ 179{
148 return 1; 180 return 1;
149} 181}
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 362cc59332ae..2bc5fbff2b5d 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -1,7 +1,8 @@
1 1%pure-parser
2%name-prefix "parse_events_" 2%name-prefix "parse_events_"
3%parse-param {struct list_head *list_all} 3%parse-param {void *_data}
4%parse-param {int *idx} 4%parse-param {void *scanner}
5%lex-param {void* scanner}
5 6
6%{ 7%{
7 8
@@ -12,8 +13,9 @@
12#include "types.h" 13#include "types.h"
13#include "util.h" 14#include "util.h"
14#include "parse-events.h" 15#include "parse-events.h"
16#include "parse-events-bison.h"
15 17
16extern int parse_events_lex (void); 18extern int parse_events_lex (YYSTYPE* lvalp, void* scanner);
17 19
18#define ABORT_ON(val) \ 20#define ABORT_ON(val) \
19do { \ 21do { \
@@ -23,14 +25,16 @@ do { \
23 25
24%} 26%}
25 27
26%token PE_VALUE PE_VALUE_SYM PE_RAW PE_TERM 28%token PE_START_EVENTS PE_START_TERMS
29%token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM
27%token PE_NAME 30%token PE_NAME
28%token PE_MODIFIER_EVENT PE_MODIFIER_BP 31%token PE_MODIFIER_EVENT PE_MODIFIER_BP
29%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT 32%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
30%token PE_PREFIX_MEM PE_PREFIX_RAW 33%token PE_PREFIX_MEM PE_PREFIX_RAW
31%token PE_ERROR 34%token PE_ERROR
32%type <num> PE_VALUE 35%type <num> PE_VALUE
33%type <num> PE_VALUE_SYM 36%type <num> PE_VALUE_SYM_HW
37%type <num> PE_VALUE_SYM_SW
34%type <num> PE_RAW 38%type <num> PE_RAW
35%type <num> PE_TERM 39%type <num> PE_TERM
36%type <str> PE_NAME 40%type <str> PE_NAME
@@ -38,6 +42,7 @@ do { \
38%type <str> PE_NAME_CACHE_OP_RESULT 42%type <str> PE_NAME_CACHE_OP_RESULT
39%type <str> PE_MODIFIER_EVENT 43%type <str> PE_MODIFIER_EVENT
40%type <str> PE_MODIFIER_BP 44%type <str> PE_MODIFIER_BP
45%type <num> value_sym
41%type <head> event_config 46%type <head> event_config
42%type <term> event_term 47%type <term> event_term
43%type <head> event_pmu 48%type <head> event_pmu
@@ -58,24 +63,33 @@ do { \
58} 63}
59%% 64%%
60 65
66start:
67PE_START_EVENTS events
68|
69PE_START_TERMS terms
70
61events: 71events:
62events ',' event | event 72events ',' event | event
63 73
64event: 74event:
65event_def PE_MODIFIER_EVENT 75event_def PE_MODIFIER_EVENT
66{ 76{
77 struct parse_events_data__events *data = _data;
78
67 /* 79 /*
68 * Apply modifier on all events added by single event definition 80 * Apply modifier on all events added by single event definition
69 * (there could be more events added for multiple tracepoint 81 * (there could be more events added for multiple tracepoint
70 * definitions via '*?'. 82 * definitions via '*?'.
71 */ 83 */
72 ABORT_ON(parse_events_modifier($1, $2)); 84 ABORT_ON(parse_events_modifier($1, $2));
73 parse_events_update_lists($1, list_all); 85 parse_events_update_lists($1, &data->list);
74} 86}
75| 87|
76event_def 88event_def
77{ 89{
78 parse_events_update_lists($1, list_all); 90 struct parse_events_data__events *data = _data;
91
92 parse_events_update_lists($1, &data->list);
79} 93}
80 94
81event_def: event_pmu | 95event_def: event_pmu |
@@ -89,104 +103,131 @@ event_def: event_pmu |
89event_pmu: 103event_pmu:
90PE_NAME '/' event_config '/' 104PE_NAME '/' event_config '/'
91{ 105{
106 struct parse_events_data__events *data = _data;
92 struct list_head *list = NULL; 107 struct list_head *list = NULL;
93 108
94 ABORT_ON(parse_events_add_pmu(&list, idx, $1, $3)); 109 ABORT_ON(parse_events_add_pmu(&list, &data->idx, $1, $3));
95 parse_events__free_terms($3); 110 parse_events__free_terms($3);
96 $$ = list; 111 $$ = list;
97} 112}
98 113
114value_sym:
115PE_VALUE_SYM_HW
116|
117PE_VALUE_SYM_SW
118
99event_legacy_symbol: 119event_legacy_symbol:
100PE_VALUE_SYM '/' event_config '/' 120value_sym '/' event_config '/'
101{ 121{
122 struct parse_events_data__events *data = _data;
102 struct list_head *list = NULL; 123 struct list_head *list = NULL;
103 int type = $1 >> 16; 124 int type = $1 >> 16;
104 int config = $1 & 255; 125 int config = $1 & 255;
105 126
106 ABORT_ON(parse_events_add_numeric(&list, idx, type, config, $3)); 127 ABORT_ON(parse_events_add_numeric(&list, &data->idx,
128 type, config, $3));
107 parse_events__free_terms($3); 129 parse_events__free_terms($3);
108 $$ = list; 130 $$ = list;
109} 131}
110| 132|
111PE_VALUE_SYM sep_slash_dc 133value_sym sep_slash_dc
112{ 134{
135 struct parse_events_data__events *data = _data;
113 struct list_head *list = NULL; 136 struct list_head *list = NULL;
114 int type = $1 >> 16; 137 int type = $1 >> 16;
115 int config = $1 & 255; 138 int config = $1 & 255;
116 139
117 ABORT_ON(parse_events_add_numeric(&list, idx, type, config, NULL)); 140 ABORT_ON(parse_events_add_numeric(&list, &data->idx,
141 type, config, NULL));
118 $$ = list; 142 $$ = list;
119} 143}
120 144
121event_legacy_cache: 145event_legacy_cache:
122PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT 146PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT
123{ 147{
148 struct parse_events_data__events *data = _data;
124 struct list_head *list = NULL; 149 struct list_head *list = NULL;
125 150
126 ABORT_ON(parse_events_add_cache(&list, idx, $1, $3, $5)); 151 ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, $5));
127 $$ = list; 152 $$ = list;
128} 153}
129| 154|
130PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT 155PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT
131{ 156{
157 struct parse_events_data__events *data = _data;
132 struct list_head *list = NULL; 158 struct list_head *list = NULL;
133 159
134 ABORT_ON(parse_events_add_cache(&list, idx, $1, $3, NULL)); 160 ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, NULL));
135 $$ = list; 161 $$ = list;
136} 162}
137| 163|
138PE_NAME_CACHE_TYPE 164PE_NAME_CACHE_TYPE
139{ 165{
166 struct parse_events_data__events *data = _data;
140 struct list_head *list = NULL; 167 struct list_head *list = NULL;
141 168
142 ABORT_ON(parse_events_add_cache(&list, idx, $1, NULL, NULL)); 169 ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, NULL, NULL));
143 $$ = list; 170 $$ = list;
144} 171}
145 172
146event_legacy_mem: 173event_legacy_mem:
147PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc 174PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
148{ 175{
176 struct parse_events_data__events *data = _data;
149 struct list_head *list = NULL; 177 struct list_head *list = NULL;
150 178
151 ABORT_ON(parse_events_add_breakpoint(&list, idx, (void *) $2, $4)); 179 ABORT_ON(parse_events_add_breakpoint(&list, &data->idx,
180 (void *) $2, $4));
152 $$ = list; 181 $$ = list;
153} 182}
154| 183|
155PE_PREFIX_MEM PE_VALUE sep_dc 184PE_PREFIX_MEM PE_VALUE sep_dc
156{ 185{
186 struct parse_events_data__events *data = _data;
157 struct list_head *list = NULL; 187 struct list_head *list = NULL;
158 188
159 ABORT_ON(parse_events_add_breakpoint(&list, idx, (void *) $2, NULL)); 189 ABORT_ON(parse_events_add_breakpoint(&list, &data->idx,
190 (void *) $2, NULL));
160 $$ = list; 191 $$ = list;
161} 192}
162 193
163event_legacy_tracepoint: 194event_legacy_tracepoint:
164PE_NAME ':' PE_NAME 195PE_NAME ':' PE_NAME
165{ 196{
197 struct parse_events_data__events *data = _data;
166 struct list_head *list = NULL; 198 struct list_head *list = NULL;
167 199
168 ABORT_ON(parse_events_add_tracepoint(&list, idx, $1, $3)); 200 ABORT_ON(parse_events_add_tracepoint(&list, &data->idx, $1, $3));
169 $$ = list; 201 $$ = list;
170} 202}
171 203
172event_legacy_numeric: 204event_legacy_numeric:
173PE_VALUE ':' PE_VALUE 205PE_VALUE ':' PE_VALUE
174{ 206{
207 struct parse_events_data__events *data = _data;
175 struct list_head *list = NULL; 208 struct list_head *list = NULL;
176 209
177 ABORT_ON(parse_events_add_numeric(&list, idx, $1, $3, NULL)); 210 ABORT_ON(parse_events_add_numeric(&list, &data->idx, $1, $3, NULL));
178 $$ = list; 211 $$ = list;
179} 212}
180 213
181event_legacy_raw: 214event_legacy_raw:
182PE_RAW 215PE_RAW
183{ 216{
217 struct parse_events_data__events *data = _data;
184 struct list_head *list = NULL; 218 struct list_head *list = NULL;
185 219
186 ABORT_ON(parse_events_add_numeric(&list, idx, PERF_TYPE_RAW, $1, NULL)); 220 ABORT_ON(parse_events_add_numeric(&list, &data->idx,
221 PERF_TYPE_RAW, $1, NULL));
187 $$ = list; 222 $$ = list;
188} 223}
189 224
225terms: event_config
226{
227 struct parse_events_data__terms *data = _data;
228 data->terms = $1;
229}
230
190event_config: 231event_config:
191event_config ',' event_term 232event_config ',' event_term
192{ 233{
@@ -267,8 +308,7 @@ sep_slash_dc: '/' | ':' |
267 308
268%% 309%%
269 310
270void parse_events_error(struct list_head *list_all __used, 311void parse_events_error(void *data __used, void *scanner __used,
271 int *idx __used,
272 char const *msg __used) 312 char const *msg __used)
273{ 313{
274} 314}
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index a119a5371699..67715a42cd6d 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -72,7 +72,7 @@ static int pmu_format(char *name, struct list_head *format)
72 "%s/bus/event_source/devices/%s/format", sysfs, name); 72 "%s/bus/event_source/devices/%s/format", sysfs, name);
73 73
74 if (stat(path, &st) < 0) 74 if (stat(path, &st) < 0)
75 return -1; 75 return 0; /* no error if format does not exist */
76 76
77 if (pmu_format_parse(path, format)) 77 if (pmu_format_parse(path, format))
78 return -1; 78 return -1;
@@ -80,6 +80,114 @@ static int pmu_format(char *name, struct list_head *format)
80 return 0; 80 return 0;
81} 81}
82 82
83static int perf_pmu__new_alias(struct list_head *list, char *name, FILE *file)
84{
85 struct perf_pmu__alias *alias;
86 char buf[256];
87 int ret;
88
89 ret = fread(buf, 1, sizeof(buf), file);
90 if (ret == 0)
91 return -EINVAL;
92 buf[ret] = 0;
93
94 alias = malloc(sizeof(*alias));
95 if (!alias)
96 return -ENOMEM;
97
98 INIT_LIST_HEAD(&alias->terms);
99 ret = parse_events_terms(&alias->terms, buf);
100 if (ret) {
101 free(alias);
102 return ret;
103 }
104
105 alias->name = strdup(name);
106 list_add_tail(&alias->list, list);
107 return 0;
108}
109
110/*
111 * Process all the sysfs attributes located under the directory
112 * specified in 'dir' parameter.
113 */
114static int pmu_aliases_parse(char *dir, struct list_head *head)
115{
116 struct dirent *evt_ent;
117 DIR *event_dir;
118 int ret = 0;
119
120 event_dir = opendir(dir);
121 if (!event_dir)
122 return -EINVAL;
123
124 while (!ret && (evt_ent = readdir(event_dir))) {
125 char path[PATH_MAX];
126 char *name = evt_ent->d_name;
127 FILE *file;
128
129 if (!strcmp(name, ".") || !strcmp(name, ".."))
130 continue;
131
132 snprintf(path, PATH_MAX, "%s/%s", dir, name);
133
134 ret = -EINVAL;
135 file = fopen(path, "r");
136 if (!file)
137 break;
138 ret = perf_pmu__new_alias(head, name, file);
139 fclose(file);
140 }
141
142 closedir(event_dir);
143 return ret;
144}
145
146/*
147 * Reading the pmu event aliases definition, which should be located at:
148 * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
149 */
150static int pmu_aliases(char *name, struct list_head *head)
151{
152 struct stat st;
153 char path[PATH_MAX];
154 const char *sysfs;
155
156 sysfs = sysfs_find_mountpoint();
157 if (!sysfs)
158 return -1;
159
160 snprintf(path, PATH_MAX,
161 "%s/bus/event_source/devices/%s/events", sysfs, name);
162
163 if (stat(path, &st) < 0)
164 return -1;
165
166 if (pmu_aliases_parse(path, head))
167 return -1;
168
169 return 0;
170}
171
172static int pmu_alias_terms(struct perf_pmu__alias *alias,
173 struct list_head *terms)
174{
175 struct parse_events__term *term, *clone;
176 LIST_HEAD(list);
177 int ret;
178
179 list_for_each_entry(term, &alias->terms, list) {
180 ret = parse_events__term_clone(&clone, term);
181 if (ret) {
182 parse_events__free_terms(&list);
183 return ret;
184 }
185 list_add_tail(&clone->list, &list);
186 }
187 list_splice(&list, terms);
188 return 0;
189}
190
83/* 191/*
84 * Reading/parsing the default pmu type value, which should be 192 * Reading/parsing the default pmu type value, which should be
85 * located at: 193 * located at:
@@ -118,6 +226,7 @@ static struct perf_pmu *pmu_lookup(char *name)
118{ 226{
119 struct perf_pmu *pmu; 227 struct perf_pmu *pmu;
120 LIST_HEAD(format); 228 LIST_HEAD(format);
229 LIST_HEAD(aliases);
121 __u32 type; 230 __u32 type;
122 231
123 /* 232 /*
@@ -135,10 +244,15 @@ static struct perf_pmu *pmu_lookup(char *name)
135 if (!pmu) 244 if (!pmu)
136 return NULL; 245 return NULL;
137 246
247 pmu_aliases(name, &aliases);
248
138 INIT_LIST_HEAD(&pmu->format); 249 INIT_LIST_HEAD(&pmu->format);
250 INIT_LIST_HEAD(&pmu->aliases);
139 list_splice(&format, &pmu->format); 251 list_splice(&format, &pmu->format);
252 list_splice(&aliases, &pmu->aliases);
140 pmu->name = strdup(name); 253 pmu->name = strdup(name);
141 pmu->type = type; 254 pmu->type = type;
255 list_add_tail(&pmu->list, &pmus);
142 return pmu; 256 return pmu;
143} 257}
144 258
@@ -279,6 +393,59 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
279 return pmu_config(&pmu->format, attr, head_terms); 393 return pmu_config(&pmu->format, attr, head_terms);
280} 394}
281 395
396static struct perf_pmu__alias *pmu_find_alias(struct perf_pmu *pmu,
397 struct parse_events__term *term)
398{
399 struct perf_pmu__alias *alias;
400 char *name;
401
402 if (parse_events__is_hardcoded_term(term))
403 return NULL;
404
405 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
406 if (term->val.num != 1)
407 return NULL;
408 if (pmu_find_format(&pmu->format, term->config))
409 return NULL;
410 name = term->config;
411 } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
412 if (strcasecmp(term->config, "event"))
413 return NULL;
414 name = term->val.str;
415 } else {
416 return NULL;
417 }
418
419 list_for_each_entry(alias, &pmu->aliases, list) {
420 if (!strcasecmp(alias->name, name))
421 return alias;
422 }
423 return NULL;
424}
425
426/*
427 * Find alias in the terms list and replace it with the terms
428 * defined for the alias
429 */
430int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms)
431{
432 struct parse_events__term *term, *h;
433 struct perf_pmu__alias *alias;
434 int ret;
435
436 list_for_each_entry_safe(term, h, head_terms, list) {
437 alias = pmu_find_alias(pmu, term);
438 if (!alias)
439 continue;
440 ret = pmu_alias_terms(alias, &term->list);
441 if (ret)
442 return ret;
443 list_del(&term->list);
444 free(term);
445 }
446 return 0;
447}
448
282int perf_pmu__new_format(struct list_head *list, char *name, 449int perf_pmu__new_format(struct list_head *list, char *name,
283 int config, unsigned long *bits) 450 int config, unsigned long *bits)
284{ 451{
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 68c0db965e1f..535f2c5258ab 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -19,17 +19,26 @@ struct perf_pmu__format {
19 struct list_head list; 19 struct list_head list;
20}; 20};
21 21
22struct perf_pmu__alias {
23 char *name;
24 struct list_head terms;
25 struct list_head list;
26};
27
22struct perf_pmu { 28struct perf_pmu {
23 char *name; 29 char *name;
24 __u32 type; 30 __u32 type;
25 struct list_head format; 31 struct list_head format;
32 struct list_head aliases;
26 struct list_head list; 33 struct list_head list;
27}; 34};
28 35
29struct perf_pmu *perf_pmu__find(char *name); 36struct perf_pmu *perf_pmu__find(char *name);
30int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, 37int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
31 struct list_head *head_terms); 38 struct list_head *head_terms);
32 39int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms);
40struct list_head *perf_pmu__alias(struct perf_pmu *pmu,
41 struct list_head *head_terms);
33int perf_pmu_wrap(void); 42int perf_pmu_wrap(void);
34void perf_pmu_error(struct list_head *list, char *name, char const *msg); 43void perf_pmu_error(struct list_head *list, char *name, char const *msg);
35 44
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index 4c1b3d72a1d2..02dfa19a467f 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -209,6 +209,10 @@ static void define_event_symbols(struct event_format *event,
209 define_symbolic_values(args->symbol.symbols, ev_name, 209 define_symbolic_values(args->symbol.symbols, ev_name,
210 cur_field_name); 210 cur_field_name);
211 break; 211 break;
212 case PRINT_HEX:
213 define_event_symbols(event, ev_name, args->hex.field);
214 define_event_symbols(event, ev_name, args->hex.size);
215 break;
212 case PRINT_BSTRING: 216 case PRINT_BSTRING:
213 case PRINT_DYNAMIC_ARRAY: 217 case PRINT_DYNAMIC_ARRAY:
214 case PRINT_STRING: 218 case PRINT_STRING:
@@ -233,7 +237,8 @@ static void define_event_symbols(struct event_format *event,
233 define_event_symbols(event, ev_name, args->next); 237 define_event_symbols(event, ev_name, args->next);
234} 238}
235 239
236static inline struct event_format *find_cache_event(int type) 240static inline
241struct event_format *find_cache_event(struct pevent *pevent, int type)
237{ 242{
238 static char ev_name[256]; 243 static char ev_name[256];
239 struct event_format *event; 244 struct event_format *event;
@@ -241,7 +246,7 @@ static inline struct event_format *find_cache_event(int type)
241 if (events[type]) 246 if (events[type])
242 return events[type]; 247 return events[type];
243 248
244 events[type] = event = trace_find_event(type); 249 events[type] = event = pevent_find_event(pevent, type);
245 if (!event) 250 if (!event)
246 return NULL; 251 return NULL;
247 252
@@ -252,7 +257,8 @@ static inline struct event_format *find_cache_event(int type)
252 return event; 257 return event;
253} 258}
254 259
255static void perl_process_tracepoint(union perf_event *pevent __unused, 260static void perl_process_tracepoint(union perf_event *perf_event __unused,
261 struct pevent *pevent,
256 struct perf_sample *sample, 262 struct perf_sample *sample,
257 struct perf_evsel *evsel, 263 struct perf_evsel *evsel,
258 struct machine *machine __unused, 264 struct machine *machine __unused,
@@ -275,13 +281,13 @@ static void perl_process_tracepoint(union perf_event *pevent __unused,
275 if (evsel->attr.type != PERF_TYPE_TRACEPOINT) 281 if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
276 return; 282 return;
277 283
278 type = trace_parse_common_type(data); 284 type = trace_parse_common_type(pevent, data);
279 285
280 event = find_cache_event(type); 286 event = find_cache_event(pevent, type);
281 if (!event) 287 if (!event)
282 die("ug! no event found for type %d", type); 288 die("ug! no event found for type %d", type);
283 289
284 pid = trace_parse_common_pid(data); 290 pid = trace_parse_common_pid(pevent, data);
285 291
286 sprintf(handler, "%s::%s", event->system, event->name); 292 sprintf(handler, "%s::%s", event->system, event->name);
287 293
@@ -314,7 +320,8 @@ static void perl_process_tracepoint(union perf_event *pevent __unused,
314 offset = field->offset; 320 offset = field->offset;
315 XPUSHs(sv_2mortal(newSVpv((char *)data + offset, 0))); 321 XPUSHs(sv_2mortal(newSVpv((char *)data + offset, 0)));
316 } else { /* FIELD_IS_NUMERIC */ 322 } else { /* FIELD_IS_NUMERIC */
317 val = read_size(data + field->offset, field->size); 323 val = read_size(pevent, data + field->offset,
324 field->size);
318 if (field->flags & FIELD_IS_SIGNED) { 325 if (field->flags & FIELD_IS_SIGNED) {
319 XPUSHs(sv_2mortal(newSViv(val))); 326 XPUSHs(sv_2mortal(newSViv(val)));
320 } else { 327 } else {
@@ -368,14 +375,15 @@ static void perl_process_event_generic(union perf_event *pevent __unused,
368 LEAVE; 375 LEAVE;
369} 376}
370 377
371static void perl_process_event(union perf_event *pevent, 378static void perl_process_event(union perf_event *event,
379 struct pevent *pevent,
372 struct perf_sample *sample, 380 struct perf_sample *sample,
373 struct perf_evsel *evsel, 381 struct perf_evsel *evsel,
374 struct machine *machine, 382 struct machine *machine,
375 struct thread *thread) 383 struct thread *thread)
376{ 384{
377 perl_process_tracepoint(pevent, sample, evsel, machine, thread); 385 perl_process_tracepoint(event, pevent, sample, evsel, machine, thread);
378 perl_process_event_generic(pevent, sample, evsel, machine, thread); 386 perl_process_event_generic(event, sample, evsel, machine, thread);
379} 387}
380 388
381static void run_start_sub(void) 389static void run_start_sub(void)
@@ -448,7 +456,7 @@ static int perl_stop_script(void)
448 return 0; 456 return 0;
449} 457}
450 458
451static int perl_generate_script(const char *outfile) 459static int perl_generate_script(struct pevent *pevent, const char *outfile)
452{ 460{
453 struct event_format *event = NULL; 461 struct event_format *event = NULL;
454 struct format_field *f; 462 struct format_field *f;
@@ -495,7 +503,7 @@ static int perl_generate_script(const char *outfile)
495 fprintf(ofp, "sub trace_begin\n{\n\t# optional\n}\n\n"); 503 fprintf(ofp, "sub trace_begin\n{\n\t# optional\n}\n\n");
496 fprintf(ofp, "sub trace_end\n{\n\t# optional\n}\n\n"); 504 fprintf(ofp, "sub trace_end\n{\n\t# optional\n}\n\n");
497 505
498 while ((event = trace_find_next_event(event))) { 506 while ((event = trace_find_next_event(pevent, event))) {
499 fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name); 507 fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name);
500 fprintf(ofp, "\tmy ("); 508 fprintf(ofp, "\tmy (");
501 509
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index acb9795286c4..ce4d1b0c3862 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -166,6 +166,10 @@ static void define_event_symbols(struct event_format *event,
166 define_values(PRINT_SYMBOL, args->symbol.symbols, ev_name, 166 define_values(PRINT_SYMBOL, args->symbol.symbols, ev_name,
167 cur_field_name); 167 cur_field_name);
168 break; 168 break;
169 case PRINT_HEX:
170 define_event_symbols(event, ev_name, args->hex.field);
171 define_event_symbols(event, ev_name, args->hex.size);
172 break;
169 case PRINT_STRING: 173 case PRINT_STRING:
170 break; 174 break;
171 case PRINT_TYPE: 175 case PRINT_TYPE:
@@ -190,7 +194,8 @@ static void define_event_symbols(struct event_format *event,
190 define_event_symbols(event, ev_name, args->next); 194 define_event_symbols(event, ev_name, args->next);
191} 195}
192 196
193static inline struct event_format *find_cache_event(int type) 197static inline
198struct event_format *find_cache_event(struct pevent *pevent, int type)
194{ 199{
195 static char ev_name[256]; 200 static char ev_name[256];
196 struct event_format *event; 201 struct event_format *event;
@@ -198,7 +203,7 @@ static inline struct event_format *find_cache_event(int type)
198 if (events[type]) 203 if (events[type])
199 return events[type]; 204 return events[type];
200 205
201 events[type] = event = trace_find_event(type); 206 events[type] = event = pevent_find_event(pevent, type);
202 if (!event) 207 if (!event)
203 return NULL; 208 return NULL;
204 209
@@ -209,7 +214,8 @@ static inline struct event_format *find_cache_event(int type)
209 return event; 214 return event;
210} 215}
211 216
212static void python_process_event(union perf_event *pevent __unused, 217static void python_process_event(union perf_event *perf_event __unused,
218 struct pevent *pevent,
213 struct perf_sample *sample, 219 struct perf_sample *sample,
214 struct perf_evsel *evsel __unused, 220 struct perf_evsel *evsel __unused,
215 struct machine *machine __unused, 221 struct machine *machine __unused,
@@ -233,13 +239,13 @@ static void python_process_event(union perf_event *pevent __unused,
233 if (!t) 239 if (!t)
234 Py_FatalError("couldn't create Python tuple"); 240 Py_FatalError("couldn't create Python tuple");
235 241
236 type = trace_parse_common_type(data); 242 type = trace_parse_common_type(pevent, data);
237 243
238 event = find_cache_event(type); 244 event = find_cache_event(pevent, type);
239 if (!event) 245 if (!event)
240 die("ug! no event found for type %d", type); 246 die("ug! no event found for type %d", type);
241 247
242 pid = trace_parse_common_pid(data); 248 pid = trace_parse_common_pid(pevent, data);
243 249
244 sprintf(handler_name, "%s__%s", event->system, event->name); 250 sprintf(handler_name, "%s__%s", event->system, event->name);
245 251
@@ -284,7 +290,8 @@ static void python_process_event(union perf_event *pevent __unused,
284 offset = field->offset; 290 offset = field->offset;
285 obj = PyString_FromString((char *)data + offset); 291 obj = PyString_FromString((char *)data + offset);
286 } else { /* FIELD_IS_NUMERIC */ 292 } else { /* FIELD_IS_NUMERIC */
287 val = read_size(data + field->offset, field->size); 293 val = read_size(pevent, data + field->offset,
294 field->size);
288 if (field->flags & FIELD_IS_SIGNED) { 295 if (field->flags & FIELD_IS_SIGNED) {
289 if ((long long)val >= LONG_MIN && 296 if ((long long)val >= LONG_MIN &&
290 (long long)val <= LONG_MAX) 297 (long long)val <= LONG_MAX)
@@ -438,7 +445,7 @@ out:
438 return err; 445 return err;
439} 446}
440 447
441static int python_generate_script(const char *outfile) 448static int python_generate_script(struct pevent *pevent, const char *outfile)
442{ 449{
443 struct event_format *event = NULL; 450 struct event_format *event = NULL;
444 struct format_field *f; 451 struct format_field *f;
@@ -487,7 +494,7 @@ static int python_generate_script(const char *outfile)
487 fprintf(ofp, "def trace_end():\n"); 494 fprintf(ofp, "def trace_end():\n");
488 fprintf(ofp, "\tprint \"in trace_end\"\n\n"); 495 fprintf(ofp, "\tprint \"in trace_end\"\n\n");
489 496
490 while ((event = trace_find_next_event(event))) { 497 while ((event = trace_find_next_event(pevent, event))) {
491 fprintf(ofp, "def %s__%s(", event->system, event->name); 498 fprintf(ofp, "def %s__%s(", event->system, event->name);
492 fprintf(ofp, "event_name, "); 499 fprintf(ofp, "event_name, ");
493 fprintf(ofp, "context, "); 500 fprintf(ofp, "context, ");
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 56142d0fb8d7..8e485592ca20 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -14,6 +14,7 @@
14#include "sort.h" 14#include "sort.h"
15#include "util.h" 15#include "util.h"
16#include "cpumap.h" 16#include "cpumap.h"
17#include "event-parse.h"
17 18
18static int perf_session__open(struct perf_session *self, bool force) 19static int perf_session__open(struct perf_session *self, bool force)
19{ 20{
@@ -289,7 +290,6 @@ struct branch_info *machine__resolve_bstack(struct machine *self,
289} 290}
290 291
291int machine__resolve_callchain(struct machine *self, 292int machine__resolve_callchain(struct machine *self,
292 struct perf_evsel *evsel __used,
293 struct thread *thread, 293 struct thread *thread,
294 struct ip_callchain *chain, 294 struct ip_callchain *chain,
295 struct symbol **parent) 295 struct symbol **parent)
@@ -1449,7 +1449,7 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
1449 ret += hists__fprintf_nr_events(&session->hists, fp); 1449 ret += hists__fprintf_nr_events(&session->hists, fp);
1450 1450
1451 list_for_each_entry(pos, &session->evlist->entries, node) { 1451 list_for_each_entry(pos, &session->evlist->entries, node) {
1452 ret += fprintf(fp, "%s stats:\n", event_name(pos)); 1452 ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos));
1453 ret += hists__fprintf_nr_events(&pos->hists, fp); 1453 ret += hists__fprintf_nr_events(&pos->hists, fp);
1454 } 1454 }
1455 1455
@@ -1490,8 +1490,8 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
1490} 1490}
1491 1491
1492void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, 1492void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
1493 struct machine *machine, struct perf_evsel *evsel, 1493 struct machine *machine, int print_sym,
1494 int print_sym, int print_dso, int print_symoffset) 1494 int print_dso, int print_symoffset)
1495{ 1495{
1496 struct addr_location al; 1496 struct addr_location al;
1497 struct callchain_cursor_node *node; 1497 struct callchain_cursor_node *node;
@@ -1505,7 +1505,7 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
1505 1505
1506 if (symbol_conf.use_callchain && sample->callchain) { 1506 if (symbol_conf.use_callchain && sample->callchain) {
1507 1507
1508 if (machine__resolve_callchain(machine, evsel, al.thread, 1508 if (machine__resolve_callchain(machine, al.thread,
1509 sample->callchain, NULL) != 0) { 1509 sample->callchain, NULL) != 0) {
1510 if (verbose) 1510 if (verbose)
1511 error("Failed to resolve callchain. Skipping\n"); 1511 error("Failed to resolve callchain. Skipping\n");
@@ -1611,3 +1611,58 @@ void perf_session__fprintf_info(struct perf_session *session, FILE *fp,
1611 perf_header__fprintf_info(session, fp, full); 1611 perf_header__fprintf_info(session, fp, full);
1612 fprintf(fp, "# ========\n#\n"); 1612 fprintf(fp, "# ========\n#\n");
1613} 1613}
1614
1615
1616int __perf_session__set_tracepoints_handlers(struct perf_session *session,
1617 const struct perf_evsel_str_handler *assocs,
1618 size_t nr_assocs)
1619{
1620 struct perf_evlist *evlist = session->evlist;
1621 struct event_format *format;
1622 struct perf_evsel *evsel;
1623 char *tracepoint, *name;
1624 size_t i;
1625 int err;
1626
1627 for (i = 0; i < nr_assocs; i++) {
1628 err = -ENOMEM;
1629 tracepoint = strdup(assocs[i].name);
1630 if (tracepoint == NULL)
1631 goto out;
1632
1633 err = -ENOENT;
1634 name = strchr(tracepoint, ':');
1635 if (name == NULL)
1636 goto out_free;
1637
1638 *name++ = '\0';
1639 format = pevent_find_event_by_name(session->pevent,
1640 tracepoint, name);
1641 if (format == NULL) {
1642 /*
1643 * Adding a handler for an event not in the session,
1644 * just ignore it.
1645 */
1646 goto next;
1647 }
1648
1649 evsel = perf_evlist__find_tracepoint_by_id(evlist, format->id);
1650 if (evsel == NULL)
1651 goto next;
1652
1653 err = -EEXIST;
1654 if (evsel->handler.func != NULL)
1655 goto out_free;
1656 evsel->handler.func = assocs[i].handler;
1657next:
1658 free(tracepoint);
1659 }
1660
1661 err = 0;
1662out:
1663 return err;
1664
1665out_free:
1666 free(tracepoint);
1667 goto out;
1668}
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 0c702e3f0a36..7c435bde6eb0 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -33,6 +33,7 @@ struct perf_session {
33 struct machine host_machine; 33 struct machine host_machine;
34 struct rb_root machines; 34 struct rb_root machines;
35 struct perf_evlist *evlist; 35 struct perf_evlist *evlist;
36 struct pevent *pevent;
36 /* 37 /*
37 * FIXME: Need to split this up further, we need global 38 * FIXME: Need to split this up further, we need global
38 * stats + per event stats. 'perf diff' also needs 39 * stats + per event stats. 'perf diff' also needs
@@ -151,11 +152,20 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
151 unsigned int type); 152 unsigned int type);
152 153
153void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, 154void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
154 struct machine *machine, struct perf_evsel *evsel, 155 struct machine *machine, int print_sym,
155 int print_sym, int print_dso, int print_symoffset); 156 int print_dso, int print_symoffset);
156 157
157int perf_session__cpu_bitmap(struct perf_session *session, 158int perf_session__cpu_bitmap(struct perf_session *session,
158 const char *cpu_list, unsigned long *cpu_bitmap); 159 const char *cpu_list, unsigned long *cpu_bitmap);
159 160
160void perf_session__fprintf_info(struct perf_session *s, FILE *fp, bool full); 161void perf_session__fprintf_info(struct perf_session *s, FILE *fp, bool full);
162
163struct perf_evsel_str_handler;
164
165int __perf_session__set_tracepoints_handlers(struct perf_session *session,
166 const struct perf_evsel_str_handler *assocs,
167 size_t nr_assocs);
168
169#define perf_session__set_tracepoints_handlers(session, array) \
170 __perf_session__set_tracepoints_handlers(session, array, ARRAY_SIZE(array))
161#endif /* __PERF_SESSION_H */ 171#endif /* __PERF_SESSION_H */
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index a27237430c5f..0f5a0a496bc4 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -241,6 +241,54 @@ struct sort_entry sort_sym = {
241 .se_width_idx = HISTC_SYMBOL, 241 .se_width_idx = HISTC_SYMBOL,
242}; 242};
243 243
244/* --sort srcline */
245
246static int64_t
247sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right)
248{
249 return (int64_t)(right->ip - left->ip);
250}
251
252static int hist_entry__srcline_snprintf(struct hist_entry *self, char *bf,
253 size_t size, unsigned int width __used)
254{
255 FILE *fp;
256 char cmd[PATH_MAX + 2], *path = self->srcline, *nl;
257 size_t line_len;
258
259 if (path != NULL)
260 goto out_path;
261
262 snprintf(cmd, sizeof(cmd), "addr2line -e %s %016" PRIx64,
263 self->ms.map->dso->long_name, self->ip);
264 fp = popen(cmd, "r");
265 if (!fp)
266 goto out_ip;
267
268 if (getline(&path, &line_len, fp) < 0 || !line_len)
269 goto out_ip;
270 fclose(fp);
271 self->srcline = strdup(path);
272 if (self->srcline == NULL)
273 goto out_ip;
274
275 nl = strchr(self->srcline, '\n');
276 if (nl != NULL)
277 *nl = '\0';
278 path = self->srcline;
279out_path:
280 return repsep_snprintf(bf, size, "%s", path);
281out_ip:
282 return repsep_snprintf(bf, size, "%-#*llx", BITS_PER_LONG / 4, self->ip);
283}
284
285struct sort_entry sort_srcline = {
286 .se_header = "Source:Line",
287 .se_cmp = sort__srcline_cmp,
288 .se_snprintf = hist_entry__srcline_snprintf,
289 .se_width_idx = HISTC_SRCLINE,
290};
291
244/* --sort parent */ 292/* --sort parent */
245 293
246static int64_t 294static int64_t
@@ -439,6 +487,7 @@ static struct sort_dimension sort_dimensions[] = {
439 DIM(SORT_PARENT, "parent", sort_parent), 487 DIM(SORT_PARENT, "parent", sort_parent),
440 DIM(SORT_CPU, "cpu", sort_cpu), 488 DIM(SORT_CPU, "cpu", sort_cpu),
441 DIM(SORT_MISPREDICT, "mispredict", sort_mispredict), 489 DIM(SORT_MISPREDICT, "mispredict", sort_mispredict),
490 DIM(SORT_SRCLINE, "srcline", sort_srcline),
442}; 491};
443 492
444int sort_dimension__add(const char *tok) 493int sort_dimension__add(const char *tok)
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 472aa5a63a58..e724b26acd51 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -71,6 +71,7 @@ struct hist_entry {
71 char level; 71 char level;
72 bool used; 72 bool used;
73 u8 filtered; 73 u8 filtered;
74 char *srcline;
74 struct symbol *parent; 75 struct symbol *parent;
75 union { 76 union {
76 unsigned long position; 77 unsigned long position;
@@ -93,6 +94,7 @@ enum sort_type {
93 SORT_SYM_FROM, 94 SORT_SYM_FROM,
94 SORT_SYM_TO, 95 SORT_SYM_TO,
95 SORT_MISPREDICT, 96 SORT_MISPREDICT,
97 SORT_SRCLINE,
96}; 98};
97 99
98/* 100/*
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c
index d5836382ff2c..199bc4d8905d 100644
--- a/tools/perf/util/string.c
+++ b/tools/perf/util/string.c
@@ -313,3 +313,25 @@ int strtailcmp(const char *s1, const char *s2)
313 return 0; 313 return 0;
314} 314}
315 315
316/**
317 * rtrim - Removes trailing whitespace from @s.
318 * @s: The string to be stripped.
319 *
320 * Note that the first trailing whitespace is replaced with a %NUL-terminator
321 * in the given string @s. Returns @s.
322 */
323char *rtrim(char *s)
324{
325 size_t size = strlen(s);
326 char *end;
327
328 if (!size)
329 return s;
330
331 end = s + size - 1;
332 while (end >= s && isspace(*end))
333 end--;
334 *(end + 1) = '\0';
335
336 return s;
337}
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 3e2e5ea0f03f..50958bbeb26a 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1478,14 +1478,31 @@ static int elf_read_build_id(Elf *elf, void *bf, size_t size)
1478 goto out; 1478 goto out;
1479 } 1479 }
1480 1480
1481 sec = elf_section_by_name(elf, &ehdr, &shdr, 1481 /*
1482 ".note.gnu.build-id", NULL); 1482 * Check following sections for notes:
1483 if (sec == NULL) { 1483 * '.note.gnu.build-id'
1484 * '.notes'
1485 * '.note' (VDSO specific)
1486 */
1487 do {
1488 sec = elf_section_by_name(elf, &ehdr, &shdr,
1489 ".note.gnu.build-id", NULL);
1490 if (sec)
1491 break;
1492
1484 sec = elf_section_by_name(elf, &ehdr, &shdr, 1493 sec = elf_section_by_name(elf, &ehdr, &shdr,
1485 ".notes", NULL); 1494 ".notes", NULL);
1486 if (sec == NULL) 1495 if (sec)
1487 goto out; 1496 break;
1488 } 1497
1498 sec = elf_section_by_name(elf, &ehdr, &shdr,
1499 ".note", NULL);
1500 if (sec)
1501 break;
1502
1503 return err;
1504
1505 } while (0);
1489 1506
1490 data = elf_getdata(sec, NULL); 1507 data = elf_getdata(sec, NULL);
1491 if (data == NULL) 1508 if (data == NULL)
@@ -1590,11 +1607,62 @@ out:
1590 return err; 1607 return err;
1591} 1608}
1592 1609
1610static int filename__read_debuglink(const char *filename,
1611 char *debuglink, size_t size)
1612{
1613 int fd, err = -1;
1614 Elf *elf;
1615 GElf_Ehdr ehdr;
1616 GElf_Shdr shdr;
1617 Elf_Data *data;
1618 Elf_Scn *sec;
1619 Elf_Kind ek;
1620
1621 fd = open(filename, O_RDONLY);
1622 if (fd < 0)
1623 goto out;
1624
1625 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
1626 if (elf == NULL) {
1627 pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
1628 goto out_close;
1629 }
1630
1631 ek = elf_kind(elf);
1632 if (ek != ELF_K_ELF)
1633 goto out_close;
1634
1635 if (gelf_getehdr(elf, &ehdr) == NULL) {
1636 pr_err("%s: cannot get elf header.\n", __func__);
1637 goto out_close;
1638 }
1639
1640 sec = elf_section_by_name(elf, &ehdr, &shdr,
1641 ".gnu_debuglink", NULL);
1642 if (sec == NULL)
1643 goto out_close;
1644
1645 data = elf_getdata(sec, NULL);
1646 if (data == NULL)
1647 goto out_close;
1648
1649 /* the start of this section is a zero-terminated string */
1650 strncpy(debuglink, data->d_buf, size);
1651
1652 elf_end(elf);
1653
1654out_close:
1655 close(fd);
1656out:
1657 return err;
1658}
1659
1593char dso__symtab_origin(const struct dso *dso) 1660char dso__symtab_origin(const struct dso *dso)
1594{ 1661{
1595 static const char origin[] = { 1662 static const char origin[] = {
1596 [SYMTAB__KALLSYMS] = 'k', 1663 [SYMTAB__KALLSYMS] = 'k',
1597 [SYMTAB__JAVA_JIT] = 'j', 1664 [SYMTAB__JAVA_JIT] = 'j',
1665 [SYMTAB__DEBUGLINK] = 'l',
1598 [SYMTAB__BUILD_ID_CACHE] = 'B', 1666 [SYMTAB__BUILD_ID_CACHE] = 'B',
1599 [SYMTAB__FEDORA_DEBUGINFO] = 'f', 1667 [SYMTAB__FEDORA_DEBUGINFO] = 'f',
1600 [SYMTAB__UBUNTU_DEBUGINFO] = 'u', 1668 [SYMTAB__UBUNTU_DEBUGINFO] = 'u',
@@ -1662,10 +1730,22 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
1662 */ 1730 */
1663 want_symtab = 1; 1731 want_symtab = 1;
1664restart: 1732restart:
1665 for (dso->symtab_type = SYMTAB__BUILD_ID_CACHE; 1733 for (dso->symtab_type = SYMTAB__DEBUGLINK;
1666 dso->symtab_type != SYMTAB__NOT_FOUND; 1734 dso->symtab_type != SYMTAB__NOT_FOUND;
1667 dso->symtab_type++) { 1735 dso->symtab_type++) {
1668 switch (dso->symtab_type) { 1736 switch (dso->symtab_type) {
1737 case SYMTAB__DEBUGLINK: {
1738 char *debuglink;
1739 strncpy(name, dso->long_name, size);
1740 debuglink = name + dso->long_name_len;
1741 while (debuglink != name && *debuglink != '/')
1742 debuglink--;
1743 if (*debuglink == '/')
1744 debuglink++;
1745 filename__read_debuglink(dso->long_name, debuglink,
1746 size - (debuglink - name));
1747 }
1748 break;
1669 case SYMTAB__BUILD_ID_CACHE: 1749 case SYMTAB__BUILD_ID_CACHE:
1670 /* skip the locally configured cache if a symfs is given */ 1750 /* skip the locally configured cache if a symfs is given */
1671 if (symbol_conf.symfs[0] || 1751 if (symbol_conf.symfs[0] ||
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index af0752b1aca1..a884b99017f0 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -257,6 +257,7 @@ enum symtab_type {
257 SYMTAB__KALLSYMS = 0, 257 SYMTAB__KALLSYMS = 0,
258 SYMTAB__GUEST_KALLSYMS, 258 SYMTAB__GUEST_KALLSYMS,
259 SYMTAB__JAVA_JIT, 259 SYMTAB__JAVA_JIT,
260 SYMTAB__DEBUGLINK,
260 SYMTAB__BUILD_ID_CACHE, 261 SYMTAB__BUILD_ID_CACHE,
261 SYMTAB__FEDORA_DEBUGINFO, 262 SYMTAB__FEDORA_DEBUGINFO,
262 SYMTAB__UBUNTU_DEBUGINFO, 263 SYMTAB__UBUNTU_DEBUGINFO,
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c
index abe0e8e95068..7eeebcee291c 100644
--- a/tools/perf/util/top.c
+++ b/tools/perf/util/top.c
@@ -65,7 +65,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
65 top->freq ? "Hz" : ""); 65 top->freq ? "Hz" : "");
66 } 66 }
67 67
68 ret += SNPRINTF(bf + ret, size - ret, "%s", event_name(top->sym_evsel)); 68 ret += SNPRINTF(bf + ret, size - ret, "%s", perf_evsel__name(top->sym_evsel));
69 69
70 ret += SNPRINTF(bf + ret, size - ret, "], "); 70 ret += SNPRINTF(bf + ret, size - ret, "], ");
71 71
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 5dd3b5ec8411..0715c843c2e7 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -32,29 +32,25 @@ int header_page_size_size;
32int header_page_ts_size; 32int header_page_ts_size;
33int header_page_data_offset; 33int header_page_data_offset;
34 34
35struct pevent *perf_pevent;
36static struct pevent *pevent;
37
38bool latency_format; 35bool latency_format;
39 36
40int read_trace_init(int file_bigendian, int host_bigendian) 37struct pevent *read_trace_init(int file_bigendian, int host_bigendian)
41{ 38{
42 if (pevent) 39 struct pevent *pevent = pevent_alloc();
43 return 0;
44
45 perf_pevent = pevent_alloc();
46 pevent = perf_pevent;
47 40
48 pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT); 41 if (pevent != NULL) {
49 pevent_set_file_bigendian(pevent, file_bigendian); 42 pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT);
50 pevent_set_host_bigendian(pevent, host_bigendian); 43 pevent_set_file_bigendian(pevent, file_bigendian);
44 pevent_set_host_bigendian(pevent, host_bigendian);
45 }
51 46
52 return 0; 47 return pevent;
53} 48}
54 49
55static int get_common_field(struct scripting_context *context, 50static int get_common_field(struct scripting_context *context,
56 int *offset, int *size, const char *type) 51 int *offset, int *size, const char *type)
57{ 52{
53 struct pevent *pevent = context->pevent;
58 struct event_format *event; 54 struct event_format *event;
59 struct format_field *field; 55 struct format_field *field;
60 56
@@ -150,7 +146,7 @@ void *raw_field_ptr(struct event_format *event, const char *name, void *data)
150 return data + field->offset; 146 return data + field->offset;
151} 147}
152 148
153int trace_parse_common_type(void *data) 149int trace_parse_common_type(struct pevent *pevent, void *data)
154{ 150{
155 struct pevent_record record; 151 struct pevent_record record;
156 152
@@ -158,7 +154,7 @@ int trace_parse_common_type(void *data)
158 return pevent_data_type(pevent, &record); 154 return pevent_data_type(pevent, &record);
159} 155}
160 156
161int trace_parse_common_pid(void *data) 157int trace_parse_common_pid(struct pevent *pevent, void *data)
162{ 158{
163 struct pevent_record record; 159 struct pevent_record record;
164 160
@@ -166,27 +162,21 @@ int trace_parse_common_pid(void *data)
166 return pevent_data_pid(pevent, &record); 162 return pevent_data_pid(pevent, &record);
167} 163}
168 164
169unsigned long long read_size(void *ptr, int size) 165unsigned long long read_size(struct pevent *pevent, void *ptr, int size)
170{ 166{
171 return pevent_read_number(pevent, ptr, size); 167 return pevent_read_number(pevent, ptr, size);
172} 168}
173 169
174struct event_format *trace_find_event(int type) 170void print_trace_event(struct pevent *pevent, int cpu, void *data, int size)
175{
176 return pevent_find_event(pevent, type);
177}
178
179
180void print_trace_event(int cpu, void *data, int size)
181{ 171{
182 struct event_format *event; 172 struct event_format *event;
183 struct pevent_record record; 173 struct pevent_record record;
184 struct trace_seq s; 174 struct trace_seq s;
185 int type; 175 int type;
186 176
187 type = trace_parse_common_type(data); 177 type = trace_parse_common_type(pevent, data);
188 178
189 event = trace_find_event(type); 179 event = pevent_find_event(pevent, type);
190 if (!event) { 180 if (!event) {
191 warning("ug! no event found for type %d", type); 181 warning("ug! no event found for type %d", type);
192 return; 182 return;
@@ -202,8 +192,8 @@ void print_trace_event(int cpu, void *data, int size)
202 trace_seq_do_printf(&s); 192 trace_seq_do_printf(&s);
203} 193}
204 194
205void print_event(int cpu, void *data, int size, unsigned long long nsecs, 195void print_event(struct pevent *pevent, int cpu, void *data, int size,
206 char *comm) 196 unsigned long long nsecs, char *comm)
207{ 197{
208 struct pevent_record record; 198 struct pevent_record record;
209 struct trace_seq s; 199 struct trace_seq s;
@@ -226,7 +216,8 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs,
226 printf("\n"); 216 printf("\n");
227} 217}
228 218
229void parse_proc_kallsyms(char *file, unsigned int size __unused) 219void parse_proc_kallsyms(struct pevent *pevent,
220 char *file, unsigned int size __unused)
230{ 221{
231 unsigned long long addr; 222 unsigned long long addr;
232 char *func; 223 char *func;
@@ -257,7 +248,8 @@ void parse_proc_kallsyms(char *file, unsigned int size __unused)
257 } 248 }
258} 249}
259 250
260void parse_ftrace_printk(char *file, unsigned int size __unused) 251void parse_ftrace_printk(struct pevent *pevent,
252 char *file, unsigned int size __unused)
261{ 253{
262 unsigned long long addr; 254 unsigned long long addr;
263 char *printk; 255 char *printk;
@@ -281,17 +273,19 @@ void parse_ftrace_printk(char *file, unsigned int size __unused)
281 } 273 }
282} 274}
283 275
284int parse_ftrace_file(char *buf, unsigned long size) 276int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size)
285{ 277{
286 return pevent_parse_event(pevent, buf, size, "ftrace"); 278 return pevent_parse_event(pevent, buf, size, "ftrace");
287} 279}
288 280
289int parse_event_file(char *buf, unsigned long size, char *sys) 281int parse_event_file(struct pevent *pevent,
282 char *buf, unsigned long size, char *sys)
290{ 283{
291 return pevent_parse_event(pevent, buf, size, sys); 284 return pevent_parse_event(pevent, buf, size, sys);
292} 285}
293 286
294struct event_format *trace_find_next_event(struct event_format *event) 287struct event_format *trace_find_next_event(struct pevent *pevent,
288 struct event_format *event)
295{ 289{
296 static int idx; 290 static int idx;
297 291
diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index f097e0dd6c5c..719ed74a8565 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -114,20 +114,20 @@ static void skip(int size)
114 }; 114 };
115} 115}
116 116
117static unsigned int read4(void) 117static unsigned int read4(struct pevent *pevent)
118{ 118{
119 unsigned int data; 119 unsigned int data;
120 120
121 read_or_die(&data, 4); 121 read_or_die(&data, 4);
122 return __data2host4(perf_pevent, data); 122 return __data2host4(pevent, data);
123} 123}
124 124
125static unsigned long long read8(void) 125static unsigned long long read8(struct pevent *pevent)
126{ 126{
127 unsigned long long data; 127 unsigned long long data;
128 128
129 read_or_die(&data, 8); 129 read_or_die(&data, 8);
130 return __data2host8(perf_pevent, data); 130 return __data2host8(pevent, data);
131} 131}
132 132
133static char *read_string(void) 133static char *read_string(void)
@@ -168,12 +168,12 @@ static char *read_string(void)
168 return str; 168 return str;
169} 169}
170 170
171static void read_proc_kallsyms(void) 171static void read_proc_kallsyms(struct pevent *pevent)
172{ 172{
173 unsigned int size; 173 unsigned int size;
174 char *buf; 174 char *buf;
175 175
176 size = read4(); 176 size = read4(pevent);
177 if (!size) 177 if (!size)
178 return; 178 return;
179 179
@@ -181,29 +181,29 @@ static void read_proc_kallsyms(void)
181 read_or_die(buf, size); 181 read_or_die(buf, size);
182 buf[size] = '\0'; 182 buf[size] = '\0';
183 183
184 parse_proc_kallsyms(buf, size); 184 parse_proc_kallsyms(pevent, buf, size);
185 185
186 free(buf); 186 free(buf);
187} 187}
188 188
189static void read_ftrace_printk(void) 189static void read_ftrace_printk(struct pevent *pevent)
190{ 190{
191 unsigned int size; 191 unsigned int size;
192 char *buf; 192 char *buf;
193 193
194 size = read4(); 194 size = read4(pevent);
195 if (!size) 195 if (!size)
196 return; 196 return;
197 197
198 buf = malloc_or_die(size); 198 buf = malloc_or_die(size);
199 read_or_die(buf, size); 199 read_or_die(buf, size);
200 200
201 parse_ftrace_printk(buf, size); 201 parse_ftrace_printk(pevent, buf, size);
202 202
203 free(buf); 203 free(buf);
204} 204}
205 205
206static void read_header_files(void) 206static void read_header_files(struct pevent *pevent)
207{ 207{
208 unsigned long long size; 208 unsigned long long size;
209 char *header_event; 209 char *header_event;
@@ -214,7 +214,7 @@ static void read_header_files(void)
214 if (memcmp(buf, "header_page", 12) != 0) 214 if (memcmp(buf, "header_page", 12) != 0)
215 die("did not read header page"); 215 die("did not read header page");
216 216
217 size = read8(); 217 size = read8(pevent);
218 skip(size); 218 skip(size);
219 219
220 /* 220 /*
@@ -227,47 +227,48 @@ static void read_header_files(void)
227 if (memcmp(buf, "header_event", 13) != 0) 227 if (memcmp(buf, "header_event", 13) != 0)
228 die("did not read header event"); 228 die("did not read header event");
229 229
230 size = read8(); 230 size = read8(pevent);
231 header_event = malloc_or_die(size); 231 header_event = malloc_or_die(size);
232 read_or_die(header_event, size); 232 read_or_die(header_event, size);
233 free(header_event); 233 free(header_event);
234} 234}
235 235
236static void read_ftrace_file(unsigned long long size) 236static void read_ftrace_file(struct pevent *pevent, unsigned long long size)
237{ 237{
238 char *buf; 238 char *buf;
239 239
240 buf = malloc_or_die(size); 240 buf = malloc_or_die(size);
241 read_or_die(buf, size); 241 read_or_die(buf, size);
242 parse_ftrace_file(buf, size); 242 parse_ftrace_file(pevent, buf, size);
243 free(buf); 243 free(buf);
244} 244}
245 245
246static void read_event_file(char *sys, unsigned long long size) 246static void read_event_file(struct pevent *pevent, char *sys,
247 unsigned long long size)
247{ 248{
248 char *buf; 249 char *buf;
249 250
250 buf = malloc_or_die(size); 251 buf = malloc_or_die(size);
251 read_or_die(buf, size); 252 read_or_die(buf, size);
252 parse_event_file(buf, size, sys); 253 parse_event_file(pevent, buf, size, sys);
253 free(buf); 254 free(buf);
254} 255}
255 256
256static void read_ftrace_files(void) 257static void read_ftrace_files(struct pevent *pevent)
257{ 258{
258 unsigned long long size; 259 unsigned long long size;
259 int count; 260 int count;
260 int i; 261 int i;
261 262
262 count = read4(); 263 count = read4(pevent);
263 264
264 for (i = 0; i < count; i++) { 265 for (i = 0; i < count; i++) {
265 size = read8(); 266 size = read8(pevent);
266 read_ftrace_file(size); 267 read_ftrace_file(pevent, size);
267 } 268 }
268} 269}
269 270
270static void read_event_files(void) 271static void read_event_files(struct pevent *pevent)
271{ 272{
272 unsigned long long size; 273 unsigned long long size;
273 char *sys; 274 char *sys;
@@ -275,15 +276,15 @@ static void read_event_files(void)
275 int count; 276 int count;
276 int i,x; 277 int i,x;
277 278
278 systems = read4(); 279 systems = read4(pevent);
279 280
280 for (i = 0; i < systems; i++) { 281 for (i = 0; i < systems; i++) {
281 sys = read_string(); 282 sys = read_string();
282 283
283 count = read4(); 284 count = read4(pevent);
284 for (x=0; x < count; x++) { 285 for (x=0; x < count; x++) {
285 size = read8(); 286 size = read8(pevent);
286 read_event_file(sys, size); 287 read_event_file(pevent, sys, size);
287 } 288 }
288 } 289 }
289} 290}
@@ -377,7 +378,7 @@ static int calc_index(void *ptr, int cpu)
377 return (unsigned long)ptr - (unsigned long)cpu_data[cpu].page; 378 return (unsigned long)ptr - (unsigned long)cpu_data[cpu].page;
378} 379}
379 380
380struct pevent_record *trace_peek_data(int cpu) 381struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu)
381{ 382{
382 struct pevent_record *data; 383 struct pevent_record *data;
383 void *page = cpu_data[cpu].page; 384 void *page = cpu_data[cpu].page;
@@ -399,15 +400,15 @@ struct pevent_record *trace_peek_data(int cpu)
399 /* FIXME: handle header page */ 400 /* FIXME: handle header page */
400 if (header_page_ts_size != 8) 401 if (header_page_ts_size != 8)
401 die("expected a long long type for timestamp"); 402 die("expected a long long type for timestamp");
402 cpu_data[cpu].timestamp = data2host8(perf_pevent, ptr); 403 cpu_data[cpu].timestamp = data2host8(pevent, ptr);
403 ptr += 8; 404 ptr += 8;
404 switch (header_page_size_size) { 405 switch (header_page_size_size) {
405 case 4: 406 case 4:
406 cpu_data[cpu].page_size = data2host4(perf_pevent, ptr); 407 cpu_data[cpu].page_size = data2host4(pevent, ptr);
407 ptr += 4; 408 ptr += 4;
408 break; 409 break;
409 case 8: 410 case 8:
410 cpu_data[cpu].page_size = data2host8(perf_pevent, ptr); 411 cpu_data[cpu].page_size = data2host8(pevent, ptr);
411 ptr += 8; 412 ptr += 8;
412 break; 413 break;
413 default: 414 default:
@@ -421,10 +422,10 @@ read_again:
421 422
422 if (idx >= cpu_data[cpu].page_size) { 423 if (idx >= cpu_data[cpu].page_size) {
423 get_next_page(cpu); 424 get_next_page(cpu);
424 return trace_peek_data(cpu); 425 return trace_peek_data(pevent, cpu);
425 } 426 }
426 427
427 type_len_ts = data2host4(perf_pevent, ptr); 428 type_len_ts = data2host4(pevent, ptr);
428 ptr += 4; 429 ptr += 4;
429 430
430 type_len = type_len4host(type_len_ts); 431 type_len = type_len4host(type_len_ts);
@@ -434,14 +435,14 @@ read_again:
434 case RINGBUF_TYPE_PADDING: 435 case RINGBUF_TYPE_PADDING:
435 if (!delta) 436 if (!delta)
436 die("error, hit unexpected end of page"); 437 die("error, hit unexpected end of page");
437 length = data2host4(perf_pevent, ptr); 438 length = data2host4(pevent, ptr);
438 ptr += 4; 439 ptr += 4;
439 length *= 4; 440 length *= 4;
440 ptr += length; 441 ptr += length;
441 goto read_again; 442 goto read_again;
442 443
443 case RINGBUF_TYPE_TIME_EXTEND: 444 case RINGBUF_TYPE_TIME_EXTEND:
444 extend = data2host4(perf_pevent, ptr); 445 extend = data2host4(pevent, ptr);
445 ptr += 4; 446 ptr += 4;
446 extend <<= TS_SHIFT; 447 extend <<= TS_SHIFT;
447 extend += delta; 448 extend += delta;
@@ -452,7 +453,7 @@ read_again:
452 ptr += 12; 453 ptr += 12;
453 break; 454 break;
454 case 0: 455 case 0:
455 length = data2host4(perf_pevent, ptr); 456 length = data2host4(pevent, ptr);
456 ptr += 4; 457 ptr += 4;
457 die("here! length=%d", length); 458 die("here! length=%d", length);
458 break; 459 break;
@@ -477,17 +478,17 @@ read_again:
477 return data; 478 return data;
478} 479}
479 480
480struct pevent_record *trace_read_data(int cpu) 481struct pevent_record *trace_read_data(struct pevent *pevent, int cpu)
481{ 482{
482 struct pevent_record *data; 483 struct pevent_record *data;
483 484
484 data = trace_peek_data(cpu); 485 data = trace_peek_data(pevent, cpu);
485 cpu_data[cpu].next = NULL; 486 cpu_data[cpu].next = NULL;
486 487
487 return data; 488 return data;
488} 489}
489 490
490ssize_t trace_report(int fd, bool __repipe) 491ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)
491{ 492{
492 char buf[BUFSIZ]; 493 char buf[BUFSIZ];
493 char test[] = { 23, 8, 68 }; 494 char test[] = { 23, 8, 68 };
@@ -519,30 +520,32 @@ ssize_t trace_report(int fd, bool __repipe)
519 file_bigendian = buf[0]; 520 file_bigendian = buf[0];
520 host_bigendian = bigendian(); 521 host_bigendian = bigendian();
521 522
522 read_trace_init(file_bigendian, host_bigendian); 523 *ppevent = read_trace_init(file_bigendian, host_bigendian);
524 if (*ppevent == NULL)
525 die("read_trace_init failed");
523 526
524 read_or_die(buf, 1); 527 read_or_die(buf, 1);
525 long_size = buf[0]; 528 long_size = buf[0];
526 529
527 page_size = read4(); 530 page_size = read4(*ppevent);
528 531
529 read_header_files(); 532 read_header_files(*ppevent);
530 533
531 read_ftrace_files(); 534 read_ftrace_files(*ppevent);
532 read_event_files(); 535 read_event_files(*ppevent);
533 read_proc_kallsyms(); 536 read_proc_kallsyms(*ppevent);
534 read_ftrace_printk(); 537 read_ftrace_printk(*ppevent);
535 538
536 size = calc_data_size - 1; 539 size = calc_data_size - 1;
537 calc_data_size = 0; 540 calc_data_size = 0;
538 repipe = false; 541 repipe = false;
539 542
540 if (show_funcs) { 543 if (show_funcs) {
541 pevent_print_funcs(perf_pevent); 544 pevent_print_funcs(*ppevent);
542 return size; 545 return size;
543 } 546 }
544 if (show_printk) { 547 if (show_printk) {
545 pevent_print_printk(perf_pevent); 548 pevent_print_printk(*ppevent);
546 return size; 549 return size;
547 } 550 }
548 551
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c
index 18ae6c1831d3..474aa7a7df43 100644
--- a/tools/perf/util/trace-event-scripting.c
+++ b/tools/perf/util/trace-event-scripting.c
@@ -36,6 +36,7 @@ static int stop_script_unsupported(void)
36} 36}
37 37
38static void process_event_unsupported(union perf_event *event __unused, 38static void process_event_unsupported(union perf_event *event __unused,
39 struct pevent *pevent __unused,
39 struct perf_sample *sample __unused, 40 struct perf_sample *sample __unused,
40 struct perf_evsel *evsel __unused, 41 struct perf_evsel *evsel __unused,
41 struct machine *machine __unused, 42 struct machine *machine __unused,
@@ -61,7 +62,8 @@ static int python_start_script_unsupported(const char *script __unused,
61 return -1; 62 return -1;
62} 63}
63 64
64static int python_generate_script_unsupported(const char *outfile __unused) 65static int python_generate_script_unsupported(struct pevent *pevent __unused,
66 const char *outfile __unused)
65{ 67{
66 print_python_unsupported_msg(); 68 print_python_unsupported_msg();
67 69
@@ -122,7 +124,8 @@ static int perl_start_script_unsupported(const char *script __unused,
122 return -1; 124 return -1;
123} 125}
124 126
125static int perl_generate_script_unsupported(const char *outfile __unused) 127static int perl_generate_script_unsupported(struct pevent *pevent __unused,
128 const char *outfile __unused)
126{ 129{
127 print_perl_unsupported_msg(); 130 print_perl_unsupported_msg();
128 131
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index 639852ac1117..8fef1d6687b7 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -8,6 +8,7 @@
8struct machine; 8struct machine;
9struct perf_sample; 9struct perf_sample;
10union perf_event; 10union perf_event;
11struct perf_tool;
11struct thread; 12struct thread;
12 13
13extern int header_page_size_size; 14extern int header_page_size_size;
@@ -29,35 +30,36 @@ enum {
29 30
30int bigendian(void); 31int bigendian(void);
31 32
32int read_trace_init(int file_bigendian, int host_bigendian); 33struct pevent *read_trace_init(int file_bigendian, int host_bigendian);
33void print_trace_event(int cpu, void *data, int size); 34void print_trace_event(struct pevent *pevent, int cpu, void *data, int size);
34 35
35void print_event(int cpu, void *data, int size, unsigned long long nsecs, 36void print_event(struct pevent *pevent, int cpu, void *data, int size,
36 char *comm); 37 unsigned long long nsecs, char *comm);
37 38
38int parse_ftrace_file(char *buf, unsigned long size); 39int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size);
39int parse_event_file(char *buf, unsigned long size, char *sys); 40int parse_event_file(struct pevent *pevent,
41 char *buf, unsigned long size, char *sys);
40 42
41struct pevent_record *trace_peek_data(int cpu); 43struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu);
42struct event_format *trace_find_event(int type);
43 44
44unsigned long long 45unsigned long long
45raw_field_value(struct event_format *event, const char *name, void *data); 46raw_field_value(struct event_format *event, const char *name, void *data);
46void *raw_field_ptr(struct event_format *event, const char *name, void *data); 47void *raw_field_ptr(struct event_format *event, const char *name, void *data);
47 48
48void parse_proc_kallsyms(char *file, unsigned int size __unused); 49void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size);
49void parse_ftrace_printk(char *file, unsigned int size __unused); 50void parse_ftrace_printk(struct pevent *pevent, char *file, unsigned int size);
50 51
51ssize_t trace_report(int fd, bool repipe); 52ssize_t trace_report(int fd, struct pevent **pevent, bool repipe);
52 53
53int trace_parse_common_type(void *data); 54int trace_parse_common_type(struct pevent *pevent, void *data);
54int trace_parse_common_pid(void *data); 55int trace_parse_common_pid(struct pevent *pevent, void *data);
55 56
56struct event_format *trace_find_next_event(struct event_format *event); 57struct event_format *trace_find_next_event(struct pevent *pevent,
57unsigned long long read_size(void *ptr, int size); 58 struct event_format *event);
59unsigned long long read_size(struct pevent *pevent, void *ptr, int size);
58unsigned long long eval_flag(const char *flag); 60unsigned long long eval_flag(const char *flag);
59 61
60struct pevent_record *trace_read_data(int cpu); 62struct pevent_record *trace_read_data(struct pevent *pevent, int cpu);
61int read_tracing_data(int fd, struct list_head *pattrs); 63int read_tracing_data(int fd, struct list_head *pattrs);
62 64
63struct tracing_data { 65struct tracing_data {
@@ -77,11 +79,12 @@ struct scripting_ops {
77 int (*start_script) (const char *script, int argc, const char **argv); 79 int (*start_script) (const char *script, int argc, const char **argv);
78 int (*stop_script) (void); 80 int (*stop_script) (void);
79 void (*process_event) (union perf_event *event, 81 void (*process_event) (union perf_event *event,
82 struct pevent *pevent,
80 struct perf_sample *sample, 83 struct perf_sample *sample,
81 struct perf_evsel *evsel, 84 struct perf_evsel *evsel,
82 struct machine *machine, 85 struct machine *machine,
83 struct thread *thread); 86 struct thread *thread);
84 int (*generate_script) (const char *outfile); 87 int (*generate_script) (struct pevent *pevent, const char *outfile);
85}; 88};
86 89
87int script_spec_register(const char *spec, struct scripting_ops *ops); 90int script_spec_register(const char *spec, struct scripting_ops *ops);
@@ -90,6 +93,7 @@ void setup_perl_scripting(void);
90void setup_python_scripting(void); 93void setup_python_scripting(void);
91 94
92struct scripting_context { 95struct scripting_context {
96 struct pevent *pevent;
93 void *event_data; 97 void *event_data;
94}; 98};
95 99
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 2daaedb83d84..b13c7331eaf8 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -264,4 +264,6 @@ bool is_power_of_2(unsigned long n)
264 264
265size_t hex_width(u64 v); 265size_t hex_width(u64 v);
266 266
267char *rtrim(char *s);
268
267#endif 269#endif