Skip to content

Commit

Permalink
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/li…
Browse files Browse the repository at this point in the history
…nux/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
  ...
  • Loading branch information
Linus Torvalds committed Jul 3, 2017
2 parents 892ad5a + 23acd3e commit 7447d56
Show file tree
Hide file tree
Showing 92 changed files with 2,524 additions and 625 deletions.
10 changes: 10 additions & 0 deletions arch/x86/events/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
63 changes: 63 additions & 0 deletions arch/x86/events/intel/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3160,6 +3160,19 @@ static int intel_pmu_cpu_prepare(int cpu)
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);
Expand All @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/events/intel/lbr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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] = {
Expand Down Expand Up @@ -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)) {
/*
Expand Down
3 changes: 3 additions & 0 deletions arch/x86/events/perf_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
2 changes: 2 additions & 0 deletions arch/x86/include/asm/msr-index.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion arch/x86/lib/x86-opcode-map.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
30 changes: 15 additions & 15 deletions kernel/events/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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))
Expand All @@ -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;
}
Expand All @@ -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;
Expand Down
10 changes: 10 additions & 0 deletions tools/include/linux/compiler-gcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
4 changes: 4 additions & 0 deletions tools/include/linux/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
35 changes: 29 additions & 6 deletions tools/include/linux/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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, ...);
Expand Down
30 changes: 30 additions & 0 deletions tools/lib/api/fs/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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);
}
4 changes: 4 additions & 0 deletions tools/lib/api/fs/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,15 @@ 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);
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__ */
2 changes: 1 addition & 1 deletion tools/objtool/arch/x86/insn/x86-opcode-map.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 7447d56

Please sign in to comment.