mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-08-18 02:22:47 -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:
"Bigger kernel side changes:
- Add backwards writing capability to the perf ring-buffer code,
which is preparation for future advanced features like robust
'overwrite support' and snapshot mode. (Wang Nan)
- Add pause and resume ioctls for the perf ringbuffer (Wang Nan)
- x86 Intel cstate code cleanups and reorgnization (Thomas Gleixner)
- x86 Intel uncore and CPU PMU driver updates (Kan Liang, Peter
Zijlstra)
- x86 AUX (Intel PT) related enhancements and updates (Alexander
Shishkin)
- x86 MSR PMU driver enhancements and updates (Huang Rui)
- ... and lots of other changes spread out over 40+ commits.
Biggest tooling side changes:
- 'perf trace' features and enhancements. (Arnaldo Carvalho de Melo)
- BPF tooling updates (Wang Nan)
- 'perf sched' updates (Jiri Olsa)
- 'perf probe' updates (Masami Hiramatsu)
- ... plus 200+ other enhancements, fixes and cleanups to tools/
The merge commits, the shortlog and the changelogs contain a lot more
details"
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (249 commits)
perf/core: Disable the event on a truncated AUX record
perf/x86/intel/pt: Generate PMI in the STOP region as well
perf buildid-cache: Use lsdir() for looking up buildid caches
perf symbols: Use lsdir() for the search in kcore cache directory
perf tools: Use SBUILD_ID_SIZE where applicable
perf tools: Fix lsdir to set errno correctly
perf trace: Move seccomp args beautifiers to tools/perf/trace/beauty/
perf trace: Move flock op beautifier to tools/perf/trace/beauty/
perf build: Add build-test for debug-frame on arm/arm64
perf build: Add build-test for libunwind cross-platforms support
perf script: Fix export of callchains with recursion in db-export
perf script: Fix callchain addresses in db-export
perf script: Fix symbol insertion behavior in db-export
perf symbols: Add dso__insert_symbol function
perf scripting python: Use Py_FatalError instead of die()
perf tools: Remove xrealloc and ALLOC_GROW
perf help: Do not use ALLOC_GROW in add_cmd_list
perf pmu: Make pmu_formats_string to check return value of strbuf
perf header: Make topology checkers to check return value of strbuf
perf tools: Make alias handler to check return value of strbuf
...
This commit is contained in:
commit
36db171cc7
217 files changed
+8344
-2747
No files matched your search
@@ -60,6 +60,7 @@ show up in /proc/sys/kernel:
|
||||
- panic_on_warn
|
||||
- perf_cpu_time_max_percent
|
||||
- perf_event_paranoid
|
||||
- perf_event_max_stack
|
||||
- pid_max
|
||||
- powersave-nap [ PPC only ]
|
||||
- printk
|
||||
@@ -654,6 +655,19 @@ users (without CAP_SYS_ADMIN). The default value is 2.
|
||||
|
||||
==============================================================
|
||||
|
||||
perf_event_max_stack:
|
||||
|
||||
Controls maximum number of stack frames to copy for (attr.sample_type &
|
||||
PERF_SAMPLE_CALLCHAIN) configured events, for instance, when using
|
||||
'perf record -g' or 'perf trace --call-graph fp'.
|
||||
|
||||
This can only be done when no events are in use that have callchains
|
||||
enabled, otherwise writing to this file will return -EBUSY.
|
||||
|
||||
The default value is 127.
|
||||
|
||||
==============================================================
|
||||
|
||||
pid_max:
|
||||
|
||||
PID allocation wrap value. When the kernel's next PID value
|
||||
|
||||
@@ -631,7 +631,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
|
||||
info->address &= ~alignment_mask;
|
||||
info->ctrl.len <<= offset;
|
||||
|
||||
if (!bp->overflow_handler) {
|
||||
if (is_default_overflow_handler(bp)) {
|
||||
/*
|
||||
* Mismatch breakpoints are required for single-stepping
|
||||
* breakpoints.
|
||||
@@ -754,7 +754,7 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
|
||||
* mismatch breakpoint so we can single-step over the
|
||||
* watchpoint trigger.
|
||||
*/
|
||||
if (!wp->overflow_handler)
|
||||
if (is_default_overflow_handler(wp))
|
||||
enable_single_step(wp, instruction_pointer(regs));
|
||||
|
||||
unlock:
|
||||
|
||||
@@ -75,7 +75,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
|
||||
|
||||
tail = (struct frame_tail __user *)regs->ARM_fp - 1;
|
||||
|
||||
while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
|
||||
while ((entry->nr < sysctl_perf_event_max_stack) &&
|
||||
tail && !((unsigned long)tail & 0x3))
|
||||
tail = user_backtrace(tail, entry);
|
||||
}
|
||||
|
||||
@@ -616,7 +616,7 @@ static int breakpoint_handler(unsigned long unused, unsigned int esr,
|
||||
perf_bp_event(bp, regs);
|
||||
|
||||
/* Do we need to handle the stepping? */
|
||||
if (!bp->overflow_handler)
|
||||
if (is_default_overflow_handler(bp))
|
||||
step = 1;
|
||||
unlock:
|
||||
rcu_read_unlock();
|
||||
@@ -712,7 +712,7 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr,
|
||||
perf_bp_event(wp, regs);
|
||||
|
||||
/* Do we need to handle the stepping? */
|
||||
if (!wp->overflow_handler)
|
||||
if (is_default_overflow_handler(wp))
|
||||
step = 1;
|
||||
|
||||
unlock:
|
||||
|
||||
@@ -122,7 +122,7 @@ void perf_callchain_user(struct perf_callchain_entry *entry,
|
||||
|
||||
tail = (struct frame_tail __user *)regs->regs[29];
|
||||
|
||||
while (entry->nr < PERF_MAX_STACK_DEPTH &&
|
||||
while (entry->nr < sysctl_perf_event_max_stack &&
|
||||
tail && !((unsigned long)tail & 0xf))
|
||||
tail = user_backtrace(tail, entry);
|
||||
} else {
|
||||
@@ -132,7 +132,7 @@ void perf_callchain_user(struct perf_callchain_entry *entry,
|
||||
|
||||
tail = (struct compat_frame_tail __user *)regs->compat_fp - 1;
|
||||
|
||||
while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
|
||||
while ((entry->nr < sysctl_perf_event_max_stack) &&
|
||||
tail && !((unsigned long)tail & 0x3))
|
||||
tail = compat_user_backtrace(tail, entry);
|
||||
#endif
|
||||
|
||||
@@ -65,7 +65,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
|
||||
|
||||
--frame;
|
||||
|
||||
while ((entry->nr < PERF_MAX_STACK_DEPTH) && frame)
|
||||
while ((entry->nr < sysctl_perf_event_max_stack) && frame)
|
||||
frame = user_backtrace(frame, entry);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ static void save_raw_perf_callchain(struct perf_callchain_entry *entry,
|
||||
addr = *sp++;
|
||||
if (__kernel_text_address(addr)) {
|
||||
perf_callchain_store(entry, addr);
|
||||
if (entry->nr >= PERF_MAX_STACK_DEPTH)
|
||||
if (entry->nr >= sysctl_perf_event_max_stack)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,7 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry,
|
||||
}
|
||||
do {
|
||||
perf_callchain_store(entry, pc);
|
||||
if (entry->nr >= PERF_MAX_STACK_DEPTH)
|
||||
if (entry->nr >= sysctl_perf_event_max_stack)
|
||||
break;
|
||||
pc = unwind_stack(current, &sp, pc, &ra);
|
||||
} while (pc);
|
||||
|
||||
@@ -247,7 +247,7 @@ static void perf_callchain_user_64(struct perf_callchain_entry *entry,
|
||||
sp = regs->gpr[1];
|
||||
perf_callchain_store(entry, next_ip);
|
||||
|
||||
while (entry->nr < PERF_MAX_STACK_DEPTH) {
|
||||
while (entry->nr < sysctl_perf_event_max_stack) {
|
||||
fp = (unsigned long __user *) sp;
|
||||
if (!valid_user_sp(sp, 1) || read_user_stack_64(fp, &next_sp))
|
||||
return;
|
||||
@@ -453,7 +453,7 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry,
|
||||
sp = regs->gpr[1];
|
||||
perf_callchain_store(entry, next_ip);
|
||||
|
||||
while (entry->nr < PERF_MAX_STACK_DEPTH) {
|
||||
while (entry->nr < sysctl_perf_event_max_stack) {
|
||||
fp = (unsigned int __user *) (unsigned long) sp;
|
||||
if (!valid_user_sp(sp, 0) || read_user_stack_32(fp, &next_sp))
|
||||
return;
|
||||
|
||||
@@ -1756,7 +1756,7 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} while (entry->nr < PERF_MAX_STACK_DEPTH);
|
||||
} while (entry->nr < sysctl_perf_event_max_stack);
|
||||
}
|
||||
|
||||
static inline int
|
||||
@@ -1790,7 +1790,7 @@ static void perf_callchain_user_64(struct perf_callchain_entry *entry,
|
||||
pc = sf.callers_pc;
|
||||
ufp = (unsigned long)sf.fp + STACK_BIAS;
|
||||
perf_callchain_store(entry, pc);
|
||||
} while (entry->nr < PERF_MAX_STACK_DEPTH);
|
||||
} while (entry->nr < sysctl_perf_event_max_stack);
|
||||
}
|
||||
|
||||
static void perf_callchain_user_32(struct perf_callchain_entry *entry,
|
||||
@@ -1822,7 +1822,7 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry,
|
||||
ufp = (unsigned long)sf.fp;
|
||||
}
|
||||
perf_callchain_store(entry, pc);
|
||||
} while (entry->nr < PERF_MAX_STACK_DEPTH);
|
||||
} while (entry->nr < sysctl_perf_event_max_stack);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+2
-13
@@ -164,10 +164,6 @@ config INSTRUCTION_DECODER
|
||||
def_bool y
|
||||
depends on KPROBES || PERF_EVENTS || UPROBES
|
||||
|
||||
config PERF_EVENTS_INTEL_UNCORE
|
||||
def_bool y
|
||||
depends on PERF_EVENTS && CPU_SUP_INTEL && PCI
|
||||
|
||||
config OUTPUT_FORMAT
|
||||
string
|
||||
default "elf32-i386" if X86_32
|
||||
@@ -1046,6 +1042,8 @@ config X86_THERMAL_VECTOR
|
||||
def_bool y
|
||||
depends on X86_MCE_INTEL
|
||||
|
||||
source "arch/x86/events/Kconfig"
|
||||
|
||||
config X86_LEGACY_VM86
|
||||
bool "Legacy VM86 support"
|
||||
default n
|
||||
@@ -1210,15 +1208,6 @@ config MICROCODE_OLD_INTERFACE
|
||||
def_bool y
|
||||
depends on MICROCODE
|
||||
|
||||
config PERF_EVENTS_AMD_POWER
|
||||
depends on PERF_EVENTS && CPU_SUP_AMD
|
||||
tristate "AMD Processor Power Reporting Mechanism"
|
||||
---help---
|
||||
Provide power reporting mechanism support for AMD processors.
|
||||
Currently, it leverages X86_FEATURE_ACC_POWER
|
||||
(CPUID Fn8000_0007_EDX[12]) interface to calculate the
|
||||
average power consumption on Family 15h processors.
|
||||
|
||||
config X86_MSR
|
||||
tristate "/dev/cpu/*/msr - Model-specific register support"
|
||||
---help---
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
menu "Performance monitoring"
|
||||
|
||||
config PERF_EVENTS_INTEL_UNCORE
|
||||
tristate "Intel uncore performance events"
|
||||
depends on PERF_EVENTS && CPU_SUP_INTEL && PCI
|
||||
default y
|
||||
---help---
|
||||
Include support for Intel uncore performance events. These are
|
||||
available on NehalemEX and more modern processors.
|
||||
|
||||
config PERF_EVENTS_INTEL_RAPL
|
||||
tristate "Intel rapl performance events"
|
||||
depends on PERF_EVENTS && CPU_SUP_INTEL && PCI
|
||||
default y
|
||||
---help---
|
||||
Include support for Intel rapl performance events for power
|
||||
monitoring on modern processors.
|
||||
|
||||
config PERF_EVENTS_INTEL_CSTATE
|
||||
tristate "Intel cstate performance events"
|
||||
depends on PERF_EVENTS && CPU_SUP_INTEL && PCI
|
||||
default y
|
||||
---help---
|
||||
Include support for Intel cstate performance events for power
|
||||
monitoring on modern processors.
|
||||
|
||||
config PERF_EVENTS_AMD_POWER
|
||||
depends on PERF_EVENTS && CPU_SUP_AMD
|
||||
tristate "AMD Processor Power Reporting Mechanism"
|
||||
---help---
|
||||
Provide power reporting mechanism support for AMD processors.
|
||||
Currently, it leverages X86_FEATURE_ACC_POWER
|
||||
(CPUID Fn8000_0007_EDX[12]) interface to calculate the
|
||||
average power consumption on Family 15h processors.
|
||||
|
||||
endmenu
|
||||
@@ -6,9 +6,6 @@ obj-$(CONFIG_X86_LOCAL_APIC) += amd/ibs.o msr.o
|
||||
ifdef CONFIG_AMD_IOMMU
|
||||
obj-$(CONFIG_CPU_SUP_AMD) += amd/iommu.o
|
||||
endif
|
||||
obj-$(CONFIG_CPU_SUP_INTEL) += intel/core.o intel/bts.o intel/cqm.o
|
||||
obj-$(CONFIG_CPU_SUP_INTEL) += intel/cstate.o intel/ds.o intel/knc.o
|
||||
obj-$(CONFIG_CPU_SUP_INTEL) += intel/lbr.o intel/p4.o intel/p6.o intel/pt.o
|
||||
obj-$(CONFIG_CPU_SUP_INTEL) += intel/rapl.o msr.o
|
||||
obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel/uncore.o intel/uncore_nhmex.o
|
||||
obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel/uncore_snb.o intel/uncore_snbep.o
|
||||
|
||||
obj-$(CONFIG_CPU_SUP_INTEL) += msr.o
|
||||
obj-$(CONFIG_CPU_SUP_INTEL) += intel/
|
||||
@@ -263,6 +263,7 @@ static const struct attribute_group *amd_uncore_attr_groups[] = {
|
||||
};
|
||||
|
||||
static struct pmu amd_nb_pmu = {
|
||||
.task_ctx_nr = perf_invalid_context,
|
||||
.attr_groups = amd_uncore_attr_groups,
|
||||
.name = "amd_nb",
|
||||
.event_init = amd_uncore_event_init,
|
||||
@@ -274,6 +275,7 @@ static struct pmu amd_nb_pmu = {
|
||||
};
|
||||
|
||||
static struct pmu amd_l2_pmu = {
|
||||
.task_ctx_nr = perf_invalid_context,
|
||||
.attr_groups = amd_uncore_attr_groups,
|
||||
.name = "amd_l2",
|
||||
.event_init = amd_uncore_event_init,
|
||||
|
||||
@@ -360,6 +360,9 @@ int x86_add_exclusive(unsigned int what)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (x86_pmu.lbr_pt_coexist)
|
||||
return 0;
|
||||
|
||||
if (!atomic_inc_not_zero(&x86_pmu.lbr_exclusive[what])) {
|
||||
mutex_lock(&pmc_reserve_mutex);
|
||||
for (i = 0; i < ARRAY_SIZE(x86_pmu.lbr_exclusive); i++) {
|
||||
@@ -380,6 +383,9 @@ fail_unlock:
|
||||
|
||||
void x86_del_exclusive(unsigned int what)
|
||||
{
|
||||
if (x86_pmu.lbr_pt_coexist)
|
||||
return;
|
||||
|
||||
atomic_dec(&x86_pmu.lbr_exclusive[what]);
|
||||
atomic_dec(&active_events);
|
||||
}
|
||||
@@ -2277,7 +2283,7 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
|
||||
|
||||
fp = compat_ptr(ss_base + regs->bp);
|
||||
pagefault_disable();
|
||||
while (entry->nr < PERF_MAX_STACK_DEPTH) {
|
||||
while (entry->nr < sysctl_perf_event_max_stack) {
|
||||
unsigned long bytes;
|
||||
frame.next_frame = 0;
|
||||
frame.return_address = 0;
|
||||
@@ -2337,7 +2343,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
|
||||
return;
|
||||
|
||||
pagefault_disable();
|
||||
while (entry->nr < PERF_MAX_STACK_DEPTH) {
|
||||
while (entry->nr < sysctl_perf_event_max_stack) {
|
||||
unsigned long bytes;
|
||||
frame.next_frame = NULL;
|
||||
frame.return_address = 0;
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
obj-$(CONFIG_CPU_SUP_INTEL) += core.o bts.o cqm.o
|
||||
obj-$(CONFIG_CPU_SUP_INTEL) += ds.o knc.o
|
||||
obj-$(CONFIG_CPU_SUP_INTEL) += lbr.o p4.o p6.o pt.o
|
||||
obj-$(CONFIG_PERF_EVENTS_INTEL_RAPL) += intel-rapl.o
|
||||
intel-rapl-objs := rapl.o
|
||||
obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel-uncore.o
|
||||
intel-uncore-objs := uncore.o uncore_nhmex.o uncore_snb.o uncore_snbep.o
|
||||
obj-$(CONFIG_PERF_EVENTS_INTEL_CSTATE) += intel-cstate.o
|
||||
intel-cstate-objs := cstate.o
|
||||
+48
-57
@@ -171,18 +171,6 @@ static void bts_buffer_pad_out(struct bts_phys *phys, unsigned long head)
|
||||
memset(page_address(phys->page) + index, 0, phys->size - index);
|
||||
}
|
||||
|
||||
static bool bts_buffer_is_full(struct bts_buffer *buf, struct bts_ctx *bts)
|
||||
{
|
||||
if (buf->snapshot)
|
||||
return false;
|
||||
|
||||
if (local_read(&buf->data_size) >= bts->handle.size ||
|
||||
bts->handle.size - local_read(&buf->data_size) < BTS_RECORD_SIZE)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void bts_update(struct bts_ctx *bts)
|
||||
{
|
||||
int cpu = raw_smp_processor_id();
|
||||
@@ -213,18 +201,15 @@ static void bts_update(struct bts_ctx *bts)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
bts_buffer_reset(struct bts_buffer *buf, struct perf_output_handle *handle);
|
||||
|
||||
static void __bts_event_start(struct perf_event *event)
|
||||
{
|
||||
struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
|
||||
struct bts_buffer *buf = perf_get_aux(&bts->handle);
|
||||
u64 config = 0;
|
||||
|
||||
if (!buf || bts_buffer_is_full(buf, bts))
|
||||
return;
|
||||
|
||||
event->hw.itrace_started = 1;
|
||||
event->hw.state = 0;
|
||||
|
||||
if (!buf->snapshot)
|
||||
config |= ARCH_PERFMON_EVENTSEL_INT;
|
||||
if (!event->attr.exclude_kernel)
|
||||
@@ -241,16 +226,41 @@ static void __bts_event_start(struct perf_event *event)
|
||||
wmb();
|
||||
|
||||
intel_pmu_enable_bts(config);
|
||||
|
||||
}
|
||||
|
||||
static void bts_event_start(struct perf_event *event, int flags)
|
||||
{
|
||||
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
||||
struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
|
||||
struct bts_buffer *buf;
|
||||
|
||||
buf = perf_aux_output_begin(&bts->handle, event);
|
||||
if (!buf)
|
||||
goto fail_stop;
|
||||
|
||||
if (bts_buffer_reset(buf, &bts->handle))
|
||||
goto fail_end_stop;
|
||||
|
||||
bts->ds_back.bts_buffer_base = cpuc->ds->bts_buffer_base;
|
||||
bts->ds_back.bts_absolute_maximum = cpuc->ds->bts_absolute_maximum;
|
||||
bts->ds_back.bts_interrupt_threshold = cpuc->ds->bts_interrupt_threshold;
|
||||
|
||||
event->hw.itrace_started = 1;
|
||||
event->hw.state = 0;
|
||||
|
||||
__bts_event_start(event);
|
||||
|
||||
/* PMI handler: this counter is running and likely generating PMIs */
|
||||
ACCESS_ONCE(bts->started) = 1;
|
||||
|
||||
return;
|
||||
|
||||
fail_end_stop:
|
||||
perf_aux_output_end(&bts->handle, 0, false);
|
||||
|
||||
fail_stop:
|
||||
event->hw.state = PERF_HES_STOPPED;
|
||||
}
|
||||
|
||||
static void __bts_event_stop(struct perf_event *event)
|
||||
@@ -269,15 +279,32 @@ static void __bts_event_stop(struct perf_event *event)
|
||||
|
||||
static void bts_event_stop(struct perf_event *event, int flags)
|
||||
{
|
||||
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
||||
struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
|
||||
struct bts_buffer *buf = perf_get_aux(&bts->handle);
|
||||
|
||||
/* PMI handler: don't restart this counter */
|
||||
ACCESS_ONCE(bts->started) = 0;
|
||||
|
||||
__bts_event_stop(event);
|
||||
|
||||
if (flags & PERF_EF_UPDATE)
|
||||
if (flags & PERF_EF_UPDATE) {
|
||||
bts_update(bts);
|
||||
|
||||
if (buf) {
|
||||
if (buf->snapshot)
|
||||
bts->handle.head =
|
||||
local_xchg(&buf->data_size,
|
||||
buf->nr_pages << PAGE_SHIFT);
|
||||
perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
|
||||
!!local_xchg(&buf->lost, 0));
|
||||
}
|
||||
|
||||
cpuc->ds->bts_index = bts->ds_back.bts_buffer_base;
|
||||
cpuc->ds->bts_buffer_base = bts->ds_back.bts_buffer_base;
|
||||
cpuc->ds->bts_absolute_maximum = bts->ds_back.bts_absolute_maximum;
|
||||
cpuc->ds->bts_interrupt_threshold = bts->ds_back.bts_interrupt_threshold;
|
||||
}
|
||||
}
|
||||
|
||||
void intel_bts_enable_local(void)
|
||||
@@ -417,34 +444,14 @@ int intel_bts_interrupt(void)
|
||||
|
||||
static void bts_event_del(struct perf_event *event, int mode)
|
||||
{
|
||||
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
||||
struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
|
||||
struct bts_buffer *buf = perf_get_aux(&bts->handle);
|
||||
|
||||
bts_event_stop(event, PERF_EF_UPDATE);
|
||||
|
||||
if (buf) {
|
||||
if (buf->snapshot)
|
||||
bts->handle.head =
|
||||
local_xchg(&buf->data_size,
|
||||
buf->nr_pages << PAGE_SHIFT);
|
||||
perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0),
|
||||
!!local_xchg(&buf->lost, 0));
|
||||
}
|
||||
|
||||
cpuc->ds->bts_index = bts->ds_back.bts_buffer_base;
|
||||
cpuc->ds->bts_buffer_base = bts->ds_back.bts_buffer_base;
|
||||
cpuc->ds->bts_absolute_maximum = bts->ds_back.bts_absolute_maximum;
|
||||
cpuc->ds->bts_interrupt_threshold = bts->ds_back.bts_interrupt_threshold;
|
||||
}
|
||||
|
||||
static int bts_event_add(struct perf_event *event, int mode)
|
||||
{
|
||||
struct bts_buffer *buf;
|
||||
struct bts_ctx *bts = this_cpu_ptr(&bts_ctx);
|
||||
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
int ret = -EBUSY;
|
||||
|
||||
event->hw.state = PERF_HES_STOPPED;
|
||||
|
||||
@@ -454,26 +461,10 @@ static int bts_event_add(struct perf_event *event, int mode)
|
||||
if (bts->handle.event)
|
||||
return -EBUSY;
|
||||
|
||||
buf = perf_aux_output_begin(&bts->handle, event);
|
||||
if (!buf)
|
||||
return -EINVAL;
|
||||
|
||||
ret = bts_buffer_reset(buf, &bts->handle);
|
||||
if (ret) {
|
||||
perf_aux_output_end(&bts->handle, 0, false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bts->ds_back.bts_buffer_base = cpuc->ds->bts_buffer_base;
|
||||
bts->ds_back.bts_absolute_maximum = cpuc->ds->bts_absolute_maximum;
|
||||
bts->ds_back.bts_interrupt_threshold = cpuc->ds->bts_interrupt_threshold;
|
||||
|
||||
if (mode & PERF_EF_START) {
|
||||
bts_event_start(event, 0);
|
||||
if (hwc->state & PERF_HES_STOPPED) {
|
||||
bts_event_del(event, 0);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (hwc->state & PERF_HES_STOPPED)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1465,6 +1465,140 @@ static __initconst const u64 slm_hw_cache_event_ids
|
||||
},
|
||||
};
|
||||
|
||||
static struct extra_reg intel_glm_extra_regs[] __read_mostly = {
|
||||
/* must define OFFCORE_RSP_X first, see intel_fixup_er() */
|
||||
INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x760005ffbfull, RSP_0),
|
||||
INTEL_UEVENT_EXTRA_REG(0x02b7, MSR_OFFCORE_RSP_1, 0x360005ffbfull, RSP_1),
|
||||
EVENT_EXTRA_END
|
||||
};
|
||||
|
||||
#define GLM_DEMAND_DATA_RD BIT_ULL(0)
|
||||
#define GLM_DEMAND_RFO BIT_ULL(1)
|
||||
#define GLM_ANY_RESPONSE BIT_ULL(16)
|
||||
#define GLM_SNP_NONE_OR_MISS BIT_ULL(33)
|
||||
#define GLM_DEMAND_READ GLM_DEMAND_DATA_RD
|
||||
#define GLM_DEMAND_WRITE GLM_DEMAND_RFO
|
||||
#define GLM_DEMAND_PREFETCH (SNB_PF_DATA_RD|SNB_PF_RFO)
|
||||
#define GLM_LLC_ACCESS GLM_ANY_RESPONSE
|
||||
#define GLM_SNP_ANY (GLM_SNP_NONE_OR_MISS|SNB_NO_FWD|SNB_HITM)
|
||||
#define GLM_LLC_MISS (GLM_SNP_ANY|SNB_NON_DRAM)
|
||||
|
||||
static __initconst const u64 glm_hw_cache_event_ids
|
||||
[PERF_COUNT_HW_CACHE_MAX]
|
||||
[PERF_COUNT_HW_CACHE_OP_MAX]
|
||||
[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
|
||||
[C(L1D)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = 0x81d0, /* MEM_UOPS_RETIRED.ALL_LOADS */
|
||||
[C(RESULT_MISS)] = 0x0,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = 0x82d0, /* MEM_UOPS_RETIRED.ALL_STORES */
|
||||
[C(RESULT_MISS)] = 0x0,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = 0x0,
|
||||
[C(RESULT_MISS)] = 0x0,
|
||||
},
|
||||
},
|
||||
[C(L1I)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = 0x0380, /* ICACHE.ACCESSES */
|
||||
[C(RESULT_MISS)] = 0x0280, /* ICACHE.MISSES */
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = -1,
|
||||
[C(RESULT_MISS)] = -1,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = 0x0,
|
||||
[C(RESULT_MISS)] = 0x0,
|
||||
},
|
||||
},
|
||||
[C(LL)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = 0x1b7, /* OFFCORE_RESPONSE */
|
||||
[C(RESULT_MISS)] = 0x1b7, /* OFFCORE_RESPONSE */
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = 0x1b7, /* OFFCORE_RESPONSE */
|
||||
[C(RESULT_MISS)] = 0x1b7, /* OFFCORE_RESPONSE */
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = 0x1b7, /* OFFCORE_RESPONSE */
|
||||
[C(RESULT_MISS)] = 0x1b7, /* OFFCORE_RESPONSE */
|
||||
},
|
||||
},
|
||||
[C(DTLB)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = 0x81d0, /* MEM_UOPS_RETIRED.ALL_LOADS */
|
||||
[C(RESULT_MISS)] = 0x0,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = 0x82d0, /* MEM_UOPS_RETIRED.ALL_STORES */
|
||||
[C(RESULT_MISS)] = 0x0,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = 0x0,
|
||||
[C(RESULT_MISS)] = 0x0,
|
||||
},
|
||||
},
|
||||
[C(ITLB)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = 0x00c0, /* INST_RETIRED.ANY_P */
|
||||
[C(RESULT_MISS)] = 0x0481, /* ITLB.MISS */
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = -1,
|
||||
[C(RESULT_MISS)] = -1,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = -1,
|
||||
[C(RESULT_MISS)] = -1,
|
||||
},
|
||||
},
|
||||
[C(BPU)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
|
||||
[C(RESULT_MISS)] = 0x00c5, /* BR_MISP_RETIRED.ALL_BRANCHES */
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = -1,
|
||||
[C(RESULT_MISS)] = -1,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = -1,
|
||||
[C(RESULT_MISS)] = -1,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static __initconst const u64 glm_hw_cache_extra_regs
|
||||
[PERF_COUNT_HW_CACHE_MAX]
|
||||
[PERF_COUNT_HW_CACHE_OP_MAX]
|
||||
[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
|
||||
[C(LL)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = GLM_DEMAND_READ|
|
||||
GLM_LLC_ACCESS,
|
||||
[C(RESULT_MISS)] = GLM_DEMAND_READ|
|
||||
GLM_LLC_MISS,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = GLM_DEMAND_WRITE|
|
||||
GLM_LLC_ACCESS,
|
||||
[C(RESULT_MISS)] = GLM_DEMAND_WRITE|
|
||||
GLM_LLC_MISS,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = GLM_DEMAND_PREFETCH|
|
||||
GLM_LLC_ACCESS,
|
||||
[C(RESULT_MISS)] = GLM_DEMAND_PREFETCH|
|
||||
GLM_LLC_MISS,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
#define KNL_OT_L2_HITE BIT_ULL(19) /* Other Tile L2 Hit */
|
||||
#define KNL_OT_L2_HITF BIT_ULL(20) /* Other Tile L2 Hit */
|
||||
#define KNL_MCDRAM_LOCAL BIT_ULL(21)
|
||||
@@ -3447,7 +3581,7 @@ __init int intel_pmu_init(void)
|
||||
memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
|
||||
sizeof(hw_cache_extra_regs));
|
||||
|
||||
intel_pmu_lbr_init_atom();
|
||||
intel_pmu_lbr_init_slm();
|
||||
|
||||
x86_pmu.event_constraints = intel_slm_event_constraints;
|
||||
x86_pmu.pebs_constraints = intel_slm_pebs_event_constraints;
|
||||
@@ -3456,6 +3590,30 @@ __init int intel_pmu_init(void)
|
||||
pr_cont("Silvermont events, ");
|
||||
break;
|
||||
|
||||
case 92: /* 14nm Atom "Goldmont" */
|
||||
case 95: /* 14nm Atom "Goldmont Denverton" */
|
||||
memcpy(hw_cache_event_ids, glm_hw_cache_event_ids,
|
||||
sizeof(hw_cache_event_ids));
|
||||
memcpy(hw_cache_extra_regs, glm_hw_cache_extra_regs,
|
||||
sizeof(hw_cache_extra_regs));
|
||||
|
||||
intel_pmu_lbr_init_skl();
|
||||
|
||||
x86_pmu.event_constraints = intel_slm_event_constraints;
|
||||
x86_pmu.pebs_constraints = intel_glm_pebs_event_constraints;
|
||||
x86_pmu.extra_regs = intel_glm_extra_regs;
|
||||
/*
|
||||
* It's recommended to use CPU_CLK_UNHALTED.CORE_P + NPEBS
|
||||
* for precise cycles.
|
||||
* :pp is identical to :ppp
|
||||
*/
|
||||
x86_pmu.pebs_aliases = NULL;
|
||||
x86_pmu.pebs_prec_dist = true;
|
||||
x86_pmu.lbr_pt_coexist = true;
|
||||
x86_pmu.flags |= PMU_FL_HAS_RSP_1;
|
||||
pr_cont("Goldmont events, ");
|
||||
break;
|
||||
|
||||
case 37: /* 32nm Westmere */
|
||||
case 44: /* 32nm Westmere-EP */
|
||||
case 47: /* 32nm Westmere-EX */
|
||||
|
||||
+254
-289
File diff suppressed because it is too large.
Load diff
@@ -645,6 +645,12 @@ struct event_constraint intel_slm_pebs_event_constraints[] = {
|
||||
EVENT_CONSTRAINT_END
|
||||
};
|
||||
|
||||
struct event_constraint intel_glm_pebs_event_constraints[] = {
|
||||
/* Allow all events as PEBS with no flags */
|
||||
INTEL_ALL_EVENT_CONSTRAINT(0, 0x1),
|
||||
EVENT_CONSTRAINT_END
|
||||
};
|
||||
|
||||
struct event_constraint intel_nehalem_pebs_event_constraints[] = {
|
||||
INTEL_PLD_CONSTRAINT(0x100b, 0xf), /* MEM_INST_RETIRED.* */
|
||||
INTEL_FLAGS_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */
|
||||
|
||||
@@ -14,7 +14,8 @@ enum {
|
||||
LBR_FORMAT_EIP_FLAGS = 0x03,
|
||||
LBR_FORMAT_EIP_FLAGS2 = 0x04,
|
||||
LBR_FORMAT_INFO = 0x05,
|
||||
LBR_FORMAT_MAX_KNOWN = LBR_FORMAT_INFO,
|
||||
LBR_FORMAT_TIME = 0x06,
|
||||
LBR_FORMAT_MAX_KNOWN = LBR_FORMAT_TIME,
|
||||
};
|
||||
|
||||
static enum {
|
||||
@@ -464,6 +465,16 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
|
||||
abort = !!(info & LBR_INFO_ABORT);
|
||||
cycles = (info & LBR_INFO_CYCLES);
|
||||
}
|
||||
|
||||
if (lbr_format == LBR_FORMAT_TIME) {
|
||||
mis = !!(from & LBR_FROM_FLAG_MISPRED);
|
||||
pred = !mis;
|
||||
skip = 1;
|
||||
cycles = ((to >> 48) & LBR_INFO_CYCLES);
|
||||
|
||||
to = (u64)((((s64)to) << 16) >> 16);
|
||||
}
|
||||
|
||||
if (lbr_flags & LBR_EIP_FLAGS) {
|
||||
mis = !!(from & LBR_FROM_FLAG_MISPRED);
|
||||
pred = !mis;
|
||||
@@ -1049,6 +1060,24 @@ void __init intel_pmu_lbr_init_atom(void)
|
||||
pr_cont("8-deep LBR, ");
|
||||
}
|
||||
|
||||
/* slm */
|
||||
void __init intel_pmu_lbr_init_slm(void)
|
||||
{
|
||||
x86_pmu.lbr_nr = 8;
|
||||
x86_pmu.lbr_tos = MSR_LBR_TOS;
|
||||
x86_pmu.lbr_from = MSR_LBR_CORE_FROM;
|
||||
x86_pmu.lbr_to = MSR_LBR_CORE_TO;
|
||||
|
||||
x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
|
||||
x86_pmu.lbr_sel_map = nhm_lbr_sel_map;
|
||||
|
||||
/*
|
||||
* SW branch filter usage:
|
||||
* - compensate for lack of HW filter
|
||||
*/
|
||||
pr_cont("8-deep LBR, ");
|
||||
}
|
||||
|
||||
/* Knights Landing */
|
||||
void intel_pmu_lbr_init_knl(void)
|
||||
{
|
||||
|
||||
Loaded 20 of 217 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user