aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-03-24 13:02:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-24 13:02:14 -0400
commit3fa2fe2ce09c5a16be69c5319eb3347271a99735 (patch)
tree7067760e7006dec7ac6fe18fe3d09851293b63ea
parentd88f48e12821ab4b2244124d50ac094568f48db5 (diff)
parent05f5ece76a88a2cd4859bc93f90379733dd8b4a3 (diff)
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf fixes from Ingo Molnar: "This tree contains various perf fixes on the kernel side, plus three hw/event-enablement late additions: - Intel Memory Bandwidth Monitoring events and handling - the AMD Accumulated Power Mechanism reporting facility - more IOMMU events ... and a final round of perf tooling updates/fixes" * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (44 commits) perf llvm: Use strerror_r instead of the thread unsafe strerror one perf llvm: Use realpath to canonicalize paths perf tools: Unexport some methods unused outside strbuf.c perf probe: No need to use formatting strbuf method perf help: Use asprintf instead of adhoc equivalents perf tools: Remove unused perf_pathdup, xstrdup functions perf tools: Do not include stringify.h from the kernel sources tools include: Copy linux/stringify.h from the kernel tools lib traceevent: Remove redundant CPU output perf tools: Remove needless 'extern' from function prototypes perf tools: Simplify die() mechanism perf tools: Remove unused DIE_IF macro perf script: Remove lots of unused arguments perf thread: Rename perf_event__preprocess_sample_addr to thread__resolve perf machine: Rename perf_event__preprocess_sample to machine__resolve perf tools: Add cpumode to struct perf_sample perf tests: Forward the perf_sample in the dwarf unwind test perf tools: Remove misplaced __maybe_unused perf list: Fix documentation of :ppp perf bench numa: Fix assertion for nodes bitfield ...
-rw-r--r--arch/x86/Kconfig9
-rw-r--r--arch/x86/events/Makefile1
-rw-r--r--arch/x86/events/amd/ibs.c37
-rw-r--r--arch/x86/events/amd/iommu.c5
-rw-r--r--arch/x86/events/amd/power.c353
-rw-r--r--arch/x86/events/core.c4
-rw-r--r--arch/x86/events/intel/cqm.c454
-rw-r--r--arch/x86/events/intel/ds.c5
-rw-r--r--arch/x86/events/intel/rapl.c2
-rw-r--r--arch/x86/events/intel/uncore_snbep.c7
-rw-r--r--arch/x86/include/asm/cpufeatures.h4
-rw-r--r--arch/x86/kernel/cpu/amd.c18
-rw-r--r--arch/x86/kernel/cpu/common.c4
-rw-r--r--include/linux/perf_event.h5
-rw-r--r--kernel/events/core.c114
-rw-r--r--kernel/events/ring_buffer.c6
-rw-r--r--tools/include/linux/stringify.h12
-rw-r--r--tools/lib/api/Makefile2
-rw-r--r--tools/lib/subcmd/Makefile2
-rw-r--r--tools/lib/traceevent/event-parse.c4
-rw-r--r--tools/perf/Documentation/Makefile2
-rw-r--r--tools/perf/Documentation/perf-list.txt6
-rw-r--r--tools/perf/Makefile.perf2
-rw-r--r--tools/perf/arch/powerpc/util/header.c4
-rw-r--r--tools/perf/bench/bench.h22
-rw-r--r--tools/perf/bench/mem-memcpy-arch.h2
-rw-r--r--tools/perf/bench/mem-memset-arch.h2
-rw-r--r--tools/perf/bench/numa.c2
-rw-r--r--tools/perf/builtin-annotate.c2
-rw-r--r--tools/perf/builtin-diff.c2
-rw-r--r--tools/perf/builtin-help.c69
-rw-r--r--tools/perf/builtin-inject.c8
-rw-r--r--tools/perf/builtin-mem.c2
-rw-r--r--tools/perf/builtin-report.c3
-rw-r--r--tools/perf/builtin-script.c46
-rw-r--r--tools/perf/builtin-timechart.c2
-rw-r--r--tools/perf/builtin-top.c8
-rw-r--r--tools/perf/builtin-trace.c9
-rw-r--r--tools/perf/builtin.h64
-rw-r--r--tools/perf/config/Makefile2
-rw-r--r--tools/perf/tests/code-reading.c5
-rw-r--r--tools/perf/tests/dwarf-unwind.c4
-rw-r--r--tools/perf/tests/hists_common.c6
-rw-r--r--tools/perf/tests/hists_cumulate.c9
-rw-r--r--tools/perf/tests/hists_filter.c9
-rw-r--r--tools/perf/tests/hists_link.c20
-rw-r--r--tools/perf/tests/hists_output.c9
-rw-r--r--tools/perf/ui/gtk/hists.c2
-rw-r--r--tools/perf/util/Build1
-rw-r--r--tools/perf/util/abspath.c37
-rw-r--r--tools/perf/util/annotate.h2
-rw-r--r--tools/perf/util/auxtrace.h2
-rw-r--r--tools/perf/util/build-id.c3
-rw-r--r--tools/perf/util/cache.h24
-rw-r--r--tools/perf/util/callchain.h4
-rw-r--r--tools/perf/util/cgroup.h4
-rw-r--r--tools/perf/util/cloexec.h2
-rw-r--r--tools/perf/util/data-convert-bt.c2
-rw-r--r--tools/perf/util/db-export.c2
-rw-r--r--tools/perf/util/dso.h3
-rw-r--r--tools/perf/util/dwarf-aux.c10
-rw-r--r--tools/perf/util/dwarf-aux.h72
-rw-r--r--tools/perf/util/event.c23
-rw-r--r--tools/perf/util/event.h13
-rw-r--r--tools/perf/util/evsel.c1
-rw-r--r--tools/perf/util/genelf.h8
-rw-r--r--tools/perf/util/header.c5
-rw-r--r--tools/perf/util/header.h2
-rw-r--r--tools/perf/util/hist.c2
-rw-r--r--tools/perf/util/hist.h3
-rw-r--r--tools/perf/util/intel-bts.c2
-rw-r--r--tools/perf/util/jit.h12
-rw-r--r--tools/perf/util/llvm-utils.c24
-rw-r--r--tools/perf/util/llvm-utils.h7
-rw-r--r--tools/perf/util/machine.c14
-rw-r--r--tools/perf/util/machine.h2
-rw-r--r--tools/perf/util/parse-events.h21
-rw-r--r--tools/perf/util/path.c30
-rw-r--r--tools/perf/util/probe-event.c2
-rw-r--r--tools/perf/util/probe-event.h57
-rw-r--r--tools/perf/util/probe-finder.c8
-rw-r--r--tools/perf/util/probe-finder.h24
-rw-r--r--tools/perf/util/quote.h2
-rw-r--r--tools/perf/util/session.c5
-rw-r--r--tools/perf/util/sort.c2
-rw-r--r--tools/perf/util/stat-shadow.c18
-rw-r--r--tools/perf/util/strbuf.c9
-rw-r--r--tools/perf/util/strbuf.h21
-rw-r--r--tools/perf/util/svghelper.h51
-rw-r--r--tools/perf/util/symbol-elf.c12
-rw-r--r--tools/perf/util/symbol.h4
-rw-r--r--tools/perf/util/usage.c8
-rw-r--r--tools/perf/util/util.h27
-rw-r--r--tools/perf/util/wrapper.c12
-rw-r--r--tools/scripts/utilities.mak (renamed from tools/perf/config/utilities.mak)0
95 files changed, 1336 insertions, 634 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 54478b7635de..2dc18605831f 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1210,6 +1210,15 @@ config MICROCODE_OLD_INTERFACE
1210 def_bool y 1210 def_bool y
1211 depends on MICROCODE 1211 depends on MICROCODE
1212 1212
1213config PERF_EVENTS_AMD_POWER
1214 depends on PERF_EVENTS && CPU_SUP_AMD
1215 tristate "AMD Processor Power Reporting Mechanism"
1216 ---help---
1217 Provide power reporting mechanism support for AMD processors.
1218 Currently, it leverages X86_FEATURE_ACC_POWER
1219 (CPUID Fn8000_0007_EDX[12]) interface to calculate the
1220 average power consumption on Family 15h processors.
1221
1213config X86_MSR 1222config X86_MSR
1214 tristate "/dev/cpu/*/msr - Model-specific register support" 1223 tristate "/dev/cpu/*/msr - Model-specific register support"
1215 ---help--- 1224 ---help---
diff --git a/arch/x86/events/Makefile b/arch/x86/events/Makefile
index fdfea1511cc0..f59618a39990 100644
--- a/arch/x86/events/Makefile
+++ b/arch/x86/events/Makefile
@@ -1,6 +1,7 @@
1obj-y += core.o 1obj-y += core.o
2 2
3obj-$(CONFIG_CPU_SUP_AMD) += amd/core.o amd/uncore.o 3obj-$(CONFIG_CPU_SUP_AMD) += amd/core.o amd/uncore.o
4obj-$(CONFIG_PERF_EVENTS_AMD_POWER) += amd/power.o
4obj-$(CONFIG_X86_LOCAL_APIC) += amd/ibs.o msr.o 5obj-$(CONFIG_X86_LOCAL_APIC) += amd/ibs.o msr.o
5ifdef CONFIG_AMD_IOMMU 6ifdef CONFIG_AMD_IOMMU
6obj-$(CONFIG_CPU_SUP_AMD) += amd/iommu.o 7obj-$(CONFIG_CPU_SUP_AMD) += amd/iommu.o
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index 51087c29b2c2..3ea25c3917c0 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -376,7 +376,13 @@ static void perf_ibs_start(struct perf_event *event, int flags)
376 hwc->state = 0; 376 hwc->state = 0;
377 377
378 perf_ibs_set_period(perf_ibs, hwc, &period); 378 perf_ibs_set_period(perf_ibs, hwc, &period);
379 /*
380 * Set STARTED before enabling the hardware, such that
381 * a subsequent NMI must observe it. Then clear STOPPING
382 * such that we don't consume NMIs by accident.
383 */
379 set_bit(IBS_STARTED, pcpu->state); 384 set_bit(IBS_STARTED, pcpu->state);
385 clear_bit(IBS_STOPPING, pcpu->state);
380 perf_ibs_enable_event(perf_ibs, hwc, period >> 4); 386 perf_ibs_enable_event(perf_ibs, hwc, period >> 4);
381 387
382 perf_event_update_userpage(event); 388 perf_event_update_userpage(event);
@@ -390,7 +396,7 @@ static void perf_ibs_stop(struct perf_event *event, int flags)
390 u64 config; 396 u64 config;
391 int stopping; 397 int stopping;
392 398
393 stopping = test_and_clear_bit(IBS_STARTED, pcpu->state); 399 stopping = test_bit(IBS_STARTED, pcpu->state);
394 400
395 if (!stopping && (hwc->state & PERF_HES_UPTODATE)) 401 if (!stopping && (hwc->state & PERF_HES_UPTODATE))
396 return; 402 return;
@@ -398,8 +404,24 @@ static void perf_ibs_stop(struct perf_event *event, int flags)
398 rdmsrl(hwc->config_base, config); 404 rdmsrl(hwc->config_base, config);
399 405
400 if (stopping) { 406 if (stopping) {
407 /*
408 * Set STOPPING before disabling the hardware, such that it
409 * must be visible to NMIs the moment we clear the EN bit,
410 * at which point we can generate an !VALID sample which
411 * we need to consume.
412 */
401 set_bit(IBS_STOPPING, pcpu->state); 413 set_bit(IBS_STOPPING, pcpu->state);
402 perf_ibs_disable_event(perf_ibs, hwc, config); 414 perf_ibs_disable_event(perf_ibs, hwc, config);
415 /*
416 * Clear STARTED after disabling the hardware; if it were
417 * cleared before an NMI hitting after the clear but before
418 * clearing the EN bit might think it a spurious NMI and not
419 * handle it.
420 *
421 * Clearing it after, however, creates the problem of the NMI
422 * handler seeing STARTED but not having a valid sample.
423 */
424 clear_bit(IBS_STARTED, pcpu->state);
403 WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); 425 WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
404 hwc->state |= PERF_HES_STOPPED; 426 hwc->state |= PERF_HES_STOPPED;
405 } 427 }
@@ -527,20 +549,24 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
527 u64 *buf, *config, period; 549 u64 *buf, *config, period;
528 550
529 if (!test_bit(IBS_STARTED, pcpu->state)) { 551 if (!test_bit(IBS_STARTED, pcpu->state)) {
552fail:
530 /* 553 /*
531 * Catch spurious interrupts after stopping IBS: After 554 * Catch spurious interrupts after stopping IBS: After
532 * disabling IBS there could be still incoming NMIs 555 * disabling IBS there could be still incoming NMIs
533 * with samples that even have the valid bit cleared. 556 * with samples that even have the valid bit cleared.
534 * Mark all this NMIs as handled. 557 * Mark all this NMIs as handled.
535 */ 558 */
536 return test_and_clear_bit(IBS_STOPPING, pcpu->state) ? 1 : 0; 559 if (test_and_clear_bit(IBS_STOPPING, pcpu->state))
560 return 1;
561
562 return 0;
537 } 563 }
538 564
539 msr = hwc->config_base; 565 msr = hwc->config_base;
540 buf = ibs_data.regs; 566 buf = ibs_data.regs;
541 rdmsrl(msr, *buf); 567 rdmsrl(msr, *buf);
542 if (!(*buf++ & perf_ibs->valid_mask)) 568 if (!(*buf++ & perf_ibs->valid_mask))
543 return 0; 569 goto fail;
544 570
545 config = &ibs_data.regs[0]; 571 config = &ibs_data.regs[0];
546 perf_ibs_event_update(perf_ibs, event, config); 572 perf_ibs_event_update(perf_ibs, event, config);
@@ -599,7 +625,7 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
599 throttle = perf_event_overflow(event, &data, &regs); 625 throttle = perf_event_overflow(event, &data, &regs);
600out: 626out:
601 if (throttle) 627 if (throttle)
602 perf_ibs_disable_event(perf_ibs, hwc, *config); 628 perf_ibs_stop(event, 0);
603 else 629 else
604 perf_ibs_enable_event(perf_ibs, hwc, period >> 4); 630 perf_ibs_enable_event(perf_ibs, hwc, period >> 4);
605 631
@@ -611,6 +637,7 @@ out:
611static int 637static int
612perf_ibs_nmi_handler(unsigned int cmd, struct pt_regs *regs) 638perf_ibs_nmi_handler(unsigned int cmd, struct pt_regs *regs)
613{ 639{
640 u64 stamp = sched_clock();
614 int handled = 0; 641 int handled = 0;
615 642
616 handled += perf_ibs_handle_irq(&perf_ibs_fetch, regs); 643 handled += perf_ibs_handle_irq(&perf_ibs_fetch, regs);
@@ -619,6 +646,8 @@ perf_ibs_nmi_handler(unsigned int cmd, struct pt_regs *regs)
619 if (handled) 646 if (handled)
620 inc_irq_stat(apic_perf_irqs); 647 inc_irq_stat(apic_perf_irqs);
621 648
649 perf_sample_event_took(sched_clock() - stamp);
650
622 return handled; 651 return handled;
623} 652}
624NOKPROBE_SYMBOL(perf_ibs_nmi_handler); 653NOKPROBE_SYMBOL(perf_ibs_nmi_handler);
diff --git a/arch/x86/events/amd/iommu.c b/arch/x86/events/amd/iommu.c
index 635e5eba0caf..40625ca7a190 100644
--- a/arch/x86/events/amd/iommu.c
+++ b/arch/x86/events/amd/iommu.c
@@ -118,6 +118,11 @@ static struct amd_iommu_event_desc amd_iommu_v2_event_descs[] = {
118 AMD_IOMMU_EVENT_DESC(cmd_processed, "csource=0x11"), 118 AMD_IOMMU_EVENT_DESC(cmd_processed, "csource=0x11"),
119 AMD_IOMMU_EVENT_DESC(cmd_processed_inv, "csource=0x12"), 119 AMD_IOMMU_EVENT_DESC(cmd_processed_inv, "csource=0x12"),
120 AMD_IOMMU_EVENT_DESC(tlb_inv, "csource=0x13"), 120 AMD_IOMMU_EVENT_DESC(tlb_inv, "csource=0x13"),
121 AMD_IOMMU_EVENT_DESC(ign_rd_wr_mmio_1ff8h, "csource=0x14"),
122 AMD_IOMMU_EVENT_DESC(vapic_int_non_guest, "csource=0x15"),
123 AMD_IOMMU_EVENT_DESC(vapic_int_guest, "csource=0x16"),
124 AMD_IOMMU_EVENT_DESC(smi_recv, "csource=0x17"),
125 AMD_IOMMU_EVENT_DESC(smi_blk, "csource=0x18"),
121 { /* end: all zeroes */ }, 126 { /* end: all zeroes */ },
122}; 127};
123 128
diff --git a/arch/x86/events/amd/power.c b/arch/x86/events/amd/power.c
new file mode 100644
index 000000000000..55a3529dbf12
--- /dev/null
+++ b/arch/x86/events/amd/power.c
@@ -0,0 +1,353 @@
1/*
2 * Performance events - AMD Processor Power Reporting Mechanism
3 *
4 * Copyright (C) 2016 Advanced Micro Devices, Inc.
5 *
6 * Author: Huang Rui <ray.huang@amd.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/perf_event.h>
16#include <asm/cpu_device_id.h>
17#include "../perf_event.h"
18
19#define MSR_F15H_CU_PWR_ACCUMULATOR 0xc001007a
20#define MSR_F15H_CU_MAX_PWR_ACCUMULATOR 0xc001007b
21#define MSR_F15H_PTSC 0xc0010280
22
23/* Event code: LSB 8 bits, passed in attr->config any other bit is reserved. */
24#define AMD_POWER_EVENT_MASK 0xFFULL
25
26/*
27 * Accumulated power status counters.
28 */
29#define AMD_POWER_EVENTSEL_PKG 1
30
31/*
32 * The ratio of compute unit power accumulator sample period to the
33 * PTSC period.
34 */
35static unsigned int cpu_pwr_sample_ratio;
36
37/* Maximum accumulated power of a compute unit. */
38static u64 max_cu_acc_power;
39
40static struct pmu pmu_class;
41
42/*
43 * Accumulated power represents the sum of each compute unit's (CU) power
44 * consumption. On any core of each CU we read the total accumulated power from
45 * MSR_F15H_CU_PWR_ACCUMULATOR. cpu_mask represents CPU bit map of all cores
46 * which are picked to measure the power for the CUs they belong to.
47 */
48static cpumask_t cpu_mask;
49
50static void event_update(struct perf_event *event)
51{
52 struct hw_perf_event *hwc = &event->hw;
53 u64 prev_pwr_acc, new_pwr_acc, prev_ptsc, new_ptsc;
54 u64 delta, tdelta;
55
56 prev_pwr_acc = hwc->pwr_acc;
57 prev_ptsc = hwc->ptsc;
58 rdmsrl(MSR_F15H_CU_PWR_ACCUMULATOR, new_pwr_acc);
59 rdmsrl(MSR_F15H_PTSC, new_ptsc);
60
61 /*
62 * Calculate the CU power consumption over a time period, the unit of
63 * final value (delta) is micro-Watts. Then add it to the event count.
64 */
65 if (new_pwr_acc < prev_pwr_acc) {
66 delta = max_cu_acc_power + new_pwr_acc;
67 delta -= prev_pwr_acc;
68 } else
69 delta = new_pwr_acc - prev_pwr_acc;
70
71 delta *= cpu_pwr_sample_ratio * 1000;
72 tdelta = new_ptsc - prev_ptsc;
73
74 do_div(delta, tdelta);
75 local64_add(delta, &event->count);
76}
77
78static void __pmu_event_start(struct perf_event *event)
79{
80 if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
81 return;
82
83 event->hw.state = 0;
84
85 rdmsrl(MSR_F15H_PTSC, event->hw.ptsc);
86 rdmsrl(MSR_F15H_CU_PWR_ACCUMULATOR, event->hw.pwr_acc);
87}
88
89static void pmu_event_start(struct perf_event *event, int mode)
90{
91 __pmu_event_start(event);
92}
93
94static void pmu_event_stop(struct perf_event *event, int mode)
95{
96 struct hw_perf_event *hwc = &event->hw;
97
98 /* Mark event as deactivated and stopped. */
99 if (!(hwc->state & PERF_HES_STOPPED))
100 hwc->state |= PERF_HES_STOPPED;
101
102 /* Check if software counter update is necessary. */
103 if ((mode & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
104 /*
105 * Drain the remaining delta count out of an event
106 * that we are disabling:
107 */
108 event_update(event);
109 hwc->state |= PERF_HES_UPTODATE;
110 }
111}
112
113static int pmu_event_add(struct perf_event *event, int mode)
114{
115 struct hw_perf_event *hwc = &event->hw;
116
117 hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
118
119 if (mode & PERF_EF_START)
120 __pmu_event_start(event);
121
122 return 0;
123}
124
125static void pmu_event_del(struct perf_event *event, int flags)
126{
127 pmu_event_stop(event, PERF_EF_UPDATE);
128}
129
130static int pmu_event_init(struct perf_event *event)
131{
132 u64 cfg = event->attr.config & AMD_POWER_EVENT_MASK;
133
134 /* Only look at AMD power events. */
135 if (event->attr.type != pmu_class.type)
136 return -ENOENT;
137
138 /* Unsupported modes and filters. */
139 if (event->attr.exclude_user ||
140 event->attr.exclude_kernel ||
141 event->attr.exclude_hv ||
142 event->attr.exclude_idle ||
143 event->attr.exclude_host ||
144 event->attr.exclude_guest ||
145 /* no sampling */
146 event->attr.sample_period)
147 return -EINVAL;
148
149 if (cfg != AMD_POWER_EVENTSEL_PKG)
150 return -EINVAL;
151
152 return 0;
153}
154
155static void pmu_event_read(struct perf_event *event)
156{
157 event_update(event);
158}
159
160static ssize_t
161get_attr_cpumask(struct device *dev, struct device_attribute *attr, char *buf)
162{
163 return cpumap_print_to_pagebuf(true, buf, &cpu_mask);
164}
165
166static DEVICE_ATTR(cpumask, S_IRUGO, get_attr_cpumask, NULL);
167
168static struct attribute *pmu_attrs[] = {
169 &dev_attr_cpumask.attr,
170 NULL,
171};
172
173static struct attribute_group pmu_attr_group = {
174 .attrs = pmu_attrs,
175};
176
177/*
178 * Currently it only supports to report the power of each
179 * processor/package.
180 */
181EVENT_ATTR_STR(power-pkg, power_pkg, "event=0x01");
182
183EVENT_ATTR_STR(power-pkg.unit, power_pkg_unit, "mWatts");
184
185/* Convert the count from micro-Watts to milli-Watts. */
186EVENT_ATTR_STR(power-pkg.scale, power_pkg_scale, "1.000000e-3");
187
188static struct attribute *events_attr[] = {
189 EVENT_PTR(power_pkg),
190 EVENT_PTR(power_pkg_unit),
191 EVENT_PTR(power_pkg_scale),
192 NULL,
193};
194
195static struct attribute_group pmu_events_group = {
196 .name = "events",
197 .attrs = events_attr,
198};
199
200PMU_FORMAT_ATTR(event, "config:0-7");
201
202static struct attribute *formats_attr[] = {
203 &format_attr_event.attr,
204 NULL,
205};
206
207static struct attribute_group pmu_format_group = {
208 .name = "format",
209 .attrs = formats_attr,
210};
211
212static const struct attribute_group *attr_groups[] = {
213 &pmu_attr_group,
214 &pmu_format_group,
215 &pmu_events_group,
216 NULL,
217};
218
219static struct pmu pmu_class = {
220 .attr_groups = attr_groups,
221 /* system-wide only */
222 .task_ctx_nr = perf_invalid_context,
223 .event_init = pmu_event_init,
224 .add = pmu_event_add,
225 .del = pmu_event_del,
226 .start = pmu_event_start,
227 .stop = pmu_event_stop,
228 .read = pmu_event_read,
229};
230
231static void power_cpu_exit(int cpu)
232{
233 int target;
234
235 if (!cpumask_test_and_clear_cpu(cpu, &cpu_mask))
236 return;
237
238 /*
239 * Find a new CPU on the same compute unit, if was set in cpumask
240 * and still some CPUs on compute unit. Then migrate event and
241 * context to new CPU.
242 */
243 target = cpumask_any_but(topology_sibling_cpumask(cpu), cpu);
244 if (target < nr_cpumask_bits) {
245 cpumask_set_cpu(target, &cpu_mask);
246 perf_pmu_migrate_context(&pmu_class, cpu, target);
247 }
248}
249
250static void power_cpu_init(int cpu)
251{
252 int target;
253
254 /*
255 * 1) If any CPU is set at cpu_mask in the same compute unit, do
256 * nothing.
257 * 2) If no CPU is set at cpu_mask in the same compute unit,
258 * set current STARTING CPU.
259 *
260 * Note: if there is a CPU aside of the new one already in the
261 * sibling mask, then it is also in cpu_mask.
262 */
263 target = cpumask_any_but(topology_sibling_cpumask(cpu), cpu);
264 if (target >= nr_cpumask_bits)
265 cpumask_set_cpu(cpu, &cpu_mask);
266}
267
268static int
269power_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
270{
271 unsigned int cpu = (long)hcpu;
272
273 switch (action & ~CPU_TASKS_FROZEN) {
274 case CPU_DOWN_FAILED:
275 case CPU_STARTING:
276 power_cpu_init(cpu);
277 break;
278 case CPU_DOWN_PREPARE:
279 power_cpu_exit(cpu);
280 break;
281 default:
282 break;
283 }
284
285 return NOTIFY_OK;
286}
287
288static struct notifier_block power_cpu_notifier_nb = {
289 .notifier_call = power_cpu_notifier,
290 .priority = CPU_PRI_PERF,
291};
292
293static const struct x86_cpu_id cpu_match[] = {
294 { .vendor = X86_VENDOR_AMD, .family = 0x15 },
295 {},
296};
297
298static int __init amd_power_pmu_init(void)
299{
300 int cpu, target, ret;
301
302 if (!x86_match_cpu(cpu_match))
303 return 0;
304
305 if (!boot_cpu_has(X86_FEATURE_ACC_POWER))
306 return -ENODEV;
307
308 cpu_pwr_sample_ratio = cpuid_ecx(0x80000007);
309
310 if (rdmsrl_safe(MSR_F15H_CU_MAX_PWR_ACCUMULATOR, &max_cu_acc_power)) {
311 pr_err("Failed to read max compute unit power accumulator MSR\n");
312 return -ENODEV;
313 }
314
315 cpu_notifier_register_begin();
316
317 /* Choose one online core of each compute unit. */
318 for_each_online_cpu(cpu) {
319 target = cpumask_first(topology_sibling_cpumask(cpu));
320 if (!cpumask_test_cpu(target, &cpu_mask))
321 cpumask_set_cpu(target, &cpu_mask);
322 }
323
324 ret = perf_pmu_register(&pmu_class, "power", -1);
325 if (WARN_ON(ret)) {
326 pr_warn("AMD Power PMU registration failed\n");
327 goto out;
328 }
329
330 __register_cpu_notifier(&power_cpu_notifier_nb);
331
332 pr_info("AMD Power PMU detected\n");
333
334out:
335 cpu_notifier_register_done();
336
337 return ret;
338}
339module_init(amd_power_pmu_init);
340
341static void __exit amd_power_pmu_exit(void)
342{
343 cpu_notifier_register_begin();
344 __unregister_cpu_notifier(&power_cpu_notifier_nb);
345 cpu_notifier_register_done();
346
347 perf_pmu_unregister(&pmu_class);
348}
349module_exit(amd_power_pmu_exit);
350
351MODULE_AUTHOR("Huang Rui <ray.huang@amd.com>");
352MODULE_DESCRIPTION("AMD Processor Power Reporting Mechanism");
353MODULE_LICENSE("GPL v2");
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 9b6ad08aa51a..041e442a3e28 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -1602,8 +1602,7 @@ __init struct attribute **merge_attr(struct attribute **a, struct attribute **b)
1602 return new; 1602 return new;
1603} 1603}
1604 1604
1605ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, 1605ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, char *page)
1606 char *page)
1607{ 1606{
1608 struct perf_pmu_events_attr *pmu_attr = \ 1607 struct perf_pmu_events_attr *pmu_attr = \
1609 container_of(attr, struct perf_pmu_events_attr, attr); 1608 container_of(attr, struct perf_pmu_events_attr, attr);
@@ -1615,6 +1614,7 @@ ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr,
1615 1614
1616 return x86_pmu.events_sysfs_show(page, config); 1615 return x86_pmu.events_sysfs_show(page, config);
1617} 1616}
1617EXPORT_SYMBOL_GPL(events_sysfs_show);
1618 1618
1619EVENT_ATTR(cpu-cycles, CPU_CYCLES ); 1619EVENT_ATTR(cpu-cycles, CPU_CYCLES );
1620EVENT_ATTR(instructions, INSTRUCTIONS ); 1620EVENT_ATTR(instructions, INSTRUCTIONS );
diff --git a/arch/x86/events/intel/cqm.c b/arch/x86/events/intel/cqm.c
index 93cb412a5579..7b5fd811ef45 100644
--- a/arch/x86/events/intel/cqm.c
+++ b/arch/x86/events/intel/cqm.c
@@ -13,8 +13,16 @@
13#define MSR_IA32_QM_CTR 0x0c8e 13#define MSR_IA32_QM_CTR 0x0c8e
14#define MSR_IA32_QM_EVTSEL 0x0c8d 14#define MSR_IA32_QM_EVTSEL 0x0c8d
15 15
16#define MBM_CNTR_WIDTH 24
17/*
18 * Guaranteed time in ms as per SDM where MBM counters will not overflow.
19 */
20#define MBM_CTR_OVERFLOW_TIME 1000
21
16static u32 cqm_max_rmid = -1; 22static u32 cqm_max_rmid = -1;
17static unsigned int cqm_l3_scale; /* supposedly cacheline size */ 23static unsigned int cqm_l3_scale; /* supposedly cacheline size */
24static bool cqm_enabled, mbm_enabled;
25unsigned int mbm_socket_max;
18 26
19/** 27/**
20 * struct intel_pqr_state - State cache for the PQR MSR 28 * struct intel_pqr_state - State cache for the PQR MSR
@@ -42,8 +50,37 @@ struct intel_pqr_state {
42 * interrupts disabled, which is sufficient for the protection. 50 * interrupts disabled, which is sufficient for the protection.
43 */ 51 */
44static DEFINE_PER_CPU(struct intel_pqr_state, pqr_state); 52static DEFINE_PER_CPU(struct intel_pqr_state, pqr_state);
53static struct hrtimer *mbm_timers;
54/**
55 * struct sample - mbm event's (local or total) data
56 * @total_bytes #bytes since we began monitoring
57 * @prev_msr previous value of MSR
58 */
59struct sample {
60 u64 total_bytes;
61 u64 prev_msr;
62};
45 63
46/* 64/*
65 * samples profiled for total memory bandwidth type events
66 */
67static struct sample *mbm_total;
68/*
69 * samples profiled for local memory bandwidth type events
70 */
71static struct sample *mbm_local;
72
73#define pkg_id topology_physical_package_id(smp_processor_id())
74/*
75 * rmid_2_index returns the index for the rmid in mbm_local/mbm_total array.
76 * mbm_total[] and mbm_local[] are linearly indexed by socket# * max number of
77 * rmids per socket, an example is given below
78 * RMID1 of Socket0: vrmid = 1
79 * RMID1 of Socket1: vrmid = 1 * (cqm_max_rmid + 1) + 1
80 * RMID1 of Socket2: vrmid = 2 * (cqm_max_rmid + 1) + 1
81 */
82#define rmid_2_index(rmid) ((pkg_id * (cqm_max_rmid + 1)) + rmid)
83/*
47 * Protects cache_cgroups and cqm_rmid_free_lru and cqm_rmid_limbo_lru. 84 * Protects cache_cgroups and cqm_rmid_free_lru and cqm_rmid_limbo_lru.
48 * Also protects event->hw.cqm_rmid 85 * Also protects event->hw.cqm_rmid
49 * 86 *
@@ -65,9 +102,13 @@ static cpumask_t cqm_cpumask;
65#define RMID_VAL_ERROR (1ULL << 63) 102#define RMID_VAL_ERROR (1ULL << 63)
66#define RMID_VAL_UNAVAIL (1ULL << 62) 103#define RMID_VAL_UNAVAIL (1ULL << 62)
67 104
68#define QOS_L3_OCCUP_EVENT_ID (1 << 0) 105/*
69 106 * Event IDs are used to program IA32_QM_EVTSEL before reading event
70#define QOS_EVENT_MASK QOS_L3_OCCUP_EVENT_ID 107 * counter from IA32_QM_CTR
108 */
109#define QOS_L3_OCCUP_EVENT_ID 0x01
110#define QOS_MBM_TOTAL_EVENT_ID 0x02
111#define QOS_MBM_LOCAL_EVENT_ID 0x03
71 112
72/* 113/*
73 * This is central to the rotation algorithm in __intel_cqm_rmid_rotate(). 114 * This is central to the rotation algorithm in __intel_cqm_rmid_rotate().
@@ -211,6 +252,21 @@ static void __put_rmid(u32 rmid)
211 list_add_tail(&entry->list, &cqm_rmid_limbo_lru); 252 list_add_tail(&entry->list, &cqm_rmid_limbo_lru);
212} 253}
213 254
255static void cqm_cleanup(void)
256{
257 int i;
258
259 if (!cqm_rmid_ptrs)
260 return;
261
262 for (i = 0; i < cqm_max_rmid; i++)
263 kfree(cqm_rmid_ptrs[i]);
264
265 kfree(cqm_rmid_ptrs);
266 cqm_rmid_ptrs = NULL;
267 cqm_enabled = false;
268}
269
214static int intel_cqm_setup_rmid_cache(void) 270static int intel_cqm_setup_rmid_cache(void)
215{ 271{
216 struct cqm_rmid_entry *entry; 272 struct cqm_rmid_entry *entry;
@@ -218,7 +274,7 @@ static int intel_cqm_setup_rmid_cache(void)
218 int r = 0; 274 int r = 0;
219 275
220 nr_rmids = cqm_max_rmid + 1; 276 nr_rmids = cqm_max_rmid + 1;
221 cqm_rmid_ptrs = kmalloc(sizeof(struct cqm_rmid_entry *) * 277 cqm_rmid_ptrs = kzalloc(sizeof(struct cqm_rmid_entry *) *
222 nr_rmids, GFP_KERNEL); 278 nr_rmids, GFP_KERNEL);
223 if (!cqm_rmid_ptrs) 279 if (!cqm_rmid_ptrs)
224 return -ENOMEM; 280 return -ENOMEM;
@@ -249,11 +305,9 @@ static int intel_cqm_setup_rmid_cache(void)
249 mutex_unlock(&cache_mutex); 305 mutex_unlock(&cache_mutex);
250 306
251 return 0; 307 return 0;
252fail:
253 while (r--)
254 kfree(cqm_rmid_ptrs[r]);
255 308
256 kfree(cqm_rmid_ptrs); 309fail:
310 cqm_cleanup();
257 return -ENOMEM; 311 return -ENOMEM;
258} 312}
259 313
@@ -281,9 +335,13 @@ static bool __match_event(struct perf_event *a, struct perf_event *b)
281 335
282 /* 336 /*
283 * Events that target same task are placed into the same cache group. 337 * Events that target same task are placed into the same cache group.
338 * Mark it as a multi event group, so that we update ->count
339 * for every event rather than just the group leader later.
284 */ 340 */
285 if (a->hw.target == b->hw.target) 341 if (a->hw.target == b->hw.target) {
342 b->hw.is_group_event = true;
286 return true; 343 return true;
344 }
287 345
288 /* 346 /*
289 * Are we an inherited event? 347 * Are we an inherited event?
@@ -392,10 +450,26 @@ static bool __conflict_event(struct perf_event *a, struct perf_event *b)
392 450
393struct rmid_read { 451struct rmid_read {
394 u32 rmid; 452 u32 rmid;
453 u32 evt_type;
395 atomic64_t value; 454 atomic64_t value;
396}; 455};
397 456
398static void __intel_cqm_event_count(void *info); 457static void __intel_cqm_event_count(void *info);
458static void init_mbm_sample(u32 rmid, u32 evt_type);
459static void __intel_mbm_event_count(void *info);
460
461static bool is_mbm_event(int e)
462{
463 return (e >= QOS_MBM_TOTAL_EVENT_ID && e <= QOS_MBM_LOCAL_EVENT_ID);
464}
465
466static void cqm_mask_call(struct rmid_read *rr)
467{
468 if (is_mbm_event(rr->evt_type))
469 on_each_cpu_mask(&cqm_cpumask, __intel_mbm_event_count, rr, 1);
470 else
471 on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count, rr, 1);
472}
399 473
400/* 474/*
401 * Exchange the RMID of a group of events. 475 * Exchange the RMID of a group of events.
@@ -413,12 +487,12 @@ static u32 intel_cqm_xchg_rmid(struct perf_event *group, u32 rmid)
413 */ 487 */
414 if (__rmid_valid(old_rmid) && !__rmid_valid(rmid)) { 488 if (__rmid_valid(old_rmid) && !__rmid_valid(rmid)) {
415 struct rmid_read rr = { 489 struct rmid_read rr = {
416 .value = ATOMIC64_INIT(0),
417 .rmid = old_rmid, 490 .rmid = old_rmid,
491 .evt_type = group->attr.config,
492 .value = ATOMIC64_INIT(0),
418 }; 493 };
419 494
420 on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count, 495 cqm_mask_call(&rr);
421 &rr, 1);
422 local64_set(&group->count, atomic64_read(&rr.value)); 496 local64_set(&group->count, atomic64_read(&rr.value));
423 } 497 }
424 498
@@ -430,6 +504,22 @@ static u32 intel_cqm_xchg_rmid(struct perf_event *group, u32 rmid)
430 504
431 raw_spin_unlock_irq(&cache_lock); 505 raw_spin_unlock_irq(&cache_lock);
432 506
507 /*
508 * If the allocation is for mbm, init the mbm stats.
509 * Need to check if each event in the group is mbm event
510 * because there could be multiple type of events in the same group.
511 */
512 if (__rmid_valid(rmid)) {
513 event = group;
514 if (is_mbm_event(event->attr.config))
515 init_mbm_sample(rmid, event->attr.config);
516
517 list_for_each_entry(event, head, hw.cqm_group_entry) {
518 if (is_mbm_event(event->attr.config))
519 init_mbm_sample(rmid, event->attr.config);
520 }
521 }
522
433 return old_rmid; 523 return old_rmid;
434} 524}
435 525
@@ -837,6 +927,72 @@ static void intel_cqm_rmid_rotate(struct work_struct *work)
837 schedule_delayed_work(&intel_cqm_rmid_work, delay); 927 schedule_delayed_work(&intel_cqm_rmid_work, delay);
838} 928}
839 929
930static u64 update_sample(unsigned int rmid, u32 evt_type, int first)
931{
932 struct sample *mbm_current;
933 u32 vrmid = rmid_2_index(rmid);
934 u64 val, bytes, shift;
935 u32 eventid;
936
937 if (evt_type == QOS_MBM_LOCAL_EVENT_ID) {
938 mbm_current = &mbm_local[vrmid];
939 eventid = QOS_MBM_LOCAL_EVENT_ID;
940 } else {
941 mbm_current = &mbm_total[vrmid];
942 eventid = QOS_MBM_TOTAL_EVENT_ID;
943 }
944
945 wrmsr(MSR_IA32_QM_EVTSEL, eventid, rmid);
946 rdmsrl(MSR_IA32_QM_CTR, val);
947 if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL))
948 return mbm_current->total_bytes;
949
950 if (first) {
951 mbm_current->prev_msr = val;
952 mbm_current->total_bytes = 0;
953 return mbm_current->total_bytes;
954 }
955
956 /*
957 * The h/w guarantees that counters will not overflow
958 * so long as we poll them at least once per second.
959 */
960 shift = 64 - MBM_CNTR_WIDTH;
961 bytes = (val << shift) - (mbm_current->prev_msr << shift);
962 bytes >>= shift;
963
964 bytes *= cqm_l3_scale;
965
966 mbm_current->total_bytes += bytes;
967 mbm_current->prev_msr = val;
968
969 return mbm_current->total_bytes;
970}
971
972static u64 rmid_read_mbm(unsigned int rmid, u32 evt_type)
973{
974 return update_sample(rmid, evt_type, 0);
975}
976
977static void __intel_mbm_event_init(void *info)
978{
979 struct rmid_read *rr = info;
980
981 update_sample(rr->rmid, rr->evt_type, 1);
982}
983
984static void init_mbm_sample(u32 rmid, u32 evt_type)
985{
986 struct rmid_read rr = {
987 .rmid = rmid,
988 .evt_type = evt_type,
989 .value = ATOMIC64_INIT(0),
990 };
991
992 /* on each socket, init sample */
993 on_each_cpu_mask(&cqm_cpumask, __intel_mbm_event_init, &rr, 1);
994}
995
840/* 996/*
841 * Find a group and setup RMID. 997 * Find a group and setup RMID.
842 * 998 *
@@ -849,6 +1005,7 @@ static void intel_cqm_setup_event(struct perf_event *event,
849 bool conflict = false; 1005 bool conflict = false;
850 u32 rmid; 1006 u32 rmid;
851 1007
1008 event->hw.is_group_event = false;
852 list_for_each_entry(iter, &cache_groups, hw.cqm_groups_entry) { 1009 list_for_each_entry(iter, &cache_groups, hw.cqm_groups_entry) {
853 rmid = iter->hw.cqm_rmid; 1010 rmid = iter->hw.cqm_rmid;
854 1011
@@ -856,6 +1013,8 @@ static void intel_cqm_setup_event(struct perf_event *event,
856 /* All tasks in a group share an RMID */ 1013 /* All tasks in a group share an RMID */
857 event->hw.cqm_rmid = rmid; 1014 event->hw.cqm_rmid = rmid;
858 *group = iter; 1015 *group = iter;
1016 if (is_mbm_event(event->attr.config) && __rmid_valid(rmid))
1017 init_mbm_sample(rmid, event->attr.config);
859 return; 1018 return;
860 } 1019 }
861 1020
@@ -872,6 +1031,9 @@ static void intel_cqm_setup_event(struct perf_event *event,
872 else 1031 else
873 rmid = __get_rmid(); 1032 rmid = __get_rmid();
874 1033
1034 if (is_mbm_event(event->attr.config) && __rmid_valid(rmid))
1035 init_mbm_sample(rmid, event->attr.config);
1036
875 event->hw.cqm_rmid = rmid; 1037 event->hw.cqm_rmid = rmid;
876} 1038}
877 1039
@@ -893,7 +1055,10 @@ static void intel_cqm_event_read(struct perf_event *event)
893 if (!__rmid_valid(rmid)) 1055 if (!__rmid_valid(rmid))
894 goto out; 1056 goto out;
895 1057
896 val = __rmid_read(rmid); 1058 if (is_mbm_event(event->attr.config))
1059 val = rmid_read_mbm(rmid, event->attr.config);
1060 else
1061 val = __rmid_read(rmid);
897 1062
898 /* 1063 /*
899 * Ignore this reading on error states and do not update the value. 1064 * Ignore this reading on error states and do not update the value.
@@ -924,10 +1089,100 @@ static inline bool cqm_group_leader(struct perf_event *event)
924 return !list_empty(&event->hw.cqm_groups_entry); 1089 return !list_empty(&event->hw.cqm_groups_entry);
925} 1090}
926 1091
1092static void __intel_mbm_event_count(void *info)
1093{
1094 struct rmid_read *rr = info;
1095 u64 val;
1096
1097 val = rmid_read_mbm(rr->rmid, rr->evt_type);
1098 if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL))
1099 return;
1100 atomic64_add(val, &rr->value);
1101}
1102
1103static enum hrtimer_restart mbm_hrtimer_handle(struct hrtimer *hrtimer)
1104{
1105 struct perf_event *iter, *iter1;
1106 int ret = HRTIMER_RESTART;
1107 struct list_head *head;
1108 unsigned long flags;
1109 u32 grp_rmid;
1110
1111 /*
1112 * Need to cache_lock as the timer Event Select MSR reads
1113 * can race with the mbm/cqm count() and mbm_init() reads.
1114 */
1115 raw_spin_lock_irqsave(&cache_lock, flags);
1116
1117 if (list_empty(&cache_groups)) {
1118 ret = HRTIMER_NORESTART;
1119 goto out;
1120 }
1121
1122 list_for_each_entry(iter, &cache_groups, hw.cqm_groups_entry) {
1123 grp_rmid = iter->hw.cqm_rmid;
1124 if (!__rmid_valid(grp_rmid))
1125 continue;
1126 if (is_mbm_event(iter->attr.config))
1127 update_sample(grp_rmid, iter->attr.config, 0);
1128
1129 head = &iter->hw.cqm_group_entry;
1130 if (list_empty(head))
1131 continue;
1132 list_for_each_entry(iter1, head, hw.cqm_group_entry) {
1133 if (!iter1->hw.is_group_event)
1134 break;
1135 if (is_mbm_event(iter1->attr.config))
1136 update_sample(iter1->hw.cqm_rmid,
1137 iter1->attr.config, 0);
1138 }
1139 }
1140
1141 hrtimer_forward_now(hrtimer, ms_to_ktime(MBM_CTR_OVERFLOW_TIME));
1142out:
1143 raw_spin_unlock_irqrestore(&cache_lock, flags);
1144
1145 return ret;
1146}
1147
1148static void __mbm_start_timer(void *info)
1149{
1150 hrtimer_start(&mbm_timers[pkg_id], ms_to_ktime(MBM_CTR_OVERFLOW_TIME),
1151 HRTIMER_MODE_REL_PINNED);
1152}
1153
1154static void __mbm_stop_timer(void *info)
1155{
1156 hrtimer_cancel(&mbm_timers[pkg_id]);
1157}
1158
1159static void mbm_start_timers(void)
1160{
1161 on_each_cpu_mask(&cqm_cpumask, __mbm_start_timer, NULL, 1);
1162}
1163
1164static void mbm_stop_timers(void)
1165{
1166 on_each_cpu_mask(&cqm_cpumask, __mbm_stop_timer, NULL, 1);
1167}
1168
1169static void mbm_hrtimer_init(void)
1170{
1171 struct hrtimer *hr;
1172 int i;
1173
1174 for (i = 0; i < mbm_socket_max; i++) {
1175 hr = &mbm_timers[i];
1176 hrtimer_init(hr, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
1177 hr->function = mbm_hrtimer_handle;
1178 }
1179}
1180
927static u64 intel_cqm_event_count(struct perf_event *event) 1181static u64 intel_cqm_event_count(struct perf_event *event)
928{ 1182{
929 unsigned long flags; 1183 unsigned long flags;
930 struct rmid_read rr = { 1184 struct rmid_read rr = {
1185 .evt_type = event->attr.config,
931 .value = ATOMIC64_INIT(0), 1186 .value = ATOMIC64_INIT(0),
932 }; 1187 };
933 1188
@@ -940,7 +1195,9 @@ static u64 intel_cqm_event_count(struct perf_event *event)
940 return __perf_event_count(event); 1195 return __perf_event_count(event);
941 1196
942 /* 1197 /*
943 * Only the group leader gets to report values. This stops us 1198 * Only the group leader gets to report values except in case of
1199 * multiple events in the same group, we still need to read the
1200 * other events.This stops us
944 * reporting duplicate values to userspace, and gives us a clear 1201 * reporting duplicate values to userspace, and gives us a clear
945 * rule for which task gets to report the values. 1202 * rule for which task gets to report the values.
946 * 1203 *
@@ -948,7 +1205,7 @@ static u64 intel_cqm_event_count(struct perf_event *event)
948 * specific packages - we forfeit that ability when we create 1205 * specific packages - we forfeit that ability when we create
949 * task events. 1206 * task events.
950 */ 1207 */
951 if (!cqm_group_leader(event)) 1208 if (!cqm_group_leader(event) && !event->hw.is_group_event)
952 return 0; 1209 return 0;
953 1210
954 /* 1211 /*
@@ -975,7 +1232,7 @@ static u64 intel_cqm_event_count(struct perf_event *event)
975 if (!__rmid_valid(rr.rmid)) 1232 if (!__rmid_valid(rr.rmid))
976 goto out; 1233 goto out;
977 1234
978 on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count, &rr, 1); 1235 cqm_mask_call(&rr);
979 1236
980 raw_spin_lock_irqsave(&cache_lock, flags); 1237 raw_spin_lock_irqsave(&cache_lock, flags);
981 if (event->hw.cqm_rmid == rr.rmid) 1238 if (event->hw.cqm_rmid == rr.rmid)
@@ -1046,8 +1303,14 @@ static int intel_cqm_event_add(struct perf_event *event, int mode)
1046static void intel_cqm_event_destroy(struct perf_event *event) 1303static void intel_cqm_event_destroy(struct perf_event *event)
1047{ 1304{
1048 struct perf_event *group_other = NULL; 1305 struct perf_event *group_other = NULL;
1306 unsigned long flags;
1049 1307
1050 mutex_lock(&cache_mutex); 1308 mutex_lock(&cache_mutex);
1309 /*
1310 * Hold the cache_lock as mbm timer handlers could be
1311 * scanning the list of events.
1312 */
1313 raw_spin_lock_irqsave(&cache_lock, flags);
1051 1314
1052 /* 1315 /*
1053 * If there's another event in this group... 1316 * If there's another event in this group...
@@ -1079,6 +1342,14 @@ static void intel_cqm_event_destroy(struct perf_event *event)
1079 } 1342 }
1080 } 1343 }
1081 1344
1345 raw_spin_unlock_irqrestore(&cache_lock, flags);
1346
1347 /*
1348 * Stop the mbm overflow timers when the last event is destroyed.
1349 */
1350 if (mbm_enabled && list_empty(&cache_groups))
1351 mbm_stop_timers();
1352
1082 mutex_unlock(&cache_mutex); 1353 mutex_unlock(&cache_mutex);
1083} 1354}
1084 1355
@@ -1086,11 +1357,13 @@ static int intel_cqm_event_init(struct perf_event *event)
1086{ 1357{
1087 struct perf_event *group = NULL; 1358 struct perf_event *group = NULL;
1088 bool rotate = false; 1359 bool rotate = false;
1360 unsigned long flags;
1089 1361
1090 if (event->attr.type != intel_cqm_pmu.type) 1362 if (event->attr.type != intel_cqm_pmu.type)
1091 return -ENOENT; 1363 return -ENOENT;
1092 1364
1093 if (event->attr.config & ~QOS_EVENT_MASK) 1365 if ((event->attr.config < QOS_L3_OCCUP_EVENT_ID) ||
1366 (event->attr.config > QOS_MBM_LOCAL_EVENT_ID))
1094 return -EINVAL; 1367 return -EINVAL;
1095 1368
1096 /* unsupported modes and filters */ 1369 /* unsupported modes and filters */
@@ -1110,9 +1383,21 @@ static int intel_cqm_event_init(struct perf_event *event)
1110 1383
1111 mutex_lock(&cache_mutex); 1384 mutex_lock(&cache_mutex);
1112 1385
1386 /*
1387 * Start the mbm overflow timers when the first event is created.
1388 */
1389 if (mbm_enabled && list_empty(&cache_groups))
1390 mbm_start_timers();
1391
1113 /* Will also set rmid */ 1392 /* Will also set rmid */
1114 intel_cqm_setup_event(event, &group); 1393 intel_cqm_setup_event(event, &group);
1115 1394
1395 /*
1396 * Hold the cache_lock as mbm timer handlers be
1397 * scanning the list of events.
1398 */
1399 raw_spin_lock_irqsave(&cache_lock, flags);
1400
1116 if (group) { 1401 if (group) {
1117 list_add_tail(&event->hw.cqm_group_entry, 1402 list_add_tail(&event->hw.cqm_group_entry,
1118 &group->hw.cqm_group_entry); 1403 &group->hw.cqm_group_entry);
@@ -1131,6 +1416,7 @@ static int intel_cqm_event_init(struct perf_event *event)
1131 rotate = true; 1416 rotate = true;
1132 } 1417 }
1133 1418
1419 raw_spin_unlock_irqrestore(&cache_lock, flags);
1134 mutex_unlock(&cache_mutex); 1420 mutex_unlock(&cache_mutex);
1135 1421
1136 if (rotate) 1422 if (rotate)
@@ -1145,6 +1431,16 @@ EVENT_ATTR_STR(llc_occupancy.unit, intel_cqm_llc_unit, "Bytes");
1145EVENT_ATTR_STR(llc_occupancy.scale, intel_cqm_llc_scale, NULL); 1431EVENT_ATTR_STR(llc_occupancy.scale, intel_cqm_llc_scale, NULL);
1146EVENT_ATTR_STR(llc_occupancy.snapshot, intel_cqm_llc_snapshot, "1"); 1432EVENT_ATTR_STR(llc_occupancy.snapshot, intel_cqm_llc_snapshot, "1");
1147 1433
1434EVENT_ATTR_STR(total_bytes, intel_cqm_total_bytes, "event=0x02");
1435EVENT_ATTR_STR(total_bytes.per-pkg, intel_cqm_total_bytes_pkg, "1");
1436EVENT_ATTR_STR(total_bytes.unit, intel_cqm_total_bytes_unit, "MB");
1437EVENT_ATTR_STR(total_bytes.scale, intel_cqm_total_bytes_scale, "1e-6");
1438
1439EVENT_ATTR_STR(local_bytes, intel_cqm_local_bytes, "event=0x03");
1440EVENT_ATTR_STR(local_bytes.per-pkg, intel_cqm_local_bytes_pkg, "1");
1441EVENT_ATTR_STR(local_bytes.unit, intel_cqm_local_bytes_unit, "MB");
1442EVENT_ATTR_STR(local_bytes.scale, intel_cqm_local_bytes_scale, "1e-6");
1443
1148static struct attribute *intel_cqm_events_attr[] = { 1444static struct attribute *intel_cqm_events_attr[] = {
1149 EVENT_PTR(intel_cqm_llc), 1445 EVENT_PTR(intel_cqm_llc),
1150 EVENT_PTR(intel_cqm_llc_pkg), 1446 EVENT_PTR(intel_cqm_llc_pkg),
@@ -1154,9 +1450,38 @@ static struct attribute *intel_cqm_events_attr[] = {
1154 NULL, 1450 NULL,
1155}; 1451};
1156 1452
1453static struct attribute *intel_mbm_events_attr[] = {
1454 EVENT_PTR(intel_cqm_total_bytes),
1455 EVENT_PTR(intel_cqm_local_bytes),
1456 EVENT_PTR(intel_cqm_total_bytes_pkg),
1457 EVENT_PTR(intel_cqm_local_bytes_pkg),
1458 EVENT_PTR(intel_cqm_total_bytes_unit),
1459 EVENT_PTR(intel_cqm_local_bytes_unit),
1460 EVENT_PTR(intel_cqm_total_bytes_scale),
1461 EVENT_PTR(intel_cqm_local_bytes_scale),
1462 NULL,
1463};
1464
1465static struct attribute *intel_cmt_mbm_events_attr[] = {
1466 EVENT_PTR(intel_cqm_llc),
1467 EVENT_PTR(intel_cqm_total_bytes),
1468 EVENT_PTR(intel_cqm_local_bytes),
1469 EVENT_PTR(intel_cqm_llc_pkg),
1470 EVENT_PTR(intel_cqm_total_bytes_pkg),
1471 EVENT_PTR(intel_cqm_local_bytes_pkg),
1472 EVENT_PTR(intel_cqm_llc_unit),
1473 EVENT_PTR(intel_cqm_total_bytes_unit),
1474 EVENT_PTR(intel_cqm_local_bytes_unit),
1475 EVENT_PTR(intel_cqm_llc_scale),
1476 EVENT_PTR(intel_cqm_total_bytes_scale),
1477 EVENT_PTR(intel_cqm_local_bytes_scale),
1478 EVENT_PTR(intel_cqm_llc_snapshot),
1479 NULL,
1480};
1481
1157static struct attribute_group intel_cqm_events_group = { 1482static struct attribute_group intel_cqm_events_group = {
1158 .name = "events", 1483 .name = "events",
1159 .attrs = intel_cqm_events_attr, 1484 .attrs = NULL,
1160}; 1485};
1161 1486
1162PMU_FORMAT_ATTR(event, "config:0-7"); 1487PMU_FORMAT_ATTR(event, "config:0-7");
@@ -1303,12 +1628,70 @@ static const struct x86_cpu_id intel_cqm_match[] = {
1303 {} 1628 {}
1304}; 1629};
1305 1630
1631static void mbm_cleanup(void)
1632{
1633 if (!mbm_enabled)
1634 return;
1635
1636 kfree(mbm_local);
1637 kfree(mbm_total);
1638 mbm_enabled = false;
1639}
1640
1641static const struct x86_cpu_id intel_mbm_local_match[] = {
1642 { .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_MBM_LOCAL },
1643 {}
1644};
1645
1646static const struct x86_cpu_id intel_mbm_total_match[] = {
1647 { .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_MBM_TOTAL },
1648 {}
1649};
1650
1651static int intel_mbm_init(void)
1652{
1653 int ret = 0, array_size, maxid = cqm_max_rmid + 1;
1654
1655 mbm_socket_max = topology_max_packages();
1656 array_size = sizeof(struct sample) * maxid * mbm_socket_max;
1657 mbm_local = kmalloc(array_size, GFP_KERNEL);
1658 if (!mbm_local)
1659 return -ENOMEM;
1660
1661 mbm_total = kmalloc(array_size, GFP_KERNEL);
1662 if (!mbm_total) {
1663 ret = -ENOMEM;
1664 goto out;
1665 }
1666
1667 array_size = sizeof(struct hrtimer) * mbm_socket_max;
1668 mbm_timers = kmalloc(array_size, GFP_KERNEL);
1669 if (!mbm_timers) {
1670 ret = -ENOMEM;
1671 goto out;
1672 }
1673 mbm_hrtimer_init();
1674
1675out:
1676 if (ret)
1677 mbm_cleanup();
1678
1679 return ret;
1680}
1681
1306static int __init intel_cqm_init(void) 1682static int __init intel_cqm_init(void)
1307{ 1683{
1308 char *str, scale[20]; 1684 char *str = NULL, scale[20];
1309 int i, cpu, ret; 1685 int i, cpu, ret;
1310 1686
1311 if (!x86_match_cpu(intel_cqm_match)) 1687 if (x86_match_cpu(intel_cqm_match))
1688 cqm_enabled = true;
1689
1690 if (x86_match_cpu(intel_mbm_local_match) &&
1691 x86_match_cpu(intel_mbm_total_match))
1692 mbm_enabled = true;
1693
1694 if (!cqm_enabled && !mbm_enabled)
1312 return -ENODEV; 1695 return -ENODEV;
1313 1696
1314 cqm_l3_scale = boot_cpu_data.x86_cache_occ_scale; 1697 cqm_l3_scale = boot_cpu_data.x86_cache_occ_scale;
@@ -1365,16 +1748,41 @@ static int __init intel_cqm_init(void)
1365 cqm_pick_event_reader(i); 1748 cqm_pick_event_reader(i);
1366 } 1749 }
1367 1750
1368 __perf_cpu_notifier(intel_cqm_cpu_notifier); 1751 if (mbm_enabled)
1752 ret = intel_mbm_init();
1753 if (ret && !cqm_enabled)
1754 goto out;
1755
1756 if (cqm_enabled && mbm_enabled)
1757 intel_cqm_events_group.attrs = intel_cmt_mbm_events_attr;
1758 else if (!cqm_enabled && mbm_enabled)
1759 intel_cqm_events_group.attrs = intel_mbm_events_attr;
1760 else if (cqm_enabled && !mbm_enabled)
1761 intel_cqm_events_group.attrs = intel_cqm_events_attr;
1369 1762
1370 ret = perf_pmu_register(&intel_cqm_pmu, "intel_cqm", -1); 1763 ret = perf_pmu_register(&intel_cqm_pmu, "intel_cqm", -1);
1371 if (ret) 1764 if (ret) {
1372 pr_err("Intel CQM perf registration failed: %d\n", ret); 1765 pr_err("Intel CQM perf registration failed: %d\n", ret);
1373 else 1766 goto out;
1767 }
1768
1769 if (cqm_enabled)
1374 pr_info("Intel CQM monitoring enabled\n"); 1770 pr_info("Intel CQM monitoring enabled\n");
1771 if (mbm_enabled)
1772 pr_info("Intel MBM enabled\n");
1375 1773
1774 /*
1775 * Register the hot cpu notifier once we are sure cqm
1776 * is enabled to avoid notifier leak.
1777 */
1778 __perf_cpu_notifier(intel_cqm_cpu_notifier);
1376out: 1779out:
1377 cpu_notifier_register_done(); 1780 cpu_notifier_register_done();
1781 if (ret) {
1782 kfree(str);
1783 cqm_cleanup();
1784 mbm_cleanup();
1785 }
1378 1786
1379 return ret; 1787 return ret;
1380} 1788}
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index ce7211a07c0b..8584b90d8e0b 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -570,11 +570,12 @@ int intel_pmu_drain_bts_buffer(void)
570 * We will overwrite the from and to address before we output 570 * We will overwrite the from and to address before we output
571 * the sample. 571 * the sample.
572 */ 572 */
573 rcu_read_lock();
573 perf_prepare_sample(&header, &data, event, &regs); 574 perf_prepare_sample(&header, &data, event, &regs);
574 575
575 if (perf_output_begin(&handle, event, header.size * 576 if (perf_output_begin(&handle, event, header.size *
576 (top - base - skip))) 577 (top - base - skip)))
577 return 1; 578 goto unlock;
578 579
579 for (at = base; at < top; at++) { 580 for (at = base; at < top; at++) {
580 /* Filter out any records that contain kernel addresses. */ 581 /* Filter out any records that contain kernel addresses. */
@@ -593,6 +594,8 @@ int intel_pmu_drain_bts_buffer(void)
593 /* There's new data available. */ 594 /* There's new data available. */
594 event->hw.interrupts++; 595 event->hw.interrupts++;
595 event->pending_kill = POLL_IN; 596 event->pending_kill = POLL_IN;
597unlock:
598 rcu_read_unlock();
596 return 1; 599 return 1;
597} 600}
598 601
diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c
index b834a3f55a01..70c93f9b03ac 100644
--- a/arch/x86/events/intel/rapl.c
+++ b/arch/x86/events/intel/rapl.c
@@ -711,6 +711,7 @@ static int __init rapl_pmu_init(void)
711 rapl_pmu_events_group.attrs = rapl_events_cln_attr; 711 rapl_pmu_events_group.attrs = rapl_events_cln_attr;
712 break; 712 break;
713 case 63: /* Haswell-Server */ 713 case 63: /* Haswell-Server */
714 case 79: /* Broadwell-Server */
714 apply_quirk = true; 715 apply_quirk = true;
715 rapl_cntr_mask = RAPL_IDX_SRV; 716 rapl_cntr_mask = RAPL_IDX_SRV;
716 rapl_pmu_events_group.attrs = rapl_events_srv_attr; 717 rapl_pmu_events_group.attrs = rapl_events_srv_attr;
@@ -718,6 +719,7 @@ static int __init rapl_pmu_init(void)
718 case 60: /* Haswell */ 719 case 60: /* Haswell */
719 case 69: /* Haswell-Celeron */ 720 case 69: /* Haswell-Celeron */
720 case 61: /* Broadwell */ 721 case 61: /* Broadwell */
722 case 71: /* Broadwell-H */
721 rapl_cntr_mask = RAPL_IDX_HSW; 723 rapl_cntr_mask = RAPL_IDX_HSW;
722 rapl_pmu_events_group.attrs = rapl_events_hsw_attr; 724 rapl_pmu_events_group.attrs = rapl_events_hsw_attr;
723 break; 725 break;
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index 93f6bd9bf761..ab2bcaaebe38 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -46,7 +46,6 @@
46 (SNBEP_PMON_CTL_EV_SEL_MASK | \ 46 (SNBEP_PMON_CTL_EV_SEL_MASK | \
47 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ 47 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \
48 SNBEP_PMON_CTL_EDGE_DET | \ 48 SNBEP_PMON_CTL_EDGE_DET | \
49 SNBEP_PMON_CTL_EV_SEL_EXT | \
50 SNBEP_PMON_CTL_INVERT | \ 49 SNBEP_PMON_CTL_INVERT | \
51 SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ 50 SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \
52 SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ 51 SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \
@@ -148,7 +147,6 @@
148/* IVBEP PCU */ 147/* IVBEP PCU */
149#define IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK \ 148#define IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK \
150 (SNBEP_PMON_CTL_EV_SEL_MASK | \ 149 (SNBEP_PMON_CTL_EV_SEL_MASK | \
151 SNBEP_PMON_CTL_EV_SEL_EXT | \
152 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ 150 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \
153 SNBEP_PMON_CTL_EDGE_DET | \ 151 SNBEP_PMON_CTL_EDGE_DET | \
154 SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ 152 SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \
@@ -258,7 +256,6 @@
258 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ 256 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \
259 SNBEP_PMON_CTL_EDGE_DET | \ 257 SNBEP_PMON_CTL_EDGE_DET | \
260 SNBEP_CBO_PMON_CTL_TID_EN | \ 258 SNBEP_CBO_PMON_CTL_TID_EN | \
261 SNBEP_PMON_CTL_EV_SEL_EXT | \
262 SNBEP_PMON_CTL_INVERT | \ 259 SNBEP_PMON_CTL_INVERT | \
263 KNL_PCU_MSR_PMON_CTL_TRESH_MASK | \ 260 KNL_PCU_MSR_PMON_CTL_TRESH_MASK | \
264 SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ 261 SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \
@@ -472,7 +469,7 @@ static struct attribute *snbep_uncore_cbox_formats_attr[] = {
472}; 469};
473 470
474static struct attribute *snbep_uncore_pcu_formats_attr[] = { 471static struct attribute *snbep_uncore_pcu_formats_attr[] = {
475 &format_attr_event_ext.attr, 472 &format_attr_event.attr,
476 &format_attr_occ_sel.attr, 473 &format_attr_occ_sel.attr,
477 &format_attr_edge.attr, 474 &format_attr_edge.attr,
478 &format_attr_inv.attr, 475 &format_attr_inv.attr,
@@ -1313,7 +1310,7 @@ static struct attribute *ivbep_uncore_cbox_formats_attr[] = {
1313}; 1310};
1314 1311
1315static struct attribute *ivbep_uncore_pcu_formats_attr[] = { 1312static struct attribute *ivbep_uncore_pcu_formats_attr[] = {
1316 &format_attr_event_ext.attr, 1313 &format_attr_event.attr,
1317 &format_attr_occ_sel.attr, 1314 &format_attr_occ_sel.attr,
1318 &format_attr_edge.attr, 1315 &format_attr_edge.attr,
1319 &format_attr_thresh5.attr, 1316 &format_attr_thresh5.attr,
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 3d1a84383162..8f9afefd2dc5 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -94,7 +94,7 @@
94#define X86_FEATURE_REP_GOOD ( 3*32+16) /* rep microcode works well */ 94#define X86_FEATURE_REP_GOOD ( 3*32+16) /* rep microcode works well */
95#define X86_FEATURE_MFENCE_RDTSC ( 3*32+17) /* "" Mfence synchronizes RDTSC */ 95#define X86_FEATURE_MFENCE_RDTSC ( 3*32+17) /* "" Mfence synchronizes RDTSC */
96#define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" Lfence synchronizes RDTSC */ 96#define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" Lfence synchronizes RDTSC */
97/* free, was #define X86_FEATURE_11AP ( 3*32+19) * "" Bad local APIC aka 11AP */ 97#define X86_FEATURE_ACC_POWER ( 3*32+19) /* AMD Accumulated Power Mechanism */
98#define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */ 98#define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */
99#define X86_FEATURE_ALWAYS ( 3*32+21) /* "" Always-present feature */ 99#define X86_FEATURE_ALWAYS ( 3*32+21) /* "" Always-present feature */
100#define X86_FEATURE_XTOPOLOGY ( 3*32+22) /* cpu topology enum extensions */ 100#define X86_FEATURE_XTOPOLOGY ( 3*32+22) /* cpu topology enum extensions */
@@ -245,6 +245,8 @@
245 245
246/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12 */ 246/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12 */
247#define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring if 1 */ 247#define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring if 1 */
248#define X86_FEATURE_CQM_MBM_TOTAL (12*32+ 1) /* LLC Total MBM monitoring */
249#define X86_FEATURE_CQM_MBM_LOCAL (12*32+ 2) /* LLC Local MBM monitoring */
248 250
249/* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */ 251/* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */
250#define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */ 252#define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index e51021c9207a..6e47e3a916f1 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -309,7 +309,6 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
309 u32 eax, ebx, ecx, edx; 309 u32 eax, ebx, ecx, edx;
310 310
311 cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); 311 cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
312 nodes_per_socket = ((ecx >> 8) & 7) + 1;
313 node_id = ecx & 7; 312 node_id = ecx & 7;
314 313
315 /* get compute unit information */ 314 /* get compute unit information */
@@ -320,7 +319,6 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
320 u64 value; 319 u64 value;
321 320
322 rdmsrl(MSR_FAM10H_NODE_ID, value); 321 rdmsrl(MSR_FAM10H_NODE_ID, value);
323 nodes_per_socket = ((value >> 3) & 7) + 1;
324 node_id = value & 7; 322 node_id = value & 7;
325 } else 323 } else
326 return; 324 return;
@@ -522,6 +520,18 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
522 520
523 if (cpu_has(c, X86_FEATURE_MWAITX)) 521 if (cpu_has(c, X86_FEATURE_MWAITX))
524 use_mwaitx_delay(); 522 use_mwaitx_delay();
523
524 if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
525 u32 ecx;
526
527 ecx = cpuid_ecx(0x8000001e);
528 nodes_per_socket = ((ecx >> 8) & 7) + 1;
529 } else if (boot_cpu_has(X86_FEATURE_NODEID_MSR)) {
530 u64 value;
531
532 rdmsrl(MSR_FAM10H_NODE_ID, value);
533 nodes_per_socket = ((value >> 3) & 7) + 1;
534 }
525} 535}
526 536
527static void early_init_amd(struct cpuinfo_x86 *c) 537static void early_init_amd(struct cpuinfo_x86 *c)
@@ -539,6 +549,10 @@ static void early_init_amd(struct cpuinfo_x86 *c)
539 set_sched_clock_stable(); 549 set_sched_clock_stable();
540 } 550 }
541 551
552 /* Bit 12 of 8000_0007 edx is accumulated power mechanism. */
553 if (c->x86_power & BIT(12))
554 set_cpu_cap(c, X86_FEATURE_ACC_POWER);
555
542#ifdef CONFIG_X86_64 556#ifdef CONFIG_X86_64
543 set_cpu_cap(c, X86_FEATURE_SYSCALL32); 557 set_cpu_cap(c, X86_FEATURE_SYSCALL32);
544#else 558#else
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 9988caf42161..8394b3d1f94f 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -692,7 +692,9 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
692 cpuid_count(0x0000000F, 1, &eax, &ebx, &ecx, &edx); 692 cpuid_count(0x0000000F, 1, &eax, &ebx, &ecx, &edx);
693 c->x86_capability[CPUID_F_1_EDX] = edx; 693 c->x86_capability[CPUID_F_1_EDX] = edx;
694 694
695 if (cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) { 695 if ((cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) ||
696 ((cpu_has(c, X86_FEATURE_CQM_MBM_TOTAL)) ||
697 (cpu_has(c, X86_FEATURE_CQM_MBM_LOCAL)))) {
696 c->x86_cache_max_rmid = ecx; 698 c->x86_cache_max_rmid = ecx;
697 c->x86_cache_occ_scale = ebx; 699 c->x86_cache_occ_scale = ebx;
698 } 700 }
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 78fda2a69ab8..f291275ffd71 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -121,6 +121,7 @@ struct hw_perf_event {
121 struct { /* intel_cqm */ 121 struct { /* intel_cqm */
122 int cqm_state; 122 int cqm_state;
123 u32 cqm_rmid; 123 u32 cqm_rmid;
124 int is_group_event;
124 struct list_head cqm_events_entry; 125 struct list_head cqm_events_entry;
125 struct list_head cqm_groups_entry; 126 struct list_head cqm_groups_entry;
126 struct list_head cqm_group_entry; 127 struct list_head cqm_group_entry;
@@ -128,6 +129,10 @@ struct hw_perf_event {
128 struct { /* itrace */ 129 struct { /* itrace */
129 int itrace_started; 130 int itrace_started;
130 }; 131 };
132 struct { /* amd_power */
133 u64 pwr_acc;
134 u64 ptsc;
135 };
131#ifdef CONFIG_HAVE_HW_BREAKPOINT 136#ifdef CONFIG_HAVE_HW_BREAKPOINT
132 struct { /* breakpoint */ 137 struct { /* breakpoint */
133 /* 138 /*
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 712570dddacd..de24fbce5277 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -376,8 +376,11 @@ static void update_perf_cpu_limits(void)
376 u64 tmp = perf_sample_period_ns; 376 u64 tmp = perf_sample_period_ns;
377 377
378 tmp *= sysctl_perf_cpu_time_max_percent; 378 tmp *= sysctl_perf_cpu_time_max_percent;
379 do_div(tmp, 100); 379 tmp = div_u64(tmp, 100);
380 ACCESS_ONCE(perf_sample_allowed_ns) = tmp; 380 if (!tmp)
381 tmp = 1;
382
383 WRITE_ONCE(perf_sample_allowed_ns, tmp);
381} 384}
382 385
383static int perf_rotate_context(struct perf_cpu_context *cpuctx); 386static int perf_rotate_context(struct perf_cpu_context *cpuctx);
@@ -409,7 +412,13 @@ int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write,
409 if (ret || !write) 412 if (ret || !write)
410 return ret; 413 return ret;
411 414
412 update_perf_cpu_limits(); 415 if (sysctl_perf_cpu_time_max_percent == 100) {
416 printk(KERN_WARNING
417 "perf: Dynamic interrupt throttling disabled, can hang your system!\n");
418 WRITE_ONCE(perf_sample_allowed_ns, 0);
419 } else {
420 update_perf_cpu_limits();
421 }
413 422
414 return 0; 423 return 0;
415} 424}
@@ -423,62 +432,68 @@ int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write,
423#define NR_ACCUMULATED_SAMPLES 128 432#define NR_ACCUMULATED_SAMPLES 128
424static DEFINE_PER_CPU(u64, running_sample_length); 433static DEFINE_PER_CPU(u64, running_sample_length);
425 434
435static u64 __report_avg;
436static u64 __report_allowed;
437
426static void perf_duration_warn(struct irq_work *w) 438static void perf_duration_warn(struct irq_work *w)
427{ 439{
428 u64 allowed_ns = ACCESS_ONCE(perf_sample_allowed_ns);
429 u64 avg_local_sample_len;
430 u64 local_samples_len;
431
432 local_samples_len = __this_cpu_read(running_sample_length);
433 avg_local_sample_len = local_samples_len/NR_ACCUMULATED_SAMPLES;
434
435 printk_ratelimited(KERN_WARNING 440 printk_ratelimited(KERN_WARNING
436 "perf interrupt took too long (%lld > %lld), lowering " 441 "perf: interrupt took too long (%lld > %lld), lowering "
437 "kernel.perf_event_max_sample_rate to %d\n", 442 "kernel.perf_event_max_sample_rate to %d\n",
438 avg_local_sample_len, allowed_ns >> 1, 443 __report_avg, __report_allowed,
439 sysctl_perf_event_sample_rate); 444 sysctl_perf_event_sample_rate);
440} 445}
441 446
442static DEFINE_IRQ_WORK(perf_duration_work, perf_duration_warn); 447static DEFINE_IRQ_WORK(perf_duration_work, perf_duration_warn);
443 448
444void perf_sample_event_took(u64 sample_len_ns) 449void perf_sample_event_took(u64 sample_len_ns)
445{ 450{
446 u64 allowed_ns = ACCESS_ONCE(perf_sample_allowed_ns); 451 u64 max_len = READ_ONCE(perf_sample_allowed_ns);
447 u64 avg_local_sample_len; 452 u64 running_len;
448 u64 local_samples_len; 453 u64 avg_len;
454 u32 max;
449 455
450 if (allowed_ns == 0) 456 if (max_len == 0)
451 return; 457 return;
452 458
453 /* decay the counter by 1 average sample */ 459 /* Decay the counter by 1 average sample. */
454 local_samples_len = __this_cpu_read(running_sample_length); 460 running_len = __this_cpu_read(running_sample_length);
455 local_samples_len -= local_samples_len/NR_ACCUMULATED_SAMPLES; 461 running_len -= running_len/NR_ACCUMULATED_SAMPLES;
456 local_samples_len += sample_len_ns; 462 running_len += sample_len_ns;
457 __this_cpu_write(running_sample_length, local_samples_len); 463 __this_cpu_write(running_sample_length, running_len);
458 464
459 /* 465 /*
460 * note: this will be biased artifically low until we have 466 * Note: this will be biased artifically low until we have
461 * seen NR_ACCUMULATED_SAMPLES. Doing it this way keeps us 467 * seen NR_ACCUMULATED_SAMPLES. Doing it this way keeps us
462 * from having to maintain a count. 468 * from having to maintain a count.
463 */ 469 */
464 avg_local_sample_len = local_samples_len/NR_ACCUMULATED_SAMPLES; 470 avg_len = running_len/NR_ACCUMULATED_SAMPLES;
465 471 if (avg_len <= max_len)
466 if (avg_local_sample_len <= allowed_ns)
467 return; 472 return;
468 473
469 if (max_samples_per_tick <= 1) 474 __report_avg = avg_len;
470 return; 475 __report_allowed = max_len;
471 476
472 max_samples_per_tick = DIV_ROUND_UP(max_samples_per_tick, 2); 477 /*
473 sysctl_perf_event_sample_rate = max_samples_per_tick * HZ; 478 * Compute a throttle threshold 25% below the current duration.
474 perf_sample_period_ns = NSEC_PER_SEC / sysctl_perf_event_sample_rate; 479 */
480 avg_len += avg_len / 4;
481 max = (TICK_NSEC / 100) * sysctl_perf_cpu_time_max_percent;
482 if (avg_len < max)
483 max /= (u32)avg_len;
484 else
485 max = 1;
475 486
476 update_perf_cpu_limits(); 487 WRITE_ONCE(perf_sample_allowed_ns, avg_len);
488 WRITE_ONCE(max_samples_per_tick, max);
489
490 sysctl_perf_event_sample_rate = max * HZ;
491 perf_sample_period_ns = NSEC_PER_SEC / sysctl_perf_event_sample_rate;
477 492
478 if (!irq_work_queue(&perf_duration_work)) { 493 if (!irq_work_queue(&perf_duration_work)) {
479 early_printk("perf interrupt took too long (%lld > %lld), lowering " 494 early_printk("perf: interrupt took too long (%lld > %lld), lowering "
480 "kernel.perf_event_max_sample_rate to %d\n", 495 "kernel.perf_event_max_sample_rate to %d\n",
481 avg_local_sample_len, allowed_ns >> 1, 496 __report_avg, __report_allowed,
482 sysctl_perf_event_sample_rate); 497 sysctl_perf_event_sample_rate);
483 } 498 }
484} 499}
@@ -4210,6 +4225,14 @@ static void __perf_event_period(struct perf_event *event,
4210 active = (event->state == PERF_EVENT_STATE_ACTIVE); 4225 active = (event->state == PERF_EVENT_STATE_ACTIVE);
4211 if (active) { 4226 if (active) {
4212 perf_pmu_disable(ctx->pmu); 4227 perf_pmu_disable(ctx->pmu);
4228 /*
4229 * We could be throttled; unthrottle now to avoid the tick
4230 * trying to unthrottle while we already re-started the event.
4231 */
4232 if (event->hw.interrupts == MAX_INTERRUPTS) {
4233 event->hw.interrupts = 0;
4234 perf_log_throttle(event, 1);
4235 }
4213 event->pmu->stop(event, PERF_EF_UPDATE); 4236 event->pmu->stop(event, PERF_EF_UPDATE);
4214 } 4237 }
4215 4238
@@ -9426,10 +9449,29 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu)
9426 switch (action & ~CPU_TASKS_FROZEN) { 9449 switch (action & ~CPU_TASKS_FROZEN) {
9427 9450
9428 case CPU_UP_PREPARE: 9451 case CPU_UP_PREPARE:
9452 /*
9453 * This must be done before the CPU comes alive, because the
9454 * moment we can run tasks we can encounter (software) events.
9455 *
9456 * Specifically, someone can have inherited events on kthreadd
9457 * or a pre-existing worker thread that gets re-bound.
9458 */
9429 perf_event_init_cpu(cpu); 9459 perf_event_init_cpu(cpu);
9430 break; 9460 break;
9431 9461
9432 case CPU_DOWN_PREPARE: 9462 case CPU_DOWN_PREPARE:
9463 /*
9464 * This must be done before the CPU dies because after that an
9465 * active event might want to IPI the CPU and that'll not work
9466 * so great for dead CPUs.
9467 *
9468 * XXX smp_call_function_single() return -ENXIO without a warn
9469 * so we could possibly deal with this.
9470 *
9471 * This is safe against new events arriving because
9472 * sys_perf_event_open() serializes against hotplug using
9473 * get_online_cpus().
9474 */
9433 perf_event_exit_cpu(cpu); 9475 perf_event_exit_cpu(cpu);
9434 break; 9476 break;
9435 default: 9477 default:
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
index 1faad2cfdb9e..c61f0cbd308b 100644
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -746,8 +746,10 @@ struct ring_buffer *rb_alloc(int nr_pages, long watermark, int cpu, int flags)
746 746
747 rb->user_page = all_buf; 747 rb->user_page = all_buf;
748 rb->data_pages[0] = all_buf + PAGE_SIZE; 748 rb->data_pages[0] = all_buf + PAGE_SIZE;
749 rb->page_order = ilog2(nr_pages); 749 if (nr_pages) {
750 rb->nr_pages = !!nr_pages; 750 rb->nr_pages = 1;
751 rb->page_order = ilog2(nr_pages);
752 }
751 753
752 ring_buffer_init(rb, watermark, flags); 754 ring_buffer_init(rb, watermark, flags);
753 755
diff --git a/tools/include/linux/stringify.h b/tools/include/linux/stringify.h
new file mode 100644
index 000000000000..841cec8ed525
--- /dev/null
+++ b/tools/include/linux/stringify.h
@@ -0,0 +1,12 @@
1#ifndef __LINUX_STRINGIFY_H
2#define __LINUX_STRINGIFY_H
3
4/* Indirect stringification. Doing two levels allows the parameter to be a
5 * macro itself. For example, compile with -DFOO=bar, __stringify(FOO)
6 * converts to "bar".
7 */
8
9#define __stringify_1(x...) #x
10#define __stringify(x...) __stringify_1(x)
11
12#endif /* !__LINUX_STRINGIFY_H */
diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile
index bbc82c614bee..316f308a63ea 100644
--- a/tools/lib/api/Makefile
+++ b/tools/lib/api/Makefile
@@ -1,5 +1,5 @@
1include ../../scripts/Makefile.include 1include ../../scripts/Makefile.include
2include ../../perf/config/utilities.mak # QUIET_CLEAN 2include ../../scripts/utilities.mak # QUIET_CLEAN
3 3
4ifeq ($(srctree),) 4ifeq ($(srctree),)
5srctree := $(patsubst %/,%,$(dir $(shell pwd))) 5srctree := $(patsubst %/,%,$(dir $(shell pwd)))
diff --git a/tools/lib/subcmd/Makefile b/tools/lib/subcmd/Makefile
index 1faecb82ad42..a8103700c172 100644
--- a/tools/lib/subcmd/Makefile
+++ b/tools/lib/subcmd/Makefile
@@ -1,5 +1,5 @@
1include ../../scripts/Makefile.include 1include ../../scripts/Makefile.include
2include ../../perf/config/utilities.mak # QUIET_CLEAN 2include ../../scripts/utilities.mak # QUIET_CLEAN
3 3
4ifeq ($(srctree),) 4ifeq ($(srctree),)
5srctree := $(patsubst %/,%,$(dir $(shell pwd))) 5srctree := $(patsubst %/,%,$(dir $(shell pwd)))
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 190cc886ab91..a8b6357d1ffe 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -5427,10 +5427,8 @@ void pevent_print_event_time(struct pevent *pevent, struct trace_seq *s,
5427 } 5427 }
5428 5428
5429 if (pevent->latency_format) { 5429 if (pevent->latency_format) {
5430 trace_seq_printf(s, " %3d", record->cpu);
5431 pevent_data_lat_fmt(pevent, s, record); 5430 pevent_data_lat_fmt(pevent, s, record);
5432 } else 5431 }
5433 trace_seq_printf(s, " [%03d]", record->cpu);
5434 5432
5435 if (use_usec_format) { 5433 if (use_usec_format) {
5436 if (pevent->flags & PEVENT_NSEC_OUTPUT) { 5434 if (pevent->flags & PEVENT_NSEC_OUTPUT) {
diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile
index 3ba1c0b09908..098cfb9ca8f0 100644
--- a/tools/perf/Documentation/Makefile
+++ b/tools/perf/Documentation/Makefile
@@ -1,5 +1,5 @@
1include ../../scripts/Makefile.include 1include ../../scripts/Makefile.include
2include ../config/utilities.mak 2include ../../scripts/utilities.mak
3 3
4MAN1_TXT= \ 4MAN1_TXT= \
5 $(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \ 5 $(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index 79483f40e991..ec723d0a5bb3 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -40,10 +40,12 @@ address should be. The 'p' modifier can be specified multiple times:
40 0 - SAMPLE_IP can have arbitrary skid 40 0 - SAMPLE_IP can have arbitrary skid
41 1 - SAMPLE_IP must have constant skid 41 1 - SAMPLE_IP must have constant skid
42 2 - SAMPLE_IP requested to have 0 skid 42 2 - SAMPLE_IP requested to have 0 skid
43 3 - SAMPLE_IP must have 0 skid 43 3 - SAMPLE_IP must have 0 skid, or uses randomization to avoid
44 sample shadowing effects.
44 45
45For Intel systems precise event sampling is implemented with PEBS 46For Intel systems precise event sampling is implemented with PEBS
46which supports up to precise-level 2. 47which supports up to precise-level 2, and precise level 3 for
48some special cases
47 49
48On AMD systems it is implemented using IBS (up to precise-level 2). 50On AMD systems it is implemented using IBS (up to precise-level 2).
49The precise modifier works with event types 0x76 (cpu-cycles, CPU 51The precise modifier works with event types 0x76 (cpu-cycles, CPU
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 4a4fad4182f5..000ea210389d 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -3,7 +3,7 @@ include ../scripts/Makefile.include
3# The default target of this Makefile is... 3# The default target of this Makefile is...
4all: 4all:
5 5
6include config/utilities.mak 6include ../scripts/utilities.mak
7 7
8# Define V to have a more verbose compile. 8# Define V to have a more verbose compile.
9# 9#
diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c
index 6c1b8a75db09..6138bdef6e63 100644
--- a/tools/perf/arch/powerpc/util/header.c
+++ b/tools/perf/arch/powerpc/util/header.c
@@ -3,9 +3,7 @@
3#include <stdio.h> 3#include <stdio.h>
4#include <stdlib.h> 4#include <stdlib.h>
5#include <string.h> 5#include <string.h>
6 6#include <linux/stringify.h>
7#include "../../util/header.h"
8#include "../../util/util.h"
9 7
10#define mfspr(rn) ({unsigned long rval; \ 8#define mfspr(rn) ({unsigned long rval; \
11 asm volatile("mfspr %0," __stringify(rn) \ 9 asm volatile("mfspr %0," __stringify(rn) \
diff --git a/tools/perf/bench/bench.h b/tools/perf/bench/bench.h
index a50df86f2b9b..579a592990dd 100644
--- a/tools/perf/bench/bench.h
+++ b/tools/perf/bench/bench.h
@@ -25,19 +25,17 @@
25# endif 25# endif
26#endif 26#endif
27 27
28extern int bench_numa(int argc, const char **argv, const char *prefix); 28int bench_numa(int argc, const char **argv, const char *prefix);
29extern int bench_sched_messaging(int argc, const char **argv, const char *prefix); 29int bench_sched_messaging(int argc, const char **argv, const char *prefix);
30extern int bench_sched_pipe(int argc, const char **argv, const char *prefix); 30int bench_sched_pipe(int argc, const char **argv, const char *prefix);
31extern int bench_mem_memcpy(int argc, const char **argv, 31int bench_mem_memcpy(int argc, const char **argv, const char *prefix);
32 const char *prefix __maybe_unused); 32int bench_mem_memset(int argc, const char **argv, const char *prefix);
33extern int bench_mem_memset(int argc, const char **argv, const char *prefix); 33int bench_futex_hash(int argc, const char **argv, const char *prefix);
34extern int bench_futex_hash(int argc, const char **argv, const char *prefix); 34int bench_futex_wake(int argc, const char **argv, const char *prefix);
35extern int bench_futex_wake(int argc, const char **argv, const char *prefix); 35int bench_futex_wake_parallel(int argc, const char **argv, const char *prefix);
36extern int bench_futex_wake_parallel(int argc, const char **argv, 36int bench_futex_requeue(int argc, const char **argv, const char *prefix);
37 const char *prefix);
38extern int bench_futex_requeue(int argc, const char **argv, const char *prefix);
39/* pi futexes */ 37/* pi futexes */
40extern int bench_futex_lock_pi(int argc, const char **argv, const char *prefix); 38int bench_futex_lock_pi(int argc, const char **argv, const char *prefix);
41 39
42#define BENCH_FORMAT_DEFAULT_STR "default" 40#define BENCH_FORMAT_DEFAULT_STR "default"
43#define BENCH_FORMAT_DEFAULT 0 41#define BENCH_FORMAT_DEFAULT 0
diff --git a/tools/perf/bench/mem-memcpy-arch.h b/tools/perf/bench/mem-memcpy-arch.h
index 57b4ed871459..5aad2a9408b0 100644
--- a/tools/perf/bench/mem-memcpy-arch.h
+++ b/tools/perf/bench/mem-memcpy-arch.h
@@ -2,7 +2,7 @@
2#ifdef HAVE_ARCH_X86_64_SUPPORT 2#ifdef HAVE_ARCH_X86_64_SUPPORT
3 3
4#define MEMCPY_FN(fn, name, desc) \ 4#define MEMCPY_FN(fn, name, desc) \
5 extern void *fn(void *, const void *, size_t); 5 void *fn(void *, const void *, size_t);
6 6
7#include "mem-memcpy-x86-64-asm-def.h" 7#include "mem-memcpy-x86-64-asm-def.h"
8 8
diff --git a/tools/perf/bench/mem-memset-arch.h b/tools/perf/bench/mem-memset-arch.h
index 633800cb0dcb..0d15786d9ae3 100644
--- a/tools/perf/bench/mem-memset-arch.h
+++ b/tools/perf/bench/mem-memset-arch.h
@@ -2,7 +2,7 @@
2#ifdef HAVE_ARCH_X86_64_SUPPORT 2#ifdef HAVE_ARCH_X86_64_SUPPORT
3 3
4#define MEMSET_FN(fn, name, desc) \ 4#define MEMSET_FN(fn, name, desc) \
5 extern void *fn(void *, int, size_t); 5 void *fn(void *, int, size_t);
6 6
7#include "mem-memset-x86-64-asm-def.h" 7#include "mem-memset-x86-64-asm-def.h"
8 8
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c
index 5049d6357a46..7500d959d7eb 100644
--- a/tools/perf/bench/numa.c
+++ b/tools/perf/bench/numa.c
@@ -293,7 +293,7 @@ static void bind_to_memnode(int node)
293 if (node == -1) 293 if (node == -1)
294 return; 294 return;
295 295
296 BUG_ON(g->p.nr_nodes > (int)sizeof(nodemask)); 296 BUG_ON(g->p.nr_nodes > (int)sizeof(nodemask)*8);
297 nodemask = 1L << node; 297 nodemask = 1L << node;
298 298
299 ret = set_mempolicy(MPOL_BIND, &nodemask, sizeof(nodemask)*8); 299 ret = set_mempolicy(MPOL_BIND, &nodemask, sizeof(nodemask)*8);
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index cfe366375c4b..814158393656 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -94,7 +94,7 @@ static int process_sample_event(struct perf_tool *tool,
94 struct addr_location al; 94 struct addr_location al;
95 int ret = 0; 95 int ret = 0;
96 96
97 if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { 97 if (machine__resolve(machine, &al, sample) < 0) {
98 pr_warning("problem processing %d event, skipping it.\n", 98 pr_warning("problem processing %d event, skipping it.\n",
99 event->header.type); 99 event->header.type);
100 return -1; 100 return -1;
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 4d72359fd15a..8053a8ceefda 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -330,7 +330,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
330 struct hists *hists = evsel__hists(evsel); 330 struct hists *hists = evsel__hists(evsel);
331 int ret = -1; 331 int ret = -1;
332 332
333 if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { 333 if (machine__resolve(machine, &al, sample) < 0) {
334 pr_warning("problem processing %d event, skipping it.\n", 334 pr_warning("problem processing %d event, skipping it.\n",
335 event->header.type); 335 event->header.type);
336 return -1; 336 return -1;
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c
index 49d55e21b1b0..bc1de9b8fd67 100644
--- a/tools/perf/builtin-help.c
+++ b/tools/perf/builtin-help.c
@@ -106,12 +106,14 @@ static void exec_woman_emacs(const char *path, const char *page)
106 106
107 if (!check_emacsclient_version()) { 107 if (!check_emacsclient_version()) {
108 /* This works only with emacsclient version >= 22. */ 108 /* This works only with emacsclient version >= 22. */
109 struct strbuf man_page = STRBUF_INIT; 109 char *man_page;
110 110
111 if (!path) 111 if (!path)
112 path = "emacsclient"; 112 path = "emacsclient";
113 strbuf_addf(&man_page, "(woman \"%s\")", page); 113 if (asprintf(&man_page, "(woman \"%s\")", page) > 0) {
114 execlp(path, "emacsclient", "-e", man_page.buf, NULL); 114 execlp(path, "emacsclient", "-e", man_page, NULL);
115 free(man_page);
116 }
115 warning("failed to exec '%s': %s", path, 117 warning("failed to exec '%s': %s", path,
116 strerror_r(errno, sbuf, sizeof(sbuf))); 118 strerror_r(errno, sbuf, sizeof(sbuf)));
117 } 119 }
@@ -122,7 +124,7 @@ static void exec_man_konqueror(const char *path, const char *page)
122 const char *display = getenv("DISPLAY"); 124 const char *display = getenv("DISPLAY");
123 125
124 if (display && *display) { 126 if (display && *display) {
125 struct strbuf man_page = STRBUF_INIT; 127 char *man_page;
126 const char *filename = "kfmclient"; 128 const char *filename = "kfmclient";
127 char sbuf[STRERR_BUFSIZE]; 129 char sbuf[STRERR_BUFSIZE];
128 130
@@ -141,8 +143,10 @@ static void exec_man_konqueror(const char *path, const char *page)
141 filename = file; 143 filename = file;
142 } else 144 } else
143 path = "kfmclient"; 145 path = "kfmclient";
144 strbuf_addf(&man_page, "man:%s(1)", page); 146 if (asprintf(&man_page, "man:%s(1)", page) > 0) {
145 execlp(path, filename, "newTab", man_page.buf, NULL); 147 execlp(path, filename, "newTab", man_page, NULL);
148 free(man_page);
149 }
146 warning("failed to exec '%s': %s", path, 150 warning("failed to exec '%s': %s", path,
147 strerror_r(errno, sbuf, sizeof(sbuf))); 151 strerror_r(errno, sbuf, sizeof(sbuf)));
148 } 152 }
@@ -161,11 +165,13 @@ static void exec_man_man(const char *path, const char *page)
161 165
162static void exec_man_cmd(const char *cmd, const char *page) 166static void exec_man_cmd(const char *cmd, const char *page)
163{ 167{
164 struct strbuf shell_cmd = STRBUF_INIT;
165 char sbuf[STRERR_BUFSIZE]; 168 char sbuf[STRERR_BUFSIZE];
169 char *shell_cmd;
166 170
167 strbuf_addf(&shell_cmd, "%s %s", cmd, page); 171 if (asprintf(&shell_cmd, "%s %s", cmd, page) > 0) {
168 execl("/bin/sh", "sh", "-c", shell_cmd.buf, NULL); 172 execl("/bin/sh", "sh", "-c", shell_cmd, NULL);
173 free(shell_cmd);
174 }
169 warning("failed to exec '%s': %s", cmd, 175 warning("failed to exec '%s': %s", cmd,
170 strerror_r(errno, sbuf, sizeof(sbuf))); 176 strerror_r(errno, sbuf, sizeof(sbuf)));
171} 177}
@@ -299,43 +305,33 @@ static int is_perf_command(const char *s)
299 is_in_cmdlist(&other_cmds, s); 305 is_in_cmdlist(&other_cmds, s);
300} 306}
301 307
302static const char *prepend(const char *prefix, const char *cmd)
303{
304 size_t pre_len = strlen(prefix);
305 size_t cmd_len = strlen(cmd);
306 char *p = malloc(pre_len + cmd_len + 1);
307 memcpy(p, prefix, pre_len);
308 strcpy(p + pre_len, cmd);
309 return p;
310}
311
312static const char *cmd_to_page(const char *perf_cmd) 308static const char *cmd_to_page(const char *perf_cmd)
313{ 309{
310 char *s;
311
314 if (!perf_cmd) 312 if (!perf_cmd)
315 return "perf"; 313 return "perf";
316 else if (!prefixcmp(perf_cmd, "perf")) 314 else if (!prefixcmp(perf_cmd, "perf"))
317 return perf_cmd; 315 return perf_cmd;
318 else 316
319 return prepend("perf-", perf_cmd); 317 return asprintf(&s, "perf-%s", perf_cmd) < 0 ? NULL : s;
320} 318}
321 319
322static void setup_man_path(void) 320static void setup_man_path(void)
323{ 321{
324 struct strbuf new_path = STRBUF_INIT; 322 char *new_path;
325 const char *old_path = getenv("MANPATH"); 323 const char *old_path = getenv("MANPATH");
326 324
327 /* We should always put ':' after our path. If there is no 325 /* We should always put ':' after our path. If there is no
328 * old_path, the ':' at the end will let 'man' to try 326 * old_path, the ':' at the end will let 'man' to try
329 * system-wide paths after ours to find the manual page. If 327 * system-wide paths after ours to find the manual page. If
330 * there is old_path, we need ':' as delimiter. */ 328 * there is old_path, we need ':' as delimiter. */
331 strbuf_addstr(&new_path, system_path(PERF_MAN_PATH)); 329 if (asprintf(&new_path, "%s:%s", system_path(PERF_MAN_PATH), old_path ?: "") > 0) {
332 strbuf_addch(&new_path, ':'); 330 setenv("MANPATH", new_path, 1);
333 if (old_path) 331 free(new_path);
334 strbuf_addstr(&new_path, old_path); 332 } else {
335 333 error("Unable to setup man path");
336 setenv("MANPATH", new_path.buf, 1); 334 }
337
338 strbuf_release(&new_path);
339} 335}
340 336
341static void exec_viewer(const char *name, const char *page) 337static void exec_viewer(const char *name, const char *page)
@@ -380,7 +376,7 @@ static int show_info_page(const char *perf_cmd)
380 return -1; 376 return -1;
381} 377}
382 378
383static int get_html_page_path(struct strbuf *page_path, const char *page) 379static int get_html_page_path(char **page_path, const char *page)
384{ 380{
385 struct stat st; 381 struct stat st;
386 const char *html_path = system_path(PERF_HTML_PATH); 382 const char *html_path = system_path(PERF_HTML_PATH);
@@ -392,10 +388,7 @@ static int get_html_page_path(struct strbuf *page_path, const char *page)
392 return -1; 388 return -1;
393 } 389 }
394 390
395 strbuf_init(page_path, 0); 391 return asprintf(page_path, "%s/%s.html", html_path, page);
396 strbuf_addf(page_path, "%s/%s.html", html_path, page);
397
398 return 0;
399} 392}
400 393
401/* 394/*
@@ -413,12 +406,12 @@ static void open_html(const char *path)
413static int show_html_page(const char *perf_cmd) 406static int show_html_page(const char *perf_cmd)
414{ 407{
415 const char *page = cmd_to_page(perf_cmd); 408 const char *page = cmd_to_page(perf_cmd);
416 struct strbuf page_path; /* it leaks but we exec bellow */ 409 char *page_path; /* it leaks but we exec bellow */
417 410
418 if (get_html_page_path(&page_path, page) != 0) 411 if (get_html_page_path(&page_path, page) < 0)
419 return -1; 412 return -1;
420 413
421 open_html(page_path.buf); 414 open_html(page_path);
422 415
423 return 0; 416 return 0;
424} 417}
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 7fa68663ed72..d1a2d104f2bc 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -131,8 +131,7 @@ static int copy_bytes(struct perf_inject *inject, int fd, off_t size)
131 131
132static s64 perf_event__repipe_auxtrace(struct perf_tool *tool, 132static s64 perf_event__repipe_auxtrace(struct perf_tool *tool,
133 union perf_event *event, 133 union perf_event *event,
134 struct perf_session *session 134 struct perf_session *session)
135 __maybe_unused)
136{ 135{
137 struct perf_inject *inject = container_of(tool, struct perf_inject, 136 struct perf_inject *inject = container_of(tool, struct perf_inject,
138 tool); 137 tool);
@@ -417,9 +416,6 @@ static int perf_event__inject_buildid(struct perf_tool *tool,
417{ 416{
418 struct addr_location al; 417 struct addr_location al;
419 struct thread *thread; 418 struct thread *thread;
420 u8 cpumode;
421
422 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
423 419
424 thread = machine__findnew_thread(machine, sample->pid, sample->tid); 420 thread = machine__findnew_thread(machine, sample->pid, sample->tid);
425 if (thread == NULL) { 421 if (thread == NULL) {
@@ -428,7 +424,7 @@ static int perf_event__inject_buildid(struct perf_tool *tool,
428 goto repipe; 424 goto repipe;
429 } 425 }
430 426
431 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->ip, &al); 427 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, sample->ip, &al);
432 428
433 if (al.map != NULL) { 429 if (al.map != NULL) {
434 if (!al.map->dso->hit) { 430 if (!al.map->dso->hit) {
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
index 88aeac9aa1da..85db3be4b3cb 100644
--- a/tools/perf/builtin-mem.c
+++ b/tools/perf/builtin-mem.c
@@ -131,7 +131,7 @@ dump_raw_samples(struct perf_tool *tool,
131 struct addr_location al; 131 struct addr_location al;
132 const char *fmt; 132 const char *fmt;
133 133
134 if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { 134 if (machine__resolve(machine, &al, sample) < 0) {
135 fprintf(stderr, "problem processing %d event, skipping it.\n", 135 fprintf(stderr, "problem processing %d event, skipping it.\n",
136 event->header.type); 136 event->header.type);
137 return -1; 137 return -1;
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 7eea49f9ed46..160ea23b45aa 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -41,6 +41,7 @@
41 41
42#include <dlfcn.h> 42#include <dlfcn.h>
43#include <linux/bitmap.h> 43#include <linux/bitmap.h>
44#include <linux/stringify.h>
44 45
45struct report { 46struct report {
46 struct perf_tool tool; 47 struct perf_tool tool;
@@ -154,7 +155,7 @@ static int process_sample_event(struct perf_tool *tool,
154 }; 155 };
155 int ret = 0; 156 int ret = 0;
156 157
157 if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { 158 if (machine__resolve(machine, &al, sample) < 0) {
158 pr_debug("problem processing %d event, skipping it.\n", 159 pr_debug("problem processing %d event, skipping it.\n",
159 event->header.type); 160 event->header.type);
160 return -1; 161 return -1;
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 57f9a7e7f7d3..3770c3dffe5e 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -405,9 +405,7 @@ out:
405 return 0; 405 return 0;
406} 406}
407 407
408static void print_sample_iregs(union perf_event *event __maybe_unused, 408static void print_sample_iregs(struct perf_sample *sample,
409 struct perf_sample *sample,
410 struct thread *thread __maybe_unused,
411 struct perf_event_attr *attr) 409 struct perf_event_attr *attr)
412{ 410{
413 struct regs_dump *regs = &sample->intr_regs; 411 struct regs_dump *regs = &sample->intr_regs;
@@ -476,10 +474,7 @@ mispred_str(struct branch_entry *br)
476 return br->flags.predicted ? 'P' : 'M'; 474 return br->flags.predicted ? 'P' : 'M';
477} 475}
478 476
479static void print_sample_brstack(union perf_event *event __maybe_unused, 477static void print_sample_brstack(struct perf_sample *sample)
480 struct perf_sample *sample,
481 struct thread *thread __maybe_unused,
482 struct perf_event_attr *attr __maybe_unused)
483{ 478{
484 struct branch_stack *br = sample->branch_stack; 479 struct branch_stack *br = sample->branch_stack;
485 u64 i; 480 u64 i;
@@ -498,14 +493,11 @@ static void print_sample_brstack(union perf_event *event __maybe_unused,
498 } 493 }
499} 494}
500 495
501static void print_sample_brstacksym(union perf_event *event __maybe_unused, 496static void print_sample_brstacksym(struct perf_sample *sample,
502 struct perf_sample *sample, 497 struct thread *thread)
503 struct thread *thread __maybe_unused,
504 struct perf_event_attr *attr __maybe_unused)
505{ 498{
506 struct branch_stack *br = sample->branch_stack; 499 struct branch_stack *br = sample->branch_stack;
507 struct addr_location alf, alt; 500 struct addr_location alf, alt;
508 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
509 u64 i, from, to; 501 u64 i, from, to;
510 502
511 if (!(br && br->nr)) 503 if (!(br && br->nr))
@@ -518,11 +510,11 @@ static void print_sample_brstacksym(union perf_event *event __maybe_unused,
518 from = br->entries[i].from; 510 from = br->entries[i].from;
519 to = br->entries[i].to; 511 to = br->entries[i].to;
520 512
521 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, from, &alf); 513 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf);
522 if (alf.map) 514 if (alf.map)
523 alf.sym = map__find_symbol(alf.map, alf.addr, NULL); 515 alf.sym = map__find_symbol(alf.map, alf.addr, NULL);
524 516
525 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, to, &alt); 517 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt);
526 if (alt.map) 518 if (alt.map)
527 alt.sym = map__find_symbol(alt.map, alt.addr, NULL); 519 alt.sym = map__find_symbol(alt.map, alt.addr, NULL);
528 520
@@ -538,8 +530,7 @@ static void print_sample_brstacksym(union perf_event *event __maybe_unused,
538} 530}
539 531
540 532
541static void print_sample_addr(union perf_event *event, 533static void print_sample_addr(struct perf_sample *sample,
542 struct perf_sample *sample,
543 struct thread *thread, 534 struct thread *thread,
544 struct perf_event_attr *attr) 535 struct perf_event_attr *attr)
545{ 536{
@@ -550,7 +541,7 @@ static void print_sample_addr(union perf_event *event,
550 if (!sample_addr_correlates_sym(attr)) 541 if (!sample_addr_correlates_sym(attr))
551 return; 542 return;
552 543
553 perf_event__preprocess_sample_addr(event, sample, thread, &al); 544 thread__resolve(thread, &al, sample);
554 545
555 if (PRINT_FIELD(SYM)) { 546 if (PRINT_FIELD(SYM)) {
556 printf(" "); 547 printf(" ");
@@ -567,8 +558,7 @@ static void print_sample_addr(union perf_event *event,
567 } 558 }
568} 559}
569 560
570static void print_sample_bts(union perf_event *event, 561static void print_sample_bts(struct perf_sample *sample,
571 struct perf_sample *sample,
572 struct perf_evsel *evsel, 562 struct perf_evsel *evsel,
573 struct thread *thread, 563 struct thread *thread,
574 struct addr_location *al) 564 struct addr_location *al)
@@ -598,7 +588,7 @@ static void print_sample_bts(union perf_event *event,
598 ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && 588 ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
599 !output[attr->type].user_set)) { 589 !output[attr->type].user_set)) {
600 printf(" => "); 590 printf(" => ");
601 print_sample_addr(event, sample, thread, attr); 591 print_sample_addr(sample, thread, attr);
602 } 592 }
603 593
604 if (print_srcline_last) 594 if (print_srcline_last)
@@ -747,7 +737,7 @@ static size_t data_src__printf(u64 data_src)
747 return printf("%-*s", maxlen, out); 737 return printf("%-*s", maxlen, out);
748} 738}
749 739
750static void process_event(struct perf_script *script, union perf_event *event, 740static void process_event(struct perf_script *script,
751 struct perf_sample *sample, struct perf_evsel *evsel, 741 struct perf_sample *sample, struct perf_evsel *evsel,
752 struct addr_location *al) 742 struct addr_location *al)
753{ 743{
@@ -776,7 +766,7 @@ static void process_event(struct perf_script *script, union perf_event *event,
776 print_sample_flags(sample->flags); 766 print_sample_flags(sample->flags);
777 767
778 if (is_bts_event(attr)) { 768 if (is_bts_event(attr)) {
779 print_sample_bts(event, sample, evsel, thread, al); 769 print_sample_bts(sample, evsel, thread, al);
780 return; 770 return;
781 } 771 }
782 772
@@ -784,7 +774,7 @@ static void process_event(struct perf_script *script, union perf_event *event,
784 event_format__print(evsel->tp_format, sample->cpu, 774 event_format__print(evsel->tp_format, sample->cpu,
785 sample->raw_data, sample->raw_size); 775 sample->raw_data, sample->raw_size);
786 if (PRINT_FIELD(ADDR)) 776 if (PRINT_FIELD(ADDR))
787 print_sample_addr(event, sample, thread, attr); 777 print_sample_addr(sample, thread, attr);
788 778
789 if (PRINT_FIELD(DATA_SRC)) 779 if (PRINT_FIELD(DATA_SRC))
790 data_src__printf(sample->data_src); 780 data_src__printf(sample->data_src);
@@ -804,12 +794,12 @@ static void process_event(struct perf_script *script, union perf_event *event,
804 } 794 }
805 795
806 if (PRINT_FIELD(IREGS)) 796 if (PRINT_FIELD(IREGS))
807 print_sample_iregs(event, sample, thread, attr); 797 print_sample_iregs(sample, attr);
808 798
809 if (PRINT_FIELD(BRSTACK)) 799 if (PRINT_FIELD(BRSTACK))
810 print_sample_brstack(event, sample, thread, attr); 800 print_sample_brstack(sample);
811 else if (PRINT_FIELD(BRSTACKSYM)) 801 else if (PRINT_FIELD(BRSTACKSYM))
812 print_sample_brstacksym(event, sample, thread, attr); 802 print_sample_brstacksym(sample, thread);
813 803
814 if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT)) 804 if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
815 print_sample_bpf_output(sample); 805 print_sample_bpf_output(sample);
@@ -905,7 +895,7 @@ static int process_sample_event(struct perf_tool *tool,
905 return 0; 895 return 0;
906 } 896 }
907 897
908 if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { 898 if (machine__resolve(machine, &al, sample) < 0) {
909 pr_err("problem processing %d event, skipping it.\n", 899 pr_err("problem processing %d event, skipping it.\n",
910 event->header.type); 900 event->header.type);
911 return -1; 901 return -1;
@@ -920,7 +910,7 @@ static int process_sample_event(struct perf_tool *tool,
920 if (scripting_ops) 910 if (scripting_ops)
921 scripting_ops->process_event(event, sample, evsel, &al); 911 scripting_ops->process_event(event, sample, evsel, &al);
922 else 912 else
923 process_event(scr, event, sample, evsel, &al); 913 process_event(scr, sample, evsel, &al);
924 914
925out_put: 915out_put:
926 addr_location__put(&al); 916 addr_location__put(&al);
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index bd7a7757176f..40cc9bb3506c 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -489,7 +489,7 @@ static const char *cat_backtrace(union perf_event *event,
489 if (!chain) 489 if (!chain)
490 goto exit; 490 goto exit;
491 491
492 if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { 492 if (machine__resolve(machine, &al, sample) < 0) {
493 fprintf(stderr, "problem processing %d event, skipping it.\n", 493 fprintf(stderr, "problem processing %d event, skipping it.\n",
494 event->header.type); 494 event->header.type);
495 goto exit; 495 goto exit;
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 94af190f6843..833214979c4f 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -67,6 +67,7 @@
67#include <sys/utsname.h> 67#include <sys/utsname.h>
68#include <sys/mman.h> 68#include <sys/mman.h>
69 69
70#include <linux/stringify.h>
70#include <linux/types.h> 71#include <linux/types.h>
71 72
72static volatile int done; 73static volatile int done;
@@ -728,7 +729,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
728 if (event->header.misc & PERF_RECORD_MISC_EXACT_IP) 729 if (event->header.misc & PERF_RECORD_MISC_EXACT_IP)
729 top->exact_samples++; 730 top->exact_samples++;
730 731
731 if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) 732 if (machine__resolve(machine, &al, sample) < 0)
732 return; 733 return;
733 734
734 if (!top->kptr_restrict_warned && 735 if (!top->kptr_restrict_warned &&
@@ -809,7 +810,6 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
809 struct perf_session *session = top->session; 810 struct perf_session *session = top->session;
810 union perf_event *event; 811 union perf_event *event;
811 struct machine *machine; 812 struct machine *machine;
812 u8 origin;
813 int ret; 813 int ret;
814 814
815 while ((event = perf_evlist__mmap_read(top->evlist, idx)) != NULL) { 815 while ((event = perf_evlist__mmap_read(top->evlist, idx)) != NULL) {
@@ -822,12 +822,10 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
822 evsel = perf_evlist__id2evsel(session->evlist, sample.id); 822 evsel = perf_evlist__id2evsel(session->evlist, sample.id);
823 assert(evsel != NULL); 823 assert(evsel != NULL);
824 824
825 origin = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
826
827 if (event->header.type == PERF_RECORD_SAMPLE) 825 if (event->header.type == PERF_RECORD_SAMPLE)
828 ++top->samples; 826 ++top->samples;
829 827
830 switch (origin) { 828 switch (sample.cpumode) {
831 case PERF_RECORD_MISC_USER: 829 case PERF_RECORD_MISC_USER:
832 ++top->us_samples; 830 ++top->us_samples;
833 if (top->hide_user_symbols) 831 if (top->hide_user_symbols)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 8dc98c598b1a..93ac724fb635 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2256,11 +2256,10 @@ static void print_location(FILE *f, struct perf_sample *sample,
2256 2256
2257static int trace__pgfault(struct trace *trace, 2257static int trace__pgfault(struct trace *trace,
2258 struct perf_evsel *evsel, 2258 struct perf_evsel *evsel,
2259 union perf_event *event, 2259 union perf_event *event __maybe_unused,
2260 struct perf_sample *sample) 2260 struct perf_sample *sample)
2261{ 2261{
2262 struct thread *thread; 2262 struct thread *thread;
2263 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
2264 struct addr_location al; 2263 struct addr_location al;
2265 char map_type = 'd'; 2264 char map_type = 'd';
2266 struct thread_trace *ttrace; 2265 struct thread_trace *ttrace;
@@ -2279,7 +2278,7 @@ static int trace__pgfault(struct trace *trace,
2279 if (trace->summary_only) 2278 if (trace->summary_only)
2280 goto out; 2279 goto out;
2281 2280
2282 thread__find_addr_location(thread, cpumode, MAP__FUNCTION, 2281 thread__find_addr_location(thread, sample->cpumode, MAP__FUNCTION,
2283 sample->ip, &al); 2282 sample->ip, &al);
2284 2283
2285 trace__fprintf_entry_head(trace, thread, 0, sample->time, trace->output); 2284 trace__fprintf_entry_head(trace, thread, 0, sample->time, trace->output);
@@ -2292,11 +2291,11 @@ static int trace__pgfault(struct trace *trace,
2292 2291
2293 fprintf(trace->output, "] => "); 2292 fprintf(trace->output, "] => ");
2294 2293
2295 thread__find_addr_location(thread, cpumode, MAP__VARIABLE, 2294 thread__find_addr_location(thread, sample->cpumode, MAP__VARIABLE,
2296 sample->addr, &al); 2295 sample->addr, &al);
2297 2296
2298 if (!al.map) { 2297 if (!al.map) {
2299 thread__find_addr_location(thread, cpumode, 2298 thread__find_addr_location(thread, sample->cpumode,
2300 MAP__FUNCTION, sample->addr, &al); 2299 MAP__FUNCTION, sample->addr, &al);
2301 2300
2302 if (al.map) 2301 if (al.map)
diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index 3f871b54e261..41c24010ab43 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -7,38 +7,38 @@
7extern const char perf_usage_string[]; 7extern const char perf_usage_string[];
8extern const char perf_more_info_string[]; 8extern const char perf_more_info_string[];
9 9
10extern void list_common_cmds_help(void); 10void list_common_cmds_help(void);
11extern const char *help_unknown_cmd(const char *cmd); 11const char *help_unknown_cmd(const char *cmd);
12extern void prune_packed_objects(int); 12void prune_packed_objects(int);
13extern int read_line_with_nul(char *buf, int size, FILE *file); 13int read_line_with_nul(char *buf, int size, FILE *file);
14extern int check_pager_config(const char *cmd); 14int check_pager_config(const char *cmd);
15 15
16extern int cmd_annotate(int argc, const char **argv, const char *prefix); 16int cmd_annotate(int argc, const char **argv, const char *prefix);
17extern int cmd_bench(int argc, const char **argv, const char *prefix); 17int cmd_bench(int argc, const char **argv, const char *prefix);
18extern int cmd_buildid_cache(int argc, const char **argv, const char *prefix); 18int cmd_buildid_cache(int argc, const char **argv, const char *prefix);
19extern int cmd_buildid_list(int argc, const char **argv, const char *prefix); 19int cmd_buildid_list(int argc, const char **argv, const char *prefix);
20extern int cmd_config(int argc, const char **argv, const char *prefix); 20int cmd_config(int argc, const char **argv, const char *prefix);
21extern int cmd_diff(int argc, const char **argv, const char *prefix); 21int cmd_diff(int argc, const char **argv, const char *prefix);
22extern int cmd_evlist(int argc, const char **argv, const char *prefix); 22int cmd_evlist(int argc, const char **argv, const char *prefix);
23extern int cmd_help(int argc, const char **argv, const char *prefix); 23int cmd_help(int argc, const char **argv, const char *prefix);
24extern int cmd_sched(int argc, const char **argv, const char *prefix); 24int cmd_sched(int argc, const char **argv, const char *prefix);
25extern int cmd_list(int argc, const char **argv, const char *prefix); 25int cmd_list(int argc, const char **argv, const char *prefix);
26extern int cmd_record(int argc, const char **argv, const char *prefix); 26int cmd_record(int argc, const char **argv, const char *prefix);
27extern int cmd_report(int argc, const char **argv, const char *prefix); 27int cmd_report(int argc, const char **argv, const char *prefix);
28extern int cmd_stat(int argc, const char **argv, const char *prefix); 28int cmd_stat(int argc, const char **argv, const char *prefix);
29extern int cmd_timechart(int argc, const char **argv, const char *prefix); 29int cmd_timechart(int argc, const char **argv, const char *prefix);
30extern int cmd_top(int argc, const char **argv, const char *prefix); 30int cmd_top(int argc, const char **argv, const char *prefix);
31extern int cmd_script(int argc, const char **argv, const char *prefix); 31int cmd_script(int argc, const char **argv, const char *prefix);
32extern int cmd_version(int argc, const char **argv, const char *prefix); 32int cmd_version(int argc, const char **argv, const char *prefix);
33extern int cmd_probe(int argc, const char **argv, const char *prefix); 33int cmd_probe(int argc, const char **argv, const char *prefix);
34extern int cmd_kmem(int argc, const char **argv, const char *prefix); 34int cmd_kmem(int argc, const char **argv, const char *prefix);
35extern int cmd_lock(int argc, const char **argv, const char *prefix); 35int cmd_lock(int argc, const char **argv, const char *prefix);
36extern int cmd_kvm(int argc, const char **argv, const char *prefix); 36int cmd_kvm(int argc, const char **argv, const char *prefix);
37extern int cmd_test(int argc, const char **argv, const char *prefix); 37int cmd_test(int argc, const char **argv, const char *prefix);
38extern int cmd_trace(int argc, const char **argv, const char *prefix); 38int cmd_trace(int argc, const char **argv, const char *prefix);
39extern int cmd_inject(int argc, const char **argv, const char *prefix); 39int cmd_inject(int argc, const char **argv, const char *prefix);
40extern int cmd_mem(int argc, const char **argv, const char *prefix); 40int cmd_mem(int argc, const char **argv, const char *prefix);
41extern int cmd_data(int argc, const char **argv, const char *prefix); 41int cmd_data(int argc, const char **argv, const char *prefix);
42 42
43extern int find_scripts(char **scripts_array, char **scripts_path_array); 43int find_scripts(char **scripts_array, char **scripts_path_array);
44#endif 44#endif
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index eca6a912e8c2..f7d7f5a1cad5 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -109,7 +109,7 @@ ifdef PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
109 CFLAGS += -DHAVE_ARCH_REGS_QUERY_REGISTER_OFFSET 109 CFLAGS += -DHAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
110endif 110endif
111 111
112include $(src-perf)/config/utilities.mak 112include $(srctree)/tools/scripts/utilities.mak
113 113
114ifeq ($(call get-executable,$(FLEX)),) 114ifeq ($(call get-executable,$(FLEX)),)
115 dummy := $(error Error: $(FLEX) is missing on this system, please install it) 115 dummy := $(error Error: $(FLEX) is missing on this system, please install it)
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index afc9ad0a0515..abd3f0ec0c0b 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -293,7 +293,6 @@ static int process_sample_event(struct machine *machine,
293{ 293{
294 struct perf_sample sample; 294 struct perf_sample sample;
295 struct thread *thread; 295 struct thread *thread;
296 u8 cpumode;
297 int ret; 296 int ret;
298 297
299 if (perf_evlist__parse_sample(evlist, event, &sample)) { 298 if (perf_evlist__parse_sample(evlist, event, &sample)) {
@@ -307,9 +306,7 @@ static int process_sample_event(struct machine *machine,
307 return -1; 306 return -1;
308 } 307 }
309 308
310 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 309 ret = read_object_code(sample.ip, READLEN, sample.cpumode, thread, state);
311
312 ret = read_object_code(sample.ip, READLEN, cpumode, thread, state);
313 thread__put(thread); 310 thread__put(thread);
314 return ret; 311 return ret;
315} 312}
diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c
index 1c5c0221cea2..8f6eb853aaf7 100644
--- a/tools/perf/tests/dwarf-unwind.c
+++ b/tools/perf/tests/dwarf-unwind.c
@@ -20,10 +20,10 @@
20 20
21static int mmap_handler(struct perf_tool *tool __maybe_unused, 21static int mmap_handler(struct perf_tool *tool __maybe_unused,
22 union perf_event *event, 22 union perf_event *event,
23 struct perf_sample *sample __maybe_unused, 23 struct perf_sample *sample,
24 struct machine *machine) 24 struct machine *machine)
25{ 25{
26 return machine__process_mmap2_event(machine, event, NULL); 26 return machine__process_mmap2_event(machine, event, sample);
27} 27}
28 28
29static int init_live_machine(struct machine *machine) 29static int init_live_machine(struct machine *machine)
diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c
index 071a8b5f5232..f55f4bd47932 100644
--- a/tools/perf/tests/hists_common.c
+++ b/tools/perf/tests/hists_common.c
@@ -100,9 +100,11 @@ struct machine *setup_fake_machine(struct machines *machines)
100 } 100 }
101 101
102 for (i = 0; i < ARRAY_SIZE(fake_mmap_info); i++) { 102 for (i = 0; i < ARRAY_SIZE(fake_mmap_info); i++) {
103 struct perf_sample sample = {
104 .cpumode = PERF_RECORD_MISC_USER,
105 };
103 union perf_event fake_mmap_event = { 106 union perf_event fake_mmap_event = {
104 .mmap = { 107 .mmap = {
105 .header = { .misc = PERF_RECORD_MISC_USER, },
106 .pid = fake_mmap_info[i].pid, 108 .pid = fake_mmap_info[i].pid,
107 .tid = fake_mmap_info[i].pid, 109 .tid = fake_mmap_info[i].pid,
108 .start = fake_mmap_info[i].start, 110 .start = fake_mmap_info[i].start,
@@ -114,7 +116,7 @@ struct machine *setup_fake_machine(struct machines *machines)
114 strcpy(fake_mmap_event.mmap.filename, 116 strcpy(fake_mmap_event.mmap.filename,
115 fake_mmap_info[i].filename); 117 fake_mmap_info[i].filename);
116 118
117 machine__process_mmap_event(machine, &fake_mmap_event, NULL); 119 machine__process_mmap_event(machine, &fake_mmap_event, &sample);
118 } 120 }
119 121
120 for (i = 0; i < ARRAY_SIZE(fake_symbols); i++) { 122 for (i = 0; i < ARRAY_SIZE(fake_symbols); i++) {
diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c
index ecf136c385d5..ed5aa9eaeb6c 100644
--- a/tools/perf/tests/hists_cumulate.c
+++ b/tools/perf/tests/hists_cumulate.c
@@ -81,11 +81,6 @@ static int add_hist_entries(struct hists *hists, struct machine *machine)
81 size_t i; 81 size_t i;
82 82
83 for (i = 0; i < ARRAY_SIZE(fake_samples); i++) { 83 for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {
84 const union perf_event event = {
85 .header = {
86 .misc = PERF_RECORD_MISC_USER,
87 },
88 };
89 struct hist_entry_iter iter = { 84 struct hist_entry_iter iter = {
90 .evsel = evsel, 85 .evsel = evsel,
91 .sample = &sample, 86 .sample = &sample,
@@ -97,13 +92,13 @@ static int add_hist_entries(struct hists *hists, struct machine *machine)
97 else 92 else
98 iter.ops = &hist_iter_normal; 93 iter.ops = &hist_iter_normal;
99 94
95 sample.cpumode = PERF_RECORD_MISC_USER;
100 sample.pid = fake_samples[i].pid; 96 sample.pid = fake_samples[i].pid;
101 sample.tid = fake_samples[i].pid; 97 sample.tid = fake_samples[i].pid;
102 sample.ip = fake_samples[i].ip; 98 sample.ip = fake_samples[i].ip;
103 sample.callchain = (struct ip_callchain *)fake_callchains[i]; 99 sample.callchain = (struct ip_callchain *)fake_callchains[i];
104 100
105 if (perf_event__preprocess_sample(&event, machine, &al, 101 if (machine__resolve(machine, &al, &sample) < 0)
106 &sample) < 0)
107 goto out; 102 goto out;
108 103
109 if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH, 104 if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH,
diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c
index 34b945a55d4d..b825d24f8186 100644
--- a/tools/perf/tests/hists_filter.c
+++ b/tools/perf/tests/hists_filter.c
@@ -58,11 +58,6 @@ static int add_hist_entries(struct perf_evlist *evlist,
58 */ 58 */
59 evlist__for_each(evlist, evsel) { 59 evlist__for_each(evlist, evsel) {
60 for (i = 0; i < ARRAY_SIZE(fake_samples); i++) { 60 for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {
61 const union perf_event event = {
62 .header = {
63 .misc = PERF_RECORD_MISC_USER,
64 },
65 };
66 struct hist_entry_iter iter = { 61 struct hist_entry_iter iter = {
67 .evsel = evsel, 62 .evsel = evsel,
68 .sample = &sample, 63 .sample = &sample,
@@ -76,12 +71,12 @@ static int add_hist_entries(struct perf_evlist *evlist,
76 hists->dso_filter = NULL; 71 hists->dso_filter = NULL;
77 hists->symbol_filter_str = NULL; 72 hists->symbol_filter_str = NULL;
78 73
74 sample.cpumode = PERF_RECORD_MISC_USER;
79 sample.pid = fake_samples[i].pid; 75 sample.pid = fake_samples[i].pid;
80 sample.tid = fake_samples[i].pid; 76 sample.tid = fake_samples[i].pid;
81 sample.ip = fake_samples[i].ip; 77 sample.ip = fake_samples[i].ip;
82 78
83 if (perf_event__preprocess_sample(&event, machine, &al, 79 if (machine__resolve(machine, &al, &sample) < 0)
84 &sample) < 0)
85 goto out; 80 goto out;
86 81
87 al.socket = fake_samples[i].socket; 82 al.socket = fake_samples[i].socket;
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index 64b257d8d557..358324e47805 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -76,17 +76,12 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
76 struct hists *hists = evsel__hists(evsel); 76 struct hists *hists = evsel__hists(evsel);
77 77
78 for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) { 78 for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) {
79 const union perf_event event = { 79 sample.cpumode = PERF_RECORD_MISC_USER;
80 .header = {
81 .misc = PERF_RECORD_MISC_USER,
82 },
83 };
84
85 sample.pid = fake_common_samples[k].pid; 80 sample.pid = fake_common_samples[k].pid;
86 sample.tid = fake_common_samples[k].pid; 81 sample.tid = fake_common_samples[k].pid;
87 sample.ip = fake_common_samples[k].ip; 82 sample.ip = fake_common_samples[k].ip;
88 if (perf_event__preprocess_sample(&event, machine, &al, 83
89 &sample) < 0) 84 if (machine__resolve(machine, &al, &sample) < 0)
90 goto out; 85 goto out;
91 86
92 he = __hists__add_entry(hists, &al, NULL, 87 he = __hists__add_entry(hists, &al, NULL,
@@ -102,17 +97,10 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
102 } 97 }
103 98
104 for (k = 0; k < ARRAY_SIZE(fake_samples[i]); k++) { 99 for (k = 0; k < ARRAY_SIZE(fake_samples[i]); k++) {
105 const union perf_event event = {
106 .header = {
107 .misc = PERF_RECORD_MISC_USER,
108 },
109 };
110
111 sample.pid = fake_samples[i][k].pid; 100 sample.pid = fake_samples[i][k].pid;
112 sample.tid = fake_samples[i][k].pid; 101 sample.tid = fake_samples[i][k].pid;
113 sample.ip = fake_samples[i][k].ip; 102 sample.ip = fake_samples[i][k].ip;
114 if (perf_event__preprocess_sample(&event, machine, &al, 103 if (machine__resolve(machine, &al, &sample) < 0)
115 &sample) < 0)
116 goto out; 104 goto out;
117 105
118 he = __hists__add_entry(hists, &al, NULL, 106 he = __hists__add_entry(hists, &al, NULL,
diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c
index 23cce67c7e48..d3556fbe8c5c 100644
--- a/tools/perf/tests/hists_output.c
+++ b/tools/perf/tests/hists_output.c
@@ -51,11 +51,6 @@ static int add_hist_entries(struct hists *hists, struct machine *machine)
51 size_t i; 51 size_t i;
52 52
53 for (i = 0; i < ARRAY_SIZE(fake_samples); i++) { 53 for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {
54 const union perf_event event = {
55 .header = {
56 .misc = PERF_RECORD_MISC_USER,
57 },
58 };
59 struct hist_entry_iter iter = { 54 struct hist_entry_iter iter = {
60 .evsel = evsel, 55 .evsel = evsel,
61 .sample = &sample, 56 .sample = &sample,
@@ -63,13 +58,13 @@ static int add_hist_entries(struct hists *hists, struct machine *machine)
63 .hide_unresolved = false, 58 .hide_unresolved = false,
64 }; 59 };
65 60
61 sample.cpumode = PERF_RECORD_MISC_USER;
66 sample.cpu = fake_samples[i].cpu; 62 sample.cpu = fake_samples[i].cpu;
67 sample.pid = fake_samples[i].pid; 63 sample.pid = fake_samples[i].pid;
68 sample.tid = fake_samples[i].pid; 64 sample.tid = fake_samples[i].pid;
69 sample.ip = fake_samples[i].ip; 65 sample.ip = fake_samples[i].ip;
70 66
71 if (perf_event__preprocess_sample(&event, machine, &al, 67 if (machine__resolve(machine, &al, &sample) < 0)
72 &sample) < 0)
73 goto out; 68 goto out;
74 69
75 if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH, 70 if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH,
diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index bd9bf7e343b1..2aa45b606fa4 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -55,7 +55,7 @@ static u64 he_get_acc_##_field(struct hist_entry *he) \
55 return he->stat_acc->_field; \ 55 return he->stat_acc->_field; \
56} \ 56} \
57 \ 57 \
58static int perf_gtk__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ 58static int perf_gtk__hpp_color_##_type(struct perf_hpp_fmt *fmt, \
59 struct perf_hpp *hpp, \ 59 struct perf_hpp *hpp, \
60 struct hist_entry *he) \ 60 struct hist_entry *he) \
61{ \ 61{ \
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index eea25e2424e9..da48fd843438 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -1,4 +1,3 @@
1libperf-y += abspath.o
2libperf-y += alias.o 1libperf-y += alias.o
3libperf-y += annotate.o 2libperf-y += annotate.o
4libperf-y += build-id.o 3libperf-y += build-id.o
diff --git a/tools/perf/util/abspath.c b/tools/perf/util/abspath.c
deleted file mode 100644
index 0e76affe9c36..000000000000
--- a/tools/perf/util/abspath.c
+++ /dev/null
@@ -1,37 +0,0 @@
1#include "cache.h"
2
3static const char *get_pwd_cwd(void)
4{
5 static char cwd[PATH_MAX + 1];
6 char *pwd;
7 struct stat cwd_stat, pwd_stat;
8 if (getcwd(cwd, PATH_MAX) == NULL)
9 return NULL;
10 pwd = getenv("PWD");
11 if (pwd && strcmp(pwd, cwd)) {
12 stat(cwd, &cwd_stat);
13 if (!stat(pwd, &pwd_stat) &&
14 pwd_stat.st_dev == cwd_stat.st_dev &&
15 pwd_stat.st_ino == cwd_stat.st_ino) {
16 strlcpy(cwd, pwd, PATH_MAX);
17 }
18 }
19 return cwd;
20}
21
22const char *make_nonrelative_path(const char *path)
23{
24 static char buf[PATH_MAX + 1];
25
26 if (is_absolute_path(path)) {
27 if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX)
28 die("Too long path: %.*s", 60, path);
29 } else {
30 const char *cwd = get_pwd_cwd();
31 if (!cwd)
32 die("Cannot determine the current working directory");
33 if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX)
34 die("Too long path: %.*s", 60, path);
35 }
36 return buf;
37}
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index cea323d9ee7e..9241f8c2b7e1 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -158,7 +158,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize);
158 158
159int hist_entry__annotate(struct hist_entry *he, size_t privsize); 159int hist_entry__annotate(struct hist_entry *he, size_t privsize);
160 160
161int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym); 161int symbol__annotate_init(struct map *map, struct symbol *sym);
162int symbol__annotate_printf(struct symbol *sym, struct map *map, 162int symbol__annotate_printf(struct symbol *sym, struct map *map,
163 struct perf_evsel *evsel, bool full_paths, 163 struct perf_evsel *evsel, bool full_paths,
164 int min_pcnt, int max_lines, int context); 164 int min_pcnt, int max_lines, int context);
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index e5a8e2d4f2af..57ff31ecb8e4 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -517,7 +517,7 @@ static inline void auxtrace__free(struct perf_session *session)
517 517
518static inline struct auxtrace_record * 518static inline struct auxtrace_record *
519auxtrace_record__init(struct perf_evlist *evlist __maybe_unused, 519auxtrace_record__init(struct perf_evlist *evlist __maybe_unused,
520 int *err __maybe_unused) 520 int *err)
521{ 521{
522 *err = 0; 522 *err = 0;
523 return NULL; 523 return NULL;
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index f1479eeef7da..0573c2ec861d 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -28,7 +28,6 @@ int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused,
28 struct machine *machine) 28 struct machine *machine)
29{ 29{
30 struct addr_location al; 30 struct addr_location al;
31 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
32 struct thread *thread = machine__findnew_thread(machine, sample->pid, 31 struct thread *thread = machine__findnew_thread(machine, sample->pid,
33 sample->tid); 32 sample->tid);
34 33
@@ -38,7 +37,7 @@ int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused,
38 return -1; 37 return -1;
39 } 38 }
40 39
41 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->ip, &al); 40 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, sample->ip, &al);
42 41
43 if (al.map != NULL) 42 if (al.map != NULL)
44 al.map->dso->hit = 1; 43 al.map->dso->hit = 1;
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index 3ca453f0c51f..1f5a93c2c9a2 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -26,14 +26,14 @@
26extern const char *config_exclusive_filename; 26extern const char *config_exclusive_filename;
27 27
28typedef int (*config_fn_t)(const char *, const char *, void *); 28typedef int (*config_fn_t)(const char *, const char *, void *);
29extern int perf_default_config(const char *, const char *, void *); 29int perf_default_config(const char *, const char *, void *);
30extern int perf_config(config_fn_t fn, void *); 30int perf_config(config_fn_t fn, void *);
31extern int perf_config_int(const char *, const char *); 31int perf_config_int(const char *, const char *);
32extern u64 perf_config_u64(const char *, const char *); 32u64 perf_config_u64(const char *, const char *);
33extern int perf_config_bool(const char *, const char *); 33int perf_config_bool(const char *, const char *);
34extern int config_error_nonbool(const char *); 34int config_error_nonbool(const char *);
35extern const char *perf_config_dirname(const char *, const char *); 35const char *perf_config_dirname(const char *, const char *);
36extern const char *perf_etc_perfconfig(void); 36const char *perf_etc_perfconfig(void);
37 37
38char *alias_lookup(const char *alias); 38char *alias_lookup(const char *alias);
39int split_cmdline(char *cmdline, const char ***argv); 39int split_cmdline(char *cmdline, const char ***argv);
@@ -64,13 +64,9 @@ static inline int is_absolute_path(const char *path)
64 return path[0] == '/'; 64 return path[0] == '/';
65} 65}
66 66
67const char *make_nonrelative_path(const char *path);
68char *strip_path_suffix(const char *path, const char *suffix); 67char *strip_path_suffix(const char *path, const char *suffix);
69 68
70extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2))); 69char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
71extern char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2))); 70char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
72
73extern char *perf_pathdup(const char *fmt, ...)
74 __attribute__((format (printf, 1, 2)));
75 71
76#endif /* __PERF_CACHE_H */ 72#endif /* __PERF_CACHE_H */
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 18dd22269764..d2a9e694810c 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -220,7 +220,7 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *
220 bool hide_unresolved); 220 bool hide_unresolved);
221 221
222extern const char record_callchain_help[]; 222extern const char record_callchain_help[];
223extern int parse_callchain_record(const char *arg, struct callchain_param *param); 223int parse_callchain_record(const char *arg, struct callchain_param *param);
224int parse_callchain_record_opt(const char *arg, struct callchain_param *param); 224int parse_callchain_record_opt(const char *arg, struct callchain_param *param);
225int parse_callchain_report_opt(const char *arg); 225int parse_callchain_report_opt(const char *arg);
226int parse_callchain_top_opt(const char *arg); 226int parse_callchain_top_opt(const char *arg);
@@ -236,7 +236,7 @@ static inline void callchain_cursor_snapshot(struct callchain_cursor *dest,
236} 236}
237 237
238#ifdef HAVE_SKIP_CALLCHAIN_IDX 238#ifdef HAVE_SKIP_CALLCHAIN_IDX
239extern int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain); 239int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain);
240#else 240#else
241static inline int arch_skip_callchain_idx(struct thread *thread __maybe_unused, 241static inline int arch_skip_callchain_idx(struct thread *thread __maybe_unused,
242 struct ip_callchain *chain __maybe_unused) 242 struct ip_callchain *chain __maybe_unused)
diff --git a/tools/perf/util/cgroup.h b/tools/perf/util/cgroup.h
index b4b8cb42fe5e..31f8dcdbd7ef 100644
--- a/tools/perf/util/cgroup.h
+++ b/tools/perf/util/cgroup.h
@@ -13,7 +13,7 @@ struct cgroup_sel {
13 13
14 14
15extern int nr_cgroups; /* number of explicit cgroups defined */ 15extern int nr_cgroups; /* number of explicit cgroups defined */
16extern void close_cgroup(struct cgroup_sel *cgrp); 16void close_cgroup(struct cgroup_sel *cgrp);
17extern int parse_cgroups(const struct option *opt, const char *str, int unset); 17int parse_cgroups(const struct option *opt, const char *str, int unset);
18 18
19#endif /* __CGROUP_H__ */ 19#endif /* __CGROUP_H__ */
diff --git a/tools/perf/util/cloexec.h b/tools/perf/util/cloexec.h
index 3bee6773ddb0..d0d465953d36 100644
--- a/tools/perf/util/cloexec.h
+++ b/tools/perf/util/cloexec.h
@@ -5,7 +5,7 @@ unsigned long perf_event_open_cloexec_flag(void);
5 5
6#ifdef __GLIBC_PREREQ 6#ifdef __GLIBC_PREREQ
7#if !__GLIBC_PREREQ(2, 6) && !defined(__UCLIBC__) 7#if !__GLIBC_PREREQ(2, 6) && !defined(__UCLIBC__)
8extern int sched_getcpu(void) __THROW; 8int sched_getcpu(void) __THROW;
9#endif 9#endif
10#endif 10#endif
11 11
diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c
index 811af89ce0bb..bbf69d248ec5 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -632,7 +632,7 @@ static bool is_flush_needed(struct ctf_stream *cs)
632} 632}
633 633
634static int process_sample_event(struct perf_tool *tool, 634static int process_sample_event(struct perf_tool *tool,
635 union perf_event *_event __maybe_unused, 635 union perf_event *_event,
636 struct perf_sample *sample, 636 struct perf_sample *sample,
637 struct perf_evsel *evsel, 637 struct perf_evsel *evsel,
638 struct machine *machine __maybe_unused) 638 struct machine *machine __maybe_unused)
diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c
index 1c9689e4cc17..049438d51b9a 100644
--- a/tools/perf/util/db-export.c
+++ b/tools/perf/util/db-export.c
@@ -333,7 +333,7 @@ int db_export__sample(struct db_export *dbe, union perf_event *event,
333 sample_addr_correlates_sym(&evsel->attr)) { 333 sample_addr_correlates_sym(&evsel->attr)) {
334 struct addr_location addr_al; 334 struct addr_location addr_al;
335 335
336 perf_event__preprocess_sample_addr(event, sample, thread, &addr_al); 336 thread__resolve(thread, &addr_al, sample);
337 err = db_ids_from_al(dbe, &addr_al, &es.addr_dso_db_id, 337 err = db_ids_from_al(dbe, &addr_al, &es.addr_dso_db_id,
338 &es.addr_sym_db_id, &es.addr_offset); 338 &es.addr_sym_db_id, &es.addr_offset);
339 if (err) 339 if (err)
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 45ec4d0a50ed..0953280629cf 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -162,6 +162,7 @@ struct dso {
162 u8 loaded; 162 u8 loaded;
163 u8 rel; 163 u8 rel;
164 u8 build_id[BUILD_ID_SIZE]; 164 u8 build_id[BUILD_ID_SIZE];
165 u64 text_offset;
165 const char *short_name; 166 const char *short_name;
166 const char *long_name; 167 const char *long_name;
167 u16 long_name_len; 168 u16 long_name_len;
@@ -301,7 +302,7 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,
301 * TODO 302 * TODO
302*/ 303*/
303int dso__data_get_fd(struct dso *dso, struct machine *machine); 304int dso__data_get_fd(struct dso *dso, struct machine *machine);
304void dso__data_put_fd(struct dso *dso __maybe_unused); 305void dso__data_put_fd(struct dso *dso);
305void dso__data_close(struct dso *dso); 306void dso__data_close(struct dso *dso);
306 307
307off_t dso__data_size(struct dso *dso, struct machine *machine); 308off_t dso__data_size(struct dso *dso, struct machine *machine);
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
index a509aa8433a1..577e600c8eb1 100644
--- a/tools/perf/util/dwarf-aux.c
+++ b/tools/perf/util/dwarf-aux.c
@@ -915,7 +915,7 @@ int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf)
915 tmp = "*"; 915 tmp = "*";
916 else if (tag == DW_TAG_subroutine_type) { 916 else if (tag == DW_TAG_subroutine_type) {
917 /* Function pointer */ 917 /* Function pointer */
918 strbuf_addf(buf, "(function_type)"); 918 strbuf_add(buf, "(function_type)", 15);
919 return 0; 919 return 0;
920 } else { 920 } else {
921 if (!dwarf_diename(&type)) 921 if (!dwarf_diename(&type))
@@ -932,7 +932,7 @@ int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf)
932 } 932 }
933 ret = die_get_typename(&type, buf); 933 ret = die_get_typename(&type, buf);
934 if (ret == 0) 934 if (ret == 0)
935 strbuf_addf(buf, "%s", tmp); 935 strbuf_addstr(buf, tmp);
936 936
937 return ret; 937 return ret;
938} 938}
@@ -951,7 +951,7 @@ int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf)
951 ret = die_get_typename(vr_die, buf); 951 ret = die_get_typename(vr_die, buf);
952 if (ret < 0) { 952 if (ret < 0) {
953 pr_debug("Failed to get type, make it unknown.\n"); 953 pr_debug("Failed to get type, make it unknown.\n");
954 strbuf_addf(buf, "(unknown_type)"); 954 strbuf_add(buf, " (unknown_type)", 14);
955 } 955 }
956 956
957 strbuf_addf(buf, "\t%s", dwarf_diename(vr_die)); 957 strbuf_addf(buf, "\t%s", dwarf_diename(vr_die));
@@ -1013,7 +1013,7 @@ static int die_get_var_innermost_scope(Dwarf_Die *sp_die, Dwarf_Die *vr_die,
1013 } 1013 }
1014 1014
1015 if (!first) 1015 if (!first)
1016 strbuf_addf(buf, "]>"); 1016 strbuf_add(buf, "]>", 2);
1017 1017
1018out: 1018out:
1019 free(scopes); 1019 free(scopes);
@@ -1076,7 +1076,7 @@ int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf)
1076 } 1076 }
1077 1077
1078 if (!first) 1078 if (!first)
1079 strbuf_addf(buf, "]>"); 1079 strbuf_add(buf, "]>", 2);
1080 1080
1081 return ret; 1081 return ret;
1082} 1082}
diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h
index c42ec366f2a7..dc0ce1adb075 100644
--- a/tools/perf/util/dwarf-aux.h
+++ b/tools/perf/util/dwarf-aux.h
@@ -25,48 +25,48 @@
25#include <elfutils/version.h> 25#include <elfutils/version.h>
26 26
27/* Find the realpath of the target file */ 27/* Find the realpath of the target file */
28extern const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname); 28const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname);
29 29
30/* Get DW_AT_comp_dir (should be NULL with older gcc) */ 30/* Get DW_AT_comp_dir (should be NULL with older gcc) */
31extern const char *cu_get_comp_dir(Dwarf_Die *cu_die); 31const char *cu_get_comp_dir(Dwarf_Die *cu_die);
32 32
33/* Get a line number and file name for given address */ 33/* Get a line number and file name for given address */
34extern int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr, 34int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr,
35 const char **fname, int *lineno); 35 const char **fname, int *lineno);
36 36
37/* Walk on funcitons at given address */ 37/* Walk on funcitons at given address */
38extern int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, 38int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr,
39 int (*callback)(Dwarf_Die *, void *), void *data); 39 int (*callback)(Dwarf_Die *, void *), void *data);
40 40
41/* Ensure that this DIE is a subprogram and definition (not declaration) */ 41/* Ensure that this DIE is a subprogram and definition (not declaration) */
42extern bool die_is_func_def(Dwarf_Die *dw_die); 42bool die_is_func_def(Dwarf_Die *dw_die);
43 43
44/* Ensure that this DIE is an instance of a subprogram */ 44/* Ensure that this DIE is an instance of a subprogram */
45extern bool die_is_func_instance(Dwarf_Die *dw_die); 45bool die_is_func_instance(Dwarf_Die *dw_die);
46 46
47/* Compare diename and tname */ 47/* Compare diename and tname */
48extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname); 48bool die_compare_name(Dwarf_Die *dw_die, const char *tname);
49 49
50/* Matching diename with glob pattern */ 50/* Matching diename with glob pattern */
51extern bool die_match_name(Dwarf_Die *dw_die, const char *glob); 51bool die_match_name(Dwarf_Die *dw_die, const char *glob);
52 52
53/* Get callsite line number of inline-function instance */ 53/* Get callsite line number of inline-function instance */
54extern int die_get_call_lineno(Dwarf_Die *in_die); 54int die_get_call_lineno(Dwarf_Die *in_die);
55 55
56/* Get callsite file name of inlined function instance */ 56/* Get callsite file name of inlined function instance */
57extern const char *die_get_call_file(Dwarf_Die *in_die); 57const char *die_get_call_file(Dwarf_Die *in_die);
58 58
59/* Get type die */ 59/* Get type die */
60extern Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem); 60Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem);
61 61
62/* Get a type die, but skip qualifiers and typedef */ 62/* Get a type die, but skip qualifiers and typedef */
63extern Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem); 63Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem);
64 64
65/* Check whether the DIE is signed or not */ 65/* Check whether the DIE is signed or not */
66extern bool die_is_signed_type(Dwarf_Die *tp_die); 66bool die_is_signed_type(Dwarf_Die *tp_die);
67 67
68/* Get data_member_location offset */ 68/* Get data_member_location offset */
69extern int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs); 69int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs);
70 70
71/* Return values for die_find_child() callbacks */ 71/* Return values for die_find_child() callbacks */
72enum { 72enum {
@@ -77,29 +77,29 @@ enum {
77}; 77};
78 78
79/* Search child DIEs */ 79/* Search child DIEs */
80extern Dwarf_Die *die_find_child(Dwarf_Die *rt_die, 80Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
81 int (*callback)(Dwarf_Die *, void *), 81 int (*callback)(Dwarf_Die *, void *),
82 void *data, Dwarf_Die *die_mem); 82 void *data, Dwarf_Die *die_mem);
83 83
84/* Search a non-inlined function including given address */ 84/* Search a non-inlined function including given address */
85extern Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, 85Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
86 Dwarf_Die *die_mem); 86 Dwarf_Die *die_mem);
87 87
88/* Search a non-inlined function with tail call at given address */ 88/* Search a non-inlined function with tail call at given address */
89Dwarf_Die *die_find_tailfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, 89Dwarf_Die *die_find_tailfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
90 Dwarf_Die *die_mem); 90 Dwarf_Die *die_mem);
91 91
92/* Search the top inlined function including given address */ 92/* Search the top inlined function including given address */
93extern Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 93Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
94 Dwarf_Die *die_mem); 94 Dwarf_Die *die_mem);
95 95
96/* Search the deepest inlined function including given address */ 96/* Search the deepest inlined function including given address */
97extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 97Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
98 Dwarf_Die *die_mem); 98 Dwarf_Die *die_mem);
99 99
100/* Walk on the instances of given DIE */ 100/* Walk on the instances of given DIE */
101extern int die_walk_instances(Dwarf_Die *in_die, 101int die_walk_instances(Dwarf_Die *in_die,
102 int (*callback)(Dwarf_Die *, void *), void *data); 102 int (*callback)(Dwarf_Die *, void *), void *data);
103 103
104/* Walker on lines (Note: line number will not be sorted) */ 104/* Walker on lines (Note: line number will not be sorted) */
105typedef int (* line_walk_callback_t) (const char *fname, int lineno, 105typedef int (* line_walk_callback_t) (const char *fname, int lineno,
@@ -109,22 +109,20 @@ typedef int (* line_walk_callback_t) (const char *fname, int lineno,
109 * Walk on lines inside given DIE. If the DIE is a subprogram, walk only on 109 * Walk on lines inside given DIE. If the DIE is a subprogram, walk only on
110 * the lines inside the subprogram, otherwise the DIE must be a CU DIE. 110 * the lines inside the subprogram, otherwise the DIE must be a CU DIE.
111 */ 111 */
112extern int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, 112int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data);
113 void *data);
114 113
115/* Find a variable called 'name' at given address */ 114/* Find a variable called 'name' at given address */
116extern Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name, 115Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name,
117 Dwarf_Addr addr, Dwarf_Die *die_mem); 116 Dwarf_Addr addr, Dwarf_Die *die_mem);
118 117
119/* Find a member called 'name' */ 118/* Find a member called 'name' */
120extern Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name, 119Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
121 Dwarf_Die *die_mem); 120 Dwarf_Die *die_mem);
122 121
123/* Get the name of given variable DIE */ 122/* Get the name of given variable DIE */
124extern int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf); 123int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf);
125 124
126/* Get the name and type of given variable DIE, stored as "type\tname" */ 125/* Get the name and type of given variable DIE, stored as "type\tname" */
127extern int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf); 126int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf);
128extern int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, 127int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf);
129 struct strbuf *buf);
130#endif 128#endif
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 7bad5c3fa7b7..52cf479bc593 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -1295,12 +1295,9 @@ void thread__find_addr_location(struct thread *thread,
1295 * Callers need to drop the reference to al->thread, obtained in 1295 * Callers need to drop the reference to al->thread, obtained in
1296 * machine__findnew_thread() 1296 * machine__findnew_thread()
1297 */ 1297 */
1298int perf_event__preprocess_sample(const union perf_event *event, 1298int machine__resolve(struct machine *machine, struct addr_location *al,
1299 struct machine *machine, 1299 struct perf_sample *sample)
1300 struct addr_location *al,
1301 struct perf_sample *sample)
1302{ 1300{
1303 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
1304 struct thread *thread = machine__findnew_thread(machine, sample->pid, 1301 struct thread *thread = machine__findnew_thread(machine, sample->pid,
1305 sample->tid); 1302 sample->tid);
1306 1303
@@ -1315,11 +1312,11 @@ int perf_event__preprocess_sample(const union perf_event *event,
1315 * events, but for older perf.data files there was no such thing, so do 1312 * events, but for older perf.data files there was no such thing, so do
1316 * it now. 1313 * it now.
1317 */ 1314 */
1318 if (cpumode == PERF_RECORD_MISC_KERNEL && 1315 if (sample->cpumode == PERF_RECORD_MISC_KERNEL &&
1319 machine__kernel_map(machine) == NULL) 1316 machine__kernel_map(machine) == NULL)
1320 machine__create_kernel_maps(machine); 1317 machine__create_kernel_maps(machine);
1321 1318
1322 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->ip, al); 1319 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, sample->ip, al);
1323 dump_printf(" ...... dso: %s\n", 1320 dump_printf(" ...... dso: %s\n",
1324 al->map ? al->map->dso->long_name : 1321 al->map ? al->map->dso->long_name :
1325 al->level == 'H' ? "[hypervisor]" : "<not found>"); 1322 al->level == 'H' ? "[hypervisor]" : "<not found>");
@@ -1395,16 +1392,12 @@ bool sample_addr_correlates_sym(struct perf_event_attr *attr)
1395 return false; 1392 return false;
1396} 1393}
1397 1394
1398void perf_event__preprocess_sample_addr(union perf_event *event, 1395void thread__resolve(struct thread *thread, struct addr_location *al,
1399 struct perf_sample *sample, 1396 struct perf_sample *sample)
1400 struct thread *thread,
1401 struct addr_location *al)
1402{ 1397{
1403 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 1398 thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, sample->addr, al);
1404
1405 thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->addr, al);
1406 if (!al->map) 1399 if (!al->map)
1407 thread__find_addr_map(thread, cpumode, MAP__VARIABLE, 1400 thread__find_addr_map(thread, sample->cpumode, MAP__VARIABLE,
1408 sample->addr, al); 1401 sample->addr, al);
1409 1402
1410 al->cpu = sample->cpu; 1403 al->cpu = sample->cpu;
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index b7ffb7ee9971..6bb1c928350d 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -192,6 +192,7 @@ struct perf_sample {
192 u64 data_src; 192 u64 data_src;
193 u32 flags; 193 u32 flags;
194 u16 insn_len; 194 u16 insn_len;
195 u8 cpumode;
195 void *raw_data; 196 void *raw_data;
196 struct ip_callchain *callchain; 197 struct ip_callchain *callchain;
197 struct branch_stack *branch_stack; 198 struct branch_stack *branch_stack;
@@ -597,10 +598,8 @@ int perf_event__process(struct perf_tool *tool,
597 598
598struct addr_location; 599struct addr_location;
599 600
600int perf_event__preprocess_sample(const union perf_event *event, 601int machine__resolve(struct machine *machine, struct addr_location *al,
601 struct machine *machine, 602 struct perf_sample *sample);
602 struct addr_location *al,
603 struct perf_sample *sample);
604 603
605void addr_location__put(struct addr_location *al); 604void addr_location__put(struct addr_location *al);
606 605
@@ -608,10 +607,8 @@ struct thread;
608 607
609bool is_bts_event(struct perf_event_attr *attr); 608bool is_bts_event(struct perf_event_attr *attr);
610bool sample_addr_correlates_sym(struct perf_event_attr *attr); 609bool sample_addr_correlates_sym(struct perf_event_attr *attr);
611void perf_event__preprocess_sample_addr(union perf_event *event, 610void thread__resolve(struct thread *thread, struct addr_location *al,
612 struct perf_sample *sample, 611 struct perf_sample *sample);
613 struct thread *thread,
614 struct addr_location *al);
615 612
616const char *perf_event__name(unsigned int id); 613const char *perf_event__name(unsigned int id);
617 614
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 0902fe418754..738ce226002b 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1643,6 +1643,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
1643 data->stream_id = data->id = data->time = -1ULL; 1643 data->stream_id = data->id = data->time = -1ULL;
1644 data->period = evsel->attr.sample_period; 1644 data->period = evsel->attr.sample_period;
1645 data->weight = 0; 1645 data->weight = 0;
1646 data->cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
1646 1647
1647 if (event->header.type != PERF_RECORD_SAMPLE) { 1648 if (event->header.type != PERF_RECORD_SAMPLE) {
1648 if (!evsel->attr.sample_id_all) 1649 if (!evsel->attr.sample_id_all)
diff --git a/tools/perf/util/genelf.h b/tools/perf/util/genelf.h
index 45bf9c6d3257..cd67e64a0494 100644
--- a/tools/perf/util/genelf.h
+++ b/tools/perf/util/genelf.h
@@ -2,12 +2,10 @@
2#define __GENELF_H__ 2#define __GENELF_H__
3 3
4/* genelf.c */ 4/* genelf.c */
5extern int jit_write_elf(int fd, uint64_t code_addr, const char *sym, 5int jit_write_elf(int fd, uint64_t code_addr, const char *sym,
6 const void *code, int csize, 6 const void *code, int csize, void *debug, int nr_debug_entries);
7 void *debug, int nr_debug_entries);
8/* genelf_debug.c */ 7/* genelf_debug.c */
9extern int jit_add_debug_info(Elf *e, uint64_t code_addr, 8int jit_add_debug_info(Elf *e, uint64_t code_addr, void *debug, int nr_debug_entries);
10 void *debug, int nr_debug_entries);
11 9
12#if defined(__arm__) 10#if defined(__arm__)
13#define GEN_ELF_ARCH EM_ARM 11#define GEN_ELF_ARCH EM_ARM
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 73e38e472ecd..90680ec9f8b8 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1872,11 +1872,6 @@ static int process_cpu_topology(struct perf_file_section *section,
1872 if (ph->needs_swap) 1872 if (ph->needs_swap)
1873 nr = bswap_32(nr); 1873 nr = bswap_32(nr);
1874 1874
1875 if (nr > (u32)cpu_nr) {
1876 pr_debug("core_id number is too big."
1877 "You may need to upgrade the perf tool.\n");
1878 goto free_cpu;
1879 }
1880 ph->env.cpu[i].core_id = nr; 1875 ph->env.cpu[i].core_id = nr;
1881 1876
1882 ret = readn(fd, &nr, sizeof(nr)); 1877 ret = readn(fd, &nr, sizeof(nr));
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 3d87ca823c0a..d306ca118449 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -121,7 +121,7 @@ int perf_event__synthesize_event_update_cpus(struct perf_tool *tool,
121 perf_event__handler_t process); 121 perf_event__handler_t process);
122int perf_event__process_attr(struct perf_tool *tool, union perf_event *event, 122int perf_event__process_attr(struct perf_tool *tool, union perf_event *event,
123 struct perf_evlist **pevlist); 123 struct perf_evlist **pevlist);
124int perf_event__process_event_update(struct perf_tool *tool __maybe_unused, 124int perf_event__process_event_update(struct perf_tool *tool,
125 union perf_event *event, 125 union perf_event *event,
126 struct perf_evlist **pevlist); 126 struct perf_evlist **pevlist);
127size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp); 127size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp);
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 290b3cbf6877..31c4641fe5ff 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -670,7 +670,7 @@ iter_prepare_branch_entry(struct hist_entry_iter *iter, struct addr_location *al
670} 670}
671 671
672static int 672static int
673iter_add_single_branch_entry(struct hist_entry_iter *iter __maybe_unused, 673iter_add_single_branch_entry(struct hist_entry_iter *iter,
674 struct addr_location *al __maybe_unused) 674 struct addr_location *al __maybe_unused)
675{ 675{
676 /* to avoid calling callback function */ 676 /* to avoid calling callback function */
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index ead18c82294f..bec0cd660fbd 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -433,8 +433,7 @@ void hist__account_cycles(struct branch_stack *bs, struct addr_location *al,
433 struct perf_sample *sample, bool nonany_branch_mode); 433 struct perf_sample *sample, bool nonany_branch_mode);
434 434
435struct option; 435struct option;
436int parse_filter_percentage(const struct option *opt __maybe_unused, 436int parse_filter_percentage(const struct option *opt, const char *arg, int unset);
437 const char *arg, int unset __maybe_unused);
438int perf_hist_config(const char *var, const char *value); 437int perf_hist_config(const char *var, const char *value);
439 438
440void perf_hpp_list__init(struct perf_hpp_list *list); 439void perf_hpp_list__init(struct perf_hpp_list *list);
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c
index eb0e7f8bf515..6bc3ecd2e7ca 100644
--- a/tools/perf/util/intel-bts.c
+++ b/tools/perf/util/intel-bts.c
@@ -678,7 +678,7 @@ static int intel_bts_process_auxtrace_event(struct perf_session *session,
678 return 0; 678 return 0;
679} 679}
680 680
681static int intel_bts_flush(struct perf_session *session __maybe_unused, 681static int intel_bts_flush(struct perf_session *session,
682 struct perf_tool *tool __maybe_unused) 682 struct perf_tool *tool __maybe_unused)
683{ 683{
684 struct intel_bts *bts = container_of(session->auxtrace, struct intel_bts, 684 struct intel_bts *bts = container_of(session->auxtrace, struct intel_bts,
diff --git a/tools/perf/util/jit.h b/tools/perf/util/jit.h
index a1e99da0715a..3f42ee4d2a0b 100644
--- a/tools/perf/util/jit.h
+++ b/tools/perf/util/jit.h
@@ -3,13 +3,9 @@
3 3
4#include <data.h> 4#include <data.h>
5 5
6extern int jit_process(struct perf_session *session, 6int jit_process(struct perf_session *session, struct perf_data_file *output,
7 struct perf_data_file *output, 7 struct machine *machine, char *filename, pid_t pid, u64 *nbytes);
8 struct machine *machine, 8
9 char *filename, 9int jit_inject_record(const char *filename);
10 pid_t pid,
11 u64 *nbytes);
12
13extern int jit_inject_record(const char *filename);
14 10
15#endif /* __JIT_H__ */ 11#endif /* __JIT_H__ */
diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c
index 00724d496d38..33071d6159bc 100644
--- a/tools/perf/util/llvm-utils.c
+++ b/tools/perf/util/llvm-utils.c
@@ -3,11 +3,11 @@
3 * Copyright (C) 2015, Huawei Inc. 3 * Copyright (C) 2015, Huawei Inc.
4 */ 4 */
5 5
6#include <limits.h>
6#include <stdio.h> 7#include <stdio.h>
7#include "util.h" 8#include <stdlib.h>
8#include "debug.h" 9#include "debug.h"
9#include "llvm-utils.h" 10#include "llvm-utils.h"
10#include "cache.h"
11 11
12#define CLANG_BPF_CMD_DEFAULT_TEMPLATE \ 12#define CLANG_BPF_CMD_DEFAULT_TEMPLATE \
13 "$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\ 13 "$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\
@@ -98,11 +98,12 @@ read_from_pipe(const char *cmd, void **p_buf, size_t *p_read_sz)
98 void *buf = NULL; 98 void *buf = NULL;
99 FILE *file = NULL; 99 FILE *file = NULL;
100 size_t read_sz = 0, buf_sz = 0; 100 size_t read_sz = 0, buf_sz = 0;
101 char serr[STRERR_BUFSIZE];
101 102
102 file = popen(cmd, "r"); 103 file = popen(cmd, "r");
103 if (!file) { 104 if (!file) {
104 pr_err("ERROR: unable to popen cmd: %s\n", 105 pr_err("ERROR: unable to popen cmd: %s\n",
105 strerror(errno)); 106 strerror_r(errno, serr, sizeof(serr)));
106 return -EINVAL; 107 return -EINVAL;
107 } 108 }
108 109
@@ -136,7 +137,7 @@ read_from_pipe(const char *cmd, void **p_buf, size_t *p_read_sz)
136 137
137 if (ferror(file)) { 138 if (ferror(file)) {
138 pr_err("ERROR: error occurred when reading from pipe: %s\n", 139 pr_err("ERROR: error occurred when reading from pipe: %s\n",
139 strerror(errno)); 140 strerror_r(errno, serr, sizeof(serr)));
140 err = -EIO; 141 err = -EIO;
141 goto errout; 142 goto errout;
142 } 143 }
@@ -334,10 +335,18 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
334 unsigned int kernel_version; 335 unsigned int kernel_version;
335 char linux_version_code_str[64]; 336 char linux_version_code_str[64];
336 const char *clang_opt = llvm_param.clang_opt; 337 const char *clang_opt = llvm_param.clang_opt;
337 char clang_path[PATH_MAX], nr_cpus_avail_str[64]; 338 char clang_path[PATH_MAX], abspath[PATH_MAX], nr_cpus_avail_str[64];
339 char serr[STRERR_BUFSIZE];
338 char *kbuild_dir = NULL, *kbuild_include_opts = NULL; 340 char *kbuild_dir = NULL, *kbuild_include_opts = NULL;
339 const char *template = llvm_param.clang_bpf_cmd_template; 341 const char *template = llvm_param.clang_bpf_cmd_template;
340 342
343 if (path[0] != '-' && realpath(path, abspath) == NULL) {
344 err = errno;
345 pr_err("ERROR: problems with path %s: %s\n",
346 path, strerror_r(err, serr, sizeof(serr)));
347 return -err;
348 }
349
341 if (!template) 350 if (!template)
342 template = CLANG_BPF_CMD_DEFAULT_TEMPLATE; 351 template = CLANG_BPF_CMD_DEFAULT_TEMPLATE;
343 352
@@ -362,7 +371,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
362 if (nr_cpus_avail <= 0) { 371 if (nr_cpus_avail <= 0) {
363 pr_err( 372 pr_err(
364"WARNING:\tunable to get available CPUs in this system: %s\n" 373"WARNING:\tunable to get available CPUs in this system: %s\n"
365" \tUse 128 instead.\n", strerror(errno)); 374" \tUse 128 instead.\n", strerror_r(errno, serr, sizeof(serr)));
366 nr_cpus_avail = 128; 375 nr_cpus_avail = 128;
367 } 376 }
368 snprintf(nr_cpus_avail_str, sizeof(nr_cpus_avail_str), "%d", 377 snprintf(nr_cpus_avail_str, sizeof(nr_cpus_avail_str), "%d",
@@ -387,8 +396,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
387 * stdin to be source file (testing). 396 * stdin to be source file (testing).
388 */ 397 */
389 force_set_env("CLANG_SOURCE", 398 force_set_env("CLANG_SOURCE",
390 (path[0] == '-') ? path : 399 (path[0] == '-') ? path : abspath);
391 make_nonrelative_path(path));
392 400
393 pr_debug("llvm compiling command template: %s\n", template); 401 pr_debug("llvm compiling command template: %s\n", template);
394 err = read_from_pipe(template, &obj_buf, &obj_buf_sz); 402 err = read_from_pipe(template, &obj_buf, &obj_buf_sz);
diff --git a/tools/perf/util/llvm-utils.h b/tools/perf/util/llvm-utils.h
index 5b3cf1c229e2..23b9a743fe72 100644
--- a/tools/perf/util/llvm-utils.h
+++ b/tools/perf/util/llvm-utils.h
@@ -39,11 +39,10 @@ struct llvm_param {
39}; 39};
40 40
41extern struct llvm_param llvm_param; 41extern struct llvm_param llvm_param;
42extern int perf_llvm_config(const char *var, const char *value); 42int perf_llvm_config(const char *var, const char *value);
43 43
44extern int llvm__compile_bpf(const char *path, void **p_obj_buf, 44int llvm__compile_bpf(const char *path, void **p_obj_buf, size_t *p_obj_buf_sz);
45 size_t *p_obj_buf_sz);
46 45
47/* This function is for test__llvm() use only */ 46/* This function is for test__llvm() use only */
48extern int llvm__search_clang(void); 47int llvm__search_clang(void);
49#endif 48#endif
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index ad79297c76c8..80b9b6a87990 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1301,9 +1301,8 @@ out_problem:
1301 1301
1302int machine__process_mmap2_event(struct machine *machine, 1302int machine__process_mmap2_event(struct machine *machine,
1303 union perf_event *event, 1303 union perf_event *event,
1304 struct perf_sample *sample __maybe_unused) 1304 struct perf_sample *sample)
1305{ 1305{
1306 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
1307 struct thread *thread; 1306 struct thread *thread;
1308 struct map *map; 1307 struct map *map;
1309 enum map_type type; 1308 enum map_type type;
@@ -1312,8 +1311,8 @@ int machine__process_mmap2_event(struct machine *machine,
1312 if (dump_trace) 1311 if (dump_trace)
1313 perf_event__fprintf_mmap2(event, stdout); 1312 perf_event__fprintf_mmap2(event, stdout);
1314 1313
1315 if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL || 1314 if (sample->cpumode == PERF_RECORD_MISC_GUEST_KERNEL ||
1316 cpumode == PERF_RECORD_MISC_KERNEL) { 1315 sample->cpumode == PERF_RECORD_MISC_KERNEL) {
1317 ret = machine__process_kernel_mmap_event(machine, event); 1316 ret = machine__process_kernel_mmap_event(machine, event);
1318 if (ret < 0) 1317 if (ret < 0)
1319 goto out_problem; 1318 goto out_problem;
@@ -1355,9 +1354,8 @@ out_problem:
1355} 1354}
1356 1355
1357int machine__process_mmap_event(struct machine *machine, union perf_event *event, 1356int machine__process_mmap_event(struct machine *machine, union perf_event *event,
1358 struct perf_sample *sample __maybe_unused) 1357 struct perf_sample *sample)
1359{ 1358{
1360 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
1361 struct thread *thread; 1359 struct thread *thread;
1362 struct map *map; 1360 struct map *map;
1363 enum map_type type; 1361 enum map_type type;
@@ -1366,8 +1364,8 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event
1366 if (dump_trace) 1364 if (dump_trace)
1367 perf_event__fprintf_mmap(event, stdout); 1365 perf_event__fprintf_mmap(event, stdout);
1368 1366
1369 if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL || 1367 if (sample->cpumode == PERF_RECORD_MISC_GUEST_KERNEL ||
1370 cpumode == PERF_RECORD_MISC_KERNEL) { 1368 sample->cpumode == PERF_RECORD_MISC_KERNEL) {
1371 ret = machine__process_kernel_mmap_event(machine, event); 1369 ret = machine__process_kernel_mmap_event(machine, event);
1372 if (ret < 0) 1370 if (ret < 0)
1373 goto out_problem; 1371 goto out_problem;
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 1a3e45baf97f..8499db281158 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -94,7 +94,7 @@ int machine__process_aux_event(struct machine *machine,
94 union perf_event *event); 94 union perf_event *event);
95int machine__process_itrace_start_event(struct machine *machine, 95int machine__process_itrace_start_event(struct machine *machine,
96 union perf_event *event); 96 union perf_event *event);
97int machine__process_switch_event(struct machine *machine __maybe_unused, 97int machine__process_switch_event(struct machine *machine,
98 union perf_event *event); 98 union perf_event *event);
99int machine__process_mmap_event(struct machine *machine, union perf_event *event, 99int machine__process_mmap_event(struct machine *machine, union perf_event *event,
100 struct perf_sample *sample); 100 struct perf_sample *sample);
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 67e493088e81..d740c3ca9a1d 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -22,19 +22,18 @@ struct tracepoint_path {
22 struct tracepoint_path *next; 22 struct tracepoint_path *next;
23}; 23};
24 24
25extern struct tracepoint_path *tracepoint_id_to_path(u64 config); 25struct tracepoint_path *tracepoint_id_to_path(u64 config);
26extern struct tracepoint_path *tracepoint_name_to_path(const char *name); 26struct tracepoint_path *tracepoint_name_to_path(const char *name);
27extern bool have_tracepoints(struct list_head *evlist); 27bool have_tracepoints(struct list_head *evlist);
28 28
29const char *event_type(int type); 29const char *event_type(int type);
30 30
31extern int parse_events_option(const struct option *opt, const char *str, 31int parse_events_option(const struct option *opt, const char *str, int unset);
32 int unset); 32int parse_events(struct perf_evlist *evlist, const char *str,
33extern int parse_events(struct perf_evlist *evlist, const char *str, 33 struct parse_events_error *error);
34 struct parse_events_error *error); 34int parse_events_terms(struct list_head *terms, const char *str);
35extern int parse_events_terms(struct list_head *terms, const char *str); 35int parse_filter(const struct option *opt, const char *str, int unset);
36extern int parse_filter(const struct option *opt, const char *str, int unset); 36int exclude_perf(const struct option *opt, const char *arg, int unset);
37extern int exclude_perf(const struct option *opt, const char *arg, int unset);
38 37
39#define EVENTS_HELP_MAX (128*1024) 38#define EVENTS_HELP_MAX (128*1024)
40 39
@@ -183,7 +182,7 @@ void print_symbol_events(const char *event_glob, unsigned type,
183void print_tracepoint_events(const char *subsys_glob, const char *event_glob, 182void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
184 bool name_only); 183 bool name_only);
185int print_hwcache_events(const char *event_glob, bool name_only); 184int print_hwcache_events(const char *event_glob, bool name_only);
186extern int is_valid_tracepoint(const char *event_string); 185int is_valid_tracepoint(const char *event_string);
187 186
188int valid_event_mount(const char *eventfs); 187int valid_event_mount(const char *eventfs);
189char *parse_events_formats_error_string(char *additional_terms); 188char *parse_events_formats_error_string(char *additional_terms);
diff --git a/tools/perf/util/path.c b/tools/perf/util/path.c
index 3654d964e49d..3bf6bf82ff2d 100644
--- a/tools/perf/util/path.c
+++ b/tools/perf/util/path.c
@@ -41,36 +41,6 @@ static char *cleanup_path(char *path)
41 return path; 41 return path;
42} 42}
43 43
44static char *perf_vsnpath(char *buf, size_t n, const char *fmt, va_list args)
45{
46 const char *perf_dir = get_perf_dir();
47 size_t len;
48
49 len = strlen(perf_dir);
50 if (n < len + 1)
51 goto bad;
52 memcpy(buf, perf_dir, len);
53 if (len && !is_dir_sep(perf_dir[len-1]))
54 buf[len++] = '/';
55 len += vsnprintf(buf + len, n - len, fmt, args);
56 if (len >= n)
57 goto bad;
58 return cleanup_path(buf);
59bad:
60 strlcpy(buf, bad_path, n);
61 return buf;
62}
63
64char *perf_pathdup(const char *fmt, ...)
65{
66 char path[PATH_MAX];
67 va_list args;
68 va_start(args, fmt);
69 (void)perf_vsnpath(path, sizeof(path), fmt, args);
70 va_end(args);
71 return xstrdup(path);
72}
73
74char *mkpath(const char *fmt, ...) 44char *mkpath(const char *fmt, ...)
75{ 45{
76 va_list args; 46 va_list args;
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 93996ec4bbe3..8319fbb08636 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2179,7 +2179,7 @@ static int perf_probe_event__sprintf(const char *group, const char *event,
2179 strbuf_addf(result, " in %s", module); 2179 strbuf_addf(result, " in %s", module);
2180 2180
2181 if (pev->nargs > 0) { 2181 if (pev->nargs > 0) {
2182 strbuf_addstr(result, " with"); 2182 strbuf_add(result, " with", 5);
2183 for (i = 0; i < pev->nargs; i++) { 2183 for (i = 0; i < pev->nargs; i++) {
2184 ret = synthesize_perf_probe_arg(&pev->args[i], 2184 ret = synthesize_perf_probe_arg(&pev->args[i],
2185 buf, 128); 2185 buf, 128);
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index ba926c30f8cd..e54e7b011577 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -114,49 +114,44 @@ int init_probe_symbol_maps(bool user_only);
114void exit_probe_symbol_maps(void); 114void exit_probe_symbol_maps(void);
115 115
116/* Command string to events */ 116/* Command string to events */
117extern int parse_perf_probe_command(const char *cmd, 117int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev);
118 struct perf_probe_event *pev); 118int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev);
119extern int parse_probe_trace_command(const char *cmd,
120 struct probe_trace_event *tev);
121 119
122/* Events to command string */ 120/* Events to command string */
123extern char *synthesize_perf_probe_command(struct perf_probe_event *pev); 121char *synthesize_perf_probe_command(struct perf_probe_event *pev);
124extern char *synthesize_probe_trace_command(struct probe_trace_event *tev); 122char *synthesize_probe_trace_command(struct probe_trace_event *tev);
125extern int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, 123int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len);
126 size_t len);
127 124
128/* Check the perf_probe_event needs debuginfo */ 125/* Check the perf_probe_event needs debuginfo */
129extern bool perf_probe_event_need_dwarf(struct perf_probe_event *pev); 126bool perf_probe_event_need_dwarf(struct perf_probe_event *pev);
130 127
131/* Release event contents */ 128/* Release event contents */
132extern void clear_perf_probe_event(struct perf_probe_event *pev); 129void clear_perf_probe_event(struct perf_probe_event *pev);
133extern void clear_probe_trace_event(struct probe_trace_event *tev); 130void clear_probe_trace_event(struct probe_trace_event *tev);
134 131
135/* Command string to line-range */ 132/* Command string to line-range */
136extern int parse_line_range_desc(const char *cmd, struct line_range *lr); 133int parse_line_range_desc(const char *cmd, struct line_range *lr);
137 134
138/* Release line range members */ 135/* Release line range members */
139extern void line_range__clear(struct line_range *lr); 136void line_range__clear(struct line_range *lr);
140 137
141/* Initialize line range */ 138/* Initialize line range */
142extern int line_range__init(struct line_range *lr); 139int line_range__init(struct line_range *lr);
143 140
144extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs); 141int add_perf_probe_events(struct perf_probe_event *pevs, int npevs);
145extern int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs); 142int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs);
146extern int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs); 143int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs);
147extern void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs); 144void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs);
148extern int del_perf_probe_events(struct strfilter *filter); 145int del_perf_probe_events(struct strfilter *filter);
149 146
150extern int show_perf_probe_event(const char *group, const char *event, 147int show_perf_probe_event(const char *group, const char *event,
151 struct perf_probe_event *pev, 148 struct perf_probe_event *pev,
152 const char *module, bool use_stdout); 149 const char *module, bool use_stdout);
153extern int show_perf_probe_events(struct strfilter *filter); 150int show_perf_probe_events(struct strfilter *filter);
154extern int show_line_range(struct line_range *lr, const char *module, 151int show_line_range(struct line_range *lr, const char *module, bool user);
155 bool user); 152int show_available_vars(struct perf_probe_event *pevs, int npevs,
156extern int show_available_vars(struct perf_probe_event *pevs, int npevs, 153 struct strfilter *filter);
157 struct strfilter *filter); 154int show_available_funcs(const char *module, struct strfilter *filter, bool user);
158extern int show_available_funcs(const char *module, struct strfilter *filter,
159 bool user);
160bool arch__prefers_symtab(void); 155bool arch__prefers_symtab(void);
161void arch__fix_tev_from_maps(struct perf_probe_event *pev, 156void arch__fix_tev_from_maps(struct perf_probe_event *pev,
162 struct probe_trace_event *tev, struct map *map); 157 struct probe_trace_event *tev, struct map *map);
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 4ce5c5e18f48..b3bd0fba0237 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -1314,18 +1314,18 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
1314 if (probe_conf.show_location_range) { 1314 if (probe_conf.show_location_range) {
1315 if (!externs) { 1315 if (!externs) {
1316 if (ret) 1316 if (ret)
1317 strbuf_addf(&buf, "[INV]\t"); 1317 strbuf_add(&buf, "[INV]\t", 6);
1318 else 1318 else
1319 strbuf_addf(&buf, "[VAL]\t"); 1319 strbuf_add(&buf, "[VAL]\t", 6);
1320 } else 1320 } else
1321 strbuf_addf(&buf, "[EXT]\t"); 1321 strbuf_add(&buf, "[EXT]\t", 6);
1322 } 1322 }
1323 1323
1324 ret2 = die_get_varname(die_mem, &buf); 1324 ret2 = die_get_varname(die_mem, &buf);
1325 1325
1326 if (!ret2 && probe_conf.show_location_range && 1326 if (!ret2 && probe_conf.show_location_range &&
1327 !externs) { 1327 !externs) {
1328 strbuf_addf(&buf, "\t"); 1328 strbuf_addch(&buf, '\t');
1329 ret2 = die_get_var_range(&af->pf.sp_die, 1329 ret2 = die_get_var_range(&af->pf.sp_die,
1330 die_mem, &buf); 1330 die_mem, &buf);
1331 } 1331 }
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index 0aec7704e395..51137fccb9c8 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -34,27 +34,25 @@ struct debuginfo {
34}; 34};
35 35
36/* This also tries to open distro debuginfo */ 36/* This also tries to open distro debuginfo */
37extern struct debuginfo *debuginfo__new(const char *path); 37struct debuginfo *debuginfo__new(const char *path);
38extern void debuginfo__delete(struct debuginfo *dbg); 38void debuginfo__delete(struct debuginfo *dbg);
39 39
40/* Find probe_trace_events specified by perf_probe_event from debuginfo */ 40/* Find probe_trace_events specified by perf_probe_event from debuginfo */
41extern int debuginfo__find_trace_events(struct debuginfo *dbg, 41int debuginfo__find_trace_events(struct debuginfo *dbg,
42 struct perf_probe_event *pev, 42 struct perf_probe_event *pev,
43 struct probe_trace_event **tevs); 43 struct probe_trace_event **tevs);
44 44
45/* Find a perf_probe_point from debuginfo */ 45/* Find a perf_probe_point from debuginfo */
46extern int debuginfo__find_probe_point(struct debuginfo *dbg, 46int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
47 unsigned long addr, 47 struct perf_probe_point *ppt);
48 struct perf_probe_point *ppt);
49 48
50/* Find a line range */ 49/* Find a line range */
51extern int debuginfo__find_line_range(struct debuginfo *dbg, 50int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr);
52 struct line_range *lr);
53 51
54/* Find available variables */ 52/* Find available variables */
55extern int debuginfo__find_available_vars_at(struct debuginfo *dbg, 53int debuginfo__find_available_vars_at(struct debuginfo *dbg,
56 struct perf_probe_event *pev, 54 struct perf_probe_event *pev,
57 struct variable_list **vls); 55 struct variable_list **vls);
58 56
59/* Find a src file from a DWARF tag path */ 57/* Find a src file from a DWARF tag path */
60int get_real_path(const char *raw_path, const char *comp_dir, 58int get_real_path(const char *raw_path, const char *comp_dir,
diff --git a/tools/perf/util/quote.h b/tools/perf/util/quote.h
index 172889ea234f..3340c9c4a6ca 100644
--- a/tools/perf/util/quote.h
+++ b/tools/perf/util/quote.h
@@ -24,6 +24,6 @@
24 * sq_quote() in a real application. 24 * sq_quote() in a real application.
25 */ 25 */
26 26
27extern void sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen); 27void sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen);
28 28
29#endif /* __PERF_QUOTE_H */ 29#endif /* __PERF_QUOTE_H */
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 60b3593d210d..4abd85c6346d 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1107,12 +1107,11 @@ static struct machine *machines__find_for_cpumode(struct machines *machines,
1107 union perf_event *event, 1107 union perf_event *event,
1108 struct perf_sample *sample) 1108 struct perf_sample *sample)
1109{ 1109{
1110 const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
1111 struct machine *machine; 1110 struct machine *machine;
1112 1111
1113 if (perf_guest && 1112 if (perf_guest &&
1114 ((cpumode == PERF_RECORD_MISC_GUEST_KERNEL) || 1113 ((sample->cpumode == PERF_RECORD_MISC_GUEST_KERNEL) ||
1115 (cpumode == PERF_RECORD_MISC_GUEST_USER))) { 1114 (sample->cpumode == PERF_RECORD_MISC_GUEST_USER))) {
1116 u32 pid; 1115 u32 pid;
1117 1116
1118 if (event->header.type == PERF_RECORD_MMAP 1117 if (event->header.type == PERF_RECORD_MMAP
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 93fa136b0025..47966a1618c7 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -2225,7 +2225,7 @@ int hpp_dimension__add_output(unsigned col)
2225} 2225}
2226 2226
2227static int sort_dimension__add(struct perf_hpp_list *list, const char *tok, 2227static int sort_dimension__add(struct perf_hpp_list *list, const char *tok,
2228 struct perf_evlist *evlist __maybe_unused, 2228 struct perf_evlist *evlist,
2229 int level) 2229 int level)
2230{ 2230{
2231 unsigned int i; 2231 unsigned int i;
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index b33ffb2af2cf..fdb71961143e 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -152,8 +152,7 @@ static const char *get_ratio_color(enum grc_type type, double ratio)
152} 152}
153 153
154static void print_stalled_cycles_frontend(int cpu, 154static void print_stalled_cycles_frontend(int cpu,
155 struct perf_evsel *evsel 155 struct perf_evsel *evsel, double avg,
156 __maybe_unused, double avg,
157 struct perf_stat_output_ctx *out) 156 struct perf_stat_output_ctx *out)
158{ 157{
159 double total, ratio = 0.0; 158 double total, ratio = 0.0;
@@ -175,8 +174,7 @@ static void print_stalled_cycles_frontend(int cpu,
175} 174}
176 175
177static void print_stalled_cycles_backend(int cpu, 176static void print_stalled_cycles_backend(int cpu,
178 struct perf_evsel *evsel 177 struct perf_evsel *evsel, double avg,
179 __maybe_unused, double avg,
180 struct perf_stat_output_ctx *out) 178 struct perf_stat_output_ctx *out)
181{ 179{
182 double total, ratio = 0.0; 180 double total, ratio = 0.0;
@@ -194,7 +192,7 @@ static void print_stalled_cycles_backend(int cpu,
194} 192}
195 193
196static void print_branch_misses(int cpu, 194static void print_branch_misses(int cpu,
197 struct perf_evsel *evsel __maybe_unused, 195 struct perf_evsel *evsel,
198 double avg, 196 double avg,
199 struct perf_stat_output_ctx *out) 197 struct perf_stat_output_ctx *out)
200{ 198{
@@ -213,7 +211,7 @@ static void print_branch_misses(int cpu,
213} 211}
214 212
215static void print_l1_dcache_misses(int cpu, 213static void print_l1_dcache_misses(int cpu,
216 struct perf_evsel *evsel __maybe_unused, 214 struct perf_evsel *evsel,
217 double avg, 215 double avg,
218 struct perf_stat_output_ctx *out) 216 struct perf_stat_output_ctx *out)
219{ 217{
@@ -232,7 +230,7 @@ static void print_l1_dcache_misses(int cpu,
232} 230}
233 231
234static void print_l1_icache_misses(int cpu, 232static void print_l1_icache_misses(int cpu,
235 struct perf_evsel *evsel __maybe_unused, 233 struct perf_evsel *evsel,
236 double avg, 234 double avg,
237 struct perf_stat_output_ctx *out) 235 struct perf_stat_output_ctx *out)
238{ 236{
@@ -250,7 +248,7 @@ static void print_l1_icache_misses(int cpu,
250} 248}
251 249
252static void print_dtlb_cache_misses(int cpu, 250static void print_dtlb_cache_misses(int cpu,
253 struct perf_evsel *evsel __maybe_unused, 251 struct perf_evsel *evsel,
254 double avg, 252 double avg,
255 struct perf_stat_output_ctx *out) 253 struct perf_stat_output_ctx *out)
256{ 254{
@@ -268,7 +266,7 @@ static void print_dtlb_cache_misses(int cpu,
268} 266}
269 267
270static void print_itlb_cache_misses(int cpu, 268static void print_itlb_cache_misses(int cpu,
271 struct perf_evsel *evsel __maybe_unused, 269 struct perf_evsel *evsel,
272 double avg, 270 double avg,
273 struct perf_stat_output_ctx *out) 271 struct perf_stat_output_ctx *out)
274{ 272{
@@ -286,7 +284,7 @@ static void print_itlb_cache_misses(int cpu,
286} 284}
287 285
288static void print_ll_cache_misses(int cpu, 286static void print_ll_cache_misses(int cpu,
289 struct perf_evsel *evsel __maybe_unused, 287 struct perf_evsel *evsel,
290 double avg, 288 double avg,
291 struct perf_stat_output_ctx *out) 289 struct perf_stat_output_ctx *out)
292{ 290{
diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c
index d3d279275432..8fb73295ec34 100644
--- a/tools/perf/util/strbuf.c
+++ b/tools/perf/util/strbuf.c
@@ -51,6 +51,13 @@ void strbuf_grow(struct strbuf *sb, size_t extra)
51 ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc); 51 ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc);
52} 52}
53 53
54void strbuf_addch(struct strbuf *sb, int c)
55{
56 strbuf_grow(sb, 1);
57 sb->buf[sb->len++] = c;
58 sb->buf[sb->len] = '\0';
59}
60
54void strbuf_add(struct strbuf *sb, const void *data, size_t len) 61void strbuf_add(struct strbuf *sb, const void *data, size_t len)
55{ 62{
56 strbuf_grow(sb, len); 63 strbuf_grow(sb, len);
@@ -58,7 +65,7 @@ void strbuf_add(struct strbuf *sb, const void *data, size_t len)
58 strbuf_setlen(sb, sb->len + len); 65 strbuf_setlen(sb, sb->len + len);
59} 66}
60 67
61void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap) 68static void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap)
62{ 69{
63 int len; 70 int len;
64 va_list ap_saved; 71 va_list ap_saved;
diff --git a/tools/perf/util/strbuf.h b/tools/perf/util/strbuf.h
index 7a32c838884d..ab9be0fbbd40 100644
--- a/tools/perf/util/strbuf.h
+++ b/tools/perf/util/strbuf.h
@@ -51,16 +51,16 @@ struct strbuf {
51#define STRBUF_INIT { 0, 0, strbuf_slopbuf } 51#define STRBUF_INIT { 0, 0, strbuf_slopbuf }
52 52
53/*----- strbuf life cycle -----*/ 53/*----- strbuf life cycle -----*/
54extern void strbuf_init(struct strbuf *buf, ssize_t hint); 54void strbuf_init(struct strbuf *buf, ssize_t hint);
55extern void strbuf_release(struct strbuf *); 55void strbuf_release(struct strbuf *buf);
56extern char *strbuf_detach(struct strbuf *, size_t *); 56char *strbuf_detach(struct strbuf *buf, size_t *);
57 57
58/*----- strbuf size related -----*/ 58/*----- strbuf size related -----*/
59static inline ssize_t strbuf_avail(const struct strbuf *sb) { 59static inline ssize_t strbuf_avail(const struct strbuf *sb) {
60 return sb->alloc ? sb->alloc - sb->len - 1 : 0; 60 return sb->alloc ? sb->alloc - sb->len - 1 : 0;
61} 61}
62 62
63extern void strbuf_grow(struct strbuf *, size_t); 63void strbuf_grow(struct strbuf *buf, size_t);
64 64
65static inline void strbuf_setlen(struct strbuf *sb, size_t len) { 65static inline void strbuf_setlen(struct strbuf *sb, size_t len) {
66 if (!sb->alloc) 66 if (!sb->alloc)
@@ -71,22 +71,17 @@ static inline void strbuf_setlen(struct strbuf *sb, size_t len) {
71} 71}
72 72
73/*----- add data in your buffer -----*/ 73/*----- add data in your buffer -----*/
74static inline void strbuf_addch(struct strbuf *sb, int c) { 74void strbuf_addch(struct strbuf *sb, int c);
75 strbuf_grow(sb, 1);
76 sb->buf[sb->len++] = c;
77 sb->buf[sb->len] = '\0';
78}
79 75
80extern void strbuf_add(struct strbuf *, const void *, size_t); 76void strbuf_add(struct strbuf *buf, const void *, size_t);
81static inline void strbuf_addstr(struct strbuf *sb, const char *s) { 77static inline void strbuf_addstr(struct strbuf *sb, const char *s) {
82 strbuf_add(sb, s, strlen(s)); 78 strbuf_add(sb, s, strlen(s));
83} 79}
84 80
85__attribute__((format(printf,2,3))) 81__attribute__((format(printf,2,3)))
86extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...); 82void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
87extern void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap);
88 83
89/* XXX: if read fails, any partial read is undone */ 84/* XXX: if read fails, any partial read is undone */
90extern ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint); 85ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint);
91 86
92#endif /* __PERF_STRBUF_H */ 87#endif /* __PERF_STRBUF_H */
diff --git a/tools/perf/util/svghelper.h b/tools/perf/util/svghelper.h
index 9292a5291445..946fdf2db97c 100644
--- a/tools/perf/util/svghelper.h
+++ b/tools/perf/util/svghelper.h
@@ -3,32 +3,31 @@
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5 5
6extern void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end); 6void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end);
7extern void svg_ubox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges); 7void svg_ubox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges);
8extern void svg_lbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges); 8void svg_lbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges);
9extern void svg_fbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges); 9void svg_fbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges);
10extern void svg_box(int Yslot, u64 start, u64 end, const char *type); 10void svg_box(int Yslot, u64 start, u64 end, const char *type);
11extern void svg_blocked(int Yslot, int cpu, u64 start, u64 end, const char *backtrace); 11void svg_blocked(int Yslot, int cpu, u64 start, u64 end, const char *backtrace);
12extern void svg_running(int Yslot, int cpu, u64 start, u64 end, const char *backtrace); 12void svg_running(int Yslot, int cpu, u64 start, u64 end, const char *backtrace);
13extern void svg_waiting(int Yslot, int cpu, u64 start, u64 end, const char *backtrace); 13void svg_waiting(int Yslot, int cpu, u64 start, u64 end, const char *backtrace);
14extern void svg_cpu_box(int cpu, u64 max_frequency, u64 turbo_frequency); 14void svg_cpu_box(int cpu, u64 max_frequency, u64 turbo_frequency);
15 15
16 16
17extern void svg_process(int cpu, u64 start, u64 end, int pid, const char *name, const char *backtrace); 17void svg_process(int cpu, u64 start, u64 end, int pid, const char *name, const char *backtrace);
18extern void svg_cstate(int cpu, u64 start, u64 end, int type); 18void svg_cstate(int cpu, u64 start, u64 end, int type);
19extern void svg_pstate(int cpu, u64 start, u64 end, u64 freq); 19void svg_pstate(int cpu, u64 start, u64 end, u64 freq);
20 20
21 21
22extern void svg_time_grid(double min_thickness); 22void svg_time_grid(double min_thickness);
23extern void svg_io_legenda(void); 23void svg_io_legenda(void);
24extern void svg_legenda(void); 24void svg_legenda(void);
25extern void svg_wakeline(u64 start, int row1, int row2, const char *backtrace); 25void svg_wakeline(u64 start, int row1, int row2, const char *backtrace);
26extern void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc2, const char *backtrace); 26void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc2, const char *backtrace);
27extern void svg_interrupt(u64 start, int row, const char *backtrace); 27void svg_interrupt(u64 start, int row, const char *backtrace);
28extern void svg_text(int Yslot, u64 start, const char *text); 28void svg_text(int Yslot, u64 start, const char *text);
29extern void svg_close(void); 29void svg_close(void);
30extern int svg_build_topology_map(char *sib_core, int sib_core_nr, 30int svg_build_topology_map(char *sib_core, int sib_core_nr, char *sib_thr, int sib_thr_nr);
31 char *sib_thr, int sib_thr_nr);
32 31
33extern int svg_page_width; 32extern int svg_page_width;
34extern u64 svg_highlight; 33extern u64 svg_highlight;
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index b1dd68f358fc..bc229a74c6a9 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -793,6 +793,7 @@ int dso__load_sym(struct dso *dso, struct map *map,
793 uint32_t idx; 793 uint32_t idx;
794 GElf_Ehdr ehdr; 794 GElf_Ehdr ehdr;
795 GElf_Shdr shdr; 795 GElf_Shdr shdr;
796 GElf_Shdr tshdr;
796 Elf_Data *syms, *opddata = NULL; 797 Elf_Data *syms, *opddata = NULL;
797 GElf_Sym sym; 798 GElf_Sym sym;
798 Elf_Scn *sec, *sec_strndx; 799 Elf_Scn *sec, *sec_strndx;
@@ -832,6 +833,9 @@ int dso__load_sym(struct dso *dso, struct map *map,
832 sec = syms_ss->symtab; 833 sec = syms_ss->symtab;
833 shdr = syms_ss->symshdr; 834 shdr = syms_ss->symshdr;
834 835
836 if (elf_section_by_name(elf, &ehdr, &tshdr, ".text", NULL))
837 dso->text_offset = tshdr.sh_addr - tshdr.sh_offset;
838
835 if (runtime_ss->opdsec) 839 if (runtime_ss->opdsec)
836 opddata = elf_rawdata(runtime_ss->opdsec, NULL); 840 opddata = elf_rawdata(runtime_ss->opdsec, NULL);
837 841
@@ -880,12 +884,8 @@ int dso__load_sym(struct dso *dso, struct map *map,
880 * Handle any relocation of vdso necessary because older kernels 884 * Handle any relocation of vdso necessary because older kernels
881 * attempted to prelink vdso to its virtual address. 885 * attempted to prelink vdso to its virtual address.
882 */ 886 */
883 if (dso__is_vdso(dso)) { 887 if (dso__is_vdso(dso))
884 GElf_Shdr tshdr; 888 map->reloc = map->start - dso->text_offset;
885
886 if (elf_section_by_name(elf, &ehdr, &tshdr, ".text", NULL))
887 map->reloc = map->start - tshdr.sh_addr + tshdr.sh_offset;
888 }
889 889
890 dso->adjust_symbols = runtime_ss->adjust_symbols || ref_reloc(kmap); 890 dso->adjust_symbols = runtime_ss->adjust_symbols || ref_reloc(kmap);
891 /* 891 /*
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index a937053a0ae0..c8b7544d9267 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -34,8 +34,8 @@
34#endif 34#endif
35 35
36#ifdef HAVE_LIBELF_SUPPORT 36#ifdef HAVE_LIBELF_SUPPORT
37extern Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, 37Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
38 GElf_Shdr *shp, const char *name, size_t *idx); 38 GElf_Shdr *shp, const char *name, size_t *idx);
39#endif 39#endif
40 40
41#ifndef DMGL_PARAMS 41#ifndef DMGL_PARAMS
diff --git a/tools/perf/util/usage.c b/tools/perf/util/usage.c
index 6adfa18cdd4e..996046a66fe5 100644
--- a/tools/perf/util/usage.c
+++ b/tools/perf/util/usage.c
@@ -41,15 +41,9 @@ static void warn_builtin(const char *warn, va_list params)
41/* If we are in a dlopen()ed .so write to a global variable would segfault 41/* If we are in a dlopen()ed .so write to a global variable would segfault
42 * (ugh), so keep things static. */ 42 * (ugh), so keep things static. */
43static void (*usage_routine)(const char *err) NORETURN = usage_builtin; 43static void (*usage_routine)(const char *err) NORETURN = usage_builtin;
44static void (*die_routine)(const char *err, va_list params) NORETURN = die_builtin;
45static void (*error_routine)(const char *err, va_list params) = error_builtin; 44static void (*error_routine)(const char *err, va_list params) = error_builtin;
46static void (*warn_routine)(const char *err, va_list params) = warn_builtin; 45static void (*warn_routine)(const char *err, va_list params) = warn_builtin;
47 46
48void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN)
49{
50 die_routine = routine;
51}
52
53void set_warning_routine(void (*routine)(const char *err, va_list params)) 47void set_warning_routine(void (*routine)(const char *err, va_list params))
54{ 48{
55 warn_routine = routine; 49 warn_routine = routine;
@@ -65,7 +59,7 @@ void die(const char *err, ...)
65 va_list params; 59 va_list params;
66 60
67 va_start(params, err); 61 va_start(params, err);
68 die_routine(err, params); 62 die_builtin(err, params);
69 va_end(params); 63 va_end(params);
70} 64}
71 65
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index d0d50cef8b2a..8298d607c738 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -133,25 +133,15 @@ extern char buildid_dir[];
133#define PERF_GTK_DSO "libperf-gtk.so" 133#define PERF_GTK_DSO "libperf-gtk.so"
134 134
135/* General helper functions */ 135/* General helper functions */
136extern void usage(const char *err) NORETURN; 136void usage(const char *err) NORETURN;
137extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); 137void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
138extern int error(const char *err, ...) __attribute__((format (printf, 1, 2))); 138int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
139extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2))); 139void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
140 140
141#include "../../../include/linux/stringify.h" 141void set_warning_routine(void (*routine)(const char *err, va_list params));
142 142
143#define DIE_IF(cnd) \ 143int prefixcmp(const char *str, const char *prefix);
144 do { if (cnd) \ 144void set_buildid_dir(const char *dir);
145 die(" at (" __FILE__ ":" __stringify(__LINE__) "): " \
146 __stringify(cnd) "\n"); \
147 } while (0)
148
149
150extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);
151extern void set_warning_routine(void (*routine)(const char *err, va_list params));
152
153extern int prefixcmp(const char *str, const char *prefix);
154extern void set_buildid_dir(const char *dir);
155 145
156#ifdef __GLIBC_PREREQ 146#ifdef __GLIBC_PREREQ
157#if __GLIBC_PREREQ(2, 1) 147#if __GLIBC_PREREQ(2, 1)
@@ -172,8 +162,7 @@ static inline char *gitstrchrnul(const char *s, int c)
172/* 162/*
173 * Wrappers: 163 * Wrappers:
174 */ 164 */
175extern char *xstrdup(const char *str); 165void *xrealloc(void *ptr, size_t size) __attribute__((weak));
176extern void *xrealloc(void *ptr, size_t size) __attribute__((weak));
177 166
178 167
179static inline void *zalloc(size_t size) 168static inline void *zalloc(size_t size)
diff --git a/tools/perf/util/wrapper.c b/tools/perf/util/wrapper.c
index 19f15b650703..5f1a07c4b87b 100644
--- a/tools/perf/util/wrapper.c
+++ b/tools/perf/util/wrapper.c
@@ -12,18 +12,6 @@ static inline void release_pack_memory(size_t size __maybe_unused,
12{ 12{
13} 13}
14 14
15char *xstrdup(const char *str)
16{
17 char *ret = strdup(str);
18 if (!ret) {
19 release_pack_memory(strlen(str) + 1, -1);
20 ret = strdup(str);
21 if (!ret)
22 die("Out of memory, strdup failed");
23 }
24 return ret;
25}
26
27void *xrealloc(void *ptr, size_t size) 15void *xrealloc(void *ptr, size_t size)
28{ 16{
29 void *ret = realloc(ptr, size); 17 void *ret = realloc(ptr, size);
diff --git a/tools/perf/config/utilities.mak b/tools/scripts/utilities.mak
index c16ce833079c..c16ce833079c 100644
--- a/tools/perf/config/utilities.mak
+++ b/tools/scripts/utilities.mak