mirror of
https://github.com/suyu-emu/horinux.git
synced 2026-09-21 14:15:21 -07:00
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Ingo Molnar:
"Most of the changes are for tooling, the main changes in this cycle were:
- Improve Intel-PT hardware tracing support, both on the kernel and
on the tooling side: PTWRITE instruction support, power events for
C-state tracing, etc. (Adrian Hunter)
- Add support to measure SMI cost to the x86 architecture, with
tooling support in 'perf stat' (Kan Liang)
- Support function filtering in 'perf ftrace', plus related
improvements (Namhyung Kim)
- Allow adding and removing fields to the default 'perf script'
columns, using + or - as field prefixes to do so (Andi Kleen)
- Allow resolving the DSO name with 'perf script -F brstack{sym,off},dso'
(Mark Santaniello)
- Add perf tooling unwind support for PowerPC (Paolo Bonzini)
- ... and various other improvements as well"
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (84 commits)
perf auxtrace: Add CPU filter support
perf intel-pt: Do not use TSC packets for calculating CPU cycles to TSC
perf intel-pt: Update documentation to include new ptwrite and power events
perf intel-pt: Add example script for power events and PTWRITE
perf intel-pt: Synthesize new power and "ptwrite" events
perf intel-pt: Move code in intel_pt_synth_events() to simplify attr setting
perf intel-pt: Factor out intel_pt_set_event_name()
perf intel-pt: Tidy messages into called function intel_pt_synth_event()
perf intel-pt: Tidy Intel PT evsel lookup into separate function
perf intel-pt: Join needlessly wrapped lines
perf intel-pt: Remove unused instructions_sample_period
perf intel-pt: Factor out common code synthesizing event samples
perf script: Add synthesized Intel PT power and ptwrite events
perf/x86/intel: Constify the 'lbr_desc[]' array and make a function static
perf script: Add 'synth' field for synthesized event payloads
perf auxtrace: Add itrace option to output power events
perf auxtrace: Add itrace option to output ptwrite events
tools include: Add byte-swapping macros to kernel.h
perf script: Add 'synth' event type for synthesized events
x86/insn: perf tools: Add new ptwrite instruction
...
This commit is contained in:
@@ -1750,6 +1750,8 @@ ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct attribute_group x86_pmu_attr_group;
|
||||
|
||||
static int __init init_hw_perf_events(void)
|
||||
{
|
||||
struct x86_pmu_quirk *quirk;
|
||||
@@ -1813,6 +1815,14 @@ static int __init init_hw_perf_events(void)
|
||||
x86_pmu_events_group.attrs = tmp;
|
||||
}
|
||||
|
||||
if (x86_pmu.attrs) {
|
||||
struct attribute **tmp;
|
||||
|
||||
tmp = merge_attr(x86_pmu_attr_group.attrs, x86_pmu.attrs);
|
||||
if (!WARN_ON(!tmp))
|
||||
x86_pmu_attr_group.attrs = tmp;
|
||||
}
|
||||
|
||||
pr_info("... version: %d\n", x86_pmu.version);
|
||||
pr_info("... bit width: %d\n", x86_pmu.cntval_bits);
|
||||
pr_info("... generic registers: %d\n", x86_pmu.num_counters);
|
||||
|
||||
@@ -3160,6 +3160,19 @@ err:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void flip_smm_bit(void *data)
|
||||
{
|
||||
unsigned long set = *(unsigned long *)data;
|
||||
|
||||
if (set > 0) {
|
||||
msr_set_bit(MSR_IA32_DEBUGCTLMSR,
|
||||
DEBUGCTLMSR_FREEZE_IN_SMM_BIT);
|
||||
} else {
|
||||
msr_clear_bit(MSR_IA32_DEBUGCTLMSR,
|
||||
DEBUGCTLMSR_FREEZE_IN_SMM_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void intel_pmu_cpu_starting(int cpu)
|
||||
{
|
||||
struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
|
||||
@@ -3174,6 +3187,8 @@ static void intel_pmu_cpu_starting(int cpu)
|
||||
|
||||
cpuc->lbr_sel = NULL;
|
||||
|
||||
flip_smm_bit(&x86_pmu.attr_freeze_on_smi);
|
||||
|
||||
if (!cpuc->shared_regs)
|
||||
return;
|
||||
|
||||
@@ -3595,6 +3610,52 @@ static struct attribute *hsw_events_attrs[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static ssize_t freeze_on_smi_show(struct device *cdev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%lu\n", x86_pmu.attr_freeze_on_smi);
|
||||
}
|
||||
|
||||
static DEFINE_MUTEX(freeze_on_smi_mutex);
|
||||
|
||||
static ssize_t freeze_on_smi_store(struct device *cdev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long val;
|
||||
ssize_t ret;
|
||||
|
||||
ret = kstrtoul(buf, 0, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (val > 1)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&freeze_on_smi_mutex);
|
||||
|
||||
if (x86_pmu.attr_freeze_on_smi == val)
|
||||
goto done;
|
||||
|
||||
x86_pmu.attr_freeze_on_smi = val;
|
||||
|
||||
get_online_cpus();
|
||||
on_each_cpu(flip_smm_bit, &val, 1);
|
||||
put_online_cpus();
|
||||
done:
|
||||
mutex_unlock(&freeze_on_smi_mutex);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(freeze_on_smi);
|
||||
|
||||
static struct attribute *intel_pmu_attrs[] = {
|
||||
&dev_attr_freeze_on_smi.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
__init int intel_pmu_init(void)
|
||||
{
|
||||
union cpuid10_edx edx;
|
||||
@@ -3641,6 +3702,8 @@ __init int intel_pmu_init(void)
|
||||
|
||||
x86_pmu.max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters);
|
||||
|
||||
|
||||
x86_pmu.attrs = intel_pmu_attrs;
|
||||
/*
|
||||
* Quirk: v2 perfmon does not report fixed-purpose events, so
|
||||
* assume at least 3 events, when not running in a hypervisor:
|
||||
|
||||
@@ -18,7 +18,7 @@ enum {
|
||||
LBR_FORMAT_MAX_KNOWN = LBR_FORMAT_TIME,
|
||||
};
|
||||
|
||||
static enum {
|
||||
static const enum {
|
||||
LBR_EIP_FLAGS = 1,
|
||||
LBR_TSX = 2,
|
||||
} lbr_desc[LBR_FORMAT_MAX_KNOWN + 1] = {
|
||||
@@ -287,7 +287,7 @@ inline u64 lbr_from_signext_quirk_wr(u64 val)
|
||||
/*
|
||||
* If quirk is needed, ensure sign extension is 61 bits:
|
||||
*/
|
||||
u64 lbr_from_signext_quirk_rd(u64 val)
|
||||
static u64 lbr_from_signext_quirk_rd(u64 val)
|
||||
{
|
||||
if (static_branch_unlikely(&lbr_from_quirk_key)) {
|
||||
/*
|
||||
|
||||
@@ -562,6 +562,9 @@ struct x86_pmu {
|
||||
ssize_t (*events_sysfs_show)(char *page, u64 config);
|
||||
struct attribute **cpu_events;
|
||||
|
||||
unsigned long attr_freeze_on_smi;
|
||||
struct attribute **attrs;
|
||||
|
||||
/*
|
||||
* CPU Hotplug hooks
|
||||
*/
|
||||
|
||||
@@ -137,6 +137,8 @@
|
||||
#define DEBUGCTLMSR_BTS_OFF_OS (1UL << 9)
|
||||
#define DEBUGCTLMSR_BTS_OFF_USR (1UL << 10)
|
||||
#define DEBUGCTLMSR_FREEZE_LBRS_ON_PMI (1UL << 11)
|
||||
#define DEBUGCTLMSR_FREEZE_IN_SMM_BIT 14
|
||||
#define DEBUGCTLMSR_FREEZE_IN_SMM (1UL << DEBUGCTLMSR_FREEZE_IN_SMM_BIT)
|
||||
|
||||
#define MSR_PEBS_FRONTEND 0x000003f7
|
||||
|
||||
|
||||
@@ -1009,7 +1009,7 @@ GrpTable: Grp15
|
||||
1: fxstor | RDGSBASE Ry (F3),(11B)
|
||||
2: vldmxcsr Md (v1) | WRFSBASE Ry (F3),(11B)
|
||||
3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B)
|
||||
4: XSAVE
|
||||
4: XSAVE | ptwrite Ey (F3),(11B)
|
||||
5: XRSTOR | lfence (11B)
|
||||
6: XSAVEOPT | clwb (66) | mfence (11B)
|
||||
7: clflush | clflushopt (66) | sfence (11B)
|
||||
|
||||
+15
-15
@@ -925,11 +925,6 @@ static inline int is_cgroup_event(struct perf_event *event)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u64 perf_cgroup_event_cgrp_time(struct perf_event *event)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void update_cgrp_time_from_event(struct perf_event *event)
|
||||
{
|
||||
}
|
||||
@@ -5729,9 +5724,6 @@ static void perf_output_read_one(struct perf_output_handle *handle,
|
||||
__output_copy(handle, values, n * sizeof(u64));
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX PERF_FORMAT_GROUP vs inherited events seems difficult.
|
||||
*/
|
||||
static void perf_output_read_group(struct perf_output_handle *handle,
|
||||
struct perf_event *event,
|
||||
u64 enabled, u64 running)
|
||||
@@ -5776,6 +5768,13 @@ static void perf_output_read_group(struct perf_output_handle *handle,
|
||||
#define PERF_FORMAT_TOTAL_TIMES (PERF_FORMAT_TOTAL_TIME_ENABLED|\
|
||||
PERF_FORMAT_TOTAL_TIME_RUNNING)
|
||||
|
||||
/*
|
||||
* XXX PERF_SAMPLE_READ vs inherited events seems difficult.
|
||||
*
|
||||
* The problem is that its both hard and excessively expensive to iterate the
|
||||
* child list, not to mention that its impossible to IPI the children running
|
||||
* on another CPU, from interrupt/NMI context.
|
||||
*/
|
||||
static void perf_output_read(struct perf_output_handle *handle,
|
||||
struct perf_event *event)
|
||||
{
|
||||
@@ -9193,7 +9192,7 @@ static int perf_try_init_event(struct pmu *pmu, struct perf_event *event)
|
||||
|
||||
static struct pmu *perf_init_event(struct perf_event *event)
|
||||
{
|
||||
struct pmu *pmu = NULL;
|
||||
struct pmu *pmu;
|
||||
int idx;
|
||||
int ret;
|
||||
|
||||
@@ -9462,9 +9461,10 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
|
||||
local64_set(&hwc->period_left, hwc->sample_period);
|
||||
|
||||
/*
|
||||
* we currently do not support PERF_FORMAT_GROUP on inherited events
|
||||
* We currently do not support PERF_SAMPLE_READ on inherited events.
|
||||
* See perf_output_read().
|
||||
*/
|
||||
if (attr->inherit && (attr->read_format & PERF_FORMAT_GROUP))
|
||||
if (attr->inherit && (attr->sample_type & PERF_SAMPLE_READ))
|
||||
goto err_ns;
|
||||
|
||||
if (!has_branch_stack(event))
|
||||
@@ -9477,9 +9477,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
|
||||
}
|
||||
|
||||
pmu = perf_init_event(event);
|
||||
if (!pmu)
|
||||
goto err_ns;
|
||||
else if (IS_ERR(pmu)) {
|
||||
if (IS_ERR(pmu)) {
|
||||
err = PTR_ERR(pmu);
|
||||
goto err_ns;
|
||||
}
|
||||
@@ -9492,8 +9490,10 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
|
||||
event->addr_filters_offs = kcalloc(pmu->nr_addr_filters,
|
||||
sizeof(unsigned long),
|
||||
GFP_KERNEL);
|
||||
if (!event->addr_filters_offs)
|
||||
if (!event->addr_filters_offs) {
|
||||
err = -ENOMEM;
|
||||
goto err_per_task;
|
||||
}
|
||||
|
||||
/* force hw sync on the address filters */
|
||||
event->addr_filters_gen = 1;
|
||||
|
||||
@@ -19,3 +19,13 @@
|
||||
|
||||
/* &a[0] degrades to a pointer: a different type from an array */
|
||||
#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
|
||||
|
||||
#define noinline __attribute__((noinline))
|
||||
|
||||
#define __packed __attribute__((packed))
|
||||
|
||||
#define __noreturn __attribute__((noreturn))
|
||||
|
||||
#define __aligned(x) __attribute__((aligned(x)))
|
||||
#define __printf(a, b) __attribute__((format(printf, a, b)))
|
||||
#define __scanf(a, b) __attribute__((format(scanf, a, b)))
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
# define __always_inline inline __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
#ifndef noinline
|
||||
#define noinline
|
||||
#endif
|
||||
|
||||
/* Are two types/vars the same type (ignoring qualifiers)? */
|
||||
#ifndef __same_type
|
||||
# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <endian.h>
|
||||
#include <byteswap.h>
|
||||
|
||||
#ifndef UINT_MAX
|
||||
#define UINT_MAX (~0U)
|
||||
@@ -68,12 +70,33 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Both need more care to handle endianness
|
||||
* (Don't use bitmap_copy_le() for now)
|
||||
*/
|
||||
#define cpu_to_le64(x) (x)
|
||||
#define cpu_to_le32(x) (x)
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define cpu_to_le16 bswap_16
|
||||
#define cpu_to_le32 bswap_32
|
||||
#define cpu_to_le64 bswap_64
|
||||
#define le16_to_cpu bswap_16
|
||||
#define le32_to_cpu bswap_32
|
||||
#define le64_to_cpu bswap_64
|
||||
#define cpu_to_be16
|
||||
#define cpu_to_be32
|
||||
#define cpu_to_be64
|
||||
#define be16_to_cpu
|
||||
#define be32_to_cpu
|
||||
#define be64_to_cpu
|
||||
#else
|
||||
#define cpu_to_le16
|
||||
#define cpu_to_le32
|
||||
#define cpu_to_le64
|
||||
#define le16_to_cpu
|
||||
#define le32_to_cpu
|
||||
#define le64_to_cpu
|
||||
#define cpu_to_be16 bswap_16
|
||||
#define cpu_to_be32 bswap_32
|
||||
#define cpu_to_be64 bswap_64
|
||||
#define be16_to_cpu bswap_16
|
||||
#define be32_to_cpu bswap_32
|
||||
#define be64_to_cpu bswap_64
|
||||
#endif
|
||||
|
||||
int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
|
||||
int scnprintf(char * buf, size_t size, const char * fmt, ...);
|
||||
|
||||
@@ -387,6 +387,22 @@ int filename__read_str(const char *filename, char **buf, size_t *sizep)
|
||||
return err;
|
||||
}
|
||||
|
||||
int filename__write_int(const char *filename, int value)
|
||||
{
|
||||
int fd = open(filename, O_WRONLY), err = -1;
|
||||
char buf[64];
|
||||
|
||||
if (fd < 0)
|
||||
return err;
|
||||
|
||||
sprintf(buf, "%d", value);
|
||||
if (write(fd, buf, sizeof(buf)) == sizeof(buf))
|
||||
err = 0;
|
||||
|
||||
close(fd);
|
||||
return err;
|
||||
}
|
||||
|
||||
int procfs__read_str(const char *entry, char **buf, size_t *sizep)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
@@ -480,3 +496,17 @@ int sysctl__read_int(const char *sysctl, int *value)
|
||||
|
||||
return filename__read_int(path, value);
|
||||
}
|
||||
|
||||
int sysfs__write_int(const char *entry, int value)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
const char *sysfs = sysfs__mountpoint();
|
||||
|
||||
if (!sysfs)
|
||||
return -1;
|
||||
|
||||
if (snprintf(path, sizeof(path), "%s/%s", sysfs, entry) >= PATH_MAX)
|
||||
return -1;
|
||||
|
||||
return filename__write_int(path, value);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ int filename__read_int(const char *filename, int *value);
|
||||
int filename__read_ull(const char *filename, unsigned long long *value);
|
||||
int filename__read_str(const char *filename, char **buf, size_t *sizep);
|
||||
|
||||
int filename__write_int(const char *filename, int value);
|
||||
|
||||
int procfs__read_str(const char *entry, char **buf, size_t *sizep);
|
||||
|
||||
int sysctl__read_int(const char *sysctl, int *value);
|
||||
@@ -38,4 +40,6 @@ int sysfs__read_int(const char *entry, int *value);
|
||||
int sysfs__read_ull(const char *entry, unsigned long long *value);
|
||||
int sysfs__read_str(const char *entry, char **buf, size_t *sizep);
|
||||
int sysfs__read_bool(const char *entry, bool *value);
|
||||
|
||||
int sysfs__write_int(const char *entry, int value);
|
||||
#endif /* __API_FS__ */
|
||||
|
||||
@@ -1009,7 +1009,7 @@ GrpTable: Grp15
|
||||
1: fxstor | RDGSBASE Ry (F3),(11B)
|
||||
2: vldmxcsr Md (v1) | WRFSBASE Ry (F3),(11B)
|
||||
3: vstmxcsr Md (v1) | WRGSBASE Ry (F3),(11B)
|
||||
4: XSAVE
|
||||
4: XSAVE | ptwrite Ey (F3),(11B)
|
||||
5: XRSTOR | lfence (11B)
|
||||
6: XSAVEOPT | clwb (66) | mfence (11B)
|
||||
7: clflush | clflushopt (66) | sfence (11B)
|
||||
|
||||
@@ -108,6 +108,9 @@ approach is available to export the data to a postgresql database. Refer to
|
||||
script export-to-postgresql.py for more details, and to script
|
||||
call-graph-from-postgresql.py for an example of using the database.
|
||||
|
||||
There is also script intel-pt-events.py which provides an example of how to
|
||||
unpack the raw data for power events and PTWRITE.
|
||||
|
||||
As mentioned above, it is easy to capture too much data. One way to limit the
|
||||
data captured is to use 'snapshot' mode which is explained further below.
|
||||
Refer to 'new snapshot option' and 'Intel PT modes of operation' further below.
|
||||
@@ -364,6 +367,42 @@ cyc_thresh Specifies how frequently CYC packets are produced - see cyc
|
||||
|
||||
CYC packets are not requested by default.
|
||||
|
||||
pt Specifies pass-through which enables the 'branch' config term.
|
||||
|
||||
The default config selects 'pt' if it is available, so a user will
|
||||
never need to specify this term.
|
||||
|
||||
branch Enable branch tracing. Branch tracing is enabled by default so to
|
||||
disable branch tracing use 'branch=0'.
|
||||
|
||||
The default config selects 'branch' if it is available.
|
||||
|
||||
ptw Enable PTWRITE packets which are produced when a ptwrite instruction
|
||||
is executed.
|
||||
|
||||
Support for this feature is indicated by:
|
||||
|
||||
/sys/bus/event_source/devices/intel_pt/caps/ptwrite
|
||||
|
||||
which contains "1" if the feature is supported and
|
||||
"0" otherwise.
|
||||
|
||||
fup_on_ptw Enable a FUP packet to follow the PTWRITE packet. The FUP packet
|
||||
provides the address of the ptwrite instruction. In the absence of
|
||||
fup_on_ptw, the decoder will use the address of the previous branch
|
||||
if branch tracing is enabled, otherwise the address will be zero.
|
||||
Note that fup_on_ptw will work even when branch tracing is disabled.
|
||||
|
||||
pwr_evt Enable power events. The power events provide information about
|
||||
changes to the CPU C-state.
|
||||
|
||||
Support for this feature is indicated by:
|
||||
|
||||
/sys/bus/event_source/devices/intel_pt/caps/power_event_trace
|
||||
|
||||
which contains "1" if the feature is supported and
|
||||
"0" otherwise.
|
||||
|
||||
|
||||
new snapshot option
|
||||
-------------------
|
||||
@@ -674,13 +713,15 @@ Having no option is the same as
|
||||
|
||||
which, in turn, is the same as
|
||||
|
||||
--itrace=ibxe
|
||||
--itrace=ibxwpe
|
||||
|
||||
The letters are:
|
||||
|
||||
i synthesize "instructions" events
|
||||
b synthesize "branches" events
|
||||
x synthesize "transactions" events
|
||||
w synthesize "ptwrite" events
|
||||
p synthesize "power" events
|
||||
c synthesize branches events (calls only)
|
||||
r synthesize branches events (returns only)
|
||||
e synthesize tracing error events
|
||||
@@ -699,7 +740,40 @@ and "r" can be combined to get calls and returns.
|
||||
'flags' field can be used in perf script to determine whether the event is a
|
||||
tranasaction start, commit or abort.
|
||||
|
||||
Error events are new. They show where the decoder lost the trace. Error events
|
||||
Note that "instructions", "branches" and "transactions" events depend on code
|
||||
flow packets which can be disabled by using the config term "branch=0". Refer
|
||||
to the config terms section above.
|
||||
|
||||
"ptwrite" events record the payload of the ptwrite instruction and whether
|
||||
"fup_on_ptw" was used. "ptwrite" events depend on PTWRITE packets which are
|
||||
recorded only if the "ptw" config term was used. Refer to the config terms
|
||||
section above. perf script "synth" field displays "ptwrite" information like
|
||||
this: "ip: 0 payload: 0x123456789abcdef0" where "ip" is 1 if "fup_on_ptw" was
|
||||
used.
|
||||
|
||||
"Power" events correspond to power event packets and CBR (core-to-bus ratio)
|
||||
packets. While CBR packets are always recorded when tracing is enabled, power
|
||||
event packets are recorded only if the "pwr_evt" config term was used. Refer to
|
||||
the config terms section above. The power events record information about
|
||||
C-state changes, whereas CBR is indicative of CPU frequency. perf script
|
||||
"event,synth" fields display information like this:
|
||||
cbr: cbr: 22 freq: 2189 MHz (200%)
|
||||
mwait: hints: 0x60 extensions: 0x1
|
||||
pwre: hw: 0 cstate: 2 sub-cstate: 0
|
||||
exstop: ip: 1
|
||||
pwrx: deepest cstate: 2 last cstate: 2 wake reason: 0x4
|
||||
Where:
|
||||
"cbr" includes the frequency and the percentage of maximum non-turbo
|
||||
"mwait" shows mwait hints and extensions
|
||||
"pwre" shows C-state transitions (to a C-state deeper than C0) and
|
||||
whether initiated by hardware
|
||||
"exstop" indicates execution stopped and whether the IP was recorded
|
||||
exactly,
|
||||
"pwrx" indicates return to C0
|
||||
For more details refer to the Intel 64 and IA-32 Architectures Software
|
||||
Developer Manuals.
|
||||
|
||||
Error events show where the decoder lost the trace. Error events
|
||||
are quite important. Users must know if what they are seeing is a complete
|
||||
picture or not.
|
||||
|
||||
|
||||
@@ -3,13 +3,15 @@
|
||||
c synthesize branches events (calls only)
|
||||
r synthesize branches events (returns only)
|
||||
x synthesize transactions events
|
||||
w synthesize ptwrite events
|
||||
p synthesize power events
|
||||
e synthesize error events
|
||||
d create a debug log
|
||||
g synthesize a call chain (use with i or x)
|
||||
l synthesize last branch entries (use with i or x)
|
||||
s skip initial number of events
|
||||
|
||||
The default is all events i.e. the same as --itrace=ibxe
|
||||
The default is all events i.e. the same as --itrace=ibxwpe
|
||||
|
||||
In addition, the period (default 100000) for instructions events
|
||||
can be specified in units of:
|
||||
@@ -26,8 +28,8 @@
|
||||
Also the number of last branch entries (default 64, max. 1024) for
|
||||
instructions or transactions events can be specified.
|
||||
|
||||
It is also possible to skip events generated (instructions, branches, transactions)
|
||||
at the beginning. This is useful to ignore initialization code.
|
||||
It is also possible to skip events generated (instructions, branches, transactions,
|
||||
ptwrite, power) at the beginning. This is useful to ignore initialization code.
|
||||
|
||||
--itrace=i0nss1000000
|
||||
|
||||
|
||||
@@ -48,6 +48,39 @@ OPTIONS
|
||||
Ranges of CPUs are specified with -: 0-2.
|
||||
Default is to trace on all online CPUs.
|
||||
|
||||
-T::
|
||||
--trace-funcs=::
|
||||
Only trace functions given by the argument. Multiple functions
|
||||
can be given by using this option more than once. The function
|
||||
argument also can be a glob pattern. It will be passed to
|
||||
'set_ftrace_filter' in tracefs.
|
||||
|
||||
-N::
|
||||
--notrace-funcs=::
|
||||
Do not trace functions given by the argument. Like -T option,
|
||||
this can be used more than once to specify multiple functions
|
||||
(or glob patterns). It will be passed to 'set_ftrace_notrace'
|
||||
in tracefs.
|
||||
|
||||
-G::
|
||||
--graph-funcs=::
|
||||
Set graph filter on the given function (or a glob pattern).
|
||||
This is useful for the function_graph tracer only and enables
|
||||
tracing for functions executed from the given function.
|
||||
This can be used more than once to specify multiple functions.
|
||||
It will be passed to 'set_graph_function' in tracefs.
|
||||
|
||||
-g::
|
||||
--nograph-funcs=::
|
||||
Set graph notrace filter on the given function (or a glob pattern).
|
||||
Like -G option, this is useful for the function_graph tracer only
|
||||
and disables tracing for function executed from the given function.
|
||||
This can be used more than once to specify multiple functions.
|
||||
It will be passed to 'set_graph_notrace' in tracefs.
|
||||
|
||||
-D::
|
||||
--graph-depth=::
|
||||
Set max depth for function graph tracer to follow
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
|
||||
@@ -116,8 +116,9 @@ OPTIONS
|
||||
--fields::
|
||||
Comma separated list of fields to print. Options are:
|
||||
comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff,
|
||||
srcline, period, iregs, brstack, brstacksym, flags, bpf-output, brstackinsn,
|
||||
callindent, insn, insnlen. Field list can be prepended with the type, trace, sw or hw,
|
||||
srcline, period, iregs, brstack, brstacksym, flags, bpf-output, brstackinsn, brstackoff,
|
||||
callindent, insn, insnlen, synth.
|
||||
Field list can be prepended with the type, trace, sw or hw,
|
||||
to indicate to which event type the field list applies.
|
||||
e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace
|
||||
|
||||
@@ -130,6 +131,14 @@ OPTIONS
|
||||
i.e., the specified fields apply to all event types if the type string
|
||||
is not given.
|
||||
|
||||
In addition to overriding fields, it is also possible to add or remove
|
||||
fields from the defaults. For example
|
||||
|
||||
-F -cpu,+insn
|
||||
|
||||
removes the cpu field and adds the insn field. Adding/removing fields
|
||||
cannot be mixed with normal overriding.
|
||||
|
||||
The arguments are processed in the order received. A later usage can
|
||||
reset a prior request. e.g.:
|
||||
|
||||
@@ -185,6 +194,9 @@ OPTIONS
|
||||
instruction bytes and the instruction length of the current
|
||||
instruction.
|
||||
|
||||
The synth field is used by synthesized events which may be created when
|
||||
Instruction Trace decoding.
|
||||
|
||||
Finally, a user may not set fields to none for all event types.
|
||||
i.e., -F "" is not allowed.
|
||||
|
||||
@@ -203,6 +215,8 @@ OPTIONS
|
||||
is printed. This is the full execution path leading to the sample. This is only supported when the
|
||||
sample was recorded with perf record -b or -j any.
|
||||
|
||||
The brstackoff field will print an offset into a specific dso/binary.
|
||||
|
||||
-k::
|
||||
--vmlinux=<file>::
|
||||
vmlinux pathname
|
||||
|
||||
@@ -239,6 +239,20 @@ taskset.
|
||||
--no-merge::
|
||||
Do not merge results from same PMUs.
|
||||
|
||||
--smi-cost::
|
||||
Measure SMI cost if msr/aperf/ and msr/smi/ events are supported.
|
||||
|
||||
During the measurement, the /sys/device/cpu/freeze_on_smi will be set to
|
||||
freeze core counters on SMI.
|
||||
The aperf counter will not be effected by the setting.
|
||||
The cost of SMI can be measured by (aperf - unhalted core cycles).
|
||||
|
||||
In practice, the percentages of SMI cycles is very useful for performance
|
||||
oriented analysis. --metric_only will be applied by default.
|
||||
The output is SMI cycles%, equals to (aperf - unhalted core cycles) / aperf
|
||||
|
||||
Users who wants to get the actual value can apply --no-metric-only.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ endif
|
||||
# Disable it on all other architectures in case libdw unwind
|
||||
# support is detected in system. Add supported architectures
|
||||
# to the check.
|
||||
ifneq ($(SRCARCH),$(filter $(SRCARCH),x86 arm))
|
||||
ifneq ($(SRCARCH),$(filter $(SRCARCH),x86 arm powerpc))
|
||||
NO_LIBDW_DWARF_UNWIND := 1
|
||||
endif
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <api/fs/fs.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/coresight-pmu.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/log2.h>
|
||||
@@ -202,19 +203,18 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
|
||||
pr_debug2("%s snapshot size: %zu\n", CORESIGHT_ETM_PMU_NAME,
|
||||
opts->auxtrace_snapshot_size);
|
||||
|
||||
if (cs_etm_evsel) {
|
||||
/*
|
||||
* To obtain the auxtrace buffer file descriptor, the auxtrace
|
||||
* event must come first.
|
||||
*/
|
||||
perf_evlist__to_front(evlist, cs_etm_evsel);
|
||||
/*
|
||||
* In the case of per-cpu mmaps, we need the CPU on the
|
||||
* AUX event.
|
||||
*/
|
||||
if (!cpu_map__empty(cpus))
|
||||
perf_evsel__set_sample_bit(cs_etm_evsel, CPU);
|
||||
}
|
||||
/*
|
||||
* To obtain the auxtrace buffer file descriptor, the auxtrace
|
||||
* event must come first.
|
||||
*/
|
||||
perf_evlist__to_front(evlist, cs_etm_evsel);
|
||||
|
||||
/*
|
||||
* In the case of per-cpu mmaps, we need the CPU on the
|
||||
* AUX event.
|
||||
*/
|
||||
if (!cpu_map__empty(cpus))
|
||||
perf_evsel__set_sample_bit(cs_etm_evsel, CPU);
|
||||
|
||||
/* Add dummy event to keep tracking */
|
||||
if (opts->full_auxtrace) {
|
||||
@@ -583,8 +583,7 @@ static FILE *cs_device__open_file(const char *name)
|
||||
|
||||
}
|
||||
|
||||
static __attribute__((format(printf, 2, 3)))
|
||||
int cs_device__print_file(const char *name, const char *fmt, ...)
|
||||
static int __printf(2, 3) cs_device__print_file(const char *name, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
FILE *file;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user