Merge: Perf sync v6.19

MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/2260

JIRA: https://redhat.atlassian.net/browse/RHEL-140195

CVE: CVE-2026-23159

CVE: CVE-2025-68375

CVE: CVE-2026-23014

CVE: CVE-2026-23127

CVE: CVE-2026-23435

Sync perf with upstream

Signed-off-by: Trevor Allison <tallison@redhat.com>

Approved-by: Michael Petlan <mpetlan@redhat.com>
Approved-by: Gary Guo <gguo@redhat.com>
Approved-by: Steve Best <sbest@redhat.com>
Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com>
Approved-by: Andrea Arcangeli <aarcange@redhat.com>

Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
This commit is contained in:
CKI KWF Bot
2026-07-10 19:52:59 +00:00
227 changed files with 11719 additions and 3447 deletions
+1 -4
View File
@@ -656,14 +656,11 @@ static int amd_uncore_df_event_init(struct perf_event *event)
struct hw_perf_event *hwc = &event->hw;
int ret = amd_uncore_event_init(event);
if (ret || pmu_version < 2)
return ret;
hwc->config = event->attr.config &
(pmu_version >= 2 ? AMD64_PERFMON_V2_RAW_EVENT_MASK_NB :
AMD64_RAW_EVENT_MASK_NB);
return 0;
return ret;
}
static int amd_uncore_df_add(struct perf_event *event, int flags)
+20 -7
View File
@@ -553,14 +553,22 @@ static inline int precise_br_compat(struct perf_event *event)
return m == b;
}
int x86_pmu_max_precise(void)
int x86_pmu_max_precise(struct pmu *pmu)
{
int precise = 0;
/* Support for constant skid */
if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) {
precise++;
/* arch PEBS */
if (x86_pmu.arch_pebs) {
precise = 2;
if (hybrid(pmu, arch_pebs_cap).pdists)
precise++;
return precise;
}
/* legacy PEBS - support for constant skid */
precise++;
/* Support for IP fixup */
if (x86_pmu.lbr_nr || x86_pmu.intel_cap.pebs_format >= 2)
precise++;
@@ -568,13 +576,14 @@ int x86_pmu_max_precise(void)
if (x86_pmu.pebs_prec_dist)
precise++;
}
return precise;
}
int x86_pmu_hw_config(struct perf_event *event)
{
if (event->attr.precise_ip) {
int precise = x86_pmu_max_precise();
int precise = x86_pmu_max_precise(event->pmu);
if (event->attr.precise_ip > precise)
return -EOPNOTSUPP;
@@ -1343,6 +1352,7 @@ static void x86_pmu_enable(struct pmu *pmu)
hwc->state |= PERF_HES_ARCH;
x86_pmu_stop(event, PERF_EF_UPDATE);
cpuc->events[hwc->idx] = NULL;
}
/*
@@ -1357,6 +1367,8 @@ static void x86_pmu_enable(struct pmu *pmu)
else if (i < n_running)
continue;
cpuc->events[hwc->idx] = event;
if (hwc->state & PERF_HES_ARCH)
continue;
@@ -1530,7 +1542,6 @@ static void x86_pmu_start(struct perf_event *event, int flags)
event->hw.state = 0;
cpuc->events[idx] = event;
__set_bit(idx, cpuc->active_mask);
static_call(x86_pmu_enable)(event);
perf_event_update_userpage(event);
@@ -1609,7 +1620,6 @@ void x86_pmu_stop(struct perf_event *event, int flags)
if (test_bit(hwc->idx, cpuc->active_mask)) {
static_call(x86_pmu_disable)(event);
__clear_bit(hwc->idx, cpuc->active_mask);
cpuc->events[hwc->idx] = NULL;
WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
hwc->state |= PERF_HES_STOPPED;
}
@@ -1647,6 +1657,7 @@ static void x86_pmu_del(struct perf_event *event, int flags)
* Not a TXN, therefore cleanup properly.
*/
x86_pmu_stop(event, PERF_EF_UPDATE);
cpuc->events[event->hw.idx] = NULL;
for (i = 0; i < cpuc->n_events; i++) {
if (event == cpuc->event_list[i])
@@ -2628,7 +2639,9 @@ static ssize_t max_precise_show(struct device *cdev,
struct device_attribute *attr,
char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", x86_pmu_max_precise());
struct pmu *pmu = dev_get_drvdata(cdev);
return snprintf(buf, PAGE_SIZE, "%d\n", x86_pmu_max_precise(pmu));
}
static DEVICE_ATTR_RO(max_precise);
+417 -30
View File
@@ -2562,6 +2562,44 @@ static void intel_pmu_disable_fixed(struct perf_event *event)
cpuc->fixed_ctrl_val &= ~mask;
}
static inline void __intel_pmu_update_event_ext(int idx, u64 ext)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
u32 msr;
if (idx < INTEL_PMC_IDX_FIXED) {
msr = MSR_IA32_PMC_V6_GP0_CFG_C +
x86_pmu.addr_offset(idx, false);
} else {
msr = MSR_IA32_PMC_V6_FX0_CFG_C +
x86_pmu.addr_offset(idx - INTEL_PMC_IDX_FIXED, false);
}
cpuc->cfg_c_val[idx] = ext;
wrmsrl(msr, ext);
}
static void intel_pmu_disable_event_ext(struct perf_event *event)
{
/*
* Only clear CFG_C MSR for PEBS counter group events,
* it avoids the HW counter's value to be added into
* other PEBS records incorrectly after PEBS counter
* group events are disabled.
*
* For other events, it's unnecessary to clear CFG_C MSRs
* since CFG_C doesn't take effect if counter is in
* disabled state. That helps to reduce the WRMSR overhead
* in context switches.
*/
if (!is_pebs_counter_event_group(event))
return;
__intel_pmu_update_event_ext(event->hw.idx, 0);
}
DEFINE_STATIC_CALL_NULL(intel_pmu_disable_event_ext, intel_pmu_disable_event_ext);
static void intel_pmu_disable_event(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
@@ -2570,9 +2608,12 @@ static void intel_pmu_disable_event(struct perf_event *event)
switch (idx) {
case 0 ... INTEL_PMC_IDX_FIXED - 1:
intel_clear_masks(event, idx);
static_call_cond(intel_pmu_disable_event_ext)(event);
x86_pmu_disable_event(event);
break;
case INTEL_PMC_IDX_FIXED ... INTEL_PMC_IDX_FIXED_BTS - 1:
static_call_cond(intel_pmu_disable_event_ext)(event);
fallthrough;
case INTEL_PMC_IDX_METRIC_BASE ... INTEL_PMC_IDX_METRIC_END:
intel_pmu_disable_fixed(event);
break;
@@ -2939,6 +2980,79 @@ static void intel_pmu_enable_acr(struct perf_event *event)
DEFINE_STATIC_CALL_NULL(intel_pmu_enable_acr_event, intel_pmu_enable_acr);
static void intel_pmu_enable_event_ext(struct perf_event *event)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
struct hw_perf_event *hwc = &event->hw;
union arch_pebs_index old, new;
struct arch_pebs_cap cap;
u64 ext = 0;
cap = hybrid(cpuc->pmu, arch_pebs_cap);
if (event->attr.precise_ip) {
u64 pebs_data_cfg = intel_get_arch_pebs_data_config(event);
ext |= ARCH_PEBS_EN;
if (hwc->flags & PERF_X86_EVENT_AUTO_RELOAD)
ext |= (-hwc->sample_period) & ARCH_PEBS_RELOAD;
if (pebs_data_cfg && cap.caps) {
if (pebs_data_cfg & PEBS_DATACFG_MEMINFO)
ext |= ARCH_PEBS_AUX & cap.caps;
if (pebs_data_cfg & PEBS_DATACFG_GP)
ext |= ARCH_PEBS_GPR & cap.caps;
if (pebs_data_cfg & PEBS_DATACFG_XMMS)
ext |= ARCH_PEBS_VECR_XMM & cap.caps;
if (pebs_data_cfg & PEBS_DATACFG_LBRS)
ext |= ARCH_PEBS_LBR & cap.caps;
if (pebs_data_cfg &
(PEBS_DATACFG_CNTR_MASK << PEBS_DATACFG_CNTR_SHIFT))
ext |= ARCH_PEBS_CNTR_GP & cap.caps;
if (pebs_data_cfg &
(PEBS_DATACFG_FIX_MASK << PEBS_DATACFG_FIX_SHIFT))
ext |= ARCH_PEBS_CNTR_FIXED & cap.caps;
if (pebs_data_cfg & PEBS_DATACFG_METRICS)
ext |= ARCH_PEBS_CNTR_METRICS & cap.caps;
}
if (cpuc->n_pebs == cpuc->n_large_pebs)
new.thresh = ARCH_PEBS_THRESH_MULTI;
else
new.thresh = ARCH_PEBS_THRESH_SINGLE;
rdmsrl(MSR_IA32_PEBS_INDEX, old.whole);
if (new.thresh != old.thresh || !old.en) {
if (old.thresh == ARCH_PEBS_THRESH_MULTI && old.wr > 0) {
/*
* Large PEBS was enabled.
* Drain PEBS buffer before applying the single PEBS.
*/
intel_pmu_drain_pebs_buffer();
} else {
new.wr = 0;
new.full = 0;
new.en = 1;
wrmsrl(MSR_IA32_PEBS_INDEX, new.whole);
}
}
}
if (is_pebs_counter_event_group(event))
ext |= ARCH_PEBS_CNTR_ALLOW;
if (cpuc->cfg_c_val[hwc->idx] != ext)
__intel_pmu_update_event_ext(hwc->idx, ext);
}
DEFINE_STATIC_CALL_NULL(intel_pmu_enable_event_ext, intel_pmu_enable_event_ext);
static void intel_pmu_enable_event(struct perf_event *event)
{
u64 enable_mask = ARCH_PERFMON_EVENTSEL_ENABLE;
@@ -2954,10 +3068,12 @@ static void intel_pmu_enable_event(struct perf_event *event)
enable_mask |= ARCH_PERFMON_EVENTSEL_BR_CNTR;
intel_set_masks(event, idx);
static_call_cond(intel_pmu_enable_acr_event)(event);
static_call_cond(intel_pmu_enable_event_ext)(event);
__x86_pmu_enable_event(hwc, enable_mask);
break;
case INTEL_PMC_IDX_FIXED ... INTEL_PMC_IDX_FIXED_BTS - 1:
static_call_cond(intel_pmu_enable_acr_event)(event);
static_call_cond(intel_pmu_enable_event_ext)(event);
fallthrough;
case INTEL_PMC_IDX_METRIC_BASE ... INTEL_PMC_IDX_METRIC_END:
intel_pmu_enable_fixed(event);
@@ -3214,6 +3330,19 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status)
status &= ~GLOBAL_STATUS_PERF_METRICS_OVF_BIT;
}
/*
* Arch PEBS sets bit 54 in the global status register
*/
if (__test_and_clear_bit(GLOBAL_STATUS_ARCH_PEBS_THRESHOLD_BIT,
(unsigned long *)&status)) {
handled++;
static_call(x86_pmu_drain_pebs)(regs, &data);
if (cpuc->events[INTEL_PMC_IDX_FIXED_SLOTS] &&
is_pebs_counter_event_group(cpuc->events[INTEL_PMC_IDX_FIXED_SLOTS]))
status &= ~GLOBAL_STATUS_PERF_METRICS_OVF_BIT;
}
/*
* Intel PT
*/
@@ -3248,6 +3377,9 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status)
if (!test_bit(bit, cpuc->active_mask))
continue;
/* Event may have already been cleared: */
if (!event)
continue;
/*
* There may be unprocessed PEBS records in the PEBS buffer,
@@ -3268,7 +3400,7 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status)
* The PEBS buffer has to be drained before handling the A-PMI
*/
if (is_pebs_counter_event_group(event))
x86_pmu.drain_pebs(regs, &data);
static_call(x86_pmu_drain_pebs)(regs, &data);
last_period = event->hw.last_period;
@@ -4028,7 +4160,9 @@ static unsigned long intel_pmu_large_pebs_flags(struct perf_event *event)
if (!event->attr.exclude_kernel)
flags &= ~PERF_SAMPLE_REGS_USER;
if (event->attr.sample_regs_user & ~PEBS_GP_REGS)
flags &= ~(PERF_SAMPLE_REGS_USER | PERF_SAMPLE_REGS_INTR);
flags &= ~PERF_SAMPLE_REGS_USER;
if (event->attr.sample_regs_intr & ~PEBS_GP_REGS)
flags &= ~PERF_SAMPLE_REGS_INTR;
return flags;
}
@@ -4203,6 +4337,20 @@ static bool intel_pmu_is_acr_group(struct perf_event *event)
return false;
}
static inline bool intel_pmu_has_pebs_counter_group(struct pmu *pmu)
{
u64 caps;
if (x86_pmu.intel_cap.pebs_format >= 6 && x86_pmu.intel_cap.pebs_baseline)
return true;
caps = hybrid(pmu, arch_pebs_cap).caps;
if (x86_pmu.arch_pebs && (caps & ARCH_PEBS_CNTR_MASK))
return true;
return false;
}
static inline void intel_pmu_set_acr_cntr_constr(struct perf_event *event,
u64 *cause_mask, int *num)
{
@@ -4236,6 +4384,8 @@ static int intel_pmu_hw_config(struct perf_event *event)
}
if (event->attr.precise_ip) {
struct arch_pebs_cap pebs_cap = hybrid(event->pmu, arch_pebs_cap);
if ((event->attr.config & INTEL_ARCH_EVENT_MASK) == INTEL_FIXED_VLBR_EVENT)
return -EINVAL;
@@ -4249,6 +4399,15 @@ static int intel_pmu_hw_config(struct perf_event *event)
}
if (x86_pmu.pebs_aliases)
x86_pmu.pebs_aliases(event);
if (x86_pmu.arch_pebs) {
u64 cntr_mask = hybrid(event->pmu, intel_ctrl) &
~GLOBAL_CTRL_EN_PERF_METRICS;
u64 pebs_mask = event->attr.precise_ip >= 3 ?
pebs_cap.pdists : pebs_cap.counters;
if (cntr_mask != pebs_mask)
event->hw.dyn_constraint &= pebs_mask;
}
}
if (needs_branch_stack(event)) {
@@ -4340,8 +4499,7 @@ static int intel_pmu_hw_config(struct perf_event *event)
}
if ((event->attr.sample_type & PERF_SAMPLE_READ) &&
(x86_pmu.intel_cap.pebs_format >= 6) &&
x86_pmu.intel_cap.pebs_baseline &&
intel_pmu_has_pebs_counter_group(event->pmu) &&
is_sampling_event(event) &&
event->attr.precise_ip)
event->group_leader->hw.flags |= PERF_X86_EVENT_PEBS_CNTR;
@@ -5211,7 +5369,13 @@ err:
static int intel_pmu_cpu_prepare(int cpu)
{
return intel_cpuc_prepare(&per_cpu(cpu_hw_events, cpu), cpu);
int ret;
ret = intel_cpuc_prepare(&per_cpu(cpu_hw_events, cpu), cpu);
if (ret)
return ret;
return alloc_arch_pebs_buf_on_cpu(cpu);
}
static void flip_smm_bit(void *data)
@@ -5256,6 +5420,163 @@ static void intel_pmu_check_event_constraints(struct event_constraint *event_con
u64 fixed_cntr_mask,
u64 intel_ctrl);
enum dyn_constr_type {
DYN_CONSTR_NONE,
DYN_CONSTR_BR_CNTR,
DYN_CONSTR_ACR_CNTR,
DYN_CONSTR_ACR_CAUSE,
DYN_CONSTR_PEBS,
DYN_CONSTR_PDIST,
DYN_CONSTR_MAX,
};
static const char * const dyn_constr_type_name[] = {
[DYN_CONSTR_NONE] = "a normal event",
[DYN_CONSTR_BR_CNTR] = "a branch counter logging event",
[DYN_CONSTR_ACR_CNTR] = "an auto-counter reload event",
[DYN_CONSTR_ACR_CAUSE] = "an auto-counter reload cause event",
[DYN_CONSTR_PEBS] = "a PEBS event",
[DYN_CONSTR_PDIST] = "a PEBS PDIST event",
};
static void __intel_pmu_check_dyn_constr(struct event_constraint *constr,
enum dyn_constr_type type, u64 mask)
{
struct event_constraint *c1, *c2;
int new_weight, check_weight;
u64 new_mask, check_mask;
for_each_event_constraint(c1, constr) {
new_mask = c1->idxmsk64 & mask;
new_weight = hweight64(new_mask);
/* ignore topdown perf metrics event */
if (c1->idxmsk64 & INTEL_PMC_MSK_TOPDOWN)
continue;
if (!new_weight && fls64(c1->idxmsk64) < INTEL_PMC_IDX_FIXED) {
pr_info("The event 0x%llx is not supported as %s.\n",
c1->code, dyn_constr_type_name[type]);
}
if (new_weight <= 1)
continue;
for_each_event_constraint(c2, c1 + 1) {
bool check_fail = false;
check_mask = c2->idxmsk64 & mask;
check_weight = hweight64(check_mask);
if (c2->idxmsk64 & INTEL_PMC_MSK_TOPDOWN ||
!check_weight)
continue;
/* The same constraints or no overlap */
if (new_mask == check_mask ||
(new_mask ^ check_mask) == (new_mask | check_mask))
continue;
/*
* A scheduler issue may be triggered in the following cases.
* - Two overlap constraints have the same weight.
* E.g., A constraints: 0x3, B constraints: 0x6
* event counter failure case
* B PMC[2:1] 1
* A PMC[1:0] 0
* A PMC[1:0] FAIL
* - Two overlap constraints have different weight.
* The constraint has a low weight, but has high last bit.
* E.g., A constraints: 0x7, B constraints: 0xC
* event counter failure case
* B PMC[3:2] 2
* A PMC[2:0] 0
* A PMC[2:0] 1
* A PMC[2:0] FAIL
*/
if (new_weight == check_weight) {
check_fail = true;
} else if (new_weight < check_weight) {
if ((new_mask | check_mask) != check_mask &&
fls64(new_mask) > fls64(check_mask))
check_fail = true;
} else {
if ((new_mask | check_mask) != new_mask &&
fls64(new_mask) < fls64(check_mask))
check_fail = true;
}
if (check_fail) {
pr_info("The two events 0x%llx and 0x%llx may not be "
"fully scheduled under some circumstances as "
"%s.\n",
c1->code, c2->code, dyn_constr_type_name[type]);
}
}
}
}
static void intel_pmu_check_dyn_constr(struct pmu *pmu,
struct event_constraint *constr,
u64 cntr_mask)
{
enum dyn_constr_type i;
u64 mask;
for (i = DYN_CONSTR_NONE; i < DYN_CONSTR_MAX; i++) {
mask = 0;
switch (i) {
case DYN_CONSTR_NONE:
mask = cntr_mask;
break;
case DYN_CONSTR_BR_CNTR:
if (x86_pmu.flags & PMU_FL_BR_CNTR)
mask = x86_pmu.lbr_counters;
break;
case DYN_CONSTR_ACR_CNTR:
mask = hybrid(pmu, acr_cntr_mask64) & GENMASK_ULL(INTEL_PMC_MAX_GENERIC - 1, 0);
break;
case DYN_CONSTR_ACR_CAUSE:
if (hybrid(pmu, acr_cntr_mask64) == hybrid(pmu, acr_cause_mask64))
continue;
mask = hybrid(pmu, acr_cause_mask64) & GENMASK_ULL(INTEL_PMC_MAX_GENERIC - 1, 0);
break;
case DYN_CONSTR_PEBS:
if (x86_pmu.arch_pebs)
mask = hybrid(pmu, arch_pebs_cap).counters;
break;
case DYN_CONSTR_PDIST:
if (x86_pmu.arch_pebs)
mask = hybrid(pmu, arch_pebs_cap).pdists;
break;
default:
pr_warn("Unsupported dynamic constraint type %d\n", i);
}
if (mask)
__intel_pmu_check_dyn_constr(constr, i, mask);
}
}
static void intel_pmu_check_event_constraints_all(struct pmu *pmu)
{
struct event_constraint *event_constraints = hybrid(pmu, event_constraints);
struct event_constraint *pebs_constraints = hybrid(pmu, pebs_constraints);
u64 cntr_mask = hybrid(pmu, cntr_mask64);
u64 fixed_cntr_mask = hybrid(pmu, fixed_cntr_mask64);
u64 intel_ctrl = hybrid(pmu, intel_ctrl);
intel_pmu_check_event_constraints(event_constraints, cntr_mask,
fixed_cntr_mask, intel_ctrl);
if (event_constraints)
intel_pmu_check_dyn_constr(pmu, event_constraints, cntr_mask);
if (pebs_constraints)
intel_pmu_check_dyn_constr(pmu, pebs_constraints, cntr_mask);
}
static void intel_pmu_check_extra_regs(struct extra_reg *extra_regs);
static inline bool intel_pmu_broken_perf_cap(void)
@@ -5268,34 +5589,89 @@ static inline bool intel_pmu_broken_perf_cap(void)
return false;
}
static inline void __intel_update_pmu_caps(struct pmu *pmu)
{
struct pmu *dest_pmu = pmu ? pmu : x86_get_pmu(smp_processor_id());
if (hybrid(pmu, arch_pebs_cap).caps & ARCH_PEBS_VECR_XMM)
dest_pmu->capabilities |= PERF_PMU_CAP_EXTENDED_REGS;
}
static inline void __intel_update_large_pebs_flags(struct pmu *pmu)
{
u64 caps = hybrid(pmu, arch_pebs_cap).caps;
x86_pmu.large_pebs_flags |= PERF_SAMPLE_TIME;
if (caps & ARCH_PEBS_LBR)
x86_pmu.large_pebs_flags |= PERF_SAMPLE_BRANCH_STACK;
if (caps & ARCH_PEBS_CNTR_MASK)
x86_pmu.large_pebs_flags |= PERF_SAMPLE_READ;
if (!(caps & ARCH_PEBS_AUX))
x86_pmu.large_pebs_flags &= ~PERF_SAMPLE_DATA_SRC;
if (!(caps & ARCH_PEBS_GPR)) {
x86_pmu.large_pebs_flags &=
~(PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER);
}
}
#define counter_mask(_gp, _fixed) ((_gp) | ((u64)(_fixed) << INTEL_PMC_IDX_FIXED))
static void update_pmu_cap(struct pmu *pmu)
{
unsigned int cntr, fixed_cntr, ecx, edx;
union cpuid35_eax eax;
union cpuid35_ebx ebx;
unsigned int eax, ebx, ecx, edx;
union cpuid35_eax eax_0;
union cpuid35_ebx ebx_0;
u64 cntrs_mask = 0;
u64 pebs_mask = 0;
u64 pdists_mask = 0;
cpuid(ARCH_PERFMON_EXT_LEAF, &eax.full, &ebx.full, &ecx, &edx);
cpuid(ARCH_PERFMON_EXT_LEAF, &eax_0.full, &ebx_0.full, &ecx, &edx);
if (ebx.split.umask2)
if (ebx_0.split.umask2)
hybrid(pmu, config_mask) |= ARCH_PERFMON_EVENTSEL_UMASK2;
if (ebx.split.eq)
if (ebx_0.split.eq)
hybrid(pmu, config_mask) |= ARCH_PERFMON_EVENTSEL_EQ;
if (eax.split.cntr_subleaf) {
if (eax_0.split.cntr_subleaf) {
cpuid_count(ARCH_PERFMON_EXT_LEAF, ARCH_PERFMON_NUM_COUNTER_LEAF,
&cntr, &fixed_cntr, &ecx, &edx);
hybrid(pmu, cntr_mask64) = cntr;
hybrid(pmu, fixed_cntr_mask64) = fixed_cntr;
&eax, &ebx, &ecx, &edx);
hybrid(pmu, cntr_mask64) = eax;
hybrid(pmu, fixed_cntr_mask64) = ebx;
cntrs_mask = counter_mask(eax, ebx);
}
if (eax.split.acr_subleaf) {
if (eax_0.split.acr_subleaf) {
cpuid_count(ARCH_PERFMON_EXT_LEAF, ARCH_PERFMON_ACR_LEAF,
&cntr, &fixed_cntr, &ecx, &edx);
&eax, &ebx, &ecx, &edx);
/* The mask of the counters which can be reloaded */
hybrid(pmu, acr_cntr_mask64) = cntr | ((u64)fixed_cntr << INTEL_PMC_IDX_FIXED);
hybrid(pmu, acr_cntr_mask64) = counter_mask(eax, ebx);
/* The mask of the counters which can cause a reload of reloadable counters */
hybrid(pmu, acr_cause_mask64) = ecx | ((u64)edx << INTEL_PMC_IDX_FIXED);
hybrid(pmu, acr_cause_mask64) = counter_mask(ecx, edx);
}
/* Bits[5:4] should be set simultaneously if arch-PEBS is supported */
if (eax_0.split.pebs_caps_subleaf && eax_0.split.pebs_cnts_subleaf) {
cpuid_count(ARCH_PERFMON_EXT_LEAF, ARCH_PERFMON_PEBS_CAP_LEAF,
&eax, &ebx, &ecx, &edx);
hybrid(pmu, arch_pebs_cap).caps = (u64)ebx << 32;
cpuid_count(ARCH_PERFMON_EXT_LEAF, ARCH_PERFMON_PEBS_COUNTER_LEAF,
&eax, &ebx, &ecx, &edx);
pebs_mask = counter_mask(eax, ecx);
pdists_mask = counter_mask(ebx, edx);
hybrid(pmu, arch_pebs_cap).counters = pebs_mask;
hybrid(pmu, arch_pebs_cap).pdists = pdists_mask;
if (WARN_ON((pebs_mask | pdists_mask) & ~cntrs_mask)) {
x86_pmu.arch_pebs = 0;
} else {
__intel_update_pmu_caps(pmu);
__intel_update_large_pebs_flags(pmu);
}
} else {
WARN_ON(x86_pmu.arch_pebs == 1);
x86_pmu.arch_pebs = 0;
}
if (!intel_pmu_broken_perf_cap()) {
@@ -5318,10 +5694,7 @@ static void intel_pmu_check_hybrid_pmus(struct x86_hybrid_pmu *pmu)
else
pmu->intel_ctrl &= ~GLOBAL_CTRL_EN_PERF_METRICS;
intel_pmu_check_event_constraints(pmu->event_constraints,
pmu->cntr_mask64,
pmu->fixed_cntr_mask64,
pmu->intel_ctrl);
intel_pmu_check_event_constraints_all(&pmu->pmu);
intel_pmu_check_extra_regs(pmu->extra_regs);
}
@@ -5417,6 +5790,7 @@ static void intel_pmu_cpu_starting(int cpu)
return;
init_debug_store_on_cpu(cpu);
init_arch_pebs_on_cpu(cpu);
/*
* Deal with CPUs that don't clear their LBRs on power-up, and that may
* even boot with LBRs enabled.
@@ -5455,6 +5829,8 @@ static void intel_pmu_cpu_starting(int cpu)
}
}
__intel_update_pmu_caps(cpuc->pmu);
if (!cpuc->shared_regs)
return;
@@ -5514,6 +5890,7 @@ static void free_excl_cntrs(struct cpu_hw_events *cpuc)
static void intel_pmu_cpu_dying(int cpu)
{
fini_debug_store_on_cpu(cpu);
fini_arch_pebs_on_cpu(cpu);
}
void intel_cpuc_finish(struct cpu_hw_events *cpuc)
@@ -5534,6 +5911,7 @@ static void intel_pmu_cpu_dead(int cpu)
{
struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
release_arch_pebs_buf_on_cpu(cpu);
intel_cpuc_finish(cpuc);
if (is_hybrid() && cpuc->pmu)
@@ -6249,7 +6627,7 @@ tsx_is_visible(struct kobject *kobj, struct attribute *attr, int i)
static umode_t
pebs_is_visible(struct kobject *kobj, struct attribute *attr, int i)
{
return x86_pmu.ds_pebs ? attr->mode : 0;
return intel_pmu_has_pebs() ? attr->mode : 0;
}
static umode_t
@@ -6939,8 +7317,11 @@ __init int intel_pmu_init(void)
* Many features on and after V6 require dynamic constraint,
* e.g., Arch PEBS, ACR.
*/
if (version >= 6)
if (version >= 6) {
x86_pmu.flags |= PMU_FL_DYN_CONSTRAINT;
x86_pmu.late_setup = intel_pmu_late_setup;
}
/*
* Install the hw-cache-events table:
*/
@@ -7726,6 +8107,14 @@ __init int intel_pmu_init(void)
if (!is_hybrid() && boot_cpu_has(X86_FEATURE_ARCH_PERFMON_EXT))
update_pmu_cap(NULL);
if (x86_pmu.arch_pebs) {
static_call_update(intel_pmu_disable_event_ext,
intel_pmu_disable_event_ext);
static_call_update(intel_pmu_enable_event_ext,
intel_pmu_enable_event_ext);
pr_cont("Architectural PEBS, ");
}
intel_pmu_check_counters_mask(&x86_pmu.cntr_mask64,
&x86_pmu.fixed_cntr_mask64,
&x86_pmu.intel_ctrl);
@@ -7734,10 +8123,8 @@ __init int intel_pmu_init(void)
if (x86_pmu.intel_cap.anythread_deprecated)
x86_pmu.format_attrs = intel_arch_formats_attr;
intel_pmu_check_event_constraints(x86_pmu.event_constraints,
x86_pmu.cntr_mask64,
x86_pmu.fixed_cntr_mask64,
x86_pmu.intel_ctrl);
intel_pmu_check_event_constraints_all(NULL);
/*
* Access LBR MSR may cause #GP under certain circumstances.
* Check all LBR MSR here.
+1 -2
View File
@@ -71,7 +71,7 @@
* perf code: 0x01
* Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,KNL,
* GLM,CNL,KBL,CML,ICL,TGL,TNT,RKL,
* ADL,RPL,MTL,ARL,LNL
* ADL,RPL,MTL,ARL
* Scope: Package (physical package)
* MSR_PKG_C6_RESIDENCY: Package C6 Residency Counter.
* perf code: 0x02
@@ -522,7 +522,6 @@ static const struct cstate_model lnl_cstates __initconst = {
BIT(PERF_CSTATE_CORE_C7_RES),
.pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
BIT(PERF_CSTATE_PKG_C3_RES) |
BIT(PERF_CSTATE_PKG_C6_RES) |
BIT(PERF_CSTATE_PKG_C10_RES),
};
+496 -107
View File
@@ -625,13 +625,18 @@ static int alloc_pebs_buffer(int cpu)
int max, node = cpu_to_node(cpu);
void *buffer, *insn_buff, *cea;
if (!x86_pmu.ds_pebs)
if (!intel_pmu_has_pebs())
return 0;
buffer = dsalloc_pages(bsiz, GFP_KERNEL, cpu);
if (unlikely(!buffer))
return -ENOMEM;
if (x86_pmu.arch_pebs) {
hwev->pebs_vaddr = buffer;
return 0;
}
/*
* HSW+ already provides us the eventing ip; no need to allocate this
* buffer then.
@@ -644,7 +649,7 @@ static int alloc_pebs_buffer(int cpu)
}
per_cpu(insn_buffer, cpu) = insn_buff;
}
hwev->ds_pebs_vaddr = buffer;
hwev->pebs_vaddr = buffer;
/* Update the cpu entry area mapping */
cea = &get_cpu_entry_area(cpu)->cpu_debug_buffers.pebs_buffer;
ds->pebs_buffer_base = (unsigned long) cea;
@@ -660,17 +665,20 @@ static void release_pebs_buffer(int cpu)
struct cpu_hw_events *hwev = per_cpu_ptr(&cpu_hw_events, cpu);
void *cea;
if (!x86_pmu.ds_pebs)
if (!intel_pmu_has_pebs())
return;
kfree(per_cpu(insn_buffer, cpu));
per_cpu(insn_buffer, cpu) = NULL;
if (x86_pmu.ds_pebs) {
kfree(per_cpu(insn_buffer, cpu));
per_cpu(insn_buffer, cpu) = NULL;
/* Clear the fixmap */
cea = &get_cpu_entry_area(cpu)->cpu_debug_buffers.pebs_buffer;
ds_clear_cea(cea, x86_pmu.pebs_buffer_size);
dsfree_pages(hwev->ds_pebs_vaddr, x86_pmu.pebs_buffer_size);
hwev->ds_pebs_vaddr = NULL;
/* Clear the fixmap */
cea = &get_cpu_entry_area(cpu)->cpu_debug_buffers.pebs_buffer;
ds_clear_cea(cea, x86_pmu.pebs_buffer_size);
}
dsfree_pages(hwev->pebs_vaddr, x86_pmu.pebs_buffer_size);
hwev->pebs_vaddr = NULL;
}
static int alloc_bts_buffer(int cpu)
@@ -823,6 +831,56 @@ void reserve_ds_buffers(void)
}
}
inline int alloc_arch_pebs_buf_on_cpu(int cpu)
{
if (!x86_pmu.arch_pebs)
return 0;
return alloc_pebs_buffer(cpu);
}
inline void release_arch_pebs_buf_on_cpu(int cpu)
{
if (!x86_pmu.arch_pebs)
return;
release_pebs_buffer(cpu);
}
void init_arch_pebs_on_cpu(int cpu)
{
struct cpu_hw_events *cpuc = per_cpu_ptr(&cpu_hw_events, cpu);
u64 arch_pebs_base;
if (!x86_pmu.arch_pebs)
return;
if (!cpuc->pebs_vaddr) {
WARN(1, "Fail to allocate PEBS buffer on CPU %d\n", cpu);
x86_pmu.pebs_active = 0;
return;
}
/*
* 4KB-aligned pointer of the output buffer
* (__alloc_pages_node() return page aligned address)
* Buffer Size = 4KB * 2^SIZE
* contiguous physical buffer (__alloc_pages_node() with order)
*/
arch_pebs_base = virt_to_phys(cpuc->pebs_vaddr) | PEBS_BUFFER_SHIFT;
wrmsr_on_cpu(cpu, MSR_IA32_PEBS_BASE, (u32)arch_pebs_base,
(u32)(arch_pebs_base >> 32));
x86_pmu.pebs_active = 1;
}
inline void fini_arch_pebs_on_cpu(int cpu)
{
if (!x86_pmu.arch_pebs)
return;
wrmsr_on_cpu(cpu, MSR_IA32_PEBS_BASE, 0, 0);
}
/*
* BTS
*/
@@ -1470,6 +1528,25 @@ pebs_update_state(bool needed_cb, struct cpu_hw_events *cpuc,
}
}
u64 intel_get_arch_pebs_data_config(struct perf_event *event)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
u64 pebs_data_cfg = 0;
u64 cntr_mask;
if (WARN_ON(event->hw.idx < 0 || event->hw.idx >= X86_PMC_IDX_MAX))
return 0;
pebs_data_cfg |= pebs_update_adaptive_cfg(event);
cntr_mask = (PEBS_DATACFG_CNTR_MASK << PEBS_DATACFG_CNTR_SHIFT) |
(PEBS_DATACFG_FIX_MASK << PEBS_DATACFG_FIX_SHIFT) |
PEBS_DATACFG_CNTR | PEBS_DATACFG_METRICS;
pebs_data_cfg |= cpuc->pebs_data_cfg & cntr_mask;
return pebs_data_cfg;
}
void intel_pmu_pebs_add(struct perf_event *event)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
@@ -1531,6 +1608,15 @@ static inline void intel_pmu_drain_large_pebs(struct cpu_hw_events *cpuc)
intel_pmu_drain_pebs_buffer();
}
static void __intel_pmu_pebs_enable(struct perf_event *event)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
struct hw_perf_event *hwc = &event->hw;
hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT;
cpuc->pebs_enabled |= 1ULL << hwc->idx;
}
void intel_pmu_pebs_enable(struct perf_event *event)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
@@ -1539,9 +1625,7 @@ void intel_pmu_pebs_enable(struct perf_event *event)
struct debug_store *ds = cpuc->ds;
unsigned int idx = hwc->idx;
hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT;
cpuc->pebs_enabled |= 1ULL << hwc->idx;
__intel_pmu_pebs_enable(event);
if ((event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT) && (x86_pmu.version < 5))
cpuc->pebs_enabled |= 1ULL << (hwc->idx + 32);
@@ -1603,14 +1687,22 @@ void intel_pmu_pebs_del(struct perf_event *event)
pebs_update_state(needed_cb, cpuc, event, false);
}
void intel_pmu_pebs_disable(struct perf_event *event)
static void __intel_pmu_pebs_disable(struct perf_event *event)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
struct hw_perf_event *hwc = &event->hw;
intel_pmu_drain_large_pebs(cpuc);
cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
hwc->config |= ARCH_PERFMON_EVENTSEL_INT;
}
void intel_pmu_pebs_disable(struct perf_event *event)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
struct hw_perf_event *hwc = &event->hw;
__intel_pmu_pebs_disable(event);
if ((event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT) &&
(x86_pmu.version < 5))
@@ -1622,8 +1714,6 @@ void intel_pmu_pebs_disable(struct perf_event *event)
if (cpuc->enabled)
wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
hwc->config |= ARCH_PERFMON_EVENTSEL_INT;
}
void intel_pmu_pebs_enable_all(void)
@@ -2059,6 +2149,90 @@ static inline void __setup_pebs_counter_group(struct cpu_hw_events *cpuc,
#define PEBS_LATENCY_MASK 0xffff
static inline void __setup_perf_sample_data(struct perf_event *event,
struct pt_regs *iregs,
struct perf_sample_data *data)
{
perf_sample_data_init(data, 0, event->hw.last_period);
/*
* We must however always use iregs for the unwinder to stay sane; the
* record BP,SP,IP can point into thin air when the record is from a
* previous PMI context or an (I)RET happened between the record and
* PMI.
*/
perf_sample_save_callchain(data, event, iregs);
}
static inline void __setup_pebs_basic_group(struct perf_event *event,
struct pt_regs *regs,
struct perf_sample_data *data,
u64 sample_type, u64 ip,
u64 tsc, u16 retire)
{
/* The ip in basic is EventingIP */
set_linear_ip(regs, ip);
regs->flags = PERF_EFLAGS_EXACT;
setup_pebs_time(event, data, tsc);
if (sample_type & PERF_SAMPLE_WEIGHT_STRUCT)
data->weight.var3_w = retire;
}
static inline void __setup_pebs_gpr_group(struct perf_event *event,
struct pt_regs *regs,
struct pebs_gprs *gprs,
u64 sample_type)
{
if (event->attr.precise_ip < 2) {
set_linear_ip(regs, gprs->ip);
regs->flags &= ~PERF_EFLAGS_EXACT;
}
if (sample_type & (PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER))
adaptive_pebs_save_regs(regs, gprs);
}
static inline void __setup_pebs_meminfo_group(struct perf_event *event,
struct perf_sample_data *data,
u64 sample_type, u64 latency,
u16 instr_latency, u64 address,
u64 aux, u64 tsx_tuning, u64 ax)
{
if (sample_type & PERF_SAMPLE_WEIGHT_TYPE) {
u64 tsx_latency = intel_get_tsx_weight(tsx_tuning);
data->weight.var2_w = instr_latency;
/*
* Although meminfo::latency is defined as a u64,
* only the lower 32 bits include the valid data
* in practice on Ice Lake and earlier platforms.
*/
if (sample_type & PERF_SAMPLE_WEIGHT)
data->weight.full = latency ?: tsx_latency;
else
data->weight.var1_dw = (u32)latency ?: tsx_latency;
data->sample_flags |= PERF_SAMPLE_WEIGHT_TYPE;
}
if (sample_type & PERF_SAMPLE_DATA_SRC) {
data->data_src.val = get_data_src(event, aux);
data->sample_flags |= PERF_SAMPLE_DATA_SRC;
}
if (sample_type & PERF_SAMPLE_ADDR_TYPE) {
data->addr = address;
data->sample_flags |= PERF_SAMPLE_ADDR;
}
if (sample_type & PERF_SAMPLE_TRANSACTION) {
data->txn = intel_get_tsx_transaction(tsx_tuning, ax);
data->sample_flags |= PERF_SAMPLE_TRANSACTION;
}
}
/*
* With adaptive PEBS the layout depends on what fields are configured.
*/
@@ -2068,12 +2242,14 @@ static void setup_pebs_adaptive_sample_data(struct perf_event *event,
struct pt_regs *regs)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
u64 sample_type = event->attr.sample_type;
struct pebs_basic *basic = __pebs;
void *next_record = basic + 1;
u64 sample_type, format_group;
struct pebs_meminfo *meminfo = NULL;
struct pebs_gprs *gprs = NULL;
struct x86_perf_regs *perf_regs;
u64 format_group;
u16 retire;
if (basic == NULL)
return;
@@ -2081,31 +2257,17 @@ static void setup_pebs_adaptive_sample_data(struct perf_event *event,
perf_regs = container_of(regs, struct x86_perf_regs, regs);
perf_regs->xmm_regs = NULL;
sample_type = event->attr.sample_type;
format_group = basic->format_group;
perf_sample_data_init(data, 0, event->hw.last_period);
setup_pebs_time(event, data, basic->tsc);
/*
* We must however always use iregs for the unwinder to stay sane; the
* record BP,SP,IP can point into thin air when the record is from a
* previous PMI context or an (I)RET happened between the record and
* PMI.
*/
perf_sample_save_callchain(data, event, iregs);
__setup_perf_sample_data(event, iregs, data);
*regs = *iregs;
/* The ip in basic is EventingIP */
set_linear_ip(regs, basic->ip);
regs->flags = PERF_EFLAGS_EXACT;
if (sample_type & PERF_SAMPLE_WEIGHT_STRUCT) {
if (x86_pmu.flags & PMU_FL_RETIRE_LATENCY)
data->weight.var3_w = basic->retire_latency;
else
data->weight.var3_w = 0;
}
/* basic group */
retire = x86_pmu.flags & PMU_FL_RETIRE_LATENCY ?
basic->retire_latency : 0;
__setup_pebs_basic_group(event, regs, data, sample_type,
basic->ip, basic->tsc, retire);
/*
* The record for MEMINFO is in front of GP
@@ -2121,54 +2283,20 @@ static void setup_pebs_adaptive_sample_data(struct perf_event *event,
gprs = next_record;
next_record = gprs + 1;
if (event->attr.precise_ip < 2) {
set_linear_ip(regs, gprs->ip);
regs->flags &= ~PERF_EFLAGS_EXACT;
}
if (sample_type & (PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER))
adaptive_pebs_save_regs(regs, gprs);
__setup_pebs_gpr_group(event, regs, gprs, sample_type);
}
if (format_group & PEBS_DATACFG_MEMINFO) {
if (sample_type & PERF_SAMPLE_WEIGHT_TYPE) {
u64 latency = x86_pmu.flags & PMU_FL_INSTR_LATENCY ?
meminfo->cache_latency : meminfo->mem_latency;
u64 latency = x86_pmu.flags & PMU_FL_INSTR_LATENCY ?
meminfo->cache_latency : meminfo->mem_latency;
u64 instr_latency = x86_pmu.flags & PMU_FL_INSTR_LATENCY ?
meminfo->instr_latency : 0;
u64 ax = gprs ? gprs->ax : 0;
if (x86_pmu.flags & PMU_FL_INSTR_LATENCY)
data->weight.var2_w = meminfo->instr_latency;
/*
* Although meminfo::latency is defined as a u64,
* only the lower 32 bits include the valid data
* in practice on Ice Lake and earlier platforms.
*/
if (sample_type & PERF_SAMPLE_WEIGHT) {
data->weight.full = latency ?:
intel_get_tsx_weight(meminfo->tsx_tuning);
} else {
data->weight.var1_dw = (u32)latency ?:
intel_get_tsx_weight(meminfo->tsx_tuning);
}
data->sample_flags |= PERF_SAMPLE_WEIGHT_TYPE;
}
if (sample_type & PERF_SAMPLE_DATA_SRC) {
data->data_src.val = get_data_src(event, meminfo->aux);
data->sample_flags |= PERF_SAMPLE_DATA_SRC;
}
if (sample_type & PERF_SAMPLE_ADDR_TYPE) {
data->addr = meminfo->address;
data->sample_flags |= PERF_SAMPLE_ADDR;
}
if (sample_type & PERF_SAMPLE_TRANSACTION) {
data->txn = intel_get_tsx_transaction(meminfo->tsx_tuning,
gprs ? gprs->ax : 0);
data->sample_flags |= PERF_SAMPLE_TRANSACTION;
}
__setup_pebs_meminfo_group(event, data, sample_type, latency,
instr_latency, meminfo->address,
meminfo->aux, meminfo->tsx_tuning,
ax);
}
if (format_group & PEBS_DATACFG_XMMS) {
@@ -2219,6 +2347,135 @@ static void setup_pebs_adaptive_sample_data(struct perf_event *event,
format_group);
}
static inline bool arch_pebs_record_continued(struct arch_pebs_header *header)
{
/* Continue bit or null PEBS record indicates fragment follows. */
return header->cont || !(header->format & GENMASK_ULL(63, 16));
}
static void setup_arch_pebs_sample_data(struct perf_event *event,
struct pt_regs *iregs,
void *__pebs,
struct perf_sample_data *data,
struct pt_regs *regs)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
u64 sample_type = event->attr.sample_type;
struct arch_pebs_header *header = NULL;
struct arch_pebs_aux *meminfo = NULL;
struct arch_pebs_gprs *gprs = NULL;
struct x86_perf_regs *perf_regs;
void *next_record;
void *at = __pebs;
if (at == NULL)
return;
perf_regs = container_of(regs, struct x86_perf_regs, regs);
perf_regs->xmm_regs = NULL;
__setup_perf_sample_data(event, iregs, data);
*regs = *iregs;
again:
header = at;
next_record = at + sizeof(struct arch_pebs_header);
if (header->basic) {
struct arch_pebs_basic *basic = next_record;
u16 retire = 0;
next_record = basic + 1;
if (sample_type & PERF_SAMPLE_WEIGHT_STRUCT)
retire = basic->valid ? basic->retire : 0;
__setup_pebs_basic_group(event, regs, data, sample_type,
basic->ip, basic->tsc, retire);
}
/*
* The record for MEMINFO is in front of GP
* But PERF_SAMPLE_TRANSACTION needs gprs->ax.
* Save the pointer here but process later.
*/
if (header->aux) {
meminfo = next_record;
next_record = meminfo + 1;
}
if (header->gpr) {
gprs = next_record;
next_record = gprs + 1;
__setup_pebs_gpr_group(event, regs,
(struct pebs_gprs *)gprs,
sample_type);
}
if (header->aux) {
u64 ax = gprs ? gprs->ax : 0;
__setup_pebs_meminfo_group(event, data, sample_type,
meminfo->cache_latency,
meminfo->instr_latency,
meminfo->address, meminfo->aux,
meminfo->tsx_tuning, ax);
}
if (header->xmm) {
struct pebs_xmm *xmm;
next_record += sizeof(struct arch_pebs_xer_header);
xmm = next_record;
perf_regs->xmm_regs = xmm->xmm;
next_record = xmm + 1;
}
if (header->lbr) {
struct arch_pebs_lbr_header *lbr_header = next_record;
struct lbr_entry *lbr;
int num_lbr;
next_record = lbr_header + 1;
lbr = next_record;
num_lbr = header->lbr == ARCH_PEBS_LBR_NUM_VAR ?
lbr_header->depth :
header->lbr * ARCH_PEBS_BASE_LBR_ENTRIES;
next_record += num_lbr * sizeof(struct lbr_entry);
if (has_branch_stack(event)) {
intel_pmu_store_pebs_lbrs(lbr);
intel_pmu_lbr_save_brstack(data, cpuc, event);
}
}
if (header->cntr) {
struct arch_pebs_cntr_header *cntr = next_record;
unsigned int nr;
next_record += sizeof(struct arch_pebs_cntr_header);
if (is_pebs_counter_event_group(event)) {
__setup_pebs_counter_group(cpuc, event,
(struct pebs_cntr_header *)cntr, next_record);
data->sample_flags |= PERF_SAMPLE_READ;
}
nr = hweight32(cntr->cntr) + hweight32(cntr->fixed);
if (cntr->metrics == INTEL_CNTR_METRICS)
nr += 2;
next_record += nr * sizeof(u64);
}
/* Parse followed fragments if there are. */
if (arch_pebs_record_continued(header)) {
at = at + header->size;
goto again;
}
}
static inline void *
get_next_pebs_record_by_bit(void *base, void *top, int bit)
{
@@ -2601,6 +2858,57 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, struct perf_sample_d
}
}
static __always_inline void
__intel_pmu_handle_pebs_record(struct pt_regs *iregs,
struct pt_regs *regs,
struct perf_sample_data *data,
void *at, u64 pebs_status,
short *counts, void **last,
setup_fn setup_sample)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
struct perf_event *event;
int bit;
for_each_set_bit(bit, (unsigned long *)&pebs_status, X86_PMC_IDX_MAX) {
event = cpuc->events[bit];
if (WARN_ON_ONCE(!event) ||
WARN_ON_ONCE(!event->attr.precise_ip))
continue;
if (counts[bit]++) {
__intel_pmu_pebs_event(event, iregs, regs, data,
last[bit], setup_sample);
}
last[bit] = at;
}
}
static __always_inline void
__intel_pmu_handle_last_pebs_record(struct pt_regs *iregs,
struct pt_regs *regs,
struct perf_sample_data *data,
u64 mask, short *counts, void **last,
setup_fn setup_sample)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
struct perf_event *event;
int bit;
for_each_set_bit(bit, (unsigned long *)&mask, X86_PMC_IDX_MAX) {
if (!counts[bit])
continue;
event = cpuc->events[bit];
__intel_pmu_pebs_last_event(event, iregs, regs, data, last[bit],
counts[bit], setup_sample);
}
}
static void intel_pmu_drain_pebs_icl(struct pt_regs *iregs, struct perf_sample_data *data)
{
short counts[INTEL_PMC_IDX_FIXED + MAX_FIXED_PEBS_EVENTS] = {};
@@ -2610,9 +2918,7 @@ static void intel_pmu_drain_pebs_icl(struct pt_regs *iregs, struct perf_sample_d
struct x86_perf_regs perf_regs;
struct pt_regs *regs = &perf_regs.regs;
struct pebs_basic *basic;
struct perf_event *event;
void *base, *at, *top;
int bit;
u64 mask;
if (!x86_pmu.pebs_active)
@@ -2625,6 +2931,7 @@ static void intel_pmu_drain_pebs_icl(struct pt_regs *iregs, struct perf_sample_d
mask = hybrid(cpuc->pmu, pebs_events_mask) |
(hybrid(cpuc->pmu, fixed_cntr_mask64) << INTEL_PMC_IDX_FIXED);
mask &= cpuc->pebs_enabled;
if (unlikely(base >= top)) {
intel_pmu_pebs_event_update_no_drain(cpuc, mask);
@@ -2642,38 +2949,114 @@ static void intel_pmu_drain_pebs_icl(struct pt_regs *iregs, struct perf_sample_d
if (basic->format_size != cpuc->pebs_record_size)
continue;
pebs_status = basic->applicable_counters & cpuc->pebs_enabled & mask;
for_each_set_bit(bit, (unsigned long *)&pebs_status, X86_PMC_IDX_MAX) {
event = cpuc->events[bit];
if (WARN_ON_ONCE(!event) ||
WARN_ON_ONCE(!event->attr.precise_ip))
continue;
if (counts[bit]++) {
__intel_pmu_pebs_event(event, iregs, regs, data, last[bit],
setup_pebs_adaptive_sample_data);
}
last[bit] = at;
}
pebs_status = mask & basic->applicable_counters;
__intel_pmu_handle_pebs_record(iregs, regs, data, at,
pebs_status, counts, last,
setup_pebs_adaptive_sample_data);
}
for_each_set_bit(bit, (unsigned long *)&mask, X86_PMC_IDX_MAX) {
if (!counts[bit])
__intel_pmu_handle_last_pebs_record(iregs, regs, data, mask, counts, last,
setup_pebs_adaptive_sample_data);
}
static void intel_pmu_drain_arch_pebs(struct pt_regs *iregs,
struct perf_sample_data *data)
{
short counts[INTEL_PMC_IDX_FIXED + MAX_FIXED_PEBS_EVENTS] = {};
void *last[INTEL_PMC_IDX_FIXED + MAX_FIXED_PEBS_EVENTS];
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
union arch_pebs_index index;
struct x86_perf_regs perf_regs;
struct pt_regs *regs = &perf_regs.regs;
void *base, *at, *top;
u64 mask;
rdmsrl(MSR_IA32_PEBS_INDEX, index.whole);
if (unlikely(!index.wr)) {
intel_pmu_pebs_event_update_no_drain(cpuc, X86_PMC_IDX_MAX);
return;
}
base = cpuc->pebs_vaddr;
top = cpuc->pebs_vaddr + (index.wr << ARCH_PEBS_INDEX_WR_SHIFT);
index.wr = 0;
index.full = 0;
index.en = 1;
if (cpuc->n_pebs == cpuc->n_large_pebs)
index.thresh = ARCH_PEBS_THRESH_MULTI;
else
index.thresh = ARCH_PEBS_THRESH_SINGLE;
wrmsrl(MSR_IA32_PEBS_INDEX, index.whole);
mask = hybrid(cpuc->pmu, arch_pebs_cap).counters & cpuc->pebs_enabled;
if (!iregs)
iregs = &dummy_iregs;
/* Process all but the last event for each counter. */
for (at = base; at < top;) {
struct arch_pebs_header *header;
struct arch_pebs_basic *basic;
u64 pebs_status;
header = at;
if (WARN_ON_ONCE(!header->size))
break;
/* 1st fragment or single record must have basic group */
if (!header->basic) {
at += header->size;
continue;
}
event = cpuc->events[bit];
basic = at + sizeof(struct arch_pebs_header);
pebs_status = mask & basic->applicable_counters;
__intel_pmu_handle_pebs_record(iregs, regs, data, at,
pebs_status, counts, last,
setup_arch_pebs_sample_data);
__intel_pmu_pebs_last_event(event, iregs, regs, data, last[bit],
counts[bit], setup_pebs_adaptive_sample_data);
/* Skip non-last fragments */
while (arch_pebs_record_continued(header)) {
if (!header->size)
break;
at += header->size;
header = at;
}
/* Skip last fragment or the single record */
at += header->size;
}
__intel_pmu_handle_last_pebs_record(iregs, regs, data, mask,
counts, last,
setup_arch_pebs_sample_data);
}
static void __init intel_arch_pebs_init(void)
{
/*
* Current hybrid platforms always both support arch-PEBS or not
* on all kinds of cores. So directly set x86_pmu.arch_pebs flag
* if boot cpu supports arch-PEBS.
*/
x86_pmu.arch_pebs = 1;
x86_pmu.pebs_buffer_size = PEBS_BUFFER_SIZE;
x86_pmu.drain_pebs = intel_pmu_drain_arch_pebs;
x86_pmu.pebs_capable = ~0ULL;
x86_pmu.flags |= PMU_FL_PEBS_ALL;
x86_pmu.pebs_enable = __intel_pmu_pebs_enable;
x86_pmu.pebs_disable = __intel_pmu_pebs_disable;
}
/*
* PEBS probe and setup
*/
void __init intel_pebs_init(void)
static void __init intel_ds_pebs_init(void)
{
/*
* No support for 32bit formats
@@ -2735,10 +3118,8 @@ void __init intel_pebs_init(void)
break;
case 6:
if (x86_pmu.intel_cap.pebs_baseline) {
if (x86_pmu.intel_cap.pebs_baseline)
x86_pmu.large_pebs_flags |= PERF_SAMPLE_READ;
x86_pmu.late_setup = intel_pmu_late_setup;
}
fallthrough;
case 5:
x86_pmu.pebs_ept = 1;
@@ -2788,6 +3169,14 @@ void __init intel_pebs_init(void)
}
}
void __init intel_pebs_init(void)
{
if (x86_pmu.intel_cap.pebs_format == 0xf)
intel_arch_pebs_init();
else
intel_ds_pebs_init();
}
void perf_restore_debug_store(void)
{
struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
+47 -7
View File
@@ -282,8 +282,9 @@ struct cpu_hw_events {
* Intel DebugStore bits
*/
struct debug_store *ds;
void *ds_pebs_vaddr;
void *ds_bts_vaddr;
/* DS based PEBS or arch-PEBS buffer address */
void *pebs_vaddr;
u64 pebs_enabled;
int n_pebs;
int n_large_pebs;
@@ -302,6 +303,8 @@ struct cpu_hw_events {
/* Intel ACR configuration */
u64 acr_cfg_b[X86_PMC_IDX_MAX];
u64 acr_cfg_c[X86_PMC_IDX_MAX];
/* Cached CFG_C values */
u64 cfg_c_val[X86_PMC_IDX_MAX];
/*
* Intel LBR bits
@@ -707,6 +710,12 @@ enum hybrid_pmu_type {
hybrid_big_small_tiny = hybrid_big | hybrid_small_tiny,
};
struct arch_pebs_cap {
u64 caps;
u64 counters;
u64 pdists;
};
struct x86_hybrid_pmu {
struct pmu pmu;
const char *name;
@@ -751,6 +760,8 @@ struct x86_hybrid_pmu {
mid_ack :1,
enabled_ack :1;
struct arch_pebs_cap arch_pebs_cap;
u64 pebs_data_source[PERF_PEBS_DATA_SOURCE_MAX];
};
@@ -905,7 +916,7 @@ struct x86_pmu {
union perf_capabilities intel_cap;
/*
* Intel DebugStore bits
* Intel DebugStore and PEBS bits
*/
unsigned int bts :1,
bts_active :1,
@@ -916,7 +927,8 @@ struct x86_pmu {
pebs_no_tlb :1,
pebs_no_isolation :1,
pebs_block :1,
pebs_ept :1;
pebs_ept :1,
arch_pebs :1;
int pebs_record_size;
int pebs_buffer_size;
u64 pebs_events_mask;
@@ -928,6 +940,11 @@ struct x86_pmu {
u64 rtm_abort_event;
u64 pebs_capable;
/*
* Intel Architectural PEBS
*/
struct arch_pebs_cap arch_pebs_cap;
/*
* Intel LBR
*/
@@ -1123,7 +1140,6 @@ static struct perf_pmu_format_hybrid_attr format_attr_hybrid_##_name = {\
.pmu_type = _pmu, \
}
int is_x86_event(struct perf_event *event);
struct pmu *x86_get_pmu(unsigned int cpu);
extern struct x86_pmu x86_pmu __read_mostly;
@@ -1216,7 +1232,7 @@ int x86_reserve_hardware(void);
void x86_release_hardware(void);
int x86_pmu_max_precise(void);
int x86_pmu_max_precise(struct pmu *pmu);
void hw_perf_lbr_event_destroy(struct perf_event *event);
@@ -1557,13 +1573,22 @@ static inline bool intel_pmu_has_bts_period(struct perf_event *event, u64 period
struct hw_perf_event *hwc = &event->hw;
unsigned int hw_event, bts_event;
if (event->attr.freq)
/*
* Only use BTS for fixed rate period==1 events.
*/
if (event->attr.freq || period != 1)
return false;
/*
* BTS doesn't virtualize.
*/
if (event->attr.exclude_host)
return false;
hw_event = hwc->config & INTEL_ARCH_EVENT_MASK;
bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
return hw_event == bts_event && period == 1;
return hw_event == bts_event;
}
static inline bool intel_pmu_has_bts(struct perf_event *event)
@@ -1603,6 +1628,14 @@ extern void intel_cpuc_finish(struct cpu_hw_events *cpuc);
int intel_pmu_init(void);
int alloc_arch_pebs_buf_on_cpu(int cpu);
void release_arch_pebs_buf_on_cpu(int cpu);
void init_arch_pebs_on_cpu(int cpu);
void fini_arch_pebs_on_cpu(int cpu);
void init_debug_store_on_cpu(int cpu);
void fini_debug_store_on_cpu(int cpu);
@@ -1759,6 +1792,8 @@ void intel_pmu_pebs_data_source_cmt(void);
void intel_pmu_pebs_data_source_lnl(void);
u64 intel_get_arch_pebs_data_config(struct perf_event *event);
int intel_pmu_setup_lbr_filter(struct perf_event *event);
void intel_pt_interrupt(void);
@@ -1791,6 +1826,11 @@ static inline int intel_pmu_max_num_pebs(struct pmu *pmu)
return fls((u32)hybrid(pmu, pebs_events_mask));
}
static inline bool intel_pmu_has_pebs(void)
{
return x86_pmu.ds_pebs || x86_pmu.arch_pebs;
}
#else /* CONFIG_CPU_SUP_INTEL */
static inline void reserve_ds_buffers(void)
+9 -1
View File
@@ -4,7 +4,15 @@
#include <linux/percpu-defs.h>
#define BTS_BUFFER_SIZE (PAGE_SIZE << 4)
#define PEBS_BUFFER_SIZE (PAGE_SIZE << 4)
#define PEBS_BUFFER_SHIFT 4
#define PEBS_BUFFER_SIZE (PAGE_SIZE << PEBS_BUFFER_SHIFT)
/*
* The largest PEBS record could consume a page, ensure
* a record at least can be written after triggering PMI.
*/
#define ARCH_PEBS_THRESH_MULTI ((PEBS_BUFFER_SIZE - PAGE_SIZE) >> PEBS_BUFFER_SHIFT)
#define ARCH_PEBS_THRESH_SINGLE 1
/* The maximal number of PEBS events: */
#define MAX_PEBS_EVENTS_FMT4 8
+20
View File
@@ -322,6 +322,26 @@
PERF_CAP_PEBS_FORMAT | PERF_CAP_PEBS_BASELINE | \
PERF_CAP_PEBS_TIMING_INFO)
/* Arch PEBS */
#define MSR_IA32_PEBS_BASE 0x000003f4
#define MSR_IA32_PEBS_INDEX 0x000003f5
#define ARCH_PEBS_OFFSET_MASK 0x7fffff
#define ARCH_PEBS_INDEX_WR_SHIFT 4
#define ARCH_PEBS_RELOAD 0xffffffff
#define ARCH_PEBS_CNTR_ALLOW BIT_ULL(35)
#define ARCH_PEBS_CNTR_GP BIT_ULL(36)
#define ARCH_PEBS_CNTR_FIXED BIT_ULL(37)
#define ARCH_PEBS_CNTR_METRICS BIT_ULL(38)
#define ARCH_PEBS_LBR_SHIFT 40
#define ARCH_PEBS_LBR (0x3ull << ARCH_PEBS_LBR_SHIFT)
#define ARCH_PEBS_VECR_XMM BIT_ULL(49)
#define ARCH_PEBS_GPR BIT_ULL(61)
#define ARCH_PEBS_AUX BIT_ULL(62)
#define ARCH_PEBS_EN BIT_ULL(63)
#define ARCH_PEBS_CNTR_MASK (ARCH_PEBS_CNTR_GP | ARCH_PEBS_CNTR_FIXED | \
ARCH_PEBS_CNTR_METRICS)
#define MSR_IA32_RTIT_CTL 0x00000570
#define RTIT_CTL_TRACEEN BIT(0)
#define RTIT_CTL_CYCLEACC BIT(1)
+112 -4
View File
@@ -141,16 +141,16 @@
#define ARCH_PERFMON_EVENTS_COUNT 7
#define PEBS_DATACFG_MEMINFO BIT_ULL(0)
#define PEBS_DATACFG_GP BIT_ULL(1)
#define PEBS_DATACFG_GP BIT_ULL(1)
#define PEBS_DATACFG_XMMS BIT_ULL(2)
#define PEBS_DATACFG_LBRS BIT_ULL(3)
#define PEBS_DATACFG_LBR_SHIFT 24
#define PEBS_DATACFG_CNTR BIT_ULL(4)
#define PEBS_DATACFG_METRICS BIT_ULL(5)
#define PEBS_DATACFG_LBR_SHIFT 24
#define PEBS_DATACFG_CNTR_SHIFT 32
#define PEBS_DATACFG_CNTR_MASK GENMASK_ULL(15, 0)
#define PEBS_DATACFG_FIX_SHIFT 48
#define PEBS_DATACFG_FIX_MASK GENMASK_ULL(7, 0)
#define PEBS_DATACFG_METRICS BIT_ULL(5)
/* Steal the highest bit of pebs_data_cfg for SW usage */
#define PEBS_UPDATE_DS_SW BIT_ULL(63)
@@ -200,6 +200,8 @@ union cpuid10_edx {
#define ARCH_PERFMON_EXT_LEAF 0x00000023
#define ARCH_PERFMON_NUM_COUNTER_LEAF 0x1
#define ARCH_PERFMON_ACR_LEAF 0x2
#define ARCH_PERFMON_PEBS_CAP_LEAF 0x4
#define ARCH_PERFMON_PEBS_COUNTER_LEAF 0x5
union cpuid35_eax {
struct {
@@ -210,7 +212,10 @@ union cpuid35_eax {
unsigned int acr_subleaf:1;
/* Events Sub-Leaf */
unsigned int events_subleaf:1;
unsigned int reserved:28;
/* arch-PEBS Sub-Leaves */
unsigned int pebs_caps_subleaf:1;
unsigned int pebs_cnts_subleaf:1;
unsigned int reserved:26;
} split;
unsigned int full;
};
@@ -432,6 +437,8 @@ static inline bool is_topdown_idx(int idx)
#define GLOBAL_STATUS_LBRS_FROZEN BIT_ULL(GLOBAL_STATUS_LBRS_FROZEN_BIT)
#define GLOBAL_STATUS_TRACE_TOPAPMI_BIT 55
#define GLOBAL_STATUS_TRACE_TOPAPMI BIT_ULL(GLOBAL_STATUS_TRACE_TOPAPMI_BIT)
#define GLOBAL_STATUS_ARCH_PEBS_THRESHOLD_BIT 54
#define GLOBAL_STATUS_ARCH_PEBS_THRESHOLD BIT_ULL(GLOBAL_STATUS_ARCH_PEBS_THRESHOLD_BIT)
#define GLOBAL_STATUS_PERF_METRICS_OVF_BIT 48
#define GLOBAL_CTRL_EN_PERF_METRICS BIT_ULL(48)
@@ -502,6 +509,107 @@ struct pebs_cntr_header {
#define INTEL_CNTR_METRICS 0x3
/*
* Arch PEBS
*/
union arch_pebs_index {
struct {
u64 rsvd:4,
wr:23,
rsvd2:4,
full:1,
en:1,
rsvd3:3,
thresh:23,
rsvd4:5;
};
u64 whole;
};
struct arch_pebs_header {
union {
u64 format;
struct {
u64 size:16, /* Record size */
rsvd:14,
mode:1, /* 64BIT_MODE */
cont:1,
rsvd2:3,
cntr:5,
lbr:2,
rsvd3:7,
xmm:1,
ymmh:1,
rsvd4:2,
opmask:1,
zmmh:1,
h16zmm:1,
rsvd5:5,
gpr:1,
aux:1,
basic:1;
};
};
u64 rsvd6;
};
struct arch_pebs_basic {
u64 ip;
u64 applicable_counters;
u64 tsc;
u64 retire :16, /* Retire Latency */
valid :1,
rsvd :47;
u64 rsvd2;
u64 rsvd3;
};
struct arch_pebs_aux {
u64 address;
u64 rsvd;
u64 rsvd2;
u64 rsvd3;
u64 rsvd4;
u64 aux;
u64 instr_latency :16,
pad2 :16,
cache_latency :16,
pad3 :16;
u64 tsx_tuning;
};
struct arch_pebs_gprs {
u64 flags, ip, ax, cx, dx, bx, sp, bp, si, di;
u64 r8, r9, r10, r11, r12, r13, r14, r15, ssp;
u64 rsvd;
};
struct arch_pebs_xer_header {
u64 xstate;
u64 rsvd;
};
#define ARCH_PEBS_LBR_NAN 0x0
#define ARCH_PEBS_LBR_NUM_8 0x1
#define ARCH_PEBS_LBR_NUM_16 0x2
#define ARCH_PEBS_LBR_NUM_VAR 0x3
#define ARCH_PEBS_BASE_LBR_ENTRIES 8
struct arch_pebs_lbr_header {
u64 rsvd;
u64 ctl;
u64 depth;
u64 ler_from;
u64 ler_to;
u64 ler_info;
};
struct arch_pebs_cntr_header {
u32 cntr;
u32 fixed;
u32 metrics;
u32 reserved;
};
/*
* AMD Extended Performance Monitoring and Debug cpuid feature detection
*/
+37
View File
@@ -87,6 +87,7 @@ struct arm_spe_pmu {
#define SPE_PMU_FEAT_INV_FILT_EVT (1UL << 6)
#define SPE_PMU_FEAT_DISCARD (1UL << 7)
#define SPE_PMU_FEAT_EFT (1UL << 8)
#define SPE_PMU_FEAT_FDS (1UL << 9)
#define SPE_PMU_FEAT_DEV_PROBED (1UL << 63)
u64 features;
@@ -252,6 +253,10 @@ static const struct attribute_group arm_spe_pmu_cap_group = {
#define ATTR_CFG_FLD_inv_event_filter_LO 0
#define ATTR_CFG_FLD_inv_event_filter_HI 63
#define ATTR_CFG_FLD_inv_data_src_filter_CFG config4 /* inverse of PMSDSFR_EL1 */
#define ATTR_CFG_FLD_inv_data_src_filter_LO 0
#define ATTR_CFG_FLD_inv_data_src_filter_HI 63
GEN_PMU_FORMAT_ATTR(ts_enable);
GEN_PMU_FORMAT_ATTR(pa_enable);
GEN_PMU_FORMAT_ATTR(pct_enable);
@@ -268,6 +273,7 @@ GEN_PMU_FORMAT_ATTR(float_filter);
GEN_PMU_FORMAT_ATTR(float_filter_mask);
GEN_PMU_FORMAT_ATTR(event_filter);
GEN_PMU_FORMAT_ATTR(inv_event_filter);
GEN_PMU_FORMAT_ATTR(inv_data_src_filter);
GEN_PMU_FORMAT_ATTR(min_latency);
GEN_PMU_FORMAT_ATTR(discard);
@@ -288,6 +294,7 @@ static struct attribute *arm_spe_pmu_formats_attr[] = {
&format_attr_float_filter_mask.attr,
&format_attr_event_filter.attr,
&format_attr_inv_event_filter.attr,
&format_attr_inv_data_src_filter.attr,
&format_attr_min_latency.attr,
&format_attr_discard.attr,
NULL,
@@ -306,6 +313,10 @@ static umode_t arm_spe_pmu_format_attr_is_visible(struct kobject *kobj,
if (attr == &format_attr_inv_event_filter.attr && !(spe_pmu->features & SPE_PMU_FEAT_INV_FILT_EVT))
return 0;
if (attr == &format_attr_inv_data_src_filter.attr &&
!(spe_pmu->features & SPE_PMU_FEAT_FDS))
return 0;
if ((attr == &format_attr_branch_filter_mask.attr ||
attr == &format_attr_load_filter_mask.attr ||
attr == &format_attr_store_filter_mask.attr ||
@@ -430,6 +441,9 @@ static u64 arm_spe_event_to_pmsfcr(struct perf_event *event)
if (ATTR_CFG_GET_FLD(attr, inv_event_filter))
reg |= PMSFCR_EL1_FnE;
if (ATTR_CFG_GET_FLD(attr, inv_data_src_filter))
reg |= PMSFCR_EL1_FDS;
if (ATTR_CFG_GET_FLD(attr, min_latency))
reg |= PMSFCR_EL1_FL;
@@ -454,6 +468,17 @@ static u64 arm_spe_event_to_pmslatfr(struct perf_event *event)
return FIELD_PREP(PMSLATFR_EL1_MINLAT, ATTR_CFG_GET_FLD(attr, min_latency));
}
static u64 arm_spe_event_to_pmsdsfr(struct perf_event *event)
{
struct perf_event_attr *attr = &event->attr;
/*
* Data src filter is inverted so that the default value of 0 is
* equivalent to no filtering.
*/
return ~ATTR_CFG_GET_FLD(attr, inv_data_src_filter);
}
static void arm_spe_pmu_pad_buf(struct perf_output_handle *handle, int len)
{
struct arm_spe_pmu_buf *buf = perf_get_aux(handle);
@@ -791,6 +816,10 @@ static int arm_spe_pmu_event_init(struct perf_event *event)
if (arm_spe_event_to_pmsnevfr(event) & spe_pmu->pmsevfr_res0)
return -EOPNOTSUPP;
if (arm_spe_event_to_pmsdsfr(event) != U64_MAX &&
!(spe_pmu->features & SPE_PMU_FEAT_FDS))
return -EOPNOTSUPP;
if (attr->exclude_idle)
return -EOPNOTSUPP;
@@ -866,6 +895,11 @@ static void arm_spe_pmu_start(struct perf_event *event, int flags)
write_sysreg_s(reg, SYS_PMSNEVFR_EL1);
}
if (spe_pmu->features & SPE_PMU_FEAT_FDS) {
reg = arm_spe_event_to_pmsdsfr(event);
write_sysreg_s(reg, SYS_PMSDSFR_EL1);
}
reg = arm_spe_event_to_pmslatfr(event);
write_sysreg_s(reg, SYS_PMSLATFR_EL1);
@@ -1125,6 +1159,9 @@ static void __arm_spe_pmu_dev_probe(void *info)
if (FIELD_GET(PMSIDR_EL1_EFT, reg))
spe_pmu->features |= SPE_PMU_FEAT_EFT;
if (FIELD_GET(PMSIDR_EL1_FDS, reg))
spe_pmu->features |= SPE_PMU_FEAT_FDS;
/* This field has a spaced out encoding, so just use a look-up */
fld = FIELD_GET(PMSIDR_EL1_INTERVAL, reg);
switch (fld) {
+5
View File
@@ -1801,6 +1801,11 @@ static __always_inline bool is_percpu_thread(void)
(current->nr_cpus_allowed == 1);
}
static __always_inline bool is_user_task(struct task_struct *task)
{
return task->mm && !(task->flags & (PF_KTHREAD | PF_USER_WORKER));
}
/* Per-process atomic flags. */
#define PFA_NO_NEW_PRIVS 0 /* May not gain new privileges. */
#define PFA_SPREAD_PAGE 1 /* Spread page cache over cpuset */
+2
View File
@@ -382,6 +382,7 @@ enum perf_event_read_format {
#define PERF_ATTR_SIZE_VER6 120 /* Add: aux_sample_size */
#define PERF_ATTR_SIZE_VER7 128 /* Add: sig_data */
#define PERF_ATTR_SIZE_VER8 136 /* Add: config3 */
#define PERF_ATTR_SIZE_VER9 144 /* add: config4 */
/*
* 'struct perf_event_attr' contains various attributes that define
@@ -543,6 +544,7 @@ struct perf_event_attr {
__u64 sig_data;
__u64 config3; /* extension of config2 */
__u64 config4; /* extension of config3 */
};
/*
+1 -1
View File
@@ -246,7 +246,7 @@ get_perf_callchain(struct pt_regs *regs, bool kernel, bool user,
if (user && !crosstask) {
if (!user_mode(regs)) {
if (current->flags & (PF_KTHREAD | PF_USER_WORKER))
if (!is_user_task(current))
goto exit_put;
regs = task_pt_regs(current);
}
+30 -13
View File
@@ -2320,8 +2320,6 @@ out:
perf_event__header_size(leader);
}
static void sync_child_event(struct perf_event *child_event);
static void perf_child_detach(struct perf_event *event)
{
struct perf_event *parent_event = event->parent;
@@ -2340,7 +2338,6 @@ static void perf_child_detach(struct perf_event *event)
lockdep_assert_held(&parent_event->child_mutex);
*/
sync_child_event(event);
list_del_init(&event->child_list);
}
@@ -4598,6 +4595,7 @@ out:
static void perf_remove_from_owner(struct perf_event *event);
static void perf_event_exit_event(struct perf_event *event,
struct perf_event_context *ctx,
struct task_struct *task,
bool revoke);
/*
@@ -4625,7 +4623,7 @@ static void perf_event_remove_on_exec(struct perf_event_context *ctx)
modified = true;
perf_event_exit_event(event, ctx, false);
perf_event_exit_event(event, ctx, ctx->task, false);
}
raw_spin_lock_irqsave(&ctx->lock, flags);
@@ -7024,6 +7022,15 @@ static int perf_mmap_rb(struct vm_area_struct *vma, struct perf_event *event,
if (data_page_nr(event->rb) != nr_pages)
return -EINVAL;
/*
* If this event doesn't have mmap_count, we're attempting to
* create an alias of another event's mmap(); this would mean
* both events will end up scribbling the same user_page;
* which makes no sense.
*/
if (!refcount_read(&event->mmap_count))
return -EBUSY;
if (refcount_inc_not_zero(&event->rb->mmap_count)) {
/*
* Success -- managed to mmap() the same buffer
@@ -7478,7 +7485,7 @@ static void perf_sample_regs_user(struct perf_regs *regs_user,
if (user_mode(regs)) {
regs_user->abi = perf_reg_abi(current);
regs_user->regs = regs;
} else if (!(current->flags & (PF_KTHREAD | PF_USER_WORKER))) {
} else if (is_user_task(current)) {
perf_get_regs_user(regs_user, regs);
} else {
regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE;
@@ -8118,7 +8125,7 @@ static u64 perf_virt_to_phys(u64 virt)
* Try IRQ-safe get_user_page_fast_only first.
* If failed, leave phys_addr as 0.
*/
if (!(current->flags & (PF_KTHREAD | PF_USER_WORKER))) {
if (is_user_task(current)) {
struct page *p;
pagefault_disable();
@@ -8231,7 +8238,7 @@ perf_callchain(struct perf_event *event, struct pt_regs *regs)
{
bool kernel = !event->attr.exclude_callchain_kernel;
bool user = !event->attr.exclude_callchain_user &&
!(current->flags & (PF_KTHREAD | PF_USER_WORKER));
is_user_task(current);
/* Disallow cross-task user callchains. */
bool crosstask = event->ctx->task && event->ctx->task != current;
const u32 max_stack = event->attr.sample_max_stack;
@@ -11863,6 +11870,11 @@ static void perf_swevent_cancel_hrtimer(struct perf_event *event)
}
}
static void perf_swevent_destroy_hrtimer(struct perf_event *event)
{
hrtimer_cancel(&event->hw.hrtimer);
}
static void perf_swevent_init_hrtimer(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
@@ -11871,6 +11883,7 @@ static void perf_swevent_init_hrtimer(struct perf_event *event)
return;
hrtimer_setup(&hwc->hrtimer, perf_swevent_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD);
event->destroy = perf_swevent_destroy_hrtimer;
/*
* Since hrtimers have a fixed rate, we can do a static freq->period
@@ -12473,7 +12486,7 @@ static void __pmu_detach_event(struct pmu *pmu, struct perf_event *event,
/*
* De-schedule the event and mark it REVOKED.
*/
perf_event_exit_event(event, ctx, true);
perf_event_exit_event(event, ctx, ctx->task, true);
/*
* All _free_event() bits that rely on event->pmu:
@@ -14032,14 +14045,13 @@ void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu)
}
EXPORT_SYMBOL_GPL(perf_pmu_migrate_context);
static void sync_child_event(struct perf_event *child_event)
static void sync_child_event(struct perf_event *child_event,
struct task_struct *task)
{
struct perf_event *parent_event = child_event->parent;
u64 child_val;
if (child_event->attr.inherit_stat) {
struct task_struct *task = child_event->ctx->task;
if (task && task != TASK_TOMBSTONE)
perf_event_read_event(child_event, task);
}
@@ -14058,7 +14070,9 @@ static void sync_child_event(struct perf_event *child_event)
static void
perf_event_exit_event(struct perf_event *event,
struct perf_event_context *ctx, bool revoke)
struct perf_event_context *ctx,
struct task_struct *task,
bool revoke)
{
struct perf_event *parent_event = event->parent;
unsigned long detach_flags = DETACH_EXIT;
@@ -14081,6 +14095,9 @@ perf_event_exit_event(struct perf_event *event,
mutex_lock(&parent_event->child_mutex);
/* PERF_ATTACH_ITRACE might be set concurrently */
attach_state = READ_ONCE(event->attach_state);
if (attach_state & PERF_ATTACH_CHILD)
sync_child_event(event, task);
}
if (revoke)
@@ -14172,7 +14189,7 @@ static void perf_event_exit_task_context(struct task_struct *task, bool exit)
perf_event_task(task, ctx, 0);
list_for_each_entry_safe(child_event, next, &ctx->event_list, event_entry)
perf_event_exit_event(child_event, ctx, false);
perf_event_exit_event(child_event, ctx, exit ? task : NULL, false);
mutex_unlock(&ctx->mutex);
+2 -2
View File
@@ -70,7 +70,7 @@ struct uprobe {
* The generic code assumes that it has two members of unknown type
* owned by the arch-specific code:
*
* insn - copy_insn() saves the original instruction here for
* insn - copy_insn() saves the original instruction here for
* arch_uprobe_analyze_insn().
*
* ixol - potentially modified instruction to execute out of
@@ -108,7 +108,7 @@ struct xol_area {
* itself. The probed process or a naughty kernel module could make
* the vma go away, and we must handle that reasonably gracefully.
*/
unsigned long vaddr; /* Page(s) of instruction slots */
unsigned long vaddr; /* Page(s) of instruction slots */
};
static void uprobe_warn(struct task_struct *t, const char *msg)
+2
View File
@@ -94,6 +94,7 @@
#define ARM_CPU_PART_NEOVERSE_V3 0xD84
#define ARM_CPU_PART_CORTEX_X925 0xD85
#define ARM_CPU_PART_CORTEX_A725 0xD87
#define ARM_CPU_PART_CORTEX_A720AE 0xD89
#define ARM_CPU_PART_NEOVERSE_N3 0xD8E
#define APM_CPU_PART_XGENE 0x000
@@ -180,6 +181,7 @@
#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)
#define MIDR_CORTEX_A720AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720AE)
#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3)
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
+15 -10
View File
@@ -337,7 +337,6 @@
#define X86_FEATURE_CLZERO (13*32+ 0) /* "clzero" CLZERO instruction */
#define X86_FEATURE_IRPERF (13*32+ 1) /* "irperf" Instructions Retired Count */
#define X86_FEATURE_XSAVEERPTR (13*32+ 2) /* "xsaveerptr" Always save/restore FP error pointers */
#define X86_FEATURE_INVLPGB (13*32+ 3) /* INVLPGB and TLBSYNC instructions supported */
#define X86_FEATURE_RDPRU (13*32+ 4) /* "rdpru" Read processor register at user level */
#define X86_FEATURE_WBNOINVD (13*32+ 9) /* "wbnoinvd" WBNOINVD instruction */
#define X86_FEATURE_AMD_IBPB (13*32+12) /* Indirect Branch Prediction Barrier */
@@ -446,14 +445,14 @@
#define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* Speculative Store Bypass Disable */
/* AMD-defined memory encryption features, CPUID level 0x8000001f (EAX), word 19 */
#define X86_FEATURE_SME (19*32+ 0) /* "sme" Secure Memory Encryption */
#define X86_FEATURE_SEV (19*32+ 1) /* "sev" Secure Encrypted Virtualization */
#define X86_FEATURE_SME (19*32+ 0) /* "sme" AMD Secure Memory Encryption */
#define X86_FEATURE_SEV (19*32+ 1) /* "sev" AMD Secure Encrypted Virtualization */
#define X86_FEATURE_VM_PAGE_FLUSH (19*32+ 2) /* VM Page Flush MSR is supported */
#define X86_FEATURE_SEV_ES (19*32+ 3) /* "sev_es" Secure Encrypted Virtualization - Encrypted State */
#define X86_FEATURE_SEV_SNP (19*32+ 4) /* "sev_snp" Secure Encrypted Virtualization - Secure Nested Paging */
#define X86_FEATURE_SEV_ES (19*32+ 3) /* "sev_es" AMD Secure Encrypted Virtualization - Encrypted State */
#define X86_FEATURE_SEV_SNP (19*32+ 4) /* "sev_snp" AMD Secure Encrypted Virtualization - Secure Nested Paging */
#define X86_FEATURE_V_TSC_AUX (19*32+ 9) /* Virtual TSC_AUX */
#define X86_FEATURE_SME_COHERENT (19*32+10) /* hardware-enforced cache coherency */
#define X86_FEATURE_DEBUG_SWAP (19*32+14) /* "debug_swap" SEV-ES full debug state swap support */
#define X86_FEATURE_SME_COHERENT (19*32+10) /* AMD hardware-enforced cache coherency */
#define X86_FEATURE_DEBUG_SWAP (19*32+14) /* "debug_swap" AMD SEV-ES full debug state swap support */
#define X86_FEATURE_RMPREAD (19*32+21) /* RMPREAD instruction */
#define X86_FEATURE_SEGMENTED_RMP (19*32+23) /* Segmented RMP support */
#define X86_FEATURE_ALLOWED_SEV_FEATURES (19*32+27) /* Allowed SEV Features */
@@ -464,6 +463,7 @@
#define X86_FEATURE_NO_NESTED_DATA_BP (20*32+ 0) /* No Nested Data Breakpoints */
#define X86_FEATURE_WRMSR_XX_BASE_NS (20*32+ 1) /* WRMSR to {FS,GS,KERNEL_GS}_BASE is non-serializing */
#define X86_FEATURE_LFENCE_RDTSC (20*32+ 2) /* LFENCE always serializing / synchronizes RDTSC */
#define X86_FEATURE_VERW_CLEAR (20*32+ 5) /* The memory form of VERW mitigates TSA */
#define X86_FEATURE_NULL_SEL_CLR_BASE (20*32+ 6) /* Null Selector Clears Base */
#define X86_FEATURE_AUTOIBRS (20*32+ 8) /* Automatic IBRS */
#define X86_FEATURE_NO_SMM_CTL_MSR (20*32+ 9) /* SMM_CTL MSR is not present */
@@ -495,6 +495,10 @@
#define X86_FEATURE_PREFER_YMM (21*32+ 8) /* Avoid ZMM registers due to downclocking */
#define X86_FEATURE_APX (21*32+ 9) /* Advanced Performance Extensions */
#define X86_FEATURE_INDIRECT_THUNK_ITS (21*32+10) /* Use thunk for indirect branches in lower half of cacheline */
#define X86_FEATURE_TSA_SQ_NO (21*32+11) /* AMD CPU not vulnerable to TSA-SQ */
#define X86_FEATURE_TSA_L1_NO (21*32+12) /* AMD CPU not vulnerable to TSA-L1 */
#define X86_FEATURE_CLEAR_CPU_BUF_VM (21*32+13) /* Clear CPU buffers using VERW before VMRUN */
#define X86_FEATURE_IBPB_EXIT_TO_USER (21*32+14) /* Use IBPB on exit-to-userspace, see VMSCAPE bug */
/*
* BUG word(s)
@@ -533,7 +537,7 @@
#define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* "itlb_multihit" CPU may incur MCE during certain page attribute changes */
#define X86_BUG_SRBDS X86_BUG(24) /* "srbds" CPU may leak RNG bits if not mitigated */
#define X86_BUG_MMIO_STALE_DATA X86_BUG(25) /* "mmio_stale_data" CPU is affected by Processor MMIO Stale Data vulnerabilities */
/* unused, was #define X86_BUG_MMIO_UNKNOWN X86_BUG(26) * "mmio_unknown" CPU is too old and its MMIO Stale Data status is unknown */
/* unused, was #define X86_BUG_MMIO_UNKNOWN X86_BUG(26) "mmio_unknown" CPU is too old and its MMIO Stale Data status is unknown */
#define X86_BUG_RETBLEED X86_BUG(27) /* "retbleed" CPU is affected by RETBleed */
#define X86_BUG_EIBRS_PBRSB X86_BUG(28) /* "eibrs_pbrsb" EIBRS is vulnerable to Post Barrier RSB Predictions */
#define X86_BUG_SMT_RSB X86_BUG(29) /* "smt_rsb" CPU is vulnerable to Cross-Thread Return Address Predictions */
@@ -545,10 +549,11 @@
#define X86_BUG_DIV0 X86_BUG( 1*32+ 1) /* "div0" AMD DIV0 speculation bug */
#define X86_BUG_RFDS X86_BUG( 1*32+ 2) /* "rfds" CPU is vulnerable to Register File Data Sampling */
#define X86_BUG_BHI X86_BUG( 1*32+ 3) /* "bhi" CPU is affected by Branch History Injection */
#define X86_BUG_IBPB_NO_RET X86_BUG( 1*32+ 4) /* "ibpb_no_ret" IBPB omits return target predictions */
#define X86_BUG_IBPB_NO_RET X86_BUG( 1*32+ 4) /* "ibpb_no_ret" IBPB omits return target predictions */
#define X86_BUG_SPECTRE_V2_USER X86_BUG( 1*32+ 5) /* "spectre_v2_user" CPU is affected by Spectre variant 2 attack between user processes */
#define X86_BUG_OLD_MICROCODE X86_BUG( 1*32+ 6) /* "old_microcode" CPU has old microcode, it is surely vulnerable to something */
#define X86_BUG_ITS X86_BUG( 1*32+ 7) /* "its" CPU is affected by Indirect Target Selection */
#define X86_BUG_ITS_NATIVE_ONLY X86_BUG( 1*32+ 8) /* "its_native_only" CPU is affected by ITS, VMX is not affected */
#define X86_BUG_TSA X86_BUG( 1*32+ 9) /* "tsa" CPU is affected by Transient Scheduler Attacks */
#define X86_BUG_VMSCAPE X86_BUG( 1*32+10) /* "vmscape" CPU is affected by VMSCAPE attacks from guests */
#endif /* _ASM_X86_CPUFEATURES_H */
+4 -4
View File
@@ -91,7 +91,6 @@ FEATURE_TESTS_BASIC := \
timerfd \
zlib \
lzma \
get_cpuid \
bpf \
scandirat \
sched_getcpu \
@@ -101,7 +100,8 @@ FEATURE_TESTS_BASIC := \
libzstd \
disassembler-four-args \
disassembler-init-styled \
file-handle
file-handle \
libopenssl
# FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list
# of all feature tests
@@ -148,10 +148,10 @@ FEATURE_DISPLAY ?= \
llvm-perf \
zlib \
lzma \
get_cpuid \
bpf \
libaio \
libzstd
libzstd \
libopenssl
#
# Declare group members of a feature to display the logical OR of the detection
+13 -7
View File
@@ -57,7 +57,6 @@ FILES= \
test-lzma.bin \
test-bpf.bin \
test-libbpf.bin \
test-get_cpuid.bin \
test-sdt.bin \
test-cxx.bin \
test-gettid.bin \
@@ -69,12 +68,13 @@ FILES= \
test-libopencsd.bin \
test-clang.bin \
test-llvm.bin \
test-llvm-perf.bin \
test-llvm-perf.bin \
test-libaio.bin \
test-libzstd.bin \
test-clang-bpf-co-re.bin \
test-file-handle.bin \
test-libpfm4.bin
test-libpfm4.bin \
test-libopenssl.bin
FILES := $(addprefix $(OUTPUT),$(FILES))
@@ -103,12 +103,18 @@ else
endif
endif
ifeq ($(findstring -static,${LDFLAGS}),-static)
PKG_CONFIG += --static
endif
all: $(FILES)
__BUILD = $(CC) $(CFLAGS) -MD -Wall -Werror -o $@ $(patsubst %.bin,%.c,$(@F)) $(LDFLAGS)
BUILD = $(__BUILD) > $(@:.bin=.make.output) 2>&1
BUILD_BFD = $(BUILD) -DPACKAGE='"perf"' -lbfd -ldl
BUILD_ALL = $(BUILD) -fstack-protector-all -O2 -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -lslang $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -ldl -lz -llzma -lzstd
BUILD_ALL = $(BUILD) -fstack-protector-all -O2 -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -lslang \
$(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -ldl -lz -llzma -lzstd \
$(shell $(PKG_CONFIG) --libs --cflags openssl 2>/dev/null)
__BUILDXX = $(CXX) $(CXXFLAGS) -MD -Wall -Werror -o $@ $(patsubst %.bin,%.cpp,$(@F)) $(LDFLAGS)
BUILDXX = $(__BUILDXX) > $(@:.bin=.make.output) 2>&1
@@ -322,9 +328,6 @@ $(OUTPUT)test-zlib.bin:
$(OUTPUT)test-lzma.bin:
$(BUILD) -llzma
$(OUTPUT)test-get_cpuid.bin:
$(BUILD)
$(OUTPUT)test-bpf.bin:
$(BUILD)
@@ -389,6 +392,9 @@ $(OUTPUT)test-file-handle.bin:
$(OUTPUT)test-libpfm4.bin:
$(BUILD) -lpfm
$(OUTPUT)test-libopenssl.bin:
$(BUILD) $(shell $(PKG_CONFIG) --libs --cflags openssl 2>/dev/null)
$(OUTPUT)test-bpftool-skeletons.bin:
$(SYSTEM_BPFTOOL) version | grep '^features:.*skeletons' \
> $(@:.bin=.make.output) 2>&1
+5 -5
View File
@@ -118,10 +118,6 @@
# include "test-lzma.c"
#undef main
#define main main_test_get_cpuid
# include "test-get_cpuid.c"
#undef main
#define main main_test_bpf
# include "test-bpf.c"
#undef main
@@ -150,6 +146,10 @@
# include "test-libtraceevent.c"
#undef main
#define main main_test_libopenssl
# include "test-libopenssl.c"
#undef main
int main(int argc, char *argv[])
{
main_test_libpython();
@@ -173,7 +173,6 @@ int main(int argc, char *argv[])
main_test_pthread_attr_setaffinity_np();
main_test_pthread_barrier();
main_test_lzma();
main_test_get_cpuid();
main_test_bpf();
main_test_scandirat();
main_test_sched_getcpu();
@@ -183,6 +182,7 @@ int main(int argc, char *argv[])
main_test_reallocarray();
main_test_libzstd();
main_test_libtraceevent();
main_test_libopenssl();
return 0;
}
-8
View File
@@ -1,8 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
#include <cpuid.h>
int main(void)
{
unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
return __get_cpuid(0x15, &eax, &ebx, &ecx, &edx);
}
+7
View File
@@ -0,0 +1,7 @@
#include <openssl/ssl.h>
#include <openssl/opensslv.h>
int main(void)
{
return SSL_library_init();
}
+51 -12
View File
@@ -597,34 +597,65 @@ struct drm_set_version {
int drm_dd_minor;
};
/* DRM_IOCTL_GEM_CLOSE ioctl argument type */
/**
* struct drm_gem_close - Argument for &DRM_IOCTL_GEM_CLOSE ioctl.
* @handle: Handle of the object to be closed.
* @pad: Padding.
*
* Releases the handle to an mm object.
*/
struct drm_gem_close {
/** Handle of the object to be closed. */
__u32 handle;
__u32 pad;
};
/* DRM_IOCTL_GEM_FLINK ioctl argument type */
/**
* struct drm_gem_flink - Argument for &DRM_IOCTL_GEM_FLINK ioctl.
* @handle: Handle for the object being named.
* @name: Returned global name.
*
* Create a global name for an object, returning the name.
*
* Note that the name does not hold a reference; when the object
* is freed, the name goes away.
*/
struct drm_gem_flink {
/** Handle for the object being named */
__u32 handle;
/** Returned global name */
__u32 name;
};
/* DRM_IOCTL_GEM_OPEN ioctl argument type */
/**
* struct drm_gem_open - Argument for &DRM_IOCTL_GEM_OPEN ioctl.
* @name: Name of object being opened.
* @handle: Returned handle for the object.
* @size: Returned size of the object
*
* Open an object using the global name, returning a handle and the size.
*
* This handle (of course) holds a reference to the object, so the object
* will not go away until the handle is deleted.
*/
struct drm_gem_open {
/** Name of object being opened */
__u32 name;
/** Returned handle for the object */
__u32 handle;
/** Returned size of the object */
__u64 size;
};
/**
* struct drm_gem_change_handle - Argument for &DRM_IOCTL_GEM_CHANGE_HANDLE ioctl.
* @handle: The handle of a gem object.
* @new_handle: An available gem handle.
*
* This ioctl changes the handle of a GEM object to the specified one.
* The new handle must be unused. On success the old handle is closed
* and all further IOCTL should refer to the new handle only.
* Calls to DRM_IOCTL_PRIME_FD_TO_HANDLE will return the new handle.
*/
struct drm_gem_change_handle {
__u32 handle;
__u32 new_handle;
};
/**
* DRM_CAP_DUMB_BUFFER
*
@@ -1309,6 +1340,14 @@ extern "C" {
*/
#define DRM_IOCTL_SET_CLIENT_NAME DRM_IOWR(0xD1, struct drm_set_client_name)
/**
* DRM_IOCTL_GEM_CHANGE_HANDLE - Move an object to a different handle
*
* Some applications (notably CRIU) need objects to have specific gem handles.
* This ioctl changes the object at one gem handle to use a new gem handle.
*/
#define DRM_IOCTL_GEM_CHANGE_HANDLE DRM_IOWR(0xD2, struct drm_gem_change_handle)
/*
* Device specific ioctls should only be in their respective headers
* The device specific ioctl range is from 0x40 to 0x9f.
+2 -2
View File
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef __LINUX_IF_ADDR_H
#define __LINUX_IF_ADDR_H
#ifndef _UAPI__LINUX_IF_ADDR_H
#define _UAPI__LINUX_IF_ADDR_H
#include <linux/types.h>
#include <linux/netlink.h>
-1
View File
@@ -969,7 +969,6 @@ struct kvm_enable_cap {
#define KVM_CAP_ARM_WRITABLE_IMP_ID_REGS 239
#define KVM_CAP_ARM_EL2 240
#define KVM_CAP_ARM_EL2_E2H0 241
#define KVM_CAP_RISCV_MP_STATE_RESET 242
#define KVM_CAP_ARM_CACHEABLE_PFNMAP_SUPPORTED 243
#define KVM_CAP_ARM_SEA_TO_USER 245
#define KVM_CAP_S390_USER_OPEREXEC 246
+2 -2
View File
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef __LINUX_NEIGHBOUR_H
#define __LINUX_NEIGHBOUR_H
#ifndef _UAPI__LINUX_NEIGHBOUR_H
#define _UAPI__LINUX_NEIGHBOUR_H
#include <linux/types.h>
#include <linux/netlink.h>
+2
View File
@@ -382,6 +382,7 @@ enum perf_event_read_format {
#define PERF_ATTR_SIZE_VER6 120 /* Add: aux_sample_size */
#define PERF_ATTR_SIZE_VER7 128 /* Add: sig_data */
#define PERF_ATTR_SIZE_VER8 136 /* Add: config3 */
#define PERF_ATTR_SIZE_VER9 144 /* add: config4 */
/*
* 'struct perf_event_attr' contains various attributes that define
@@ -543,6 +544,7 @@ struct perf_event_attr {
__u64 sig_data;
__u64 config3; /* extension of config2 */
__u64 config4; /* extension of config3 */
};
/*
+19 -10
View File
@@ -455,21 +455,33 @@ int perf_cpu_map__merge(struct perf_cpu_map **orig, struct perf_cpu_map *other)
struct perf_cpu_map *perf_cpu_map__intersect(struct perf_cpu_map *orig,
struct perf_cpu_map *other)
{
struct perf_cpu *tmp_cpus;
int tmp_len;
int i, j, k;
struct perf_cpu_map *merged = NULL;
struct perf_cpu_map *merged;
if (perf_cpu_map__is_subset(other, orig))
return perf_cpu_map__get(orig);
if (perf_cpu_map__is_subset(orig, other))
return perf_cpu_map__get(other);
tmp_len = max(__perf_cpu_map__nr(orig), __perf_cpu_map__nr(other));
tmp_cpus = malloc(tmp_len * sizeof(struct perf_cpu));
if (!tmp_cpus)
i = j = k = 0;
while (i < __perf_cpu_map__nr(orig) && j < __perf_cpu_map__nr(other)) {
if (__perf_cpu_map__cpu(orig, i).cpu < __perf_cpu_map__cpu(other, j).cpu)
i++;
else if (__perf_cpu_map__cpu(orig, i).cpu > __perf_cpu_map__cpu(other, j).cpu)
j++;
else { /* CPUs match. */
i++;
j++;
k++;
}
}
if (k == 0) /* Maps are completely disjoint. */
return NULL;
merged = perf_cpu_map__alloc(k);
if (!merged)
return NULL;
/* Entries are added to merged in sorted order, so no need to sort again. */
i = j = k = 0;
while (i < __perf_cpu_map__nr(orig) && j < __perf_cpu_map__nr(other)) {
if (__perf_cpu_map__cpu(orig, i).cpu < __perf_cpu_map__cpu(other, j).cpu)
@@ -478,11 +490,8 @@ struct perf_cpu_map *perf_cpu_map__intersect(struct perf_cpu_map *orig,
j++;
else {
j++;
tmp_cpus[k++] = __perf_cpu_map__cpu(orig, i++);
RC_CHK_ACCESS(merged)->map[k++] = __perf_cpu_map__cpu(orig, i++);
}
}
if (k)
merged = cpu_map__trim_new(k, tmp_cpus);
free(tmp_cpus);
return merged;
}
+1 -1
View File
@@ -5,7 +5,7 @@
#include <stdarg.h>
#ifndef LIBPERF_API
#define LIBPERF_API __attribute__((visibility("default")))
#define LIBPERF_API extern __attribute__((visibility("default")))
#endif
enum libperf_print_level {
+1
View File
@@ -36,6 +36,7 @@ config.mak.autogen
util/intel-pt-decoder/inat-tables.c
arch/*/include/generated/
trace/beauty/generated/
pmu-events/arch/common/common/legacy-cache.json
pmu-events/pmu-events.c
pmu-events/jevents
pmu-events/metric_test.log
+94 -8
View File
@@ -141,27 +141,65 @@ Config parameters
These are placed between the // in the event and comma separated. For example '-e
arm_spe/load_filter=1,min_latency=10/'
branch_filter=1 - collect branches only (PMSFCR.B)
event_filter=<mask> - filter on specific events (PMSEVFR) - see bitfield description below
event_filter=<mask> - logical AND filter on specific events (PMSEVFR) - see bitfield description below
inv_event_filter=<mask> - logical OR to filter out specific events (PMSNEVFR, FEAT_SPEv1p2) - see bitfield description below
jitter=1 - use jitter to avoid resonance when sampling (PMSIRR.RND)
load_filter=1 - collect loads only (PMSFCR.LD)
min_latency=<n> - collect only samples with this latency or higher* (PMSLATFR)
pa_enable=1 - collect physical address (as well as VA) of loads/stores (PMSCR.PA) - requires privilege
pct_enable=1 - collect physical timestamp instead of virtual timestamp (PMSCR.PCT) - requires privilege
store_filter=1 - collect stores only (PMSFCR.ST)
ts_enable=1 - enable timestamping with value of generic timer (PMSCR.TS)
discard=1 - enable SPE PMU events but don't collect sample data - see 'Discard mode' (PMBLIMITR.FM = DISCARD)
inv_data_src_filter=<mask> - mask to filter from 0-63 possible data sources (PMSDSFR, FEAT_SPE_FDS) - See 'Data source filtering'
+++*+++ Latency is the total latency from the point at which sampling started on that instruction, rather
than only the execution latency.
Only some events can be filtered on; these include:
Only some events can be filtered on using 'event_filter' bits. The overall
filter is the logical AND of these bits, for example if bits 3 and 5 are set
only samples that have both 'L1D cache refill' AND 'TLB walk' are recorded. When
FEAT_SPEv1p2 is implemented 'inv_event_filter' can also be used to exclude
events that have any (OR) of the filter's bits set. For example setting bits 3
and 5 in 'inv_event_filter' will exclude any events that are either L1D cache
refill OR TLB walk. If the same bit is set in both filters it's UNPREDICTABLE
whether the sample is included or excluded. Filter bits for both event_filter
and inv_event_filter are:
bit 1 - instruction retired (i.e. omit speculative instructions)
bit 1 - Instruction retired (i.e. omit speculative instructions)
bit 2 - L1D access (FEAT_SPEv1p4)
bit 3 - L1D refill
bit 4 - TLB access (FEAT_SPEv1p4)
bit 5 - TLB refill
bit 7 - mispredict
bit 11 - misaligned access
bit 6 - Not taken event (FEAT_SPEv1p2)
bit 7 - Mispredict
bit 8 - Last level cache access (FEAT_SPEv1p4)
bit 9 - Last level cache miss (FEAT_SPEv1p4)
bit 10 - Remote access (FEAT_SPEv1p4)
bit 11 - Misaligned access (FEAT_SPEv1p1)
bit 12-15 - IMPLEMENTATION DEFINED events (when implemented)
bit 16 - Transaction (FEAT_TME)
bit 17 - Partial or empty SME or SVE predicate (FEAT_SPEv1p1)
bit 18 - Empty SME or SVE predicate (FEAT_SPEv1p1)
bit 19 - L2D access (FEAT_SPEv1p4)
bit 20 - L2D miss (FEAT_SPEv1p4)
bit 21 - Cache data modified (FEAT_SPEv1p4)
bit 22 - Recently fetched (FEAT_SPEv1p4)
bit 23 - Data snooped (FEAT_SPEv1p4)
bit 24 - Streaming SVE mode event (when FEAT_SPE_SME is implemented), or
IMPLEMENTATION DEFINED event 24 (when implemented, only versions
less than FEAT_SPEv1p4)
bit 25 - SMCU or external coprocessor operation event when FEAT_SPE_SME is
implemented, or IMPLEMENTATION DEFINED event 25 (when implemented,
only versions less than FEAT_SPEv1p4)
bit 26-31 - IMPLEMENTATION DEFINED events (only versions less than FEAT_SPEv1p4)
bit 48-63 - IMPLEMENTATION DEFINED events (when implemented)
For IMPLEMENTATION DEFINED bits, refer to the CPU TRM if these bits are
implemented.
The driver will reject events if requested filter bits require unimplemented SPE
versions, but will not reject filter bits for unimplemented IMPDEF bits or when
their related feature is not present (e.g. SME). For example, if FEAT_SPEv1p2 is
not implemented, filtering on "Not taken event" (bit 6) will be rejected.
So to sample just retired instructions:
@@ -171,6 +209,31 @@ or just mispredicted branches:
perf record -e arm_spe/event_filter=0x80/ -- ./mybench
When set, the following filters can be used to select samples that match any of
the operation types (OR filtering). If only one is set then only samples of that
type are collected:
branch_filter=1 - Collect branches (PMSFCR.B)
load_filter=1 - Collect loads (PMSFCR.LD)
store_filter=1 - Collect stores (PMSFCR.ST)
When extended filtering is supported (FEAT_SPE_EFT), SIMD and float
pointer operations can also be selected:
simd_filter=1 - Collect SIMD loads, stores and operations (PMSFCR.SIMD)
float_filter=1 - Collect floating point loads, stores and operations (PMSFCR.FP)
When extended filtering is supported (FEAT_SPE_EFT), operation type filters can
be changed to AND using _mask fields. For example samples could be selected if
they are store AND SIMD by setting 'store_filter=1,simd_filter=1,
store_filter_mask=1,simd_filter_mask=1'. The new masks are as follows:
branch_filter_mask=1 - Change branch filter behavior from OR to AND (PMSFCR.Bm)
load_filter_mask=1 - Change load filter behavior from OR to AND (PMSFCR.LDm)
store_filter_mask=1 - Change store filter behavior from OR to AND (PMSFCR.STm)
simd_filter_mask=1 - Change SIMD filter behavior from OR to AND (PMSFCR.SIMDm)
float_filter_mask=1 - Change floating point filter behavior from OR to AND (PMSFCR.FPm)
Viewing the data
~~~~~~~~~~~~~~~~~
@@ -210,6 +273,10 @@ Memory access details are also stored on the samples and this can be viewed with
perf report --mem-mode
The latency value from the SPE sample is stored in the 'weight' field of the
Perf samples and can be displayed in Perf script and report outputs by enabling
its display from the command line.
Common errors
~~~~~~~~~~~~~
@@ -253,6 +320,25 @@ to minimize output. Then run perf stat:
perf record -e arm_spe/discard/ -a -N -B --no-bpf-event -o - > /dev/null &
perf stat -e SAMPLE_FEED_LD
Data source filtering
~~~~~~~~~~~~~~~~~~~~~
When FEAT_SPE_FDS is present, 'inv_data_src_filter' can be used as a mask to
filter on a subset (0 - 63) of possible data source IDs. The full range of data
sources is 0 - 65535 although these are unlikely to be used in practice. Data
sources are IMPDEF so refer to the TRM for the mappings. Each bit N of the
filter maps to data source N. The filter is an OR of all the bits, and the value
provided inv_data_src_filter is inverted before writing to PMSDSFR_EL1 so that
set bits exclude that data source and cleared bits include that data source.
Therefore the default value of 0 is equivalent to no filtering (all data sources
included).
For example, to include only data sources 0 and 3, clear bits 0 and 3
(0xFFFFFFFFFFFFFFF6)
When 'inv_data_src_filter' is set to 0xFFFFFFFFFFFFFFFF, any samples with any
data source set are excluded.
SEE ALSO
--------
+7
View File
@@ -143,6 +143,13 @@ REPORT OPTIONS
feature, which causes cacheline sharing to behave like the cacheline
size is doubled.
-M::
--disassembler-style=::
Set disassembler style for objdump.
--objdump=<path>::
Path to objdump binary.
C2C RECORD
----------
The perf c2c record command setup options related to HITM cacheline analysis
@@ -94,6 +94,9 @@ RECORD OPTIONS
-g::
--callchain::
Do call-graph (stack chain/backtrace) recording
-o::
--output=::
Select the output file (default: perf.data)
EXAMPLES
--------
+10 -10
View File
@@ -701,6 +701,11 @@ ifndef NO_LIBBPF
endif
endif
ifeq ($(feature-libopenssl), 1)
$(call detected,CONFIG_LIBOPENSSL)
CFLAGS += -DHAVE_LIBOPENSSL_SUPPORT
endif
ifndef BUILD_BPF_SKEL
# BPF skeletons control a large number of perf features, by default
# they are enabled.
@@ -717,6 +722,9 @@ ifeq ($(BUILD_BPF_SKEL),1)
else ifeq ($(filter -DHAVE_LIBBPF_SUPPORT, $(CFLAGS)),)
$(warning Warning: Disabled BPF skeletons as libbpf is required)
BUILD_BPF_SKEL := 0
else ifeq ($(filter -DHAVE_LIBOPENSSL_SUPPORT, $(CFLAGS)),)
$(warning Warning: Disabled BPF skeletons as libopenssl is required)
BUILD_BPF_SKEL := 0
else ifeq ($(call get-executable,$(CLANG)),)
$(warning Warning: Disabled BPF skeletons as clang ($(CLANG)) is missing)
BUILD_BPF_SKEL := 0
@@ -1119,16 +1127,8 @@ ifndef NO_CAPSTONE
endif
ifndef NO_AUXTRACE
ifeq ($(SRCARCH),x86)
ifeq ($(feature-get_cpuid), 0)
$(warning Your gcc lacks the __get_cpuid() builtin, disables support for auxtrace/Intel PT, please install a newer gcc)
NO_AUXTRACE := 1
endif
endif
ifndef NO_AUXTRACE
$(call detected,CONFIG_AUXTRACE)
CFLAGS += -DHAVE_AUXTRACE_SUPPORT
endif
$(call detected,CONFIG_AUXTRACE)
CFLAGS += -DHAVE_AUXTRACE_SUPPORT
endif
ifdef EXTRA_TESTS
+16 -5
View File
@@ -1272,9 +1272,24 @@ endif # CONFIG_PERF_BPF_SKEL
bpf-skel-clean:
$(call QUIET_CLEAN, bpf-skel) $(RM) -r $(SKEL_TMP_OUT) $(SKELETONS) $(SKEL_OUT)/vmlinux.h
pmu-events-clean:
ifeq ($(OUTPUT),)
$(call QUIET_CLEAN, pmu-events) $(RM) \
pmu-events/pmu-events.c \
pmu-events/metric_test.log \
pmu-events/test-empty-pmu-events.c \
pmu-events/empty-pmu-events.log
else # When an OUTPUT directory is present, clean up the copied pmu-events/arch directory.
$(call QUIET_CLEAN, pmu-events) $(RM) -r $(OUTPUT)pmu-events/arch \
$(OUTPUT)pmu-events/pmu-events.c \
$(OUTPUT)pmu-events/metric_test.log \
$(OUTPUT)pmu-events/test-empty-pmu-events.c \
$(OUTPUT)pmu-events/empty-pmu-events.log
endif
clean:: $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBSYMBOL)-clean $(LIBPERF)-clean \
arm64-sysreg-defs-clean fixdep-clean python-clean bpf-skel-clean \
tests-coresight-targets-clean
tests-coresight-targets-clean pmu-events-clean
$(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive \
$(OUTPUT)perf-iostat $(LANG_BINDINGS)
$(Q)find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '*.a' -delete -o \
@@ -1287,10 +1302,6 @@ clean:: $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBSYMBOL)-clean $(
$(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \
$(OUTPUT)util/intel-pt-decoder/inat-tables.c \
$(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c \
$(OUTPUT)pmu-events/pmu-events.c \
$(OUTPUT)pmu-events/test-empty-pmu-events.c \
$(OUTPUT)pmu-events/empty-pmu-events.log \
$(OUTPUT)pmu-events/metric_test.log \
$(OUTPUT)$(fadvise_advice_array) \
$(OUTPUT)$(fsconfig_arrays) \
$(OUTPUT)$(fsmount_arrays) \
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/compiler.h>
#include <linux/zalloc.h>
#include <errno.h>
#include <sys/types.h>
#include <regex.h>
#include <stdlib.h>
+1
View File
@@ -5,6 +5,7 @@
*/
#include <dirent.h>
#include <errno.h>
#include <stdbool.h>
#include <linux/coresight-pmu.h>
#include <linux/zalloc.h>
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/compiler.h>
#include <errno.h>
#include <sys/types.h>
#include <regex.h>
#include <stdlib.h>
+1
View File
@@ -10,6 +10,7 @@
#include <linux/log2.h>
#include <linux/string.h>
#include <linux/zalloc.h>
#include <errno.h>
#include <time.h>
#include "../../../util/cpumap.h"
+1
View File
@@ -9,6 +9,7 @@
#include <linux/bitops.h>
#include <linux/log2.h>
#include <linux/zalloc.h>
#include <errno.h>
#include <time.h>
#include <internal/lib.h> // page_size
+1 -1
View File
@@ -2,7 +2,7 @@
/*
* VPA support
*/
#include <errno.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/string.h>
+1
View File
@@ -1,3 +1,4 @@
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <linux/kernel.h>
+179 -4
View File
@@ -248,6 +248,7 @@ static void update_insn_state_x86(struct type_state *state,
tsr = &state->regs[state->ret_reg];
tsr->type = type_die;
tsr->kind = TSR_KIND_TYPE;
tsr->offset = 0;
tsr->ok = true;
pr_debug_dtp("call [%x] return -> reg%d",
@@ -284,6 +285,7 @@ static void update_insn_state_x86(struct type_state *state,
!strcmp(var_name, "this_cpu_off") &&
tsr->kind == TSR_KIND_CONST) {
tsr->kind = TSR_KIND_PERCPU_BASE;
tsr->offset = 0;
tsr->ok = true;
imm_value = tsr->imm_value;
}
@@ -291,6 +293,19 @@ static void update_insn_state_x86(struct type_state *state,
else
return;
/* Ignore add to non-pointer or non-const types */
if (tsr->kind == TSR_KIND_POINTER ||
(dwarf_tag(&tsr->type) == DW_TAG_pointer_type &&
src->reg1 != DWARF_REG_PC && tsr->kind == TSR_KIND_TYPE && !dst->mem_ref)) {
tsr->offset += imm_value;
pr_debug_dtp("add [%x] offset %#"PRIx64" to reg%d",
insn_offset, imm_value, dst->reg1);
pr_debug_type_name(&tsr->type, tsr->kind);
}
if (tsr->kind == TSR_KIND_CONST)
tsr->imm_value += imm_value;
if (tsr->kind != TSR_KIND_PERCPU_BASE)
return;
@@ -302,6 +317,7 @@ static void update_insn_state_x86(struct type_state *state,
*/
tsr->type = type_die;
tsr->kind = TSR_KIND_PERCPU_POINTER;
tsr->offset = 0;
tsr->ok = true;
pr_debug_dtp("add [%x] percpu %#"PRIx64" -> reg%d",
@@ -311,6 +327,135 @@ static void update_insn_state_x86(struct type_state *state,
return;
}
if (!strncmp(dl->ins.name, "sub", 3)) {
u64 imm_value = -1ULL;
if (!has_reg_type(state, dst->reg1))
return;
tsr = &state->regs[dst->reg1];
tsr->copied_from = -1;
if (src->imm)
imm_value = src->offset;
else if (has_reg_type(state, src->reg1) &&
state->regs[src->reg1].kind == TSR_KIND_CONST)
imm_value = state->regs[src->reg1].imm_value;
if (tsr->kind == TSR_KIND_POINTER ||
(dwarf_tag(&tsr->type) == DW_TAG_pointer_type &&
src->reg1 != DWARF_REG_PC && tsr->kind == TSR_KIND_TYPE && !dst->mem_ref)) {
tsr->offset -= imm_value;
pr_debug_dtp("sub [%x] offset %#"PRIx64" to reg%d",
insn_offset, imm_value, dst->reg1);
pr_debug_type_name(&tsr->type, tsr->kind);
}
if (tsr->kind == TSR_KIND_CONST)
tsr->imm_value -= imm_value;
return;
}
if (!strncmp(dl->ins.name, "lea", 3)) {
int sreg = src->reg1;
struct type_state_reg src_tsr;
if (!has_reg_type(state, sreg) ||
!has_reg_type(state, dst->reg1) ||
!src->mem_ref)
return;
src_tsr = state->regs[sreg];
tsr = &state->regs[dst->reg1];
tsr->copied_from = -1;
tsr->ok = false;
/* Case 1: Based on stack pointer or frame pointer */
if (sreg == fbreg || sreg == state->stack_reg) {
struct type_state_stack *stack;
int offset = src->offset - fboff;
stack = find_stack_state(state, offset);
if (!stack)
return;
tsr->type = stack->type;
tsr->kind = TSR_KIND_POINTER;
tsr->offset = offset - stack->offset;
tsr->ok = true;
if (sreg == fbreg) {
pr_debug_dtp("lea [%x] address of -%#x(stack) -> reg%d",
insn_offset, -src->offset, dst->reg1);
} else {
pr_debug_dtp("lea [%x] address of %#x(reg%d) -> reg%d",
insn_offset, src->offset, sreg, dst->reg1);
}
pr_debug_type_name(&tsr->type, tsr->kind);
}
/* Case 2: Based on a register holding a typed pointer */
else if (src_tsr.ok && (src_tsr.kind == TSR_KIND_POINTER ||
(dwarf_tag(&src_tsr.type) == DW_TAG_pointer_type &&
src_tsr.kind == TSR_KIND_TYPE))) {
if (src_tsr.kind == TSR_KIND_TYPE &&
__die_get_real_type(&state->regs[sreg].type, &type_die) == NULL)
return;
if (src_tsr.kind == TSR_KIND_POINTER)
type_die = state->regs[sreg].type;
/* Check if the target type has a member at the new offset */
if (die_get_member_type(&type_die,
src->offset + src_tsr.offset, &type_die) == NULL)
return;
tsr->type = src_tsr.type;
tsr->kind = src_tsr.kind;
tsr->offset = src->offset + src_tsr.offset;
tsr->ok = true;
pr_debug_dtp("lea [%x] address of %s%#x(reg%d) -> reg%d",
insn_offset, src->offset < 0 ? "-" : "",
abs(src->offset), sreg, dst->reg1);
pr_debug_type_name(&tsr->type, tsr->kind);
}
return;
}
/* Invalidate register states for other ops which may change pointers */
if (has_reg_type(state, dst->reg1) && !dst->mem_ref &&
dwarf_tag(&state->regs[dst->reg1].type) == DW_TAG_pointer_type) {
if (!strncmp(dl->ins.name, "imul", 4) || !strncmp(dl->ins.name, "mul", 3) ||
!strncmp(dl->ins.name, "idiv", 4) || !strncmp(dl->ins.name, "div", 3) ||
!strncmp(dl->ins.name, "shl", 3) || !strncmp(dl->ins.name, "shr", 3) ||
!strncmp(dl->ins.name, "sar", 3) || !strncmp(dl->ins.name, "and", 3) ||
!strncmp(dl->ins.name, "or", 2) || !strncmp(dl->ins.name, "neg", 3) ||
!strncmp(dl->ins.name, "inc", 3) || !strncmp(dl->ins.name, "dec", 3)) {
pr_debug_dtp("%s [%x] invalidate reg%d\n",
dl->ins.name, insn_offset, dst->reg1);
state->regs[dst->reg1].ok = false;
state->regs[dst->reg1].copied_from = -1;
return;
}
if (!strncmp(dl->ins.name, "xor", 3) && dst->reg1 == src->reg1) {
/* xor reg, reg clears the register */
pr_debug_dtp("xor [%x] clear reg%d\n",
insn_offset, dst->reg1);
state->regs[dst->reg1].kind = TSR_KIND_CONST;
state->regs[dst->reg1].imm_value = 0;
state->regs[dst->reg1].ok = true;
state->regs[dst->reg1].copied_from = -1;
return;
}
}
if (strncmp(dl->ins.name, "mov", 3))
return;
@@ -345,6 +490,7 @@ static void update_insn_state_x86(struct type_state *state,
if (var_addr == 40) {
tsr->kind = TSR_KIND_CANARY;
tsr->offset = 0;
tsr->ok = true;
pr_debug_dtp("mov [%x] stack canary -> reg%d\n",
@@ -361,6 +507,7 @@ static void update_insn_state_x86(struct type_state *state,
tsr->type = type_die;
tsr->kind = TSR_KIND_TYPE;
tsr->offset = 0;
tsr->ok = true;
pr_debug_dtp("mov [%x] this-cpu addr=%#"PRIx64" -> reg%d",
@@ -372,6 +519,7 @@ static void update_insn_state_x86(struct type_state *state,
if (src->imm) {
tsr->kind = TSR_KIND_CONST;
tsr->imm_value = src->offset;
tsr->offset = 0;
tsr->ok = true;
pr_debug_dtp("mov [%x] imm=%#x -> reg%d\n",
@@ -388,10 +536,11 @@ static void update_insn_state_x86(struct type_state *state,
tsr->type = state->regs[src->reg1].type;
tsr->kind = state->regs[src->reg1].kind;
tsr->imm_value = state->regs[src->reg1].imm_value;
tsr->offset = state->regs[src->reg1].offset;
tsr->ok = true;
/* To copy back the variable type later (hopefully) */
if (tsr->kind == TSR_KIND_TYPE)
if (tsr->kind == TSR_KIND_TYPE || tsr->kind == TSR_KIND_POINTER)
tsr->copied_from = src->reg1;
pr_debug_dtp("mov [%x] reg%d -> reg%d",
@@ -421,12 +570,14 @@ retry:
} else if (!stack->compound) {
tsr->type = stack->type;
tsr->kind = stack->kind;
tsr->offset = stack->ptr_offset;
tsr->ok = true;
} else if (die_get_member_type(&stack->type,
offset - stack->offset,
&type_die)) {
tsr->type = type_die;
tsr->kind = TSR_KIND_TYPE;
tsr->offset = 0;
tsr->ok = true;
} else {
tsr->ok = false;
@@ -446,15 +597,30 @@ retry:
else if (has_reg_type(state, sreg) && state->regs[sreg].ok &&
state->regs[sreg].kind == TSR_KIND_TYPE &&
die_deref_ptr_type(&state->regs[sreg].type,
src->offset, &type_die)) {
src->offset + state->regs[sreg].offset, &type_die)) {
tsr->type = type_die;
tsr->kind = TSR_KIND_TYPE;
tsr->offset = 0;
tsr->ok = true;
pr_debug_dtp("mov [%x] %#x(reg%d) -> reg%d",
insn_offset, src->offset, sreg, dst->reg1);
pr_debug_type_name(&tsr->type, tsr->kind);
}
/* Handle dereference of TSR_KIND_POINTER registers */
else if (has_reg_type(state, sreg) && state->regs[sreg].ok &&
state->regs[sreg].kind == TSR_KIND_POINTER &&
die_get_member_type(&state->regs[sreg].type,
src->offset + state->regs[sreg].offset, &type_die)) {
tsr->type = state->regs[sreg].type;
tsr->kind = TSR_KIND_TYPE;
tsr->offset = src->offset + state->regs[sreg].offset;
tsr->ok = true;
pr_debug_dtp("mov [%x] addr %#x(reg%d) -> reg%d",
insn_offset, src->offset, sreg, dst->reg1);
pr_debug_type_name(&tsr->type, tsr->kind);
}
/* Or check if it's a global variable */
else if (sreg == DWARF_REG_PC) {
struct map_symbol *ms = dloc->ms;
@@ -473,6 +639,7 @@ retry:
tsr->type = type_die;
tsr->kind = TSR_KIND_TYPE;
tsr->offset = 0;
tsr->ok = true;
pr_debug_dtp("mov [%x] global addr=%"PRIx64" -> reg%d",
@@ -504,6 +671,7 @@ retry:
die_get_member_type(&type_die, offset, &type_die)) {
tsr->type = type_die;
tsr->kind = TSR_KIND_TYPE;
tsr->offset = 0;
tsr->ok = true;
if (src->multi_regs) {
@@ -526,6 +694,7 @@ retry:
src->offset, &type_die)) {
tsr->type = type_die;
tsr->kind = TSR_KIND_TYPE;
tsr->offset = 0;
tsr->ok = true;
pr_debug_dtp("mov [%x] pointer %#x(reg%d) -> reg%d",
@@ -548,6 +717,7 @@ retry:
&var_name, &offset) &&
!strcmp(var_name, "__per_cpu_offset")) {
tsr->kind = TSR_KIND_PERCPU_BASE;
tsr->offset = 0;
tsr->ok = true;
pr_debug_dtp("mov [%x] percpu base reg%d\n",
@@ -583,10 +753,10 @@ retry:
*/
if (!stack->compound)
set_stack_state(stack, offset, tsr->kind,
&tsr->type);
&tsr->type, tsr->offset);
} else {
findnew_stack_state(state, offset, tsr->kind,
&tsr->type);
&tsr->type, tsr->offset);
}
if (dst->reg1 == fbreg) {
@@ -596,6 +766,11 @@ retry:
pr_debug_dtp("mov [%x] reg%d -> %#x(reg%d)",
insn_offset, src->reg1, offset, dst->reg1);
}
if (tsr->offset != 0) {
pr_debug_dtp(" reg%d offset %#x ->",
src->reg1, tsr->offset);
}
pr_debug_type_name(&tsr->type, tsr->kind);
}
/*
+3 -3
View File
@@ -3,7 +3,6 @@
#include <linux/compiler.h>
#include <linux/bits.h>
#include <string.h>
#include <cpuid.h>
#include <sched.h>
#include "intel-pt-decoder/intel-pt-pkt-decoder.h"
@@ -11,6 +10,7 @@
#include "debug.h"
#include "tests/tests.h"
#include "arch-tests.h"
#include "../util/cpuid.h"
#include "cpumap.h"
/**
@@ -363,7 +363,7 @@ static int get_pt_caps(int cpu, struct pt_caps *caps)
memset(caps, 0, sizeof(*caps));
for (i = 0; i < INTEL_PT_SUBLEAF_CNT; i++) {
__get_cpuid_count(20, i, &r.eax, &r.ebx, &r.ecx, &r.edx);
cpuid(20, i, &r.eax, &r.ebx, &r.ecx, &r.edx);
pr_debug("CPU %d CPUID leaf 20 subleaf %d\n", cpu, i);
pr_debug("eax = 0x%08x\n", r.eax);
pr_debug("ebx = 0x%08x\n", r.ebx);
@@ -380,7 +380,7 @@ static bool is_hybrid(void)
unsigned int eax, ebx, ecx, edx = 0;
bool result;
__get_cpuid_count(7, 0, &eax, &ebx, &ecx, &edx);
cpuid(7, 0, &eax, &ebx, &ecx, &edx);
result = edx & BIT(15);
pr_debug("Is %shybrid : CPUID leaf 7 subleaf 0 edx %#x (bit-15 indicates hybrid)\n",
result ? "" : "not ", edx);
+1
View File
@@ -1,4 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
#include "arch-tests.h"
#include "../util/topdown.h"
#include "debug.h"
+3 -3
View File
@@ -12,7 +12,6 @@
#include <linux/log2.h>
#include <linux/zalloc.h>
#include <linux/err.h>
#include <cpuid.h>
#include "../../../util/session.h"
#include "../../../util/event.h"
@@ -34,6 +33,7 @@
#include <internal/lib.h> // page_size
#include "../../../util/intel-pt.h"
#include <api/fs/fs.h>
#include "cpuid.h"
#define KiB(x) ((x) * 1024)
#define MiB(x) ((x) * 1024 * 1024)
@@ -72,7 +72,7 @@ static int intel_pt_parse_terms_with_default(const struct perf_pmu *pmu,
int err;
parse_events_terms__init(&terms);
err = parse_events_terms(&terms, str, /*input=*/ NULL);
err = parse_events_terms(&terms, str);
if (err)
goto out_free;
@@ -311,7 +311,7 @@ static void intel_pt_tsc_ctc_ratio(u32 *n, u32 *d)
{
unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
__get_cpuid(0x15, &eax, &ebx, &ecx, &edx);
cpuid(0x15, 0, &eax, &ebx, &ecx, &edx);
*n = ebx;
*d = eax;
}
+1
View File
@@ -1,4 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
#include "util/evlist.h"
#include "util/pmu.h"
#include "util/pmus.h"
+1
View File
@@ -1,4 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
+1
View File
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/prctl.h>
+1 -1
View File
@@ -85,7 +85,7 @@ static int add_dso(const char *fpath, const struct stat *sb __maybe_unused,
if (typeflag == FTW_D || typeflag == FTW_SL)
return 0;
if (filename__read_build_id(fpath, &bid, /*block=*/true) < 0)
if (filename__read_build_id(fpath, &bid) < 0)
return 0;
dso->name = realpath(fpath, NULL);
+1
View File
@@ -4,6 +4,7 @@
*
* Copyright 2023 Google LLC.
*/
#include <errno.h>
#include <stdio.h>
#include "bench.h"
#include "util/debug.h"
+1
View File
@@ -6,6 +6,7 @@
*
* Copyright 2019 Google LLC.
*/
#include <errno.h>
#include <stdio.h>
#include "bench.h"
#include "../util/debug.h"
+3 -2
View File
@@ -313,7 +313,8 @@ out_put:
return ret;
}
static int process_feature_event(struct perf_session *session,
static int process_feature_event(const struct perf_tool *tool __maybe_unused,
struct perf_session *session,
union perf_event *event)
{
if (event->feat.feat_id < HEADER_LAST_FEATURE)
@@ -519,7 +520,7 @@ find_next:
/* skip missing symbols */
nd = rb_next(nd);
} else if (use_browser == 1) {
key = hist_entry__tui_annotate(he, evsel, NULL);
key = hist_entry__tui_annotate(he, evsel, NULL, NO_ADDR);
switch (key) {
case -1:
+7 -5
View File
@@ -180,7 +180,7 @@ static int build_id_cache__add_file(const char *filename, struct nsinfo *nsi)
struct nscookie nsc;
nsinfo__mountns_enter(nsi, &nsc);
err = filename__read_build_id(filename, &bid, /*block=*/true);
err = filename__read_build_id(filename, &bid);
nsinfo__mountns_exit(&nsc);
if (err < 0) {
pr_debug("Couldn't read a build-id in %s\n", filename);
@@ -204,7 +204,7 @@ static int build_id_cache__remove_file(const char *filename, struct nsinfo *nsi)
int err;
nsinfo__mountns_enter(nsi, &nsc);
err = filename__read_build_id(filename, &bid, /*block=*/true);
err = filename__read_build_id(filename, &bid);
nsinfo__mountns_exit(&nsc);
if (err < 0) {
pr_debug("Couldn't read a build-id in %s\n", filename);
@@ -276,12 +276,14 @@ static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused)
{
char filename[PATH_MAX];
struct build_id bid = { .size = 0, };
int err;
if (!dso__build_id_filename(dso, filename, sizeof(filename), false))
return true;
if (filename__read_build_id(filename, &bid, /*block=*/true) == -1) {
if (errno == ENOENT)
err = filename__read_build_id(filename, &bid);
if (err < 0) {
if (err == -ENOENT)
return false;
pr_warning("Problems with %s file, consider removing it from the cache\n",
@@ -309,7 +311,7 @@ static int build_id_cache__update_file(const char *filename, struct nsinfo *nsi)
int err;
nsinfo__mountns_enter(nsi, &nsc);
err = filename__read_build_id(filename, &bid, /*block=*/true);
err = filename__read_build_id(filename, &bid);
nsinfo__mountns_exit(&nsc);
if (err < 0) {
pr_debug("Couldn't read a build-id in %s\n", filename);
+168 -27
View File
@@ -45,6 +45,8 @@
#include "pmus.h"
#include "string2.h"
#include "util/util.h"
#include "util/symbol.h"
#include "util/annotate.h"
struct c2c_hists {
struct hists hists;
@@ -62,6 +64,7 @@ struct compute_stats {
struct c2c_hist_entry {
struct c2c_hists *hists;
struct evsel *evsel;
struct c2c_stats stats;
unsigned long *cpuset;
unsigned long *nodeset;
@@ -225,6 +228,12 @@ he__get_c2c_hists(struct hist_entry *he,
return hists;
}
static void c2c_he__set_evsel(struct c2c_hist_entry *c2c_he,
struct evsel *evsel)
{
c2c_he->evsel = evsel;
}
static void c2c_he__set_cpu(struct c2c_hist_entry *c2c_he,
struct perf_sample *sample)
{
@@ -275,6 +284,33 @@ static void compute_stats(struct c2c_hist_entry *c2c_he,
update_stats(&cstats->load, weight);
}
/*
* Return true if annotation is possible. When list is NULL,
* it means that we are called at the c2c_browser level,
* in that case we allow annotation to be initialized. When list
* is non-NULL, it means that we are called at the cacheline_browser
* level, in that case we allow annotation only if use_browser
* is set and symbol information is available.
*/
static bool perf_c2c__has_annotation(struct perf_hpp_list *list)
{
if (use_browser != 1)
return false;
return !list || list->sym;
}
static void perf_c2c__evsel_hists_inc_stats(struct evsel *evsel,
struct hist_entry *he,
struct perf_sample *sample)
{
struct hists *evsel_hists = evsel__hists(evsel);
hists__inc_nr_samples(evsel_hists, he->filtered);
evsel_hists->stats.total_period += sample->period;
if (!he->filtered)
evsel_hists->stats.total_non_filtered_period += sample->period;
}
static int process_sample_event(const struct perf_tool *tool __maybe_unused,
union perf_event *event,
struct perf_sample *sample,
@@ -286,7 +322,7 @@ static int process_sample_event(const struct perf_tool *tool __maybe_unused,
struct c2c_stats stats = { .nr_entries = 0, };
struct hist_entry *he;
struct addr_location al;
struct mem_info *mi, *mi_dup;
struct mem_info *mi = NULL;
struct callchain_cursor *cursor;
int ret;
@@ -313,20 +349,15 @@ static int process_sample_event(const struct perf_tool *tool __maybe_unused,
goto out;
}
/*
* The mi object is released in hists__add_entry_ops,
* if it gets sorted out into existing data, so we need
* to take the copy now.
*/
mi_dup = mem_info__get(mi);
c2c_decode_stats(&stats, mi);
he = hists__add_entry_ops(&c2c_hists->hists, &c2c_entry_ops,
&al, NULL, NULL, mi, NULL,
sample, true);
if (he == NULL)
goto free_mi;
if (he == NULL) {
ret = -ENOMEM;
goto out;
}
c2c_he = container_of(he, struct c2c_hist_entry, he);
c2c_add_stats(&c2c_he->stats, &stats);
@@ -334,8 +365,15 @@ static int process_sample_event(const struct perf_tool *tool __maybe_unused,
c2c_he__set_cpu(c2c_he, sample);
c2c_he__set_node(c2c_he, sample);
c2c_he__set_evsel(c2c_he, evsel);
hists__inc_nr_samples(&c2c_hists->hists, he->filtered);
if (perf_c2c__has_annotation(NULL)) {
perf_c2c__evsel_hists_inc_stats(evsel, he, sample);
addr_map_symbol__inc_samples(mem_info__iaddr(mi), sample, evsel);
}
ret = hist_entry__append_callchain(he, sample);
if (!ret) {
@@ -350,17 +388,19 @@ static int process_sample_event(const struct perf_tool *tool __maybe_unused,
int cpu = sample->cpu == (unsigned int) -1 ? 0 : sample->cpu;
int node = c2c.cpu2node[cpu];
mi = mi_dup;
c2c_hists = he__get_c2c_hists(he, c2c.cl_sort, 2, machine->env);
if (!c2c_hists)
goto free_mi;
if (!c2c_hists) {
ret = -ENOMEM;
goto out;
}
he = hists__add_entry_ops(&c2c_hists->hists, &c2c_entry_ops,
&al, NULL, NULL, mi, NULL,
sample, true);
if (he == NULL)
goto free_mi;
if (he == NULL) {
ret = -ENOMEM;
goto out;
}
c2c_he = container_of(he, struct c2c_hist_entry, he);
c2c_add_stats(&c2c_he->stats, &stats);
@@ -371,20 +411,16 @@ static int process_sample_event(const struct perf_tool *tool __maybe_unused,
c2c_he__set_cpu(c2c_he, sample);
c2c_he__set_node(c2c_he, sample);
c2c_he__set_evsel(c2c_he, evsel);
hists__inc_nr_samples(&c2c_hists->hists, he->filtered);
ret = hist_entry__append_callchain(he, sample);
}
out:
mem_info__put(mi);
addr_location__exit(&al);
return ret;
free_mi:
mem_info__put(mi_dup);
mem_info__put(mi);
ret = -ENOMEM;
goto out;
}
static const char * const c2c_usage[] = {
@@ -1997,6 +2033,9 @@ static int c2c_hists__init_sort(struct perf_hpp_list *hpp_list, char *name, stru
if (dim == &dim_dso)
hpp_list->dso = 1;
if (dim == &dim_symbol || dim == &dim_iaddr)
hpp_list->sym = 1;
perf_hpp_list__register_sort_field(hpp_list, &c2c_fmt->fmt);
return 0;
}
@@ -2550,6 +2589,44 @@ static void perf_c2c__hists_fprintf(FILE *out, struct perf_session *session)
}
#ifdef HAVE_SLANG_SUPPORT
static int perf_c2c__toggle_annotation(struct hist_browser *browser)
{
struct hist_entry *he = browser->he_selection;
struct symbol *sym = NULL;
struct annotated_source *src = NULL;
struct c2c_hist_entry *c2c_he = NULL;
u64 al_addr = NO_ADDR;
if (!perf_c2c__has_annotation(he->hists->hpp_list)) {
ui_browser__help_window(&browser->b, "No annotation support");
return 0;
}
if (he == NULL) {
ui_browser__help_window(&browser->b, "No entry selected for annotation");
return 0;
}
sym = he->ms.sym;
if (sym == NULL) {
ui_browser__help_window(&browser->b, "Can not annotate, no symbol found");
return 0;
}
src = symbol__hists(sym, 0);
if (src == NULL) {
ui_browser__help_window(&browser->b, "Failed to initialize annotation source");
return 0;
}
if (he->mem_info)
al_addr = mem_info__iaddr(he->mem_info)->al_addr;
c2c_he = container_of(he, struct c2c_hist_entry, he);
return hist_entry__tui_annotate(he, c2c_he->evsel, NULL, al_addr);
}
static void c2c_browser__update_nr_entries(struct hist_browser *hb)
{
u64 nr_entries = 0;
@@ -2617,6 +2694,7 @@ static int perf_c2c__browse_cacheline(struct hist_entry *he)
" ENTER Toggle callchains (if present) \n"
" n Toggle Node details info \n"
" s Toggle full length of symbol and source line columns \n"
" a Toggle annotation view \n"
" q Return back to cacheline list \n";
if (!he)
@@ -2651,6 +2729,9 @@ static int perf_c2c__browse_cacheline(struct hist_entry *he)
c2c.node_info = (c2c.node_info + 1) % 3;
setup_nodes_header();
break;
case 'a':
perf_c2c__toggle_annotation(browser);
break;
case 'q':
goto out;
case '?':
@@ -3006,6 +3087,7 @@ static int perf_c2c__report(int argc, const char **argv)
const char *display = NULL;
const char *coalesce = NULL;
bool no_source = false;
const char *disassembler_style = NULL, *objdump_path = NULL;
const struct option options[] = {
OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
"file", "vmlinux pathname"),
@@ -3033,6 +3115,10 @@ static int perf_c2c__report(int argc, const char **argv)
OPT_BOOLEAN(0, "stitch-lbr", &c2c.stitch_lbr,
"Enable LBR callgraph stitching approach"),
OPT_BOOLEAN(0, "double-cl", &chk_double_cl, "Detect adjacent cacheline false sharing"),
OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
"Specify disassembler style (e.g. -M intel for intel syntax)"),
OPT_STRING(0, "objdump", &objdump_path, "path",
"objdump binary to use for disassembly and annotations"),
OPT_PARENT(c2c_options),
OPT_END()
};
@@ -3040,6 +3126,12 @@ static int perf_c2c__report(int argc, const char **argv)
const char *output_str, *sort_str = NULL;
struct perf_env *env;
annotation_options__init();
err = hists__init();
if (err < 0)
goto out;
argc = parse_options(argc, argv, options, report_c2c_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
if (argc)
@@ -3052,6 +3144,27 @@ static int perf_c2c__report(int argc, const char **argv)
if (c2c.stats_only)
c2c.use_stdio = true;
/**
* Annotation related options disassembler_style, objdump_path are set
* in the c2c_options, so we can use them here.
*/
if (disassembler_style) {
annotate_opts.disassembler_style = strdup(disassembler_style);
if (!annotate_opts.disassembler_style) {
err = -ENOMEM;
pr_err("Failed to allocate memory for annotation options\n");
goto out;
}
}
if (objdump_path) {
annotate_opts.objdump_path = strdup(objdump_path);
if (!annotate_opts.objdump_path) {
err = -ENOMEM;
pr_err("Failed to allocate memory for annotation options\n");
goto out;
}
}
err = symbol__validate_sym_arguments();
if (err)
goto out;
@@ -3126,6 +3239,38 @@ static int perf_c2c__report(int argc, const char **argv)
if (err)
goto out_mem2node;
if (c2c.use_stdio)
use_browser = 0;
else
use_browser = 1;
/*
* Only in the TUI browser we are doing integrated annotation,
* so don't allocate extra space that won't be used in the stdio
* implementation.
*/
if (perf_c2c__has_annotation(NULL)) {
int ret = symbol__annotation_init();
if (ret < 0)
goto out_mem2node;
/*
* For searching by name on the "Browse map details".
* providing it only in verbose mode not to bloat too
* much struct symbol.
*/
if (verbose > 0) {
/*
* XXX: Need to provide a less kludgy way to ask for
* more space per symbol, the u32 is for the index on
* the ui browser.
* See symbol__browser_index.
*/
symbol_conf.priv_size += sizeof(u32);
}
annotation_config__init();
}
if (symbol__init(env) < 0)
goto out_mem2node;
@@ -3135,11 +3280,6 @@ static int perf_c2c__report(int argc, const char **argv)
goto out_mem2node;
}
if (c2c.use_stdio)
use_browser = 0;
else
use_browser = 1;
setup_browser(false);
err = perf_session__process_events(session);
@@ -3210,6 +3350,7 @@ out_mem2node:
out_session:
perf_session__delete(session);
out:
annotation_options__exit();
return err;
}
+2 -1
View File
@@ -19,7 +19,8 @@
#include "util/tool.h"
#include "util/util.h"
static int process_header_feature(struct perf_session *session __maybe_unused,
static int process_header_feature(const struct perf_tool *tool __maybe_unused,
struct perf_session *session __maybe_unused,
union perf_event *event __maybe_unused)
{
session_done = 1;
+22 -18
View File
@@ -197,18 +197,20 @@ static int perf_event__drop_oe(const struct perf_tool *tool __maybe_unused,
}
#endif
static int perf_event__repipe_op2_synth(struct perf_session *session,
static int perf_event__repipe_op2_synth(const struct perf_tool *tool,
struct perf_session *session __maybe_unused,
union perf_event *event)
{
return perf_event__repipe_synth(session->tool, event);
return perf_event__repipe_synth(tool, event);
}
static int perf_event__repipe_op4_synth(struct perf_session *session,
static int perf_event__repipe_op4_synth(const struct perf_tool *tool,
struct perf_session *session __maybe_unused,
union perf_event *event,
u64 data __maybe_unused,
const char *str __maybe_unused)
{
return perf_event__repipe_synth(session->tool, event);
return perf_event__repipe_synth(tool, event);
}
static int perf_event__repipe_attr(const struct perf_tool *tool,
@@ -258,12 +260,11 @@ static int copy_bytes(struct perf_inject *inject, struct perf_data *data, off_t
return 0;
}
static s64 perf_event__repipe_auxtrace(struct perf_session *session,
static s64 perf_event__repipe_auxtrace(const struct perf_tool *tool,
struct perf_session *session,
union perf_event *event)
{
const struct perf_tool *tool = session->tool;
struct perf_inject *inject = container_of(tool, struct perf_inject,
tool);
struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
int ret;
inject->have_auxtrace = true;
@@ -299,7 +300,8 @@ static s64 perf_event__repipe_auxtrace(struct perf_session *session,
#else
static s64
perf_event__repipe_auxtrace(struct perf_session *session __maybe_unused,
perf_event__repipe_auxtrace(const struct perf_tool *tool __maybe_unused,
struct perf_session *session __maybe_unused,
union perf_event *event __maybe_unused)
{
pr_err("AUX area tracing not supported\n");
@@ -661,12 +663,13 @@ static int perf_event__repipe_exit(const struct perf_tool *tool,
}
#ifdef HAVE_LIBTRACEEVENT
static int perf_event__repipe_tracing_data(struct perf_session *session,
static int perf_event__repipe_tracing_data(const struct perf_tool *tool,
struct perf_session *session,
union perf_event *event)
{
perf_event__repipe_synth(session->tool, event);
perf_event__repipe_synth(tool, event);
return perf_event__process_tracing_data(session, event);
return perf_event__process_tracing_data(tool, session, event);
}
#endif
@@ -680,12 +683,12 @@ static int dso__read_build_id(struct dso *dso)
mutex_lock(dso__lock(dso));
nsinfo__mountns_enter(dso__nsinfo(dso), &nsc);
if (filename__read_build_id(dso__long_name(dso), &bid, /*block=*/true) > 0)
if (filename__read_build_id(dso__long_name(dso), &bid) > 0)
dso__set_build_id(dso, &bid);
else if (dso__nsinfo(dso)) {
char *new_name = dso__filename_with_chroot(dso, dso__long_name(dso));
if (new_name && filename__read_build_id(new_name, &bid, /*block=*/true) > 0)
if (new_name && filename__read_build_id(new_name, &bid) > 0)
dso__set_build_id(dso, &bid);
free(new_name);
}
@@ -1348,7 +1351,7 @@ static int process_build_id(const struct perf_tool *tool,
{
struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
return perf_event__process_build_id(inject->session, event);
return perf_event__process_build_id(tool, inject->session, event);
}
static int synthesize_build_id(struct perf_inject *inject, struct dso *dso, pid_t machine_pid)
@@ -1780,9 +1783,10 @@ static int host__repipe(const struct perf_tool *tool,
return perf_event__repipe(tool, event, sample, machine);
}
static int host__finished_init(struct perf_session *session, union perf_event *event)
static int host__finished_init(const struct perf_tool *tool, struct perf_session *session,
union perf_event *event)
{
struct perf_inject *inject = container_of(session->tool, struct perf_inject, tool);
struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
struct guest_session *gs = &inject->guest_session;
int ret;
@@ -1829,7 +1833,7 @@ static int host__finished_init(struct perf_session *session, union perf_event *e
if (ret)
return ret;
return perf_event__repipe_op2_synth(session, event);
return perf_event__repipe_op2_synth(tool, session, event);
}
/*
+106 -63
View File
@@ -130,7 +130,7 @@ static void default_print_event(void *ps, const char *topic,
if (deprecated && !print_state->deprecated)
return;
if (print_state->pmu_glob && pmu_name && !strglobmatch(pmu_name, print_state->pmu_glob))
if (print_state->pmu_glob && (!pmu_name || !strglobmatch(pmu_name, print_state->pmu_glob)))
return;
if (print_state->exclude_abi && pmu_type < PERF_TYPE_MAX && pmu_type != PERF_TYPE_RAW)
@@ -283,8 +283,8 @@ static void default_print_metric(void *ps,
}
struct json_print_state {
/** @fp: File to write output to. */
FILE *fp;
/** The shared print_state */
struct print_state common;
/** Should a separator be printed prior to the next item? */
bool need_sep;
};
@@ -292,7 +292,7 @@ struct json_print_state {
static void json_print_start(void *ps)
{
struct json_print_state *print_state = ps;
FILE *fp = print_state->fp;
FILE *fp = print_state->common.fp;
fprintf(fp, "[\n");
}
@@ -300,7 +300,7 @@ static void json_print_start(void *ps)
static void json_print_end(void *ps)
{
struct json_print_state *print_state = ps;
FILE *fp = print_state->fp;
FILE *fp = print_state->common.fp;
fprintf(fp, "%s]\n", print_state->need_sep ? "\n" : "");
}
@@ -370,9 +370,26 @@ static void json_print_event(void *ps, const char *topic,
{
struct json_print_state *print_state = ps;
bool need_sep = false;
FILE *fp = print_state->fp;
FILE *fp = print_state->common.fp;
struct strbuf buf;
if (deprecated && !print_state->common.deprecated)
return;
if (print_state->common.pmu_glob &&
(!pmu_name || !strglobmatch(pmu_name, print_state->common.pmu_glob)))
return;
if (print_state->common.exclude_abi && pmu_type < PERF_TYPE_MAX &&
pmu_type != PERF_TYPE_RAW)
return;
if (print_state->common.event_glob &&
(!event_name || !strglobmatch(event_name, print_state->common.event_glob)) &&
(!event_alias || !strglobmatch(event_alias, print_state->common.event_glob)) &&
(!topic || !strglobmatch_nocase(topic, print_state->common.event_glob)))
return;
strbuf_init(&buf, 0);
fprintf(fp, "%s{\n", print_state->need_sep ? ",\n" : "");
print_state->need_sep = true;
@@ -446,9 +463,16 @@ static void json_print_metric(void *ps __maybe_unused, const char *group,
{
struct json_print_state *print_state = ps;
bool need_sep = false;
FILE *fp = print_state->fp;
FILE *fp = print_state->common.fp;
struct strbuf buf;
if (print_state->common.event_glob &&
(!print_state->common.metrics || !name ||
!strglobmatch(name, print_state->common.event_glob)) &&
(!print_state->common.metricgroups || !group ||
!strglobmatch(group, print_state->common.event_glob)))
return;
strbuf_init(&buf, 0);
fprintf(fp, "%s{\n", print_state->need_sep ? ",\n" : "");
print_state->need_sep = true;
@@ -521,10 +545,12 @@ int cmd_list(int argc, const char **argv)
.fp = stdout,
.desc = true,
};
struct print_state json_ps = {
.fp = stdout,
struct json_print_state json_ps = {
.common = {
.fp = stdout,
},
};
void *ps = &default_ps;
struct print_state *ps = &default_ps;
struct print_callbacks print_cb = {
.print_start = default_print_start,
.print_end = default_print_end,
@@ -572,9 +598,11 @@ int cmd_list(int argc, const char **argv)
argc = parse_options(argc, argv, list_options, list_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
if (json)
ps = &json_ps.common;
if (output_path) {
default_ps.fp = fopen(output_path, "w");
json_ps.fp = default_ps.fp;
ps->fp = fopen(output_path, "w");
}
setup_pager();
@@ -590,14 +618,13 @@ int cmd_list(int argc, const char **argv)
.print_metric = json_print_metric,
.skip_duplicate_pmus = json_skip_duplicate_pmus,
};
ps = &json_ps;
} else {
default_ps.last_topic = strdup("");
assert(default_ps.last_topic);
default_ps.visited_metrics = strlist__new(NULL, NULL);
assert(default_ps.visited_metrics);
ps->last_topic = strdup("");
assert(ps->last_topic);
ps->visited_metrics = strlist__new(NULL, NULL);
assert(ps->visited_metrics);
if (unit_name)
default_ps.pmu_glob = strdup(unit_name);
ps->pmu_glob = strdup(unit_name);
else if (cputype) {
const struct perf_pmu *pmu = perf_pmus__pmu_for_pmu_filter(cputype);
@@ -606,14 +633,16 @@ int cmd_list(int argc, const char **argv)
ret = -1;
goto out;
}
default_ps.pmu_glob = strdup(pmu->name);
ps->pmu_glob = strdup(pmu->name);
}
}
print_cb.print_start(ps);
if (argc == 0) {
default_ps.metrics = true;
default_ps.metricgroups = true;
if (!unit_name) {
ps->metrics = true;
ps->metricgroups = true;
}
print_events(&print_cb, ps);
goto out;
}
@@ -633,41 +662,58 @@ int cmd_list(int argc, const char **argv)
zfree(&default_ps.pmu_glob);
default_ps.pmu_glob = old_pmu_glob;
} else if (strcmp(argv[i], "hw") == 0 ||
strcmp(argv[i], "hardware") == 0)
print_symbol_events(&print_cb, ps, PERF_TYPE_HARDWARE,
event_symbols_hw, PERF_COUNT_HW_MAX);
else if (strcmp(argv[i], "sw") == 0 ||
strcmp(argv[i], "hardware") == 0) {
char *old_event_glob = ps->event_glob;
ps->event_glob = strdup("legacy hardware");
if (!ps->event_glob) {
ret = -1;
goto out;
}
perf_pmus__print_pmu_events(&print_cb, ps);
zfree(&ps->event_glob);
ps->event_glob = old_event_glob;
} else if (strcmp(argv[i], "sw") == 0 ||
strcmp(argv[i], "software") == 0) {
char *old_pmu_glob = default_ps.pmu_glob;
char *old_pmu_glob = ps->pmu_glob;
static const char * const sw_globs[] = { "software", "tool" };
for (size_t j = 0; j < ARRAY_SIZE(sw_globs); j++) {
default_ps.pmu_glob = strdup(sw_globs[j]);
if (!default_ps.pmu_glob) {
ps->pmu_glob = strdup(sw_globs[j]);
if (!ps->pmu_glob) {
ret = -1;
goto out;
}
perf_pmus__print_pmu_events(&print_cb, ps);
zfree(&default_ps.pmu_glob);
zfree(&ps->pmu_glob);
}
default_ps.pmu_glob = old_pmu_glob;
ps->pmu_glob = old_pmu_glob;
} else if (strcmp(argv[i], "cache") == 0 ||
strcmp(argv[i], "hwcache") == 0)
print_hwcache_events(&print_cb, ps);
else if (strcmp(argv[i], "pmu") == 0) {
default_ps.exclude_abi = true;
strcmp(argv[i], "hwcache") == 0) {
char *old_event_glob = ps->event_glob;
ps->event_glob = strdup("legacy cache");
if (!ps->event_glob) {
ret = -1;
goto out;
}
perf_pmus__print_pmu_events(&print_cb, ps);
default_ps.exclude_abi = false;
zfree(&ps->event_glob);
ps->event_glob = old_event_glob;
} else if (strcmp(argv[i], "pmu") == 0) {
ps->exclude_abi = true;
perf_pmus__print_pmu_events(&print_cb, ps);
ps->exclude_abi = false;
} else if (strcmp(argv[i], "sdt") == 0)
print_sdt_events(&print_cb, ps);
else if (strcmp(argv[i], "metric") == 0 || strcmp(argv[i], "metrics") == 0) {
default_ps.metricgroups = false;
default_ps.metrics = true;
ps->metricgroups = false;
ps->metrics = true;
metricgroup__print(&print_cb, ps);
} else if (strcmp(argv[i], "metricgroup") == 0 ||
strcmp(argv[i], "metricgroups") == 0) {
default_ps.metricgroups = true;
default_ps.metrics = false;
ps->metricgroups = true;
ps->metrics = false;
metricgroup__print(&print_cb, ps);
}
#ifdef HAVE_LIBPFM
@@ -675,43 +721,40 @@ int cmd_list(int argc, const char **argv)
print_libpfm_events(&print_cb, ps);
#endif
else if ((sep = strchr(argv[i], ':')) != NULL) {
char *old_pmu_glob = default_ps.pmu_glob;
char *old_event_glob = default_ps.event_glob;
char *old_pmu_glob = ps->pmu_glob;
char *old_event_glob = ps->event_glob;
default_ps.event_glob = strdup(argv[i]);
if (!default_ps.event_glob) {
ps->event_glob = strdup(argv[i]);
if (!ps->event_glob) {
ret = -1;
goto out;
}
default_ps.pmu_glob = strdup("tracepoint");
if (!default_ps.pmu_glob) {
zfree(&default_ps.event_glob);
ps->pmu_glob = strdup("tracepoint");
if (!ps->pmu_glob) {
zfree(&ps->event_glob);
ret = -1;
goto out;
}
perf_pmus__print_pmu_events(&print_cb, ps);
zfree(&default_ps.pmu_glob);
default_ps.pmu_glob = old_pmu_glob;
zfree(&ps->pmu_glob);
ps->pmu_glob = old_pmu_glob;
print_sdt_events(&print_cb, ps);
default_ps.metrics = true;
default_ps.metricgroups = true;
ps->metrics = true;
ps->metricgroups = true;
metricgroup__print(&print_cb, ps);
zfree(&default_ps.event_glob);
default_ps.event_glob = old_event_glob;
zfree(&ps->event_glob);
ps->event_glob = old_event_glob;
} else {
if (asprintf(&s, "*%s*", argv[i]) < 0) {
printf("Critical: Not enough memory! Trying to continue...\n");
continue;
}
default_ps.event_glob = s;
print_symbol_events(&print_cb, ps, PERF_TYPE_HARDWARE,
event_symbols_hw, PERF_COUNT_HW_MAX);
print_hwcache_events(&print_cb, ps);
ps->event_glob = s;
perf_pmus__print_pmu_events(&print_cb, ps);
print_sdt_events(&print_cb, ps);
default_ps.metrics = true;
default_ps.metricgroups = true;
ps->metrics = true;
ps->metricgroups = true;
metricgroup__print(&print_cb, ps);
free(s);
}
@@ -719,12 +762,12 @@ int cmd_list(int argc, const char **argv)
out:
print_cb.print_end(ps);
free(default_ps.pmu_glob);
free(default_ps.last_topic);
free(default_ps.last_metricgroups);
strlist__delete(default_ps.visited_metrics);
free(ps->pmu_glob);
free(ps->last_topic);
free(ps->last_metricgroups);
strlist__delete(ps->visited_metrics);
if (output_path)
fclose(default_ps.fp);
fclose(ps->fp);
return ret;
}
+1
View File
@@ -1,4 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
+102 -22
View File
@@ -983,7 +983,6 @@ static int record__config_tracking_events(struct record *rec)
*/
if (opts->target.initial_delay || target__has_cpu(&opts->target) ||
perf_pmus__num_core_pmus() > 1) {
/*
* User space tasks can migrate between CPUs, so when tracing
* selected CPUs, sideband for all CPUs is still needed.
@@ -1388,10 +1387,27 @@ static int record__open(struct record *rec)
struct perf_session *session = rec->session;
struct record_opts *opts = &rec->opts;
int rc = 0;
bool skipped = false;
bool removed_tracking = false;
evlist__for_each_entry(evlist, pos) {
if (removed_tracking) {
/*
* Normally the head of the list has tracking enabled
* for sideband data like mmaps. If this event is
* removed, make sure to add tracking to the next
* processed event.
*/
if (!pos->tracking) {
pos->tracking = true;
evsel__config(pos, opts, &callchain_param);
}
removed_tracking = false;
}
try_again:
if (evsel__open(pos, pos->core.cpus, pos->core.threads) < 0) {
bool report_error = true;
if (evsel__fallback(pos, &opts->target, errno, msg, sizeof(msg))) {
if (verbose > 0)
ui__warning("%s\n", msg);
@@ -1403,13 +1419,73 @@ try_again:
pos = evlist__reset_weak_group(evlist, pos, true);
goto try_again;
}
rc = -errno;
evsel__open_strerror(pos, &opts->target, errno, msg, sizeof(msg));
ui__error("%s\n", msg);
goto out;
#if defined(__aarch64__) || defined(__arm__)
if (strstr(evsel__name(pos), "cycles")) {
struct evsel *pos2;
/*
* Unfortunately ARM has many events named
* "cycles" on PMUs like the system-level (L3)
* cache which don't support sampling. Only
* display such failures to open when there is
* only 1 cycles event or verbose is enabled.
*/
evlist__for_each_entry(evlist, pos2) {
if (pos2 == pos)
continue;
if (strstr(evsel__name(pos2), "cycles")) {
report_error = false;
break;
}
}
}
#endif
if (report_error || verbose > 0) {
evsel__open_strerror(pos, &opts->target, errno, msg, sizeof(msg));
ui__error("Failure to open event '%s' on PMU '%s' which will be "
"removed.\n%s\n",
evsel__name(pos), evsel__pmu_name(pos), msg);
}
if (pos->tracking)
removed_tracking = true;
pos->skippable = true;
skipped = true;
}
}
if (skipped) {
struct evsel *tmp;
int idx = 0;
bool evlist_empty = true;
/* Remove evsels that failed to open and update indices. */
evlist__for_each_entry_safe(evlist, tmp, pos) {
if (pos->skippable) {
evlist__remove(evlist, pos);
continue;
}
/*
* Note, dummy events may be command line parsed or
* added by the tool. We care about supporting `perf
* record -e dummy` which may be used as a permission
* check. Dummy events that are added to the command
* line and opened along with other events that fail,
* will still fail as if the dummy events were tool
* added events for the sake of code simplicity.
*/
if (!evsel__is_dummy_event(pos))
evlist_empty = false;
}
evlist__for_each_entry(evlist, pos) {
pos->core.idx = idx++;
}
/* If list is empty then fail. */
if (evlist_empty) {
ui__error("Failure to open any events for recording.\n");
rc = -1;
goto out;
}
}
if (symbol_conf.kptr_restrict && !evlist__exclude_kernel(evlist)) {
pr_warning(
"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
@@ -1815,15 +1891,14 @@ record__finish_output(struct record *rec)
}
/* Buildid scanning disabled or build ID in kernel and synthesized map events. */
if (!rec->no_buildid) {
if (!rec->no_buildid || !rec->no_buildid_cache) {
process_buildids(rec);
if (rec->buildid_all)
perf_session__dsos_hit_all(rec->session);
}
perf_session__write_header(rec->session, rec->evlist, fd, true);
return;
perf_session__cache_build_ids(rec->session);
}
static int record__synthesize_workload(struct record *rec, bool tail)
@@ -3008,7 +3083,7 @@ static int perf_record_config(const char *var, const char *value, void *cb)
else if (!strcmp(value, "no-cache"))
rec->no_buildid_cache = true;
else if (!strcmp(value, "skip"))
rec->no_buildid = true;
rec->no_buildid = rec->no_buildid_cache = true;
else if (!strcmp(value, "mmap"))
rec->buildid_mmap = true;
else if (!strcmp(value, "no-mmap"))
@@ -4117,24 +4192,25 @@ int cmd_record(int argc, const char **argv)
record.opts.record_switch_events = true;
}
if (!rec->buildid_mmap) {
pr_debug("Disabling build id in synthesized mmap2 events.\n");
symbol_conf.no_buildid_mmap2 = true;
} else if (rec->buildid_mmap_set) {
/*
* Explicitly passing --buildid-mmap disables buildid processing
* and cache generation.
*/
rec->no_buildid = true;
}
if (rec->buildid_mmap && !perf_can_record_build_id()) {
pr_warning("Missing support for build id in kernel mmap events.\n"
"Disable this warning with --no-buildid-mmap\n");
rec->buildid_mmap = false;
}
if (rec->buildid_mmap) {
/* Enable perf_event_attr::build_id bit. */
rec->opts.build_id = true;
/* Disable build-ID table in the header. */
rec->no_buildid = true;
} else {
pr_debug("Disabling build id in synthesized mmap2 events.\n");
symbol_conf.no_buildid_mmap2 = true;
}
if (rec->no_buildid_set && rec->no_buildid) {
/* -B implies -N for historic reasons. */
rec->no_buildid_cache = true;
}
if (rec->opts.record_cgroup && !perf_can_record_cgroup()) {
@@ -4231,7 +4307,7 @@ int cmd_record(int argc, const char **argv)
err = -ENOMEM;
if (rec->no_buildid_cache || rec->no_buildid) {
if (rec->no_buildid_cache) {
disable_buildid_cache();
} else if (rec->switch_output.enabled) {
/*
@@ -4266,9 +4342,13 @@ int cmd_record(int argc, const char **argv)
record.opts.tail_synthesize = true;
if (rec->evlist->core.nr_entries == 0) {
err = parse_event(rec->evlist, "cycles:P");
if (err)
struct evlist *def_evlist = evlist__new_default();
if (!def_evlist)
goto out;
evlist__splice_list_tail(rec->evlist, &def_evlist->core.entries);
evlist__delete(def_evlist);
}
if (rec->opts.target.tid && !rec->opts.no_inherit_set)
+3 -2
View File
@@ -240,10 +240,11 @@ static void setup_forced_leader(struct report *report,
evlist__force_leader(evlist);
}
static int process_feature_event(struct perf_session *session,
static int process_feature_event(const struct perf_tool *tool,
struct perf_session *session,
union perf_event *event)
{
struct report *rep = container_of(session->tool, struct report, tool);
struct report *rep = container_of(tool, struct report, tool);
if (event->feat.feat_id < HEADER_LAST_FEATURE)
return perf_event__process_feature(session, event);
+247 -40
View File
@@ -33,6 +33,7 @@
#include "util/path.h"
#include "util/event.h"
#include "util/mem-info.h"
#include "util/metricgroup.h"
#include "ui/ui.h"
#include "print_binary.h"
#include "print_insn.h"
@@ -341,16 +342,8 @@ struct evsel_script {
char *filename;
FILE *fp;
u64 samples;
/* For metric output */
u64 val;
int gnum;
};
static inline struct evsel_script *evsel_script(struct evsel *evsel)
{
return (struct evsel_script *)evsel->priv;
}
static struct evsel_script *evsel_script__new(struct evsel *evsel, struct perf_data *data)
{
struct evsel_script *es = zalloc(sizeof(*es));
@@ -2132,13 +2125,161 @@ static void script_new_line(struct perf_stat_config *config __maybe_unused,
fputs("\tmetric: ", mctx->fp);
}
static void perf_sample__fprint_metric(struct perf_script *script,
struct thread *thread,
struct script_find_metrics_args {
struct evlist *evlist;
bool system_wide;
};
static struct evsel *map_metric_evsel_to_script_evsel(struct evlist *script_evlist,
struct evsel *metric_evsel)
{
struct evsel *script_evsel;
evlist__for_each_entry(script_evlist, script_evsel) {
/* Skip if perf_event_attr differ. */
if (metric_evsel->core.attr.type != script_evsel->core.attr.type)
continue;
if (metric_evsel->core.attr.config != script_evsel->core.attr.config)
continue;
/* Skip if the script event has a metric_id that doesn't match. */
if (script_evsel->metric_id &&
strcmp(evsel__metric_id(metric_evsel), evsel__metric_id(script_evsel))) {
pr_debug("Skipping matching evsel due to differing metric ids '%s' vs '%s'\n",
evsel__metric_id(metric_evsel), evsel__metric_id(script_evsel));
continue;
}
return script_evsel;
}
return NULL;
}
static int script_find_metrics(const struct pmu_metric *pm,
const struct pmu_metrics_table *table __maybe_unused,
void *data)
{
struct script_find_metrics_args *args = data;
struct evlist *script_evlist = args->evlist;
struct evlist *metric_evlist = evlist__new();
struct evsel *metric_evsel;
int ret = metricgroup__parse_groups(metric_evlist,
/*pmu=*/"all",
pm->metric_name,
/*metric_no_group=*/false,
/*metric_no_merge=*/false,
/*metric_no_threshold=*/true,
/*user_requested_cpu_list=*/NULL,
args->system_wide,
/*hardware_aware_grouping=*/false);
if (ret) {
/* Metric parsing failed but continue the search. */
goto out;
}
/*
* Check the script_evlist has an entry for each metric_evlist entry. If
* the script evsel was already set up avoid changing data that may
* break it.
*/
evlist__for_each_entry(metric_evlist, metric_evsel) {
struct evsel *script_evsel =
map_metric_evsel_to_script_evsel(script_evlist, metric_evsel);
struct evsel *new_metric_leader;
if (!script_evsel) {
pr_debug("Skipping metric '%s' as evsel '%s' / '%s' is missing\n",
pm->metric_name, evsel__name(metric_evsel),
evsel__metric_id(metric_evsel));
goto out;
}
if (script_evsel->metric_leader == NULL)
continue;
if (metric_evsel->metric_leader == metric_evsel) {
new_metric_leader = script_evsel;
} else {
new_metric_leader =
map_metric_evsel_to_script_evsel(script_evlist,
metric_evsel->metric_leader);
}
/* Mismatching evsel leaders. */
if (script_evsel->metric_leader != new_metric_leader) {
pr_debug("Skipping metric '%s' due to mismatching evsel metric leaders '%s' vs '%s'\n",
pm->metric_name, evsel__metric_id(metric_evsel),
evsel__metric_id(script_evsel));
goto out;
}
}
/*
* Metric events match those in the script evlist, copy metric evsel
* data into the script evlist.
*/
evlist__for_each_entry(metric_evlist, metric_evsel) {
struct evsel *script_evsel =
map_metric_evsel_to_script_evsel(script_evlist, metric_evsel);
struct metric_event *metric_me = metricgroup__lookup(&metric_evlist->metric_events,
metric_evsel,
/*create=*/false);
if (script_evsel->metric_id == NULL) {
script_evsel->metric_id = metric_evsel->metric_id;
metric_evsel->metric_id = NULL;
}
if (script_evsel->metric_leader == NULL) {
if (metric_evsel->metric_leader == metric_evsel) {
script_evsel->metric_leader = script_evsel;
} else {
script_evsel->metric_leader =
map_metric_evsel_to_script_evsel(script_evlist,
metric_evsel->metric_leader);
}
}
if (metric_me) {
struct metric_expr *expr;
struct metric_event *script_me =
metricgroup__lookup(&script_evlist->metric_events,
script_evsel,
/*create=*/true);
if (!script_me) {
/*
* As the metric_expr is created, the only
* failure is a lack of memory.
*/
goto out;
}
list_splice_init(&metric_me->head, &script_me->head);
list_for_each_entry(expr, &script_me->head, nd) {
for (int i = 0; expr->metric_events[i]; i++) {
expr->metric_events[i] =
map_metric_evsel_to_script_evsel(script_evlist,
expr->metric_events[i]);
}
}
}
}
pr_debug("Found metric '%s' whose evsels match those of in the perf data\n",
pm->metric_name);
evlist__delete(metric_evlist);
out:
return 0;
}
static struct aggr_cpu_id script_aggr_cpu_id_get(struct perf_stat_config *config __maybe_unused,
struct perf_cpu cpu)
{
return aggr_cpu_id__global(cpu, /*data=*/NULL);
}
static void perf_sample__fprint_metric(struct thread *thread,
struct evsel *evsel,
struct perf_sample *sample,
FILE *fp)
{
struct evsel *leader = evsel__leader(evsel);
static bool init_metrics;
struct perf_stat_output_ctx ctx = {
.print_metric = script_print_metric,
.new_line = script_new_line,
@@ -2150,23 +2291,84 @@ static void perf_sample__fprint_metric(struct perf_script *script,
},
.force_header = false,
};
struct evsel *ev2;
u64 val;
struct perf_counts_values *count, *old_count;
int cpu_map_idx, thread_map_idx, aggr_idx;
struct evsel *pos;
if (!evsel->stats)
evlist__alloc_stats(&stat_config, script->session->evlist, /*alloc_raw=*/false);
if (evsel_script(leader)->gnum++ == 0)
perf_stat__reset_shadow_stats();
val = sample->period * evsel->scale;
evsel_script(evsel)->val = val;
if (evsel_script(leader)->gnum == leader->core.nr_members) {
for_each_group_member (ev2, leader) {
perf_stat__print_shadow_stats(&stat_config, ev2,
evsel_script(ev2)->val,
sample->cpu,
&ctx);
if (!init_metrics) {
/* One time initialization of stat_config and metric data. */
struct script_find_metrics_args args = {
.evlist = evsel->evlist,
.system_wide = perf_thread_map__pid(evsel->core.threads, /*idx=*/0) == -1,
};
if (!stat_config.output)
stat_config.output = stdout;
if (!stat_config.aggr_map) {
/* TODO: currently only global aggregation is supported. */
assert(stat_config.aggr_mode == AGGR_GLOBAL);
stat_config.aggr_get_id = script_aggr_cpu_id_get;
stat_config.aggr_map =
cpu_aggr_map__new(evsel->evlist->core.user_requested_cpus,
aggr_cpu_id__global, /*data=*/NULL,
/*needs_sort=*/false);
}
metricgroup__for_each_metric(pmu_metrics_table__find(), script_find_metrics, &args);
init_metrics = true;
}
if (!evsel->stats) {
if (evlist__alloc_stats(&stat_config, evsel->evlist, /*alloc_raw=*/true) < 0)
return;
}
if (!evsel->stats->aggr) {
if (evlist__alloc_aggr_stats(evsel->evlist, stat_config.aggr_map->nr) < 0)
return;
}
/* Update the evsel's count using the sample's data. */
cpu_map_idx = perf_cpu_map__idx(evsel->core.cpus, (struct perf_cpu){sample->cpu});
if (cpu_map_idx < 0) {
/* Missing CPU, check for any CPU. */
if (perf_cpu_map__cpu(evsel->core.cpus, /*idx=*/0).cpu == -1 ||
sample->cpu == (u32)-1) {
/* Place the counts in the which ever CPU is first in the map. */
cpu_map_idx = 0;
} else {
pr_info("Missing CPU map entry for CPU %d\n", sample->cpu);
return;
}
}
thread_map_idx = perf_thread_map__idx(evsel->core.threads, sample->tid);
if (thread_map_idx < 0) {
/* Missing thread, check for any thread. */
if (perf_thread_map__pid(evsel->core.threads, /*idx=*/0) == -1 ||
sample->tid == (u32)-1) {
/* Place the counts in the which ever thread is first in the map. */
thread_map_idx = 0;
} else {
pr_info("Missing thread map entry for thread %d\n", sample->tid);
return;
}
}
count = perf_counts(evsel->counts, cpu_map_idx, thread_map_idx);
old_count = perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread_map_idx);
count->val = old_count->val + sample->period;
count->run = old_count->run + 1;
count->ena = old_count->ena + 1;
/* Update the aggregated stats. */
perf_stat_process_counter(&stat_config, evsel);
/* Display all metrics. */
evlist__for_each_entry(evsel->evlist, pos) {
cpu_aggr_map__for_each_idx(aggr_idx, stat_config.aggr_map) {
perf_stat__print_shadow_stats(&stat_config, pos,
aggr_idx,
&ctx);
}
evsel_script(leader)->gnum = 0;
}
}
@@ -2348,7 +2550,7 @@ static void process_event(struct perf_script *script,
}
if (PRINT_FIELD(METRIC))
perf_sample__fprint_metric(script, thread, evsel, sample, fp);
perf_sample__fprint_metric(thread, evsel, sample, fp);
if (verbose > 0)
fflush(fp);
@@ -2729,7 +2931,8 @@ static int process_switch_event(const struct perf_tool *tool,
sample->tid);
}
static int process_auxtrace_error(struct perf_session *session,
static int process_auxtrace_error(const struct perf_tool *tool,
struct perf_session *session,
union perf_event *event)
{
if (scripting_ops && scripting_ops->process_auxtrace_error) {
@@ -2737,7 +2940,7 @@ static int process_auxtrace_error(struct perf_session *session,
return 0;
}
return perf_event__process_auxtrace_error(session, event);
return perf_event__process_auxtrace_error(tool, session, event);
}
static int
@@ -2785,7 +2988,8 @@ process_bpf_events(const struct perf_tool *tool __maybe_unused,
}
static int
process_bpf_metadata_event(struct perf_session *session __maybe_unused,
process_bpf_metadata_event(const struct perf_tool *tool __maybe_unused,
struct perf_session *session __maybe_unused,
union perf_event *event)
{
perf_event__fprintf(event, NULL, stdout);
@@ -3544,7 +3748,8 @@ static void script__setup_sample_type(struct perf_script *script)
}
}
static int process_stat_round_event(struct perf_session *session,
static int process_stat_round_event(const struct perf_tool *tool __maybe_unused,
struct perf_session *session,
union perf_event *event)
{
struct perf_record_stat_round *round = &event->stat_round;
@@ -3559,7 +3764,8 @@ static int process_stat_round_event(struct perf_session *session,
return 0;
}
static int process_stat_config_event(struct perf_session *session __maybe_unused,
static int process_stat_config_event(const struct perf_tool *tool __maybe_unused,
struct perf_session *session __maybe_unused,
union perf_event *event)
{
perf_event__read_stat_config(&stat_config, &event->stat_config);
@@ -3593,10 +3799,10 @@ static int set_maps(struct perf_script *script)
}
static
int process_thread_map_event(struct perf_session *session,
int process_thread_map_event(const struct perf_tool *tool,
struct perf_session *session __maybe_unused,
union perf_event *event)
{
const struct perf_tool *tool = session->tool;
struct perf_script *script = container_of(tool, struct perf_script, tool);
if (dump_trace)
@@ -3615,10 +3821,10 @@ int process_thread_map_event(struct perf_session *session,
}
static
int process_cpu_map_event(struct perf_session *session,
int process_cpu_map_event(const struct perf_tool *tool,
struct perf_session *session __maybe_unused,
union perf_event *event)
{
const struct perf_tool *tool = session->tool;
struct perf_script *script = container_of(tool, struct perf_script, tool);
if (dump_trace)
@@ -3636,7 +3842,8 @@ int process_cpu_map_event(struct perf_session *session,
return set_maps(script);
}
static int process_feature_event(struct perf_session *session,
static int process_feature_event(const struct perf_tool *tool __maybe_unused,
struct perf_session *session,
union perf_event *event)
{
if (event->feat.feat_id < HEADER_LAST_FEATURE)
@@ -3645,13 +3852,13 @@ static int process_feature_event(struct perf_session *session,
}
#ifdef HAVE_AUXTRACE_SUPPORT
static int perf_script__process_auxtrace_info(struct perf_session *session,
static int perf_script__process_auxtrace_info(const struct perf_tool *tool,
struct perf_session *session,
union perf_event *event)
{
int ret = perf_event__process_auxtrace_info(session, event);
int ret = perf_event__process_auxtrace_info(tool, session, event);
if (ret == 0) {
const struct perf_tool *tool = session->tool;
struct perf_script *script = container_of(tool, struct perf_script, tool);
ret = perf_script__setup_per_event_dump(script);
+181 -103
View File
@@ -74,6 +74,7 @@
#include "util/intel-tpebs.h"
#include "asm/bug.h"
#include <linux/list_sort.h>
#include <linux/time64.h>
#include <linux/zalloc.h>
#include <api/fs/fs.h>
@@ -96,9 +97,18 @@
#include <perf/evlist.h>
#include <internal/threadmap.h>
#ifdef HAVE_BPF_SKEL
#include "util/bpf_skel/bperf_cgroup.h"
#endif
#define DEFAULT_SEPARATOR " "
#define FREEZE_ON_SMI_PATH "bus/event_source/devices/cpu/freeze_on_smi"
struct rusage_stats {
struct stats ru_utime_usec_stat;
struct stats ru_stime_usec_stat;
};
static void print_counters(struct timespec *ts, int argc, const char **argv);
static struct evlist *evsel_list;
@@ -128,6 +138,7 @@ static bool interval_count;
static const char *output_name;
static int output_fd;
static char *metrics;
static struct rusage_stats ru_stats;
struct perf_stat {
bool record;
@@ -228,7 +239,7 @@ static inline void diff_timespec(struct timespec *r, struct timespec *a,
static void perf_stat__reset_stats(void)
{
evlist__reset_stats(evsel_list);
perf_stat__reset_shadow_stats();
memset(stat_config.walltime_nsecs_stats, 0, sizeof(*stat_config.walltime_nsecs_stats));
}
static int process_synthesized_event(const struct perf_tool *tool __maybe_unused,
@@ -278,17 +289,27 @@ static int read_single_counter(struct evsel *counter, int cpu_map_idx, int threa
if (err && cpu_map_idx == 0 &&
(evsel__tool_event(counter) == TOOL_PMU__EVENT_USER_TIME ||
evsel__tool_event(counter) == TOOL_PMU__EVENT_SYSTEM_TIME)) {
u64 val, *start_time;
struct perf_counts_values *count =
perf_counts(counter->counts, cpu_map_idx, thread);
struct perf_counts_values *old_count = NULL;
u64 val;
if (counter->prev_raw_counts)
old_count = perf_counts(counter->prev_raw_counts, cpu_map_idx, thread);
start_time = xyarray__entry(counter->start_times, cpu_map_idx, thread);
if (evsel__tool_event(counter) == TOOL_PMU__EVENT_USER_TIME)
val = ru_stats.ru_utime_usec_stat.mean;
else
val = ru_stats.ru_stime_usec_stat.mean;
count->ena = count->run = *start_time + val;
count->val = val;
if (old_count) {
count->run = old_count->run + 1;
count->ena = old_count->ena + 1;
} else {
count->run++;
count->ena++;
}
return 0;
}
return err;
@@ -345,7 +366,7 @@ static int read_counter_cpu(struct evsel *counter, int cpu_map_idx)
return 0;
}
static int read_affinity_counters(void)
static int read_counters_with_affinity(void)
{
struct evlist_cpu_iterator evlist_cpu_itr;
struct affinity saved_affinity, *affinity;
@@ -366,6 +387,9 @@ static int read_affinity_counters(void)
if (evsel__is_bpf(counter))
continue;
if (evsel__is_tool(counter))
continue;
if (!counter->err)
counter->err = read_counter_cpu(counter, evlist_cpu_itr.cpu_map_idx);
}
@@ -391,16 +415,46 @@ static int read_bpf_map_counters(void)
return 0;
}
static int read_counters(void)
static int read_tool_counters(void)
{
if (!stat_config.stop_read_counter) {
if (read_bpf_map_counters() ||
read_affinity_counters())
return -1;
struct evsel *counter;
evlist__for_each_entry(evsel_list, counter) {
int idx;
if (!evsel__is_tool(counter))
continue;
perf_cpu_map__for_each_idx(idx, counter->core.cpus) {
if (!counter->err)
counter->err = read_counter_cpu(counter, idx);
}
}
return 0;
}
static int read_counters(void)
{
int ret;
if (stat_config.stop_read_counter)
return 0;
// Read all BPF counters first.
ret = read_bpf_map_counters();
if (ret)
return ret;
// Read non-BPF and non-tool counters next.
ret = read_counters_with_affinity();
if (ret)
return ret;
// Read the tool counters last. This way the duration_time counter
// should always be greater than any other counter's enabled time.
return read_tool_counters();
}
static void process_counters(void)
{
struct evsel *counter;
@@ -434,8 +488,8 @@ static void process_interval(void)
pr_err("failed to write stat round event\n");
}
init_stats(&walltime_nsecs_stats);
update_stats(&walltime_nsecs_stats, stat_config.interval * 1000000ULL);
init_stats(stat_config.walltime_nsecs_stats);
update_stats(stat_config.walltime_nsecs_stats, stat_config.interval * 1000000ULL);
print_counters(&rs, 0, NULL);
}
@@ -624,8 +678,9 @@ static enum counter_recovery stat_handle_error(struct evsel *counter, int err)
*/
if (err == EINVAL || err == ENOSYS || err == ENOENT || err == ENXIO) {
if (verbose > 0) {
ui__warning("%s event is not supported by the kernel.\n",
evsel__name(counter));
evsel__open_strerror(counter, &target, err, msg, sizeof(msg));
ui__warning("%s event is not supported by the kernel.\n%s\n",
evsel__name(counter), msg);
}
return COUNTER_SKIP;
}
@@ -649,10 +704,11 @@ static enum counter_recovery stat_handle_error(struct evsel *counter, int err)
}
}
if (verbose > 0) {
evsel__open_strerror(counter, &target, err, msg, sizeof(msg));
ui__warning(err == EOPNOTSUPP
? "%s event is not supported by the kernel.\n"
: "skipping event %s that kernel failed to open.\n",
evsel__name(counter));
? "%s event is not supported by the kernel.\n%s\n"
: "skipping event %s that kernel failed to open.\n%s\n",
evsel__name(counter), msg);
}
return COUNTER_SKIP;
}
@@ -713,6 +769,17 @@ static int create_perf_stat_counter(struct evsel *evsel,
evsel->core.threads);
}
static void update_rusage_stats(const struct rusage *rusage)
{
const u64 us_to_ns = 1000;
const u64 s_to_ns = 1000000000;
update_stats(&ru_stats.ru_utime_usec_stat,
(rusage->ru_utime.tv_usec * us_to_ns + rusage->ru_utime.tv_sec * s_to_ns));
update_stats(&ru_stats.ru_stime_usec_stat,
(rusage->ru_stime.tv_usec * us_to_ns + rusage->ru_stime.tv_sec * s_to_ns));
}
static int __run_perf_stat(int argc, const char **argv, int run_idx)
{
int interval = stat_config.interval;
@@ -940,10 +1007,20 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
goto err_out;
}
if (WIFSIGNALED(status))
if (WIFSIGNALED(status)) {
/*
* We want to indicate failure to stop a repeat run,
* hence negative. We want the value to be the exit code
* of perf, which for termination by a signal is 128
* plus the signal number.
*/
err = 0 - (128 + WTERMSIG(status));
psignal(WTERMSIG(status), argv[0]);
} else {
err = WEXITSTATUS(status);
}
} else {
status = dispatch_events(forks, timeout, interval, &times);
err = dispatch_events(forks, timeout, interval, &times);
}
disable_counters();
@@ -956,15 +1033,15 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
if (interval && stat_config.summary) {
stat_config.interval = 0;
stat_config.stop_read_counter = true;
init_stats(&walltime_nsecs_stats);
update_stats(&walltime_nsecs_stats, t1 - t0);
init_stats(stat_config.walltime_nsecs_stats);
update_stats(stat_config.walltime_nsecs_stats, t1 - t0);
evlist__copy_prev_raw_counts(evsel_list);
evlist__reset_prev_raw_counts(evsel_list);
evlist__reset_aggr_stats(evsel_list);
} else {
update_stats(&walltime_nsecs_stats, t1 - t0);
update_rusage_stats(&ru_stats, &stat_config.ru_data);
update_stats(stat_config.walltime_nsecs_stats, t1 - t0);
update_rusage_stats(&stat_config.ru_data);
}
/*
@@ -983,7 +1060,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
if (!STAT_RECORD)
evlist__close(evsel_list);
return WEXITSTATUS(status);
return err;
err_out:
if (forks)
@@ -1853,6 +1930,43 @@ static int perf_stat_init_aggr_mode_file(struct perf_stat *st)
return 0;
}
static int default_evlist_evsel_cmp(void *priv __maybe_unused,
const struct list_head *l,
const struct list_head *r)
{
const struct perf_evsel *lhs_core = container_of(l, struct perf_evsel, node);
const struct evsel *lhs = container_of(lhs_core, struct evsel, core);
const struct perf_evsel *rhs_core = container_of(r, struct perf_evsel, node);
const struct evsel *rhs = container_of(rhs_core, struct evsel, core);
const struct evsel *lhs_leader = evsel__leader(lhs);
const struct evsel *rhs_leader = evsel__leader(rhs);
if (lhs_leader == rhs_leader) {
/* Within the same group, respect the original order. */
return lhs_core->idx - rhs_core->idx;
}
/*
* Compare using leader's attributes so that all members of a group
* stay together. This ensures leaders are opened before their members.
*/
/* Sort default metrics evsels first, and default show events before those. */
if (lhs_leader->default_metricgroup != rhs_leader->default_metricgroup)
return lhs_leader->default_metricgroup ? -1 : 1;
if (lhs_leader->default_show_events != rhs_leader->default_show_events)
return lhs_leader->default_show_events ? -1 : 1;
/* Sort by PMU type (prefers legacy types first). */
if (lhs_leader->pmu != rhs_leader->pmu)
return lhs_leader->pmu->type - rhs_leader->pmu->type;
/* Sort by leader's name. */
return strcmp(evsel__name((struct evsel *)lhs_leader),
evsel__name((struct evsel *)rhs_leader));
}
/*
* Add default events, if there were no attributes specified or
* if -d/--detailed, -d -d or -d -d -d is used:
@@ -1975,48 +2089,39 @@ static int add_default_events(void)
stat_config.topdown_level = 1;
if (!evlist->core.nr_entries && !evsel_list->core.nr_entries) {
/* No events so add defaults. */
if (target__has_cpu(&target))
ret = parse_events(evlist, "cpu-clock", &err);
else
ret = parse_events(evlist, "task-clock", &err);
if (ret)
goto out;
ret = parse_events(evlist,
"context-switches,"
"cpu-migrations,"
"page-faults,"
"instructions,"
"cycles,"
"stalled-cycles-frontend,"
"stalled-cycles-backend,"
"branches,"
"branch-misses",
&err);
if (ret)
goto out;
/*
* Add TopdownL1 metrics if they exist. To minimize
* multiplexing, don't request threshold computation.
* Add Default metrics. To minimize multiplexing, don't request
* threshold computation, but it will be computed if the events
* are present.
*/
if (metricgroup__has_metric_or_groups(pmu, "Default")) {
struct evlist *metric_evlist = evlist__new();
const char *default_metricgroup_names[] = {
"Default", "Default2", "Default3", "Default4",
};
for (size_t i = 0; i < ARRAY_SIZE(default_metricgroup_names); i++) {
struct evlist *metric_evlist;
if (!metricgroup__has_metric_or_groups(pmu, default_metricgroup_names[i]))
continue;
if ((int)i > detailed_run)
break;
metric_evlist = evlist__new();
if (!metric_evlist) {
ret = -ENOMEM;
goto out;
break;
}
if (metricgroup__parse_groups(metric_evlist, pmu, "Default",
if (metricgroup__parse_groups(metric_evlist, pmu, default_metricgroup_names[i],
/*metric_no_group=*/false,
/*metric_no_merge=*/false,
/*metric_no_threshold=*/true,
stat_config.user_requested_cpu_list,
stat_config.system_wide,
stat_config.hardware_aware_grouping) < 0) {
evlist__delete(metric_evlist);
ret = -1;
goto out;
break;
}
evlist__for_each_entry(metric_evlist, evsel)
@@ -2028,44 +2133,8 @@ static int add_default_events(void)
&metric_evlist->metric_events);
evlist__delete(metric_evlist);
}
}
list_sort(/*priv=*/NULL, &evlist->core.entries, default_evlist_evsel_cmp);
/* Detailed events get appended to the event list: */
if (!ret && detailed_run >= 1) {
/*
* Detailed stats (-d), covering the L1 and last level data
* caches:
*/
ret = parse_events(evlist,
"L1-dcache-loads,"
"L1-dcache-load-misses,"
"LLC-loads,"
"LLC-load-misses",
&err);
}
if (!ret && detailed_run >= 2) {
/*
* Very detailed stats (-d -d), covering the instruction cache
* and the TLB caches:
*/
ret = parse_events(evlist,
"L1-icache-loads,"
"L1-icache-load-misses,"
"dTLB-loads,"
"dTLB-load-misses,"
"iTLB-loads,"
"iTLB-load-misses",
&err);
}
if (!ret && detailed_run >= 3) {
/*
* Very, very detailed stats (-d -d -d), adding prefetch events:
*/
ret = parse_events(evlist,
"L1-dcache-prefetches,"
"L1-dcache-prefetch-misses",
&err);
}
out:
if (!ret) {
@@ -2074,7 +2143,7 @@ out:
* Make at least one event non-skippable so fatal errors are visible.
* 'cycles' always used to be default and non-skippable, so use that.
*/
if (strcmp("cycles", evsel__name(evsel)))
if (!evsel__match(evsel, HARDWARE, HW_CPU_CYCLES))
evsel->skippable = true;
}
}
@@ -2138,7 +2207,8 @@ static int __cmd_record(const struct option stat_options[], struct opt_aggr_mode
return argc;
}
static int process_stat_round_event(struct perf_session *session,
static int process_stat_round_event(const struct perf_tool *tool __maybe_unused,
struct perf_session *session,
union perf_event *event)
{
struct perf_record_stat_round *stat_round = &event->stat_round;
@@ -2150,7 +2220,7 @@ static int process_stat_round_event(struct perf_session *session,
process_counters();
if (stat_round->type == PERF_STAT_ROUND_TYPE__FINAL)
update_stats(&walltime_nsecs_stats, stat_round->time);
update_stats(stat_config.walltime_nsecs_stats, stat_round->time);
if (stat_config.interval && stat_round->time) {
tsh.tv_sec = stat_round->time / NSEC_PER_SEC;
@@ -2163,10 +2233,10 @@ static int process_stat_round_event(struct perf_session *session,
}
static
int process_stat_config_event(struct perf_session *session,
int process_stat_config_event(const struct perf_tool *tool,
struct perf_session *session,
union perf_event *event)
{
const struct perf_tool *tool = session->tool;
struct perf_stat *st = container_of(tool, struct perf_stat, tool);
perf_event__read_stat_config(&stat_config, &event->stat_config);
@@ -2212,10 +2282,10 @@ static int set_maps(struct perf_stat *st)
}
static
int process_thread_map_event(struct perf_session *session,
int process_thread_map_event(const struct perf_tool *tool,
struct perf_session *session __maybe_unused,
union perf_event *event)
{
const struct perf_tool *tool = session->tool;
struct perf_stat *st = container_of(tool, struct perf_stat, tool);
if (st->threads) {
@@ -2231,10 +2301,10 @@ int process_thread_map_event(struct perf_session *session,
}
static
int process_cpu_map_event(struct perf_session *session,
int process_cpu_map_event(const struct perf_tool *tool,
struct perf_session *session __maybe_unused,
union perf_event *event)
{
const struct perf_tool *tool = session->tool;
struct perf_stat *st = container_of(tool, struct perf_stat, tool);
struct perf_cpu_map *cpus;
@@ -2797,7 +2867,14 @@ int cmd_stat(int argc, const char **argv)
goto out;
}
}
#ifdef HAVE_BPF_SKEL
if (target.use_bpf && nr_cgroups &&
(evsel_list->core.nr_entries / nr_cgroups) > BPERF_CGROUP__MAX_EVENTS) {
pr_warning("Disabling BPF counters due to more events (%d) than the max (%d)\n",
evsel_list->core.nr_entries / nr_cgroups, BPERF_CGROUP__MAX_EVENTS);
target.use_bpf = false;
}
#endif // HAVE_BPF_SKEL
evlist__warn_user_requested_cpus(evsel_list, target.cpu_list);
evlist__for_each_entry(evsel_list, counter) {
@@ -2910,7 +2987,7 @@ int cmd_stat(int argc, const char **argv)
evlist__reset_prev_raw_counts(evsel_list);
status = run_perf_stat(argc, argv, run_idx);
if (status == -1)
if (status < 0)
break;
if (forever && !interval) {
@@ -2951,7 +3028,7 @@ int cmd_stat(int argc, const char **argv)
}
if (!interval) {
if (WRITE_STAT_ROUND_EVENT(walltime_nsecs_stats.max, FINAL))
if (WRITE_STAT_ROUND_EVENT(stat_config.walltime_nsecs_stats->max, FINAL))
pr_err("failed to write stat round event\n");
}
@@ -2980,5 +3057,6 @@ out:
evlist__close_control(stat_config.ctl_fd, stat_config.ctl_fd_ack, &stat_config.ctl_fd_close);
return status;
/* Only the low byte of status becomes the exit code. */
return abs(status);
}
+9 -6
View File
@@ -1651,7 +1651,7 @@ out_delete:
return ret;
}
static int timechart__io_record(int argc, const char **argv)
static int timechart__io_record(int argc, const char **argv, const char *output_data)
{
unsigned int rec_argc, i;
const char **rec_argv;
@@ -1659,7 +1659,7 @@ static int timechart__io_record(int argc, const char **argv)
char *filter = NULL;
const char * const common_args[] = {
"record", "-a", "-R", "-c", "1",
"record", "-a", "-R", "-c", "1", "-o", output_data,
};
unsigned int common_args_nr = ARRAY_SIZE(common_args);
@@ -1786,7 +1786,8 @@ static int timechart__io_record(int argc, const char **argv)
}
static int timechart__record(struct timechart *tchart, int argc, const char **argv)
static int timechart__record(struct timechart *tchart, int argc, const char **argv,
const char *output_data)
{
unsigned int rec_argc, i, j;
const char **rec_argv;
@@ -1794,7 +1795,7 @@ static int timechart__record(struct timechart *tchart, int argc, const char **ar
unsigned int record_elems;
const char * const common_args[] = {
"record", "-a", "-R", "-c", "1",
"record", "-a", "-R", "-c", "1", "-o", output_data,
};
unsigned int common_args_nr = ARRAY_SIZE(common_args);
@@ -1934,6 +1935,7 @@ int cmd_timechart(int argc, const char **argv)
.merge_dist = 1000,
};
const char *output_name = "output.svg";
const char *output_record_data = "perf.data";
const struct option timechart_common_options[] = {
OPT_BOOLEAN('P', "power-only", &tchart.power_only, "output power data only"),
OPT_BOOLEAN('T', "tasks-only", &tchart.tasks_only, "output processes data only"),
@@ -1976,6 +1978,7 @@ int cmd_timechart(int argc, const char **argv)
OPT_BOOLEAN('I', "io-only", &tchart.io_only,
"record only IO data"),
OPT_BOOLEAN('g', "callchain", &tchart.with_backtrace, "record callchain"),
OPT_STRING('o', "output", &output_record_data, "file", "output data file name"),
OPT_PARENT(timechart_common_options),
};
const char * const timechart_record_usage[] = {
@@ -2024,9 +2027,9 @@ int cmd_timechart(int argc, const char **argv)
}
if (tchart.io_only)
ret = timechart__io_record(argc, argv);
ret = timechart__io_record(argc, argv, output_record_data);
else
ret = timechart__record(&tchart, argc, argv);
ret = timechart__record(&tchart, argc, argv, output_record_data);
goto out;
} else if (argc)
usage_with_options(timechart_usage, timechart_options);
+5 -3
View File
@@ -1695,11 +1695,13 @@ int cmd_top(int argc, const char **argv)
goto out_delete_evlist;
if (!top.evlist->core.nr_entries) {
bool can_profile_kernel = perf_event_paranoid_check(1);
int err = parse_event(top.evlist, can_profile_kernel ? "cycles:P" : "cycles:Pu");
struct evlist *def_evlist = evlist__new_default();
if (err)
if (!def_evlist)
goto out_delete_evlist;
evlist__splice_list_tail(top.evlist, &def_evlist->core.entries);
evlist__delete(def_evlist);
}
status = evswitch__init(&top.evswitch, top.evlist, stderr);
+24 -1
View File
@@ -2005,7 +2005,9 @@ static int trace__symbols_init(struct trace *trace, int argc, const char **argv,
err = __machine__synthesize_threads(trace->host, &trace->tool, &trace->opts.target,
evlist->core.threads, trace__tool_process,
true, false, 1);
/*needs_mmap=*/callchain_param.enabled,
/*mmap_data=*/false,
/*nr_threads_synthesize=*/1);
out:
if (err) {
perf_env__exit(&trace->host_env);
@@ -2067,6 +2069,15 @@ static const struct syscall_arg_fmt *syscall_arg_fmt__find_by_name(const char *n
return __syscall_arg_fmt__find_by_name(syscall_arg_fmts__by_name, nmemb, name);
}
/*
* v6.19 kernel added new fields to read userspace memory for event tracing.
* But it's not used by perf and confuses the syscall parameters.
*/
static bool is_internal_field(struct tep_format_field *field)
{
return !strcmp(field->type, "__data_loc char[]");
}
static struct tep_format_field *
syscall_arg_fmt__init_array(struct syscall_arg_fmt *arg, struct tep_format_field *field,
bool *use_btf)
@@ -2075,6 +2086,10 @@ syscall_arg_fmt__init_array(struct syscall_arg_fmt *arg, struct tep_format_field
int len;
for (; field; field = field->next, ++arg) {
/* assume it's the last argument */
if (is_internal_field(field))
continue;
last_field = field;
if (arg->scnprintf)
@@ -2143,6 +2158,7 @@ static int syscall__read_info(struct syscall *sc, struct trace *trace)
{
char tp_name[128];
const char *name;
struct tep_format_field *field;
int err;
if (sc->nonexistent)
@@ -2199,6 +2215,13 @@ static int syscall__read_info(struct syscall *sc, struct trace *trace)
--sc->nr_args;
}
field = sc->args;
while (field) {
if (is_internal_field(field))
--sc->nr_args;
field = field->next;
}
sc->is_exit = !strcmp(name, "exit_group") || !strcmp(name, "exit");
sc->is_open = !strcmp(name, "open") || !strcmp(name, "openat");
+28 -7
View File
@@ -1,7 +1,6 @@
pmu-events-y += pmu-events.o
JDIR = pmu-events/arch/$(SRCARCH)
JSON = $(shell [ -d $(JDIR) ] && \
find $(JDIR) -name '*.json' -o -name 'mapfile.csv')
JSON = $(shell find pmu-events/arch -name '*.json' -o -name '*.csv')
JSON_DIRS = $(shell find pmu-events/arch -type d)
JDIR_TEST = pmu-events/arch/test
JSON_TEST = $(shell [ -d $(JDIR_TEST) ] && \
find $(JDIR_TEST) -name '*.json')
@@ -13,6 +12,8 @@ PMU_EVENTS_C = $(OUTPUT)pmu-events/pmu-events.c
METRIC_TEST_LOG = $(OUTPUT)pmu-events/metric_test.log
TEST_EMPTY_PMU_EVENTS_C = $(OUTPUT)pmu-events/test-empty-pmu-events.c
EMPTY_PMU_EVENTS_TEST_LOG = $(OUTPUT)pmu-events/empty-pmu-events.log
LEGACY_CACHE_PY = pmu-events/make_legacy_cache.py
LEGACY_CACHE_JSON = $(OUTPUT)pmu-events/arch/common/common/legacy-cache.json
ifeq ($(JEVENTS_ARCH),)
JEVENTS_ARCH=$(SRCARCH)
@@ -29,13 +30,33 @@ $(PMU_EVENTS_C): $(EMPTY_PMU_EVENTS_C)
$(call rule_mkdir)
$(Q)$(call echo-cmd,gen)cp $< $@
else
# Copy checked-in json to OUTPUT for generation if it's an out of source build
ifneq ($(OUTPUT),)
# Remove all output directories when any source directory timestamp changes
# so there are no stale deleted files
JSON_DIRS_ROOT = $(OUTPUT)pmu-events/arch/
$(JSON_DIRS_ROOT): $(JSON_DIRS)
$(Q)$(call echo-cmd,gen)rm -rf $@
$(Q)mkdir -p $@
$(OUTPUT)pmu-events/arch/%: pmu-events/arch/% $(JSON_DIRS_ROOT)
$(call rule_mkdir)
$(Q)$(call echo-cmd,gen)cp $< $@
endif
$(LEGACY_CACHE_JSON): $(LEGACY_CACHE_PY) $(JSON_DIRS_ROOT)
$(call rule_mkdir)
$(Q)$(call echo-cmd,gen)$(PYTHON) $(LEGACY_CACHE_PY) > $@
GEN_JSON = $(patsubst %,$(OUTPUT)%,$(JSON)) $(LEGACY_CACHE_JSON) $(JSON_DIRS)
$(METRIC_TEST_LOG): $(METRIC_TEST_PY) $(METRIC_PY)
$(call rule_mkdir)
$(Q)$(call echo-cmd,test)$(PYTHON) $< 2> $@ || (cat $@ && false)
$(TEST_EMPTY_PMU_EVENTS_C): $(JSON) $(JSON_TEST) $(JEVENTS_PY) $(METRIC_PY) $(METRIC_TEST_LOG)
$(TEST_EMPTY_PMU_EVENTS_C): $(GEN_JSON) $(JSON_TEST) $(JEVENTS_PY) $(METRIC_PY) $(METRIC_TEST_LOG)
$(call rule_mkdir)
$(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) none none pmu-events/arch $@
$(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) none none $(OUTPUT)pmu-events/arch $@
$(EMPTY_PMU_EVENTS_TEST_LOG): $(EMPTY_PMU_EVENTS_C) $(TEST_EMPTY_PMU_EVENTS_C)
$(call rule_mkdir)
@@ -63,10 +84,10 @@ $(OUTPUT)%.pylint_log: %
$(call rule_mkdir)
$(Q)$(call echo-cmd,test)pylint "$<" > $@ || (cat $@ && rm $@ && false)
$(PMU_EVENTS_C): $(JSON) $(JSON_TEST) $(JEVENTS_PY) $(METRIC_PY) $(METRIC_TEST_LOG) \
$(PMU_EVENTS_C): $(GEN_JSON) $(JSON_TEST) $(JEVENTS_PY) $(METRIC_PY) $(METRIC_TEST_LOG) \
$(EMPTY_PMU_EVENTS_TEST_LOG) $(PMU_EVENTS_MYPY_TEST_LOGS) $(PMU_EVENTS_PYLINT_TEST_LOGS)
$(call rule_mkdir)
$(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(JEVENTS_ARCH) $(JEVENTS_MODEL) pmu-events/arch $@
$(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(JEVENTS_ARCH) $(JEVENTS_MODEL) $(OUTPUT)pmu-events/arch $@
endif
# pmu-events.c file is generated in the OUTPUT directory so it needs a
@@ -0,0 +1,9 @@
[
{
"BriefDescription": "ddr cycles event",
"EventCode": "0x00",
"EventName": "imx94_ddr.cycles",
"Unit": "imx9_ddr",
"Compat": "imx94"
}
]
@@ -0,0 +1,450 @@
[
{
"BriefDescription": "bandwidth usage for lpddr5 evk board",
"MetricName": "imx94_bandwidth_usage.lpddr5",
"MetricExpr": "(( imx9_ddr0@eddrtq_pm_rd_beat_filt0\\,axi_mask\\=0x000\\,axi_id\\=0x000@ + imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x000\\,axi_id\\=0x000@ ) * 32 / duration_time) / (4266 * 1000000 * 4)",
"ScaleUnit": "1e2%",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bandwidth usage for lpddr4 evk board",
"MetricName": "imx94_bandwidth_usage.lpddr4",
"MetricExpr": "(( imx9_ddr0@eddrtq_pm_rd_beat_filt0\\,axi_mask\\=0x000\\,axi_id\\=0x000@ + imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x000\\,axi_id\\=0x000@ ) * 32 / duration_time) / (4266 * 1000000 * 4)",
"ScaleUnit": "1e2%",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of all masters read from ddr",
"MetricName": "imx94_ddr_read.all",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt0\\,axi_mask\\=0x000\\,axi_id\\=0x000@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of all masters write to ddr",
"MetricName": "imx94_ddr_write.all",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x000\\,axi_id\\=0x000@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of all a55 read from ddr",
"MetricName": "imx94_ddr_read.a55_all",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt1\\,axi_mask\\=0x3fc\\,axi_id\\=0x000@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of all a55 write from ddr",
"MetricName": "imx94_ddr_write.a55_all",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x3fc\\,axi_id\\=0x000@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of a55 core 0 read from ddr",
"MetricName": "imx94_ddr_read.a55_0",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt2\\,axi_mask\\=0x3ff\\,axi_id\\=0x000@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of a55 core 0 write to ddr",
"MetricName": "imx94_ddr_write.a55_0",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x3ff\\,axi_id\\=0x000@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of a55 core 1 read from ddr",
"MetricName": "imx94_ddr_read.a55_1",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt0\\,axi_mask\\=0x00f\\,axi_id\\=0x001@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of a55 core 1 write to ddr",
"MetricName": "imx94_ddr_write.a55_1",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x00f\\,axi_id\\=0x001@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of a55 core 2 read from ddr",
"MetricName": "imx94_ddr_read.a55_2",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt1\\,axi_mask\\=0x00f\\,axi_id\\=0x002@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of a55 core 2 write to ddr",
"MetricName": "imx94_ddr_write.a55_2",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x00f\\,axi_id\\=0x002@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of a55 core 3 read from ddr",
"MetricName": "imx94_ddr_read.a55_3",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt2\\,axi_mask\\=0x00f\\,axi_id\\=0x003@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of a55 core 3 write to ddr",
"MetricName": "imx94_ddr_write.a55_3",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x00f\\,axi_id\\=0x003@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of m7 core1 read from ddr",
"MetricName": "imx94_ddr_read.m7_1",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt0\\,axi_mask\\=0x00f\\,axi_id\\=0x004@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of m7 core1 write to ddr",
"MetricName": "imx94_ddr_write.m7_1",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x00f\\,axi_id\\=0x004@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of m33 core1 (in netc) read from ddr",
"MetricName": "imx94_ddr_read.m33_1",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt1\\,axi_mask\\=0x00f\\,axi_id\\=0x005@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of m33 core1 (in netc) write to ddr",
"MetricName": "imx94_ddr_write.m33_1",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x00f\\,axi_id\\=0x005@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of pcie2 read from ddr",
"MetricName": "imx94_ddr_read.pcie2",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt2\\,axi_mask\\=0x00f\\,axi_id\\=0x006@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of pcie2 write to ddr",
"MetricName": "imx94_ddr_write.pcie2",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x00f\\,axi_id\\=0x006@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of Cortex-A DSU L3 evicted/ACP transactions read from ddr",
"MetricName": "imx94_ddr_read.cortex_a_dsu",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt0\\,axi_mask\\=0x00f\\,axi_id\\=0x007@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of Cortex-A DSU L3 evicted/ACP transactions write to ddr",
"MetricName": "imx94_ddr_write.cortex_a_dsu",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x00f\\,axi_id\\=0x007@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of m33 core0 read from ddr",
"MetricName": "imx94_ddr_read.m33_0",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt1\\,axi_mask\\=0x00f\\,axi_id\\=0x008@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of m33 core0 write to ddr",
"MetricName": "imx94_ddr_write.m33_0",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x00f\\,axi_id\\=0x008@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of m7 core0 read from ddr",
"MetricName": "imx94_ddr_read.m7_0",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt2\\,axi_mask\\=0x00f\\,axi_id\\=0x009@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of m7 core0 write to ddr",
"MetricName": "imx94_ddr_write.m7_0",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x00f\\,axi_id\\=0x009@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of sentinel read from ddr",
"MetricName": "imx94_ddr_read.sentinel",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt0\\,axi_mask\\=0x00f\\,axi_id\\=0x00a@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of sentinel write to ddr",
"MetricName": "imx94_ddr_write.sentinel",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x00f\\,axi_id\\=0x00a@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of edma1 read from ddr",
"MetricName": "imx94_ddr_read.edma1",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt1\\,axi_mask\\=0x00f\\,axi_id\\=0x00b@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of edma1 write to ddr",
"MetricName": "imx94_ddr_write.edma1",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x00f\\,axi_id\\=0x00b@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of edma2 read from ddr",
"MetricName": "imx94_ddr_read.edma2",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt2\\,axi_mask\\=0x00f\\,axi_id\\=0x00c@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of edma2 write to ddr",
"MetricName": "imx94_ddr_write.edma2",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x00f\\,axi_id\\=0x00c@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of netc read from ddr",
"MetricName": "imx94_ddr_read.netc",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt0\\,axi_mask\\=0x00f\\,axi_id\\=0x00d@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of netc write to ddr",
"MetricName": "imx94_ddr_write.netc",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x00f\\,axi_id\\=0x00d@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of aonmix read from ddr",
"MetricName": "imx94_ddr_read.aonmix",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt2\\,axi_mask\\=0x00f\\,axi_id\\=0x00f@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of aonmix write to ddr",
"MetricName": "imx94_ddr_write.aonmix",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x00f\\,axi_id\\=0x00f@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of npumix read from ddr",
"MetricName": "imx94_ddr_read.npumix",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt0\\,axi_mask\\=0x3f0\\,axi_id\\=0x010@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of npumix write to ddr",
"MetricName": "imx94_ddr_write.npumix",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x3f0\\,axi_id\\=0x010@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of usdhc1 read from ddr",
"MetricName": "imx94_ddr_read.usdhc1",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt1\\,axi_mask\\=0x3f0\\,axi_id\\=0x0b0@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of usdhc1 write to ddr",
"MetricName": "imx94_ddr_write.usdhc1",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x3f0\\,axi_id\\=0x0b0@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of usdhc2 read from ddr",
"MetricName": "imx94_ddr_read.usdhc2",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt2\\,axi_mask\\=0x3f0\\,axi_id\\=0x0c0@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of usdhc2 write to ddr",
"MetricName": "imx94_ddr_write.usdhc2",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x3f0\\,axi_id\\=0x0c0@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of usdhc3 read from ddr",
"MetricName": "imx94_ddr_read.usdhc3",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt0\\,axi_mask\\=0x3f0\\,axi_id\\=0x0d0@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of usdhc3 write to ddr",
"MetricName": "imx94_ddr_write.usdhc3",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x3f0\\,axi_id\\=0x0d0@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of xspi read from ddr",
"MetricName": "imx94_ddr_read.xspi",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt2\\,axi_mask\\=0x3f0\\,axi_id\\=0x0f0@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of xspi write to ddr",
"MetricName": "imx94_ddr_write.xspi",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x3f0\\,axi_id\\=0x0f0@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of pcie1 read from ddr",
"MetricName": "imx94_ddr_read.pcie1",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt0\\,axi_mask\\=0x3f0\\,axi_id\\=0x100@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of pcie1 write to ddr",
"MetricName": "imx94_ddr_write.pcie1",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x3f0\\,axi_id\\=0x100@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of usb1 read from ddr",
"MetricName": "imx94_ddr_read.usb1",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt1\\,axi_mask\\=0x3f0\\,axi_id\\=0x140@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of usb1 write to ddr",
"MetricName": "imx94_ddr_write.usb1",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x3f0\\,axi_id\\=0x140@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of usb2 read from ddr",
"MetricName": "imx94_ddr_read.usb2",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt2\\,axi_mask\\=0x3f0\\,axi_id\\=0x150@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of usb2 write to ddr",
"MetricName": "imx94_ddr_write.usb2",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x3f0\\,axi_id\\=0x150@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of pxp read from ddr",
"MetricName": "imx94_ddr_read.pxp",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt0\\,axi_mask\\=0x3f0\\,axi_id\\=0x2a0@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of pxp write to ddr",
"MetricName": "imx94_ddr_write.pxp",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x3f0\\,axi_id\\=0x2a0@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of dcif read from ddr",
"MetricName": "imx94_ddr_read.dcif",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_rd_beat_filt1\\,axi_mask\\=0x3f0\\,axi_id\\=0x2b0@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
},
{
"BriefDescription": "bytes of dcif write to ddr",
"MetricName": "imx94_ddr_write.dcif",
"MetricExpr": "( imx9_ddr0@eddrtq_pm_wr_beat_filt\\,axi_mask\\=0x3f0\\,axi_id\\=0x2b0@ ) * 32",
"ScaleUnit": "9.765625e-4KB",
"Unit": "imx9_ddr",
"Compat": "imx94"
}
]
@@ -0,0 +1,72 @@
[
{
"EventName": "cpu-cycles",
"BriefDescription": "Total cycles. Be wary of what happens during CPU frequency scaling [This event is an alias of cycles].",
"LegacyConfigCode": "0"
},
{
"EventName": "cycles",
"BriefDescription": "Total cycles. Be wary of what happens during CPU frequency scaling [This event is an alias of cpu-cycles].",
"LegacyConfigCode": "0"
},
{
"EventName": "instructions",
"BriefDescription": "Retired instructions. Be careful, these can be affected by various issues, most notably hardware interrupt counts.",
"LegacyConfigCode": "1"
},
{
"EventName": "cache-references",
"BriefDescription": "Cache accesses. Usually this indicates Last Level Cache accesses but this may vary depending on your CPU. This may include prefetches and coherency messages; again this depends on the design of your CPU.",
"LegacyConfigCode": "2"
},
{
"EventName": "cache-misses",
"BriefDescription": "Cache misses. Usually this indicates Last Level Cache misses; this is intended to be used in conjunction with the PERF_COUNT_HW_CACHE_REFERENCES event to calculate cache miss rates.",
"LegacyConfigCode": "3"
},
{
"EventName": "branches",
"BriefDescription": "Retired branch instructions [This event is an alias of branch-instructions].",
"LegacyConfigCode": "4"
},
{
"EventName": "branch-instructions",
"BriefDescription": "Retired branch instructions [This event is an alias of branches].",
"LegacyConfigCode": "4"
},
{
"EventName": "branch-misses",
"BriefDescription": "Mispredicted branch instructions.",
"LegacyConfigCode": "5"
},
{
"EventName": "bus-cycles",
"BriefDescription": "Bus cycles, which can be different from total cycles.",
"LegacyConfigCode": "6"
},
{
"EventName": "stalled-cycles-frontend",
"BriefDescription": "Stalled cycles during issue [This event is an alias of idle-cycles-frontend].",
"LegacyConfigCode": "7"
},
{
"EventName": "idle-cycles-frontend",
"BriefDescription": "Stalled cycles during issue [This event is an alias of stalled-cycles-fronted].",
"LegacyConfigCode": "7"
},
{
"EventName": "stalled-cycles-backend",
"BriefDescription": "Stalled cycles during retirement [This event is an alias of idle-cycles-backend].",
"LegacyConfigCode": "8"
},
{
"EventName": "idle-cycles-backend",
"BriefDescription": "Stalled cycles during retirement [This event is an alias of stalled-cycles-backend].",
"LegacyConfigCode": "8"
},
{
"EventName": "ref-cycles",
"BriefDescription": "Total cycles; not affected by CPU frequency scaling.",
"LegacyConfigCode": "9"
}
]
@@ -0,0 +1,151 @@
[
{
"BriefDescription": "Average CPU utilization",
"MetricExpr": "(software@cpu\\-clock\\,name\\=cpu\\-clock@ if #target_cpu else software@task\\-clock\\,name\\=task\\-clock@) / (duration_time * 1e9)",
"MetricGroup": "Default",
"MetricName": "CPUs_utilized",
"ScaleUnit": "1CPUs",
"MetricConstraint": "NO_GROUP_EVENTS",
"DefaultShowEvents": "1"
},
{
"BriefDescription": "Context switches per CPU second",
"MetricExpr": "(software@context\\-switches\\,name\\=context\\-switches@ * 1e9) / (software@cpu\\-clock\\,name\\=cpu\\-clock@ if #target_cpu else software@task\\-clock\\,name\\=task\\-clock@)",
"MetricGroup": "Default",
"MetricName": "cs_per_second",
"ScaleUnit": "1cs/sec",
"MetricConstraint": "NO_GROUP_EVENTS",
"DefaultShowEvents": "1"
},
{
"BriefDescription": "Process migrations to a new CPU per CPU second",
"MetricExpr": "(software@cpu\\-migrations\\,name\\=cpu\\-migrations@ * 1e9) / (software@cpu\\-clock\\,name\\=cpu\\-clock@ if #target_cpu else software@task\\-clock\\,name\\=task\\-clock@)",
"MetricGroup": "Default",
"MetricName": "migrations_per_second",
"ScaleUnit": "1migrations/sec",
"MetricConstraint": "NO_GROUP_EVENTS",
"DefaultShowEvents": "1"
},
{
"BriefDescription": "Page faults per CPU second",
"MetricExpr": "(software@page\\-faults\\,name\\=page\\-faults@ * 1e9) / (software@cpu\\-clock\\,name\\=cpu\\-clock@ if #target_cpu else software@task\\-clock\\,name\\=task\\-clock@)",
"MetricGroup": "Default",
"MetricName": "page_faults_per_second",
"ScaleUnit": "1faults/sec",
"MetricConstraint": "NO_GROUP_EVENTS",
"DefaultShowEvents": "1"
},
{
"BriefDescription": "Instructions Per Cycle",
"MetricExpr": "instructions / cpu\\-cycles",
"MetricGroup": "Default",
"MetricName": "insn_per_cycle",
"MetricThreshold": "insn_per_cycle < 1",
"ScaleUnit": "1instructions",
"DefaultShowEvents": "1"
},
{
"BriefDescription": "Max front or backend stalls per instruction",
"MetricExpr": "(max(stalled\\-cycles\\-frontend, stalled\\-cycles\\-backend) / instructions) if (has_event(stalled\\-cycles\\-frontend) & has_event(stalled\\-cycles\\-backend)) else ((stalled\\-cycles\\-frontend / instructions) if has_event(stalled\\-cycles\\-frontend) else ((stalled\\-cycles\\-backend / instructions) if has_event(stalled\\-cycles\\-backend) else 0))",
"MetricGroup": "Default",
"MetricName": "stalled_cycles_per_instruction",
"DefaultShowEvents": "1"
},
{
"BriefDescription": "Frontend stalls per cycle",
"MetricExpr": "(stalled\\-cycles\\-frontend / cpu\\-cycles) if has_event(stalled\\-cycles\\-frontend) else 0",
"MetricGroup": "Default",
"MetricName": "frontend_cycles_idle",
"MetricThreshold": "frontend_cycles_idle > 0.1",
"DefaultShowEvents": "1"
},
{
"BriefDescription": "Backend stalls per cycle",
"MetricExpr": "(stalled\\-cycles\\-backend / cpu\\-cycles) if has_event(stalled\\-cycles\\-backend) else 0",
"MetricGroup": "Default",
"MetricName": "backend_cycles_idle",
"MetricThreshold": "backend_cycles_idle > 0.2",
"DefaultShowEvents": "1"
},
{
"BriefDescription": "Cycles per CPU second",
"MetricExpr": "cpu\\-cycles / (software@cpu\\-clock\\,name\\=cpu\\-clock@ if #target_cpu else software@task\\-clock\\,name\\=task\\-clock@)",
"MetricGroup": "Default",
"MetricName": "cycles_frequency",
"ScaleUnit": "1GHz",
"MetricConstraint": "NO_GROUP_EVENTS",
"DefaultShowEvents": "1"
},
{
"BriefDescription": "Branches per CPU second",
"MetricExpr": "branches / (software@cpu\\-clock\\,name\\=cpu\\-clock@ if #target_cpu else software@task\\-clock\\,name\\=task\\-clock@)",
"MetricGroup": "Default",
"MetricName": "branch_frequency",
"ScaleUnit": "1000M/sec",
"MetricConstraint": "NO_GROUP_EVENTS",
"DefaultShowEvents": "1"
},
{
"BriefDescription": "Branch miss rate",
"MetricExpr": "branch\\-misses / branches",
"MetricGroup": "Default",
"MetricName": "branch_miss_rate",
"MetricThreshold": "branch_miss_rate > 0.05",
"ScaleUnit": "100%",
"DefaultShowEvents": "1"
},
{
"BriefDescription": "L1D miss rate",
"MetricExpr": "L1\\-dcache\\-load\\-misses / L1\\-dcache\\-loads",
"MetricGroup": "Default2",
"MetricName": "l1d_miss_rate",
"MetricThreshold": "l1d_miss_rate > 0.05",
"ScaleUnit": "100%",
"DefaultShowEvents": "1"
},
{
"BriefDescription": "LLC miss rate",
"MetricExpr": "LLC\\-load\\-misses / LLC\\-loads",
"MetricGroup": "Default2",
"MetricName": "llc_miss_rate",
"MetricThreshold": "llc_miss_rate > 0.05",
"ScaleUnit": "100%",
"DefaultShowEvents": "1"
},
{
"BriefDescription": "L1I miss rate",
"MetricExpr": "L1\\-icache\\-load\\-misses / L1\\-icache\\-loads",
"MetricGroup": "Default3",
"MetricName": "l1i_miss_rate",
"MetricThreshold": "l1i_miss_rate > 0.05",
"ScaleUnit": "100%",
"DefaultShowEvents": "1"
},
{
"BriefDescription": "dTLB miss rate",
"MetricExpr": "dTLB\\-load\\-misses / dTLB\\-loads",
"MetricGroup": "Default3",
"MetricName": "dtlb_miss_rate",
"MetricThreshold": "dtlb_miss_rate > 0.05",
"ScaleUnit": "100%",
"DefaultShowEvents": "1"
},
{
"BriefDescription": "iTLB miss rate",
"MetricExpr": "iTLB\\-load\\-misses / iTLB\\-loads",
"MetricGroup": "Default3",
"MetricName": "itlb_miss_rate",
"MetricThreshold": "itlb_miss_rate > 0.05",
"ScaleUnit": "100%",
"DefaultShowEvents": "1"
},
{
"BriefDescription": "L1 prefetch miss rate",
"MetricExpr": "L1\\-dcache\\-prefetch\\-misses / L1\\-dcache\\-prefetches",
"MetricGroup": "Default4",
"MetricName": "l1_prefetch_miss_rate",
"MetricThreshold": "l1_prefetch_miss_rate > 0.05",
"ScaleUnit": "100%",
"DefaultShowEvents": "1"
}
]
@@ -3,13 +3,15 @@
"Unit": "software",
"EventName": "cpu-clock",
"BriefDescription": "Per-CPU high-resolution timer based event",
"ConfigCode": "0"
"ConfigCode": "0",
"ScaleUnit": "1e-6msec"
},
{
"Unit": "software",
"EventName": "task-clock",
"BriefDescription": "Per-task high-resolution timer based event",
"ConfigCode": "1"
"ConfigCode": "1",
"ScaleUnit": "1e-6msec"
},
{
"Unit": "software",
@@ -70,5 +70,17 @@
"EventName": "system_tsc_freq",
"BriefDescription": "The amount a Time Stamp Counter (TSC) increases per second",
"ConfigCode": "12"
},
{
"Unit": "tool",
"EventName": "core_wide",
"BriefDescription": "1 if not SMT, if SMT are events being gathered on all SMT threads 1 otherwise 0",
"ConfigCode": "13"
},
{
"Unit": "tool",
"EventName": "target_cpu",
"BriefDescription": "1 if CPUs being analyzed, 0 if threads/processes",
"ConfigCode": "14"
}
]
@@ -20,5 +20,6 @@
0x489-0x8000000000000008-0x[[:xdigit:]]+,v1,sifive/p550,core
0x489-0x8000000000000[1-6]08-0x[9b][[:xdigit:]]+,v1,sifive/p650,core
0x5b7-0x0-0x0,v1,thead/c900-legacy,core
0x5b7-0x80000000090c0d00-0x2047000,v1,thead/c900-legacy,core
0x67e-0x80000000db0000[89]0-0x[[:xdigit:]]+,v1,starfive/dubhe-80,core
0x31e-0x8000000000008a45-0x[[:xdigit:]]+,v1,andes/ax45,core
1 # Format:
20 0x489-0x8000000000000008-0x[[:xdigit:]]+,v1,sifive/p550,core
21 0x489-0x8000000000000[1-6]08-0x[9b][[:xdigit:]]+,v1,sifive/p650,core
22 0x5b7-0x0-0x0,v1,thead/c900-legacy,core
23 0x5b7-0x80000000090c0d00-0x2047000,v1,thead/c900-legacy,core
24 0x67e-0x80000000db0000[89]0-0x[[:xdigit:]]+,v1,starfive/dubhe-80,core
25 0x31e-0x8000000000008a45-0x[[:xdigit:]]+,v1,andes/ax45,core
@@ -7,17 +7,17 @@
{
"BriefDescription": "Cycles per Instruction",
"MetricName": "cpi",
"MetricExpr": "CPU_CYCLES / INSTRUCTIONS if has_event(INSTRUCTIONS) else 0"
"MetricExpr": "CPU_CYCLES / INSTRUCTIONS if has_event(CPU_CYCLES) else 0"
},
{
"BriefDescription": "Problem State Instruction Ratio",
"MetricName": "prbstate",
"MetricExpr": "(PROBLEM_STATE_INSTRUCTIONS / INSTRUCTIONS) * 100 if has_event(INSTRUCTIONS) else 0"
"MetricExpr": "(PROBLEM_STATE_INSTRUCTIONS / INSTRUCTIONS) * 100 if has_event(PROBLEM_STATE_INSTRUCTIONS) else 0"
},
{
"BriefDescription": "Level One Miss per 100 Instructions",
"MetricName": "l1mp",
"MetricExpr": "((L1I_DIR_WRITES + L1D_DIR_WRITES) / INSTRUCTIONS) * 100 if has_event(INSTRUCTIONS) else 0"
"MetricExpr": "((L1I_DIR_WRITES + L1D_DIR_WRITES) / INSTRUCTIONS) * 100 if has_event(L1I_DIR_WRITES) else 0"
},
{
"BriefDescription": "Percentage sourced from Level 2 cache",
@@ -52,7 +52,7 @@
{
"BriefDescription": "Estimated Instruction Complexity CPI infinite Level 1",
"MetricName": "est_cpi",
"MetricExpr": "(CPU_CYCLES / INSTRUCTIONS) - (L1C_TLB2_MISSES / INSTRUCTIONS) if has_event(INSTRUCTIONS) else 0"
"MetricExpr": "(CPU_CYCLES / INSTRUCTIONS) - (L1C_TLB2_MISSES / INSTRUCTIONS) if has_event(CPU_CYCLES) else 0"
},
{
"BriefDescription": "Estimated Sourcing Cycles per Level 1 Miss",
@@ -7,17 +7,17 @@
{
"BriefDescription": "Cycles per Instruction",
"MetricName": "cpi",
"MetricExpr": "CPU_CYCLES / INSTRUCTIONS if has_event(INSTRUCTIONS) else 0"
"MetricExpr": "CPU_CYCLES / INSTRUCTIONS if has_event(CPU_CYCLES) else 0"
},
{
"BriefDescription": "Problem State Instruction Ratio",
"MetricName": "prbstate",
"MetricExpr": "(PROBLEM_STATE_INSTRUCTIONS / INSTRUCTIONS) * 100 if has_event(INSTRUCTIONS) else 0"
"MetricExpr": "(PROBLEM_STATE_INSTRUCTIONS / INSTRUCTIONS) * 100 if has_event(PROBLEM_STATE_INSTRUCTIONS) else 0"
},
{
"BriefDescription": "Level One Miss per 100 Instructions",
"MetricName": "l1mp",
"MetricExpr": "((L1I_DIR_WRITES + L1D_DIR_WRITES) / INSTRUCTIONS) * 100 if has_event(INSTRUCTIONS) else 0"
"MetricExpr": "((L1I_DIR_WRITES + L1D_DIR_WRITES) / INSTRUCTIONS) * 100 if has_event(L1I_DIR_WRITES) else 0"
},
{
"BriefDescription": "Percentage sourced from Level 2 cache",
@@ -52,7 +52,7 @@
{
"BriefDescription": "Estimated Instruction Complexity CPI infinite Level 1",
"MetricName": "est_cpi",
"MetricExpr": "(CPU_CYCLES / INSTRUCTIONS) - (L1C_TLB2_MISSES / INSTRUCTIONS) if has_event(INSTRUCTIONS) else 0"
"MetricExpr": "(CPU_CYCLES / INSTRUCTIONS) - (L1C_TLB2_MISSES / INSTRUCTIONS) if has_event(L1C_TLB2_MISSES) else 0"
},
{
"BriefDescription": "Estimated Sourcing Cycles per Level 1 Miss",
@@ -877,7 +877,7 @@
},
{
"BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 128 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_128",
@@ -890,7 +890,7 @@
},
{
"BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 16 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_16",
@@ -903,7 +903,7 @@
},
{
"BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 256 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_256",
@@ -916,7 +916,7 @@
},
{
"BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 32 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_32",
@@ -929,7 +929,7 @@
},
{
"BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 4 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_4",
@@ -942,7 +942,7 @@
},
{
"BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 512 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_512",
@@ -955,7 +955,7 @@
},
{
"BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 64 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_64",
@@ -968,7 +968,7 @@
},
{
"BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 8 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_8",
@@ -32,8 +32,9 @@
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of active floating point and integer dividers per cycle.",
"BriefDescription": "This event is deprecated.",
"Counter": "0,1,2,3,4,5",
"Deprecated": "1",
"EventCode": "0xcd",
"EventName": "ARITH.DIV_OCCUPANCY",
"SampleAfterValue": "1000003",
@@ -41,8 +42,9 @@
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of floating point and integer divider uops executed per cycle.",
"BriefDescription": "This event is deprecated.",
"Counter": "0,1,2,3,4,5",
"Deprecated": "1",
"EventCode": "0xcd",
"EventName": "ARITH.DIV_UOPS",
"SampleAfterValue": "1000003",
@@ -247,7 +247,7 @@
},
{
"BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 128 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_128",
@@ -259,7 +259,7 @@
},
{
"BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 16 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_16",
@@ -271,7 +271,7 @@
},
{
"BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 256 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_256",
@@ -283,7 +283,7 @@
},
{
"BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 32 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_32",
@@ -295,7 +295,7 @@
},
{
"BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 4 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_4",
@@ -307,7 +307,7 @@
},
{
"BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 512 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_512",
@@ -319,7 +319,7 @@
},
{
"BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 64 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_64",
@@ -331,7 +331,7 @@
},
{
"BriefDescription": "Counts the number of tagged loads with an instruction latency that exceeds or equals the threshold of 8 cycles as defined in MEC_CR_PEBS_LD_LAT_THRESHOLD (3F6H). Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_8",
@@ -9,16 +9,18 @@
"UMask": "0x3"
},
{
"BriefDescription": "Counts the number of active floating point and integer dividers per cycle.",
"BriefDescription": "This event is deprecated.",
"Counter": "0,1,2,3,4,5",
"Deprecated": "1",
"EventCode": "0xcd",
"EventName": "ARITH.DIV_OCCUPANCY",
"SampleAfterValue": "1000003",
"UMask": "0x3"
},
{
"BriefDescription": "Counts the number of floating point and integer divider uops executed per cycle.",
"BriefDescription": "This event is deprecated.",
"Counter": "0,1,2,3,4,5",
"Deprecated": "1",
"EventCode": "0xcd",
"EventName": "ARITH.DIV_UOPS",
"SampleAfterValue": "1000003",
@@ -8,6 +8,16 @@
"SampleAfterValue": "1000003",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of L1D cacheline (dirty) evictions caused by load misses, stores, and prefetches.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x51",
"EventName": "DL1.DIRTY_EVICTION",
"PublicDescription": "Counts the number of L1D cacheline (dirty) evictions caused by load misses, stores, and prefetches. Does not count evictions or dirty writebacks caused by snoops. Does not count a replacement unless a (dirty) line was written back.",
"SampleAfterValue": "200003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of L1D cacheline (dirty) evictions caused by load misses, stores, and prefetches.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -109,6 +119,15 @@
"UMask": "0x1f",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of cache lines filled into the L2 cache that are in Exclusive state",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x25",
"EventName": "L2_LINES_IN.E",
"SampleAfterValue": "1000003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cache lines filled into the L2 cache that are in Exclusive state",
"Counter": "0,1,2,3,4,5,6,7",
@@ -119,6 +138,15 @@
"UMask": "0x4",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of cache lines filled into the L2 cache that are in Forward state",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x25",
"EventName": "L2_LINES_IN.F",
"SampleAfterValue": "1000003",
"UMask": "0x10",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cache lines filled into the L2 cache that are in Forward state",
"Counter": "0,1,2,3,4,5,6,7",
@@ -129,6 +157,25 @@
"UMask": "0x10",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of cache lines filled into the L2 cache that are in Invalid state",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x25",
"EventName": "L2_LINES_IN.I",
"PublicDescription": "Counts the number of cache lines filled into the L2 cache that are in Invalid state, does not count lines that go Invalid due to an eviction",
"SampleAfterValue": "1000003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cache lines filled into the L2 cache that are in Modified state",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x25",
"EventName": "L2_LINES_IN.M",
"SampleAfterValue": "1000003",
"UMask": "0x8",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cache lines filled into the L2 cache that are in Modified state",
"Counter": "0,1,2,3,4,5,6,7",
@@ -139,6 +186,15 @@
"UMask": "0x8",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of cache lines filled into the L2 cache that are in Shared state",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x25",
"EventName": "L2_LINES_IN.S",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cache lines filled into the L2 cache that are in Shared state",
"Counter": "0,1,2,3,4,5,6,7",
@@ -189,6 +245,16 @@
"UMask": "0x1",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of L2 cache lines that have been L2 hardware prefetched but not used by demand accesses",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x26",
"EventName": "L2_LINES_OUT.USELESS_HWPF",
"PublicDescription": "Counts the number of L2 cache lines that have been L2 hardware prefetched but not used by demand accesses. Increments on the core that brought the line in originally.",
"SampleAfterValue": "1000003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Cache lines that have been L2 hardware prefetched but not used by demand accesses",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -199,6 +265,42 @@
"UMask": "0x4",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of L2 prefetches initiated by either the L2 Stream or AMP that were throttled due to Dynamic Prefetch Throttling. The throttle requestor/source could be from the uncore/SOC or the Dead Block Predictor. Counts on a per core basis.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x28",
"EventName": "L2_PREFETCHES_THROTTLED.DPT",
"SampleAfterValue": "1000003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of L2 prefetches initiated by the L2 Stream that were throttled due to Demand Throttle Prefetcher. DTP Global Triggered with no Local Override. Counts on a per core basis.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x28",
"EventName": "L2_PREFETCHES_THROTTLED.DTP",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of L2 prefetches initiated by the L2 Stream and not throttled by DTP due to local override. These prefetches may still be throttled due to another throttler mechanism besides DTP. Counts on a per core basis.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x28",
"EventName": "L2_PREFETCHES_THROTTLED.DTP_OVERRIDE",
"SampleAfterValue": "1000003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of L2 prefetches initiated by either the L2 Stream or AMP that were throttled due to exceeding the XQ threshold set by either XQ_THRESHOLD_DTP or XQ_THRESHOLD. Counts on a per core basis.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x28",
"EventName": "L2_PREFETCHES_THROTTLED.XQ_THRESH",
"SampleAfterValue": "1000003",
"UMask": "0x8",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of demand and prefetch transactions that the External Queue (XQ) rejects due to a full or near full condition.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -208,6 +310,16 @@
"SampleAfterValue": "1000003",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of L2 Cache Accesses Counts the total number of L2 Cache Accesses - sum of hits, misses, rejects front door requests for CRd/DRd/RFO/ItoM/L2 Prefetches only, per core event",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x24",
"EventName": "L2_REQUEST.ALL",
"PublicDescription": "Counts the number of L2 Cache Accesses Counts the total number of L2 Cache Accesses - sum of hits, misses, rejects front door requests for CRd/DRd/RFO/ItoM/L2 Prefetches only.",
"SampleAfterValue": "1000003",
"UMask": "0x7",
"Unit": "cpu_atom"
},
{
"BriefDescription": "All accesses to L2 cache [This event is alias to L2_RQSTS.REFERENCES, L2_RQSTS.ANY]",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -218,6 +330,15 @@
"UMask": "0xff",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of L2 Cache Accesses that resulted in a Hit from a front door request only (does not include rejects or recycles), per core event",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x24",
"EventName": "L2_REQUEST.HIT",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of L2 Cache Accesses that resulted in a Hit from a front door request only (does not include rejects or recycles), per core event",
"Counter": "0,1,2,3,4,5,6,7",
@@ -227,6 +348,15 @@
"UMask": "0x2",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of total L2 Cache Accesses that resulted in a Miss from a front door request only (does not include rejects or recycles), per core event",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x24",
"EventName": "L2_REQUEST.MISS",
"SampleAfterValue": "1000003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Read requests with true-miss in L2 cache [This event is alias to L2_RQSTS.MISS]",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -246,6 +376,15 @@
"UMask": "0x1",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of L2 Cache Accesses that miss the L2 and get BBL reject short and long rejects (includes those counted in L2_reject_XQ.any), per core event",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x24",
"EventName": "L2_REQUEST.REJECTS",
"SampleAfterValue": "1000003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of L2 Cache Accesses that miss the L2 and get BBL reject short and long rejects, per core event",
"Counter": "0,1,2,3,4,5,6,7",
@@ -365,6 +504,51 @@
"UMask": "0x22",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of LLC prefetches that were throttled due to Dynamic Prefetch Throttling. The throttle requestor/source could be from the uncore/SOC or the Dead Block Predictor. Counts on a per core basis.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x29",
"EventName": "LLC_PREFETCHES_THROTTLED.DPT",
"SampleAfterValue": "1000003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of LLC prefetches throttled due to Demand Throttle Prefetcher. DTP Global Triggered with no Local Override. Counts on a per core basis.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x29",
"EventName": "LLC_PREFETCHES_THROTTLED.DTP",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of LLC prefetches not throttled by DTP due to local override. These prefetches may still be throttled due to another throttler mechanism. Counts on a per core basis.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x29",
"EventName": "LLC_PREFETCHES_THROTTLED.DTP_OVERRIDE",
"SampleAfterValue": "1000003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of LLC prefetches throttled due to LLC hit rate in <insert knob name here>. Counts on a per core basis.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x29",
"EventName": "LLC_PREFETCHES_THROTTLED.HIT_RATE",
"SampleAfterValue": "1000003",
"UMask": "0x10",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of LLC prefetches throttled due to exceeding the XQ threshold set by either XQ_THRESHOLD_DTP or LLC_XQ_THRESHOLD. Counts on a per core basis.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x29",
"EventName": "LLC_PREFETCHES_THROTTLED.XQ_THRESH",
"SampleAfterValue": "1000003",
"UMask": "0x8",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Cycles when L1D is locked",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -375,6 +559,16 @@
"UMask": "0x2",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of cacheable memory requests that miss in the LLC. Counts on a per core basis.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x2e",
"EventName": "LONGEST_LAT_CACHE.MISS",
"PublicDescription": "Counts the number of cacheable memory requests that miss in the Last Level Cache (LLC). Requests include demand loads, reads for ownership (RFO), instruction fetches and L1 HW prefetches. If the core has access to an L3 cache, the LLC is the L3 cache, otherwise it is the L2 cache. Counts on a per core basis.",
"SampleAfterValue": "200003",
"UMask": "0x41",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Core-originated cacheable requests that missed L3 (Except hardware prefetches to the L3)",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -385,6 +579,26 @@
"UMask": "0x41",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of cacheable memory requests that miss in the LLC. Counts on a per core basis.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x2e",
"EventName": "LONGEST_LAT_CACHE.MISS",
"PublicDescription": "Counts the number of cacheable memory requests that miss in the Last Level Cache (LLC). Requests include demand loads, reads for ownership (RFO), instruction fetches and L1 HW prefetches. If the core has access to an L3 cache, the LLC is the L3 cache, otherwise it is the L2 cache. Counts on a per core basis.",
"SampleAfterValue": "200003",
"UMask": "0x41",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of cacheable memory requests that access the LLC. Counts on a per core basis.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x2e",
"EventName": "LONGEST_LAT_CACHE.REFERENCE",
"PublicDescription": "Counts the number of cacheable memory requests that access the Last Level Cache (LLC). Requests include demand loads, reads for ownership (RFO), instruction fetches and L1 HW prefetches. If the core has access to an L3 cache, the LLC is the L3 cache, otherwise it is the L2 cache. Counts on a per core basis.",
"SampleAfterValue": "200003",
"UMask": "0x4f",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Core-originated cacheable requests that refer to L3 (Except hardware prefetches to the L3)",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -535,6 +749,15 @@
"UMask": "0x78",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of unhalted cycles when the core is stalled to a store buffer full condition",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x34",
"EventName": "MEM_BOUND_STALLS_LOAD.SBFULL",
"SampleAfterValue": "1000003",
"UMask": "0x80",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of unhalted cycles when the core is stalled to a store buffer full condition",
"Counter": "0,1,2,3,4,5,6,7",
@@ -858,6 +1081,15 @@
"UMask": "0x20",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of load ops retired that miss the L3 cache and hit in DRAM",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xd4",
"EventName": "MEM_LOAD_UOPS_MISC_RETIRED.LOCAL_DRAM",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of load ops retired that hit the L1 data cache",
"Counter": "0,1,2,3,4,5,6,7",
@@ -940,6 +1172,15 @@
"UMask": "0x1c",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of load ops retired that hit in the L3 cache.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xd1",
"EventName": "MEM_LOAD_UOPS_RETIRED.L3_HIT",
"SampleAfterValue": "200003",
"UMask": "0x1c",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of loads that hit in a write combining buffer (WCB), excluding the first load that caused the WCB to allocate.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -1039,6 +1280,16 @@
"UMask": "0x1",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of memory uops retired. A single uop that performs both a load AND a store will be counted as 1, not 2 (e.g. ADD [mem], CONST)",
"Counter": "0,1,2,3,4,5,6,7",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.ALL",
"SampleAfterValue": "200003",
"UMask": "0x83",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of load uops retired.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -1081,7 +1332,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_1024",
@@ -1093,7 +1344,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_128",
@@ -1105,7 +1356,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_128",
@@ -1117,7 +1368,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_16",
@@ -1129,7 +1380,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_16",
@@ -1141,7 +1392,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_2048",
@@ -1153,7 +1404,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_256",
@@ -1165,7 +1416,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_256",
@@ -1177,7 +1428,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_32",
@@ -1189,7 +1440,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_32",
@@ -1201,7 +1452,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_4",
@@ -1213,7 +1464,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_4",
@@ -1225,7 +1476,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_512",
@@ -1237,7 +1488,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_512",
@@ -1249,7 +1500,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_64",
@@ -1261,7 +1512,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_64",
@@ -1273,7 +1524,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_8",
@@ -1285,7 +1536,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_8",
@@ -1315,6 +1566,26 @@
"UMask": "0x21",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of memory renamed load uops retired.",
"Counter": "0,1,2,3,4,5,6,7",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.MRN_LOADS",
"SampleAfterValue": "200003",
"UMask": "0x9",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of memory renamed store uops retired.",
"Counter": "0,1,2,3,4,5,6,7",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.MRN_STORES",
"SampleAfterValue": "200003",
"UMask": "0xa",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of memory uops retired that were splits.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -1375,6 +1646,16 @@
"UMask": "0x42",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of memory uops retired that missed in the second level TLB.",
"Counter": "0,1,2,3,4,5,6,7",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.STLB_MISS",
"SampleAfterValue": "200003",
"UMask": "0x13",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of memory uops retired that missed in the second level TLB.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -1385,6 +1666,16 @@
"UMask": "0x13",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of load ops retired that filled the STLB - includes those in DTLB_LOAD_MISSES submasks",
"Counter": "0,1,2,3,4,5,6,7",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.STLB_MISS_LOADS",
"SampleAfterValue": "200003",
"UMask": "0x11",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of load uops retired that miss in the second Level TLB.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -1395,6 +1686,16 @@
"UMask": "0x11",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of store ops retired (store STLB miss)",
"Counter": "0,1,2,3,4,5,6,7",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.STLB_MISS_STORES",
"SampleAfterValue": "200003",
"UMask": "0x12",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of store uops retired that miss in the second level TLB.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -1,4 +1,14 @@
[
{
"BriefDescription": "Counts the number of cycles when any of the floating point dividers are active.",
"Counter": "0,1,2,3,4,5,6,7",
"CounterMask": "1",
"EventCode": "0xcd",
"EventName": "ARITH.FPDIV_ACTIVE",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Cycles when floating-point divide unit is busy executing divide or square root operations.",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -20,6 +30,24 @@
"UMask": "0x2",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of active floating point dividers per cycle in the loop stage.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xcd",
"EventName": "ARITH.FPDIV_OCCUPANCY",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of floating point divider uops executed per cycle.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xcd",
"EventName": "ARITH.FPDIV_UOPS",
"SampleAfterValue": "1000003",
"UMask": "0x8",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts all microcode FP assists.",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -473,6 +501,51 @@
"UMask": "0x3f",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on all floating point ports.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb2",
"EventName": "FP_VINT_UOPS_EXECUTED.ALL",
"SampleAfterValue": "1000003",
"UMask": "0x1f",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on floating point and vector integer port 0.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb2",
"EventName": "FP_VINT_UOPS_EXECUTED.P0",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on floating point and vector integer port 1.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb2",
"EventName": "FP_VINT_UOPS_EXECUTED.P1",
"SampleAfterValue": "1000003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on floating point and vector integer port 2.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb2",
"EventName": "FP_VINT_UOPS_EXECUTED.P2",
"SampleAfterValue": "1000003",
"UMask": "0x8",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on floating point and vector integer port 3.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb2",
"EventName": "FP_VINT_UOPS_EXECUTED.P3",
"SampleAfterValue": "1000003",
"UMask": "0x10",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on floating point and vector integer port 0, 1, 2, 3.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -29,6 +29,42 @@
"UMask": "0x1",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of BACLEARS due to a conditional jump.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe6",
"EventName": "BACLEARS.COND",
"SampleAfterValue": "200003",
"UMask": "0x10",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of BACLEARS due to an indirect branch.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe6",
"EventName": "BACLEARS.INDIRECT",
"SampleAfterValue": "200003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of BACLEARS due to a return branch.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe6",
"EventName": "BACLEARS.RETURN",
"SampleAfterValue": "200003",
"UMask": "0x8",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of BACLEARS due to a direct, unconditional jump.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe6",
"EventName": "BACLEARS.UNCOND",
"SampleAfterValue": "200003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Stalls caused by changing prefix length of the instruction.",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -48,6 +84,15 @@
"UMask": "0x2",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of times a decode restriction reduces the decode throughput due to wrong instruction length prediction.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe9",
"EventName": "DECODE_RESTRICTION.PREDECODE_WRONG",
"SampleAfterValue": "200003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "DSB-to-MITE switch true penalty cycles.",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -733,6 +778,15 @@
"UMask": "0x1",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of cycles that the micro-sequencer is busy.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe7",
"EventName": "MS_DECODED.MS_BUSY",
"SampleAfterValue": "200003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cycles that the micro-sequencer is busy.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -741,5 +795,23 @@
"SampleAfterValue": "1000003",
"UMask": "0x4",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of times entered into a ucode flow in the FEC. Includes inserted flows due to front-end detected faults or assists.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe7",
"EventName": "MS_DECODED.MS_ENTRY",
"SampleAfterValue": "200003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of times nanocode flow is executed.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe7",
"EventName": "MS_DECODED.NANO_CODE",
"SampleAfterValue": "200003",
"UMask": "0x2",
"Unit": "cpu_atom"
}
]
@@ -1,4 +1,13 @@
[
{
"BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer is stalled due to any number of reasons, including an L1 miss, WCB full, pagewalk, store address block or store data block.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x05",
"EventName": "LD_HEAD.ANY",
"SampleAfterValue": "1000003",
"UMask": "0x7f",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer is stalled due to any number of reasons, including an L1 miss, WCB full, pagewalk, store address block or store data block, on a load that retires.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -62,6 +71,16 @@
"UMask": "0x81",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer is stalled due to other block cases.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x05",
"EventName": "LD_HEAD.OTHER",
"PublicDescription": "Counts the number of cycles that the head (oldest load) of the load buffer is stalled due to other block cases such as pipeline conflicts, fences, etc.",
"SampleAfterValue": "1000003",
"UMask": "0x40",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer and retirement are both stalled due to other block cases.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -82,6 +101,15 @@
"UMask": "0xc0",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer is stalled due to a pagewalk.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x05",
"EventName": "LD_HEAD.PGWALK",
"SampleAfterValue": "1000003",
"UMask": "0x20",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer and retirement are both stalled due to a pagewalk.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -100,6 +128,15 @@
"UMask": "0xa0",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer is stalled due to a store address match.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x05",
"EventName": "LD_HEAD.ST_ADDR",
"SampleAfterValue": "1000003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer and retirement are both stalled due to a store address match.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -118,6 +155,24 @@
"UMask": "0x84",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer is stalled due to store data forward block.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x05",
"EventName": "LD_HEAD.ST_DATA",
"SampleAfterValue": "1000003",
"UMask": "0x8",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer is stalled due to request buffers full or lock in progress.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x05",
"EventName": "LD_HEAD.WCB_FULL",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer and retirement are both stalled due to request buffers full or lock in progress.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -155,6 +210,15 @@
"UMask": "0x2",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of machine clears that flush the pipeline and restart the machine without the use of microcode.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xc3",
"EventName": "MACHINE_CLEARS.MEMORY_ORDERING_FAST",
"SampleAfterValue": "20003",
"UMask": "0x82",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 1024 cycles.",
"Counter": "2,3,4,5,6,7,8,9",
@@ -18,6 +18,89 @@
"UMask": "0x8",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of unhalted cycles a Core is blocked due to a lock In Progress issued by another core",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x63",
"EventName": "BUS_LOCK.BLOCKED_CYCLES",
"PublicDescription": "Counts the number of unhalted cycles a Core is blocked due to a lock In Progress issued by another core. Counts on a per core basis.",
"SampleAfterValue": "1000003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of unhalted cycles a Core is blocked due to an Accepted lock it issued, includes both split and non-split lock cycles.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x63",
"EventName": "BUS_LOCK.LOCK_CYCLES",
"PublicDescription": "Counts the number of unhalted cycles a Core is blocked due to an Accepted lock it issued, includes both split and non-split lock cycles. Counts on a per core basis.",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of non-split locks such as UC locks issued by a Core (does not include cache locks)",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x63",
"EventName": "BUS_LOCK.NON_SPLIT_LOCKS",
"SampleAfterValue": "1000003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of split locks issued by a Core",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x63",
"EventName": "BUS_LOCK.SPLIT_LOCKS",
"SampleAfterValue": "1000003",
"UMask": "0x8",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cycles the L2 Prefetchers are at throttle level 0",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x32",
"EventName": "DYNAMIC_PREFETCH_THROTTLER.LEVEL0_SOC",
"SampleAfterValue": "1000003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cycles the L2 Prefetcher throttle level is at 1",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x32",
"EventName": "DYNAMIC_PREFETCH_THROTTLER.LEVEL1_SOC",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cycles the L2 Prefetcher throttle level is at 2",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x32",
"EventName": "DYNAMIC_PREFETCH_THROTTLER.LEVEL2_SOC",
"SampleAfterValue": "1000003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cycles the L2 Prefetcher throttle level is at 3",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x32",
"EventName": "DYNAMIC_PREFETCH_THROTTLER.LEVEL3_SOC",
"SampleAfterValue": "1000003",
"UMask": "0x8",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cycles the L2 Prefetcher throttle level is at 4",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x32",
"EventName": "DYNAMIC_PREFETCH_THROTTLER.LEVEL4_SOC",
"SampleAfterValue": "1000003",
"UMask": "0x10",
"Unit": "cpu_atom"
},
{
"BriefDescription": "This event is deprecated. [This event is alias to MISC_RETIRED.LBR_INSERTS]",
"Counter": "0,1,2,3,4,5,6,7",
@@ -86,5 +169,41 @@
"SampleAfterValue": "1000003",
"UMask": "0x1",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of prefetch requests that were promoted in the XQ to a demand request.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xf4",
"EventName": "XQ_PROMOTION.ALL",
"SampleAfterValue": "1000003",
"UMask": "0x7",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of prefetch requests that were promoted in the XQ to a demand code read.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xf4",
"EventName": "XQ_PROMOTION.CRDS",
"SampleAfterValue": "1000003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of prefetch requests that were promoted in the XQ to a demand read.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xf4",
"EventName": "XQ_PROMOTION.DRDS",
"SampleAfterValue": "1000003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of prefetch requests that were promoted in the XQ to a demand RFO.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xf4",
"EventName": "XQ_PROMOTION.RFOS",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
}
]
@@ -30,6 +30,16 @@
"UMask": "0x3",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of cycles when any of the integer dividers are active.",
"Counter": "0,1,2,3,4,5,6,7",
"CounterMask": "1",
"EventCode": "0xcd",
"EventName": "ARITH.IDIV_ACTIVE",
"SampleAfterValue": "1000003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Cycles when integer divide unit is busy executing divide or square root operations.",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -41,6 +51,24 @@
"UMask": "0x8",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of active integer dividers per cycle.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xcd",
"EventName": "ARITH.IDIV_OCCUPANCY",
"SampleAfterValue": "1000003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of integer divider uops executed per cycle.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xcd",
"EventName": "ARITH.IDIV_UOPS",
"SampleAfterValue": "1000003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Number of occurrences where a microcode assist is invoked by hardware.",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -117,6 +145,15 @@
"UMask": "0x7e",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of not taken JCC branch instructions retired",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xc4",
"EventName": "BR_INST_RETIRED.COND_NTAKEN",
"SampleAfterValue": "200003",
"UMask": "0x7f",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Not taken branch instructions retired.",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -252,6 +289,15 @@
"UMask": "0xfb",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of near indirect JMP branch instructions retired",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xc4",
"EventName": "BR_INST_RETIRED.INDIRECT_JMP",
"SampleAfterValue": "200003",
"UMask": "0xef",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of near indirect JMP branch instructions retired.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -261,6 +307,17 @@
"UMask": "0xef",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "This event is deprecated. Refer to new event BR_INST_RETIRED.INDIRECT_CALL",
"Counter": "0,1,2,3,4,5,6,7",
"Deprecated": "1",
"Errata": "ARL011",
"EventCode": "0xc4",
"EventName": "BR_INST_RETIRED.IND_CALL",
"SampleAfterValue": "200003",
"UMask": "0xfb",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of near CALL branch instructions retired",
"Counter": "0,1,2,3,4,5,6,7",
@@ -318,6 +375,15 @@
"UMask": "0xf7",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of taken branch instructions retired",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xc4",
"EventName": "BR_INST_RETIRED.NEAR_TAKEN",
"SampleAfterValue": "200003",
"UMask": "0xc0",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Taken branch instructions retired.",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -440,6 +506,15 @@
"UMask": "0x151",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of mispredicted not taken JCC branch instructions retired",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xc5",
"EventName": "BR_MISP_RETIRED.COND_NTAKEN",
"SampleAfterValue": "200003",
"UMask": "0x7f",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Mispredicted non-taken conditional branch instructions retired.",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -613,6 +688,15 @@
"UMask": "0xc0",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of mispredicted near indirect JMP branch instructions retired",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xc5",
"EventName": "BR_MISP_RETIRED.INDIRECT_JMP",
"SampleAfterValue": "200003",
"UMask": "0xef",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of mispredicted near indirect JMP branch instructions retired.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -622,6 +706,15 @@
"UMask": "0xef",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of mispredicted near taken branch instructions retired",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xc5",
"EventName": "BR_MISP_RETIRED.NEAR_TAKEN",
"SampleAfterValue": "200003",
"UMask": "0x80",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Number of near branch instructions retired that were mispredicted and taken.",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -689,6 +782,15 @@
"UMask": "0x48",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the total number of BTCLEARS.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe8",
"EventName": "BTCLEAR.ANY",
"PublicDescription": "Counts the total number of BTCLEARS which occurs when the Branch Target Buffer (BTB) predicts a taken branch.",
"SampleAfterValue": "1000003",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Core clocks when the thread is in the C0.1 light-weight slower wakeup time but more power saving optimized state.",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -1187,6 +1289,15 @@
"UMask": "0x80",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on all Integer ports.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb3",
"EventName": "INT_UOPS_EXECUTED.ALL",
"SampleAfterValue": "1000003",
"UMask": "0xff",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on a load port.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -1197,6 +1308,42 @@
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on integer port 0.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb3",
"EventName": "INT_UOPS_EXECUTED.P0",
"SampleAfterValue": "1000003",
"UMask": "0x8",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on integer port 1.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb3",
"EventName": "INT_UOPS_EXECUTED.P1",
"SampleAfterValue": "1000003",
"UMask": "0x10",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on integer port 2.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb3",
"EventName": "INT_UOPS_EXECUTED.P2",
"SampleAfterValue": "1000003",
"UMask": "0x20",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on integer port 3.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb3",
"EventName": "INT_UOPS_EXECUTED.P3",
"SampleAfterValue": "1000003",
"UMask": "0x40",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on integer port 0,1, 2, 3.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -1327,6 +1474,15 @@
"UMask": "0x4",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of occurrences a retired load was blocked for any of the following reasons: utlb_miss, 4k_alias, unknown_sta/bad_fwd, unready_fwd (includes md blocks and esp consuming load blocks)",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x03",
"EventName": "LD_BLOCKS.ALL",
"SampleAfterValue": "1000003",
"UMask": "0x1f",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of occurrences a retired load gets blocked because its address exactly matches an older store whose data is not ready (a.k.a. unknown). unready_fwd",
"Counter": "0,1,2,3,4,5,6,7",
@@ -1392,6 +1548,25 @@
"UMask": "0x2",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of demand loads that match on a wcb (request buffer) allocated by an L1 hardware prefetch [This event is alias to LOAD_HIT_PREFETCH.HW_PF]",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x4c",
"EventName": "LOAD_HIT_PREFETCH.HWPF",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "This event is deprecated. [This event is alias to LOAD_HIT_PREFETCH.HWPF]",
"Counter": "0,1,2,3,4,5,6,7",
"Deprecated": "1",
"EventCode": "0x4c",
"EventName": "LOAD_HIT_PREFETCH.HW_PF",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Cycles Uops delivered by the LSD, but didn't come from the decoder.",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -1432,6 +1607,15 @@
"SampleAfterValue": "20003",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of machine clears that flush the pipeline and restart the machine without the use of microcode.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xc3",
"EventName": "MACHINE_CLEARS.ANY_FAST",
"SampleAfterValue": "20003",
"UMask": "0xff",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Number of machine clears (nukes) of any type.",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -1462,6 +1646,15 @@
"UMask": "0x8",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of machine clears that flush the pipeline and restart the machine without the use of microcode.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xc3",
"EventName": "MACHINE_CLEARS.DISAMBIGUATION_FAST",
"SampleAfterValue": "20003",
"UMask": "0x88",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of nukes due to memory renaming",
"Counter": "0,1,2,3,4,5,6,7",
@@ -1471,6 +1664,15 @@
"UMask": "0x10",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of machine clears that flush the pipeline and restart the machine without the use of microcode.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xc3",
"EventName": "MACHINE_CLEARS.MRN_NUKE_FAST",
"SampleAfterValue": "20003",
"UMask": "0x90",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of times that the machine clears due to a page fault. Covers both I-Side and D-Side (Loads/Stores) page faults. A page fault occurs when either the page is not present, or an access violation.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -1574,6 +1776,15 @@
"UMask": "0x20",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of LBR entries recorded. Requires LBRs to be enabled in IA32_LBR_CTL.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe4",
"EventName": "MISC_RETIRED.LBR_INSERTS",
"SampleAfterValue": "1000003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "LBR record is inserted",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -1593,6 +1804,86 @@
"UMask": "0x1",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of CLFLUSH, CLWB, and CLDEMOTE instructions retired.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe0",
"EventName": "MISC_RETIRED1.CL_INST",
"SampleAfterValue": "1000003",
"UMask": "0xff",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of LFENCE instructions retired.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe0",
"EventName": "MISC_RETIRED1.LFENCE",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of RDPMC, RDTSC, and RDTSCP instructions retired.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe0",
"EventName": "MISC_RETIRED1.RDPMC_RDTSC_P",
"SampleAfterValue": "1000003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Count the number of WRMSR instructions retired.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe0",
"EventName": "MISC_RETIRED1.WRMSR",
"SampleAfterValue": "1000003",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of faults and software interrupts with vector < 32.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe1",
"EventName": "MISC_RETIRED2.FAULT_ALL",
"PublicDescription": "Counts the number of faults and software interrupts with vector < 32, including VOE cases.",
"SampleAfterValue": "1000003",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of PSB+ nuke events and ToPA trap events.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe1",
"EventName": "MISC_RETIRED2.INTEL_PT_CLEARS",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of user interrupts delivered.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe1",
"EventName": "MISC_RETIRED2.ULI_DELIVERY",
"SampleAfterValue": "1000003",
"UMask": "0x8",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of SENDUIPI instructions retired.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe1",
"EventName": "MISC_RETIRED2.ULI_SENDUIPI",
"SampleAfterValue": "1000003",
"UMask": "0x9",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of VM exits.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xe1",
"EventName": "MISC_RETIRED2.VM_EXIT",
"SampleAfterValue": "1000003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Cycles when Reservation Station (RS) is empty for the thread.",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -1643,6 +1934,15 @@
"UMask": "0x4",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number issue slots not consumed due to a color request for an FCW or MXCSR control register when all 4 colors (copies) are already in use",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x75",
"EventName": "SERIALIZATION.COLOR_STALLS",
"SampleAfterValue": "1000003",
"UMask": "0x8",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of issue slots where no uop could issue due to an IQ scoreboard that stalls allocation until a specified older uop retires or (in the case of jump scoreboard) executes. Commonly executed instructions with IQ scoreboards include LFENCE and MFENCE.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -1720,6 +2020,15 @@
"UMask": "0x1",
"Unit": "cpu_core"
},
{
"BriefDescription": "Fixed Counter: Counts the number of issue slots not consumed by the backend because allocation is stalled due to a mispredicted jump or a machine clear.",
"Counter": "Fixed counter 4",
"EventName": "TOPDOWN_BAD_SPECULATION.ALL",
"PublicDescription": "Fixed Counter: Counts the number of issue slots that were not consumed by the backend because allocation is stalled due to a mispredicted jump or a machine clear. Counts all issue slots blocked during this recovery window including relevant microcode flows and while uops are not yet available in the IQ. Also, includes the issue slots that were consumed by the backend but were thrown away because they were younger than the mispredict or machine clear.",
"SampleAfterValue": "1000003",
"UMask": "0x5",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of issue slots that were not consumed by the backend because allocation is stalled due to a mispredicted jump or a machine clear.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -1836,6 +2145,14 @@
"UMask": "0x1",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of retirement slots not consumed due to backend stalls",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x74",
"EventName": "TOPDOWN_BE_BOUND.ALL_NON_ARCH",
"SampleAfterValue": "1000003",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of retirement slots not consumed due to backend stalls [This event is alias to TOPDOWN_BE_BOUND.ALL]",
"Counter": "0,1,2,3,4,5,6,7",
@@ -1951,6 +2268,14 @@
"UMask": "0x6",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of retirement slots not consumed due to front end stalls",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x71",
"EventName": "TOPDOWN_FE_BOUND.ALL_NON_ARCH",
"SampleAfterValue": "1000003",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of retirement slots not consumed due to front end stalls",
"Counter": "0,1,2,3,4,5,6,7",
@@ -2148,6 +2473,14 @@
"UMask": "0x7",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of consumed retirement slots.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x72",
"EventName": "TOPDOWN_RETIRING.ALL_NON_ARCH",
"SampleAfterValue": "1000003",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of consumed retirement slots.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -2367,6 +2700,14 @@
"UMask": "0x1",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of uops retired",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xc2",
"EventName": "UOPS_RETIRED.ALL",
"SampleAfterValue": "2000003",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the total number of uops retired.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -2414,6 +2755,15 @@
"UMask": "0x10",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of uops retired that were delivered by the loop stream detector (LSD).",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xc2",
"EventName": "UOPS_RETIRED.LSD",
"SampleAfterValue": "2000003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops that are from the complex flows issued by the micro-sequencer (MS). This includes uops from flows due to complex instructions, faults, assists, and inserted flows.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -8,6 +8,15 @@
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts walks that miss the PDE_CACHE",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x08",
"EventName": "DTLB_LOAD_MISSES.PDE_CACHE_MISS",
"SampleAfterValue": "200003",
"UMask": "0x80",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of first level TLB misses but second level hits due to a demand load that did not start a page walk. Accounts for all page sizes. Will result in a DTLB write from STLB.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -47,6 +56,16 @@
"UMask": "0x10",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of page walks completed due to load DTLB misses to any page size.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x08",
"EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED",
"PublicDescription": "Counts the number of page walks completed due to loads (including SW prefetches) whose address translations missed in all Translation Lookaside Buffer (TLB) levels and were mapped to any page size. Includes page walks that page fault.",
"SampleAfterValue": "200003",
"UMask": "0xe",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Load miss in all TLB levels causes a page walk that completes. (All page sizes)",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -175,6 +194,15 @@
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts walks that miss the PDE_CACHE",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x49",
"EventName": "DTLB_STORE_MISSES.PDE_CACHE_MISS",
"SampleAfterValue": "2000003",
"UMask": "0x80",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of first level TLB misses but second level hits due to stores that did not start a page walk. Accounts for all page sizes. Will result in a DTLB write from STLB.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -215,6 +243,16 @@
"UMask": "0x10",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of page walks completed due to store DTLB misses to any page size.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x49",
"EventName": "DTLB_STORE_MISSES.WALK_COMPLETED",
"PublicDescription": "Counts the number of page walks completed due to stores whose address translations missed in all Translation Lookaside Buffer (TLB) levels and were mapped to any page size. Includes page walks that page fault.",
"SampleAfterValue": "2000003",
"UMask": "0xe",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Store misses in all TLB levels causes a page walk that completes. (All page sizes)",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -244,6 +282,16 @@
"UMask": "0x8",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of page walks completed due to store DTLB misses to a 2M or 4M page.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x49",
"EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M",
"PublicDescription": "Counts the number of page walks completed due to stores whose address translations missed in all Translation Lookaside Buffer (TLB) levels and were mapped to 2M or 4M pages. Includes page walks that page fault.",
"SampleAfterValue": "2000003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Page walks completed due to a demand data store to a 2M/4M page.",
"Counter": "0,1,2,3,4,5,6,7,8,9",
@@ -324,6 +372,16 @@
"UMask": "0x10",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of times there was an ITLB miss and a new translation was filled into the ITLB.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x81",
"EventName": "ITLB.FILLS",
"PublicDescription": "Counts the number of times the machine was unable to find a translation in the Instruction Translation Lookaside Buffer (ITLB) and a new translation was filled into the ITLB. The event is speculative in nature, but will not count translations (page walks) that are begun and not finished, or translations that are finished but not filled into the ITLB.",
"SampleAfterValue": "200003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of page walks initiated by a instruction fetch that missed the first and second level TLBs.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -342,6 +400,15 @@
"UMask": "0x1",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts walks that miss the PDE_CACHE",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x85",
"EventName": "ITLB_MISSES.PDE_CACHE_MISS",
"SampleAfterValue": "2000003",
"UMask": "0x80",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of first level TLB misses but second level hits due to an instruction fetch that did not start a page walk. Account for all pages sizes. Will result in an ITLB write from STLB.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -501,6 +568,24 @@
"UMask": "0x10",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of occurrences a load gets blocked because of a micro TLB miss",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x03",
"EventName": "LD_BLOCKS.DTLB_MISS",
"SampleAfterValue": "1000003",
"UMask": "0x8",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer is stalled due to a DTLB miss",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x05",
"EventName": "LD_HEAD.DTLB_MISS",
"SampleAfterValue": "1000003",
"UMask": "0x10",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer and retirement are both stalled due to a DTLB miss.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -518,5 +603,33 @@
"SampleAfterValue": "1000003",
"UMask": "0x90",
"Unit": "cpu_lowpower"
},
{
"BriefDescription": "Counts the number of PMH walks that hit in the L1 or WCBs",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xbc",
"EventName": "PAGE_WALKER_LOADS.DTLB_L1_HIT",
"SampleAfterValue": "1000003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of PMH walks that hit in the L2",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xbc",
"EventName": "PAGE_WALKER_LOADS.DTLB_L2_HIT",
"PublicDescription": "Counts the number of PMH walks that hit in the L2. Includes L2 Hit resulting from and L1D eviction of another core in the same module which is longer latency than a typical L2 hit.",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Count number of any STLB flush attempts (Entire, PCID, InvPage, CR3 write, etc)",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xbd",
"EventName": "TLB_FLUSHES.STLB_ANY",
"SampleAfterValue": "20003",
"UMask": "0x20",
"Unit": "cpu_atom"
}
]
@@ -22,7 +22,7 @@
"Unit": "CHA"
},
{
"BriefDescription": "LLC misses - Uncacheable reads (from cpu) . Derived from unc_cha_tor_inserts.ia_miss",
"BriefDescription": "LLC misses - Uncacheable reads (from cpu). Derived from unc_cha_tor_inserts.ia_miss",
"Counter": "0,1,2,3",
"EventCode": "0x35",
"EventName": "LLC_MISSES.UNCACHEABLE",
@@ -316,32 +316,32 @@
"Unit": "iMC"
},
{
"BriefDescription": "Intel Optane DC persistent memory bandwidth read (MB/sec). Derived from unc_m_pmm_rpq_inserts",
"BriefDescription": "Intel Optane DC persistent memory bandwidth read (MiB/sec). Derived from unc_m_pmm_rpq_inserts",
"Counter": "0,1,2,3",
"EventCode": "0xE3",
"EventName": "UNC_M_PMM_BANDWIDTH.READ",
"PerPkg": "1",
"ScaleUnit": "6.103515625E-5MB/sec",
"ScaleUnit": "6.103515625E-5MiB/sec",
"Unit": "iMC"
},
{
"BriefDescription": "Intel Optane DC persistent memory bandwidth total (MB/sec). Derived from unc_m_pmm_rpq_inserts",
"BriefDescription": "Intel Optane DC persistent memory bandwidth total (MiB/sec). Derived from unc_m_pmm_rpq_inserts",
"Counter": "0,1,2,3",
"EventCode": "0xE3",
"EventName": "UNC_M_PMM_BANDWIDTH.TOTAL",
"MetricExpr": "UNC_M_PMM_RPQ_INSERTS + UNC_M_PMM_WPQ_INSERTS",
"MetricName": "UNC_M_PMM_BANDWIDTH.TOTAL",
"PerPkg": "1",
"ScaleUnit": "6.103515625E-5MB/sec",
"ScaleUnit": "6.103515625E-5MiB/sec",
"Unit": "iMC"
},
{
"BriefDescription": "Intel Optane DC persistent memory bandwidth write (MB/sec). Derived from unc_m_pmm_wpq_inserts",
"BriefDescription": "Intel Optane DC persistent memory bandwidth write (MiB/sec). Derived from unc_m_pmm_wpq_inserts",
"Counter": "0,1,2,3",
"EventCode": "0xE7",
"EventName": "UNC_M_PMM_BANDWIDTH.WRITE",
"PerPkg": "1",
"ScaleUnit": "6.103515625E-5MB/sec",
"ScaleUnit": "6.103515625E-5MiB/sec",
"Unit": "iMC"
},
{
@@ -488,12 +488,12 @@
"UMask": "0x2"
},
{
"BriefDescription": "Retired load instructions which data sources missed L3 but serviced from local dram",
"BriefDescription": "Retired load instructions which data sources missed L3 but serviced from dram homed in the local socket",
"Counter": "0,1,2,3",
"Data_LA": "1",
"EventCode": "0xd3",
"EventName": "MEM_LOAD_L3_MISS_RETIRED.LOCAL_DRAM",
"PublicDescription": "Retired load instructions which data sources missed L3 but serviced from local DRAM. Available PDIST counters: 0",
"PublicDescription": "Retired load instructions which data sources missed L3 but serviced from DRAM homed in the local socket. Available PDIST counters: 0",
"RetirementLatencyMax": 4146,
"RetirementLatencyMean": 115.83,
"RetirementLatencyMin": 0,
@@ -9,6 +9,15 @@
"PublicDescription": "UNC_CHACMS_CLOCKTICKS",
"Unit": "CHACMS"
},
{
"BriefDescription": "UNC_CHACMS_DISTRESS_ASSERTED",
"Counter": "0,1,2,3",
"EventCode": "0x35",
"EventName": "UNC_CHACMS_DISTRESS_ASSERTED",
"PerPkg": "1",
"PortMask": "0x000",
"Unit": "CHACMS"
},
{
"BriefDescription": "Counts the number of cycles FAST trigger is received from the global FAST distress wire.",
"Counter": "0,1,2,3",
@@ -6050,7 +6050,7 @@
"EventName": "UNC_CHA_SNOOP_RESP.RSPIFWD",
"Experimental": "1",
"PerPkg": "1",
"PublicDescription": "Counts when a a transaction with the opcode type RspIFwd Snoop Response was received which indicates a remote caching agent forwarded the data and the requesting agent is able to acquire the data in E (Exclusive) or M (modified) states. This is commonly returned with RFO (the Read for Ownership issued before a write) transactions. The snoop could have either been to a cacheline in the M,E,F (Modified, Exclusive or Forward) states.",
"PublicDescription": "Counts when a transaction with the opcode type RspIFwd Snoop Response was received which indicates a remote caching agent forwarded the data and the requesting agent is able to acquire the data in E (Exclusive) or M (modified) states. This is commonly returned with RFO (the Read for Ownership issued before a write) transactions. The snoop could have either been to a cacheline in the M,E,F (Modified, Exclusive or Forward) states.",
"UMask": "0x4",
"Unit": "CHA"
},
@@ -6072,7 +6072,7 @@
"EventName": "UNC_CHA_SNOOP_RESP.RSPSFWD",
"Experimental": "1",
"PerPkg": "1",
"PublicDescription": "Counts when a a transaction with the opcode type RspSFwd Snoop Response was received which indicates a remote caching agent forwarded the data but held on to its current copy. This is common for data and code reads that hit in a remote socket in E (Exclusive) or F (Forward) state.",
"PublicDescription": "Counts when a transaction with the opcode type RspSFwd Snoop Response was received which indicates a remote caching agent forwarded the data but held on to its current copy. This is common for data and code reads that hit in a remote socket in E (Exclusive) or F (Forward) state.",
"UMask": "0x8",
"Unit": "CHA"
},
@@ -243,7 +243,7 @@
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of L2 prefetches initiated by either the L2 Stream or AMP that were throttled due to exceeding the XQ threshold set by either XQ_THRESOLD_DTP or XQ_THRESHOLD. Counts on a per core basis.",
"BriefDescription": "Counts the number of L2 prefetches initiated by either the L2 Stream or AMP that were throttled due to exceeding the XQ threshold set by either XQ_THRESHOLD_DTP or XQ_THRESHOLD. Counts on a per core basis.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x28",
"EventName": "L2_PREFETCHES_THROTTLED.XQ_THRESH",
@@ -464,7 +464,7 @@
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of LLC prefetches throttled due to exceeding the XQ threshold set by either XQ_THRESOLD_DTP or LLC_XQ_THRESHOLD. Counts on a per core basis.",
"BriefDescription": "Counts the number of LLC prefetches throttled due to exceeding the XQ threshold set by either XQ_THRESHOLD_DTP or LLC_XQ_THRESHOLD. Counts on a per core basis.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x29",
"EventName": "LLC_PREFETCHES_THROTTLED.XQ_THRESH",
@@ -1089,7 +1089,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_128",
@@ -1101,7 +1101,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_16",
@@ -1113,7 +1113,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_256",
@@ -1125,7 +1125,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_32",
@@ -1137,7 +1137,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_4",
@@ -1149,7 +1149,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_512",
@@ -1161,7 +1161,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_64",
@@ -1173,7 +1173,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_8",
@@ -178,6 +178,7 @@
"EventCode": "0xf4",
"EventName": "XQ_PROMOTION.ALL",
"SampleAfterValue": "1000003",
"UMask": "0x7",
"Unit": "cpu_atom"
},
{
@@ -21,8 +21,9 @@
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of active floating point and integer dividers per cycle.",
"BriefDescription": "This event is deprecated.",
"Counter": "0,1,2,3,4,5,6,7",
"Deprecated": "1",
"EventCode": "0xcd",
"EventName": "ARITH.DIV_OCCUPANCY",
"SampleAfterValue": "1000003",
@@ -30,8 +31,9 @@
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of floating point and integer divider uops executed per cycle.",
"BriefDescription": "This event is deprecated.",
"Counter": "0,1,2,3,4,5,6,7",
"Deprecated": "1",
"EventCode": "0xcd",
"EventName": "ARITH.DIV_UOPS",
"SampleAfterValue": "1000003",
@@ -1023,6 +1025,15 @@
"UMask": "0x10",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of uops executed on secondary integer ports 0,1,2,3.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb3",
"EventName": "INT_UOPS_EXECUTED.2ND",
"SampleAfterValue": "1000003",
"UMask": "0x80",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on all Integer ports.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -1205,7 +1216,7 @@
"EventCode": "0x03",
"EventName": "LD_BLOCKS.ALL",
"SampleAfterValue": "1000003",
"UMask": "0x10",
"UMask": "0x1f",
"Unit": "cpu_atom"
},
{
@@ -1613,6 +1624,15 @@
"UMask": "0x8",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of issue slots where no uop could issue due to an IQ scoreboard that stalls allocation until a specified older uop retires or (in the case of jump scoreboard) executes. Commonly executed instructions with IQ scoreboards include LFENCE and MFENCE.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x75",
"EventName": "SERIALIZATION.IQ_JEU_SCB",
"SampleAfterValue": "1000003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of issue slots not consumed by the backend due to a micro-sequencer (MS) scoreboard, which stalls the front-end from issuing from the UROM until a specified older uop retires.",
"Counter": "0,1,2,3,4,5,6,7",
+9 -9
View File
@@ -1,7 +1,7 @@
Family-model,Version,Filename,EventType
GenuineIntel-6-(97|9A|B7|BA|BF),v1.34,alderlake,core
GenuineIntel-6-BE,v1.34,alderlaken,core
GenuineIntel-6-C[56],v1.13,arrowlake,core
GenuineIntel-6-(97|9A|B7|BA|BF),v1.35,alderlake,core
GenuineIntel-6-BE,v1.35,alderlaken,core
GenuineIntel-6-C[56],v1.14,arrowlake,core
GenuineIntel-6-(1C|26|27|35|36),v5,bonnell,core
GenuineIntel-6-(3D|47),v30,broadwell,core
GenuineIntel-6-56,v12,broadwellde,core
@@ -13,24 +13,24 @@ GenuineIntel-6-CF,v1.20,emeraldrapids,core
GenuineIntel-6-5[CF],v13,goldmont,core
GenuineIntel-6-7A,v1.01,goldmontplus,core
GenuineIntel-6-B6,v1.10,grandridge,core
GenuineIntel-6-A[DE],v1.15,graniterapids,core
GenuineIntel-6-A[DE],v1.16,graniterapids,core
GenuineIntel-6-(3C|45|46),v36,haswell,core
GenuineIntel-6-3F,v29,haswellx,core
GenuineIntel-6-7[DE],v1.24,icelake,core
GenuineIntel-6-6[AC],v1.28,icelakex,core
GenuineIntel-6-6[AC],v1.30,icelakex,core
GenuineIntel-6-3A,v24,ivybridge,core
GenuineIntel-6-3E,v24,ivytown,core
GenuineIntel-6-2D,v24,jaketown,core
GenuineIntel-6-(57|85),v16,knightslanding,core
GenuineIntel-6-BD,v1.18,lunarlake,core
GenuineIntel-6-(AA|AC|B5),v1.17,meteorlake,core
GenuineIntel-6-BD,v1.19,lunarlake,core
GenuineIntel-6-(AA|AC|B5),v1.18,meteorlake,core
GenuineIntel-6-1[AEF],v4,nehalemep,core
GenuineIntel-6-2E,v4,nehalemex,core
GenuineIntel-6-CC,v1.00,pantherlake,core
GenuineIntel-6-CC,v1.02,pantherlake,core
GenuineIntel-6-A7,v1.04,rocketlake,core
GenuineIntel-6-2A,v19,sandybridge,core
GenuineIntel-6-8F,v1.35,sapphirerapids,core
GenuineIntel-6-AF,v1.12,sierraforest,core
GenuineIntel-6-AF,v1.13,sierraforest,core
GenuineIntel-6-(37|4A|4C|4D|5A),v15,silvermont,core
GenuineIntel-6-(4E|5E|8E|9E|A5|A6),v59,skylake,core
GenuineIntel-6-55-[01234],v1.37,skylakex,core
1 Family-model Version Filename EventType
2 GenuineIntel-6-(97|9A|B7|BA|BF) v1.34 v1.35 alderlake core
3 GenuineIntel-6-BE v1.34 v1.35 alderlaken core
4 GenuineIntel-6-C[56] v1.13 v1.14 arrowlake core
5 GenuineIntel-6-(1C|26|27|35|36) v5 bonnell core
6 GenuineIntel-6-(3D|47) v30 broadwell core
7 GenuineIntel-6-56 v12 broadwellde core
13 GenuineIntel-6-5[CF] v13 goldmont core
14 GenuineIntel-6-7A v1.01 goldmontplus core
15 GenuineIntel-6-B6 v1.10 grandridge core
16 GenuineIntel-6-A[DE] v1.15 v1.16 graniterapids core
17 GenuineIntel-6-(3C|45|46) v36 haswell core
18 GenuineIntel-6-3F v29 haswellx core
19 GenuineIntel-6-7[DE] v1.24 icelake core
20 GenuineIntel-6-6[AC] v1.28 v1.30 icelakex core
21 GenuineIntel-6-3A v24 ivybridge core
22 GenuineIntel-6-3E v24 ivytown core
23 GenuineIntel-6-2D v24 jaketown core
24 GenuineIntel-6-(57|85) v16 knightslanding core
25 GenuineIntel-6-BD v1.18 v1.19 lunarlake core
26 GenuineIntel-6-(AA|AC|B5) v1.17 v1.18 meteorlake core
27 GenuineIntel-6-1[AEF] v4 nehalemep core
28 GenuineIntel-6-2E v4 nehalemex core
29 GenuineIntel-6-CC v1.00 v1.02 pantherlake core
30 GenuineIntel-6-A7 v1.04 rocketlake core
31 GenuineIntel-6-2A v19 sandybridge core
32 GenuineIntel-6-8F v1.35 sapphirerapids core
33 GenuineIntel-6-AF v1.12 v1.13 sierraforest core
34 GenuineIntel-6-(37|4A|4C|4D|5A) v15 silvermont core
35 GenuineIntel-6-(4E|5E|8E|9E|A5|A6) v59 skylake core
36 GenuineIntel-6-55-[01234] v1.37 skylakex core
@@ -970,7 +970,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_1024",
@@ -982,7 +982,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_128",
@@ -994,7 +994,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_16",
@@ -1006,7 +1006,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_2048",
@@ -1018,7 +1018,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_256",
@@ -1030,7 +1030,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_32",
@@ -1042,7 +1042,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_4",
@@ -1054,7 +1054,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_512",
@@ -1066,7 +1066,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_64",
@@ -1078,7 +1078,7 @@
},
{
"BriefDescription": "Counts the number of tagged load uops retired that exceed the latency threshold defined in MEC_CR_PEBS_LD_LAT_THRESHOLD - Only counts with PEBS enabled.",
"Counter": "0,1,2,3,4,5,6,7",
"Counter": "0,1",
"Data_LA": "1",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.LOAD_LATENCY_GT_8",
@@ -383,6 +383,15 @@
"UMask": "0x10",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of unhalted cycles when the core is stalled due to a demand load miss which missed all the caches, a snoop was required, and hits in other core or module on same die. Another core provides the data with a fwd, no fwd, or hitM.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x34",
"EventName": "MEM_BOUND_STALLS_LOAD.LLC_MISS_OTHERMOD",
"SampleAfterValue": "1000003",
"UMask": "0x8",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts all retired load instructions.",
"Counter": "0,1,2,3",
@@ -727,6 +736,16 @@
"UMask": "0x40",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of load ops retired that hit in the L3 cache in which a snoop was required and modified data was forwarded.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xd4",
"EventName": "MEM_LOAD_UOPS_MISC_RETIRED.L3_HIT_SNOOP_HITM",
"PublicDescription": "Counts the number of load ops retired that hit in the L3 cache in which a snoop was required and modified data was forwarded. Available PDIST counters: 0,1",
"SampleAfterValue": "1000003",
"UMask": "0x8",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of load ops retired that hit the L1 data cache.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -830,6 +849,16 @@
"SampleAfterValue": "100021",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of memory uops retired. A single uop that performs both a load AND a store will be counted as 1, not 2 (e.g. ADD [mem], CONST).",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xd0",
"EventName": "MEM_UOPS_RETIRED.ALL",
"PublicDescription": "Counts the number of memory uops retired. A single uop that performs both a load AND a store will be counted as 1, not 2 (e.g. ADD [mem], CONST). Available PDIST counters: 0,1",
"SampleAfterValue": "1000003",
"UMask": "0x83",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of load ops retired.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -1371,5 +1400,14 @@
"SampleAfterValue": "100003",
"UMask": "0x4",
"Unit": "cpu_core"
},
{
"BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to an icache miss",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x71",
"EventName": "TOPDOWN_FE_BOUND.ICACHE",
"SampleAfterValue": "1000003",
"UMask": "0x20",
"Unit": "cpu_atom"
}
]
@@ -273,6 +273,69 @@
"UMask": "0x3f",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on all floating point ports.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb2",
"EventName": "FP_VINT_UOPS_EXECUTED.ALL",
"SampleAfterValue": "1000003",
"UMask": "0x1f",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on floating point and vector integer port 0.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb2",
"EventName": "FP_VINT_UOPS_EXECUTED.P0",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on floating point and vector integer port 1.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb2",
"EventName": "FP_VINT_UOPS_EXECUTED.P1",
"SampleAfterValue": "1000003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on floating point and vector integer port 2.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb2",
"EventName": "FP_VINT_UOPS_EXECUTED.P2",
"SampleAfterValue": "1000003",
"UMask": "0x8",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on floating point and vector integer port 3.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb2",
"EventName": "FP_VINT_UOPS_EXECUTED.P3",
"SampleAfterValue": "1000003",
"UMask": "0x10",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on floating point and vector integer port 0, 1, 2, 3.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb2",
"EventName": "FP_VINT_UOPS_EXECUTED.PRIMARY",
"SampleAfterValue": "1000003",
"UMask": "0x1e",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of uops executed on floating point and vector integer store data port.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xb2",
"EventName": "FP_VINT_UOPS_EXECUTED.STD",
"SampleAfterValue": "1000003",
"UMask": "0x1",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of floating point operations retired that required microcode assist.",
"Counter": "0,1,2,3,4,5,6,7",
@@ -282,5 +345,15 @@
"SampleAfterValue": "1000003",
"UMask": "0x4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of floating point divide uops retired (x87 and sse, including x87 sqrt).",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0xc2",
"EventName": "UOPS_RETIRED.FPDIV",
"PublicDescription": "Counts the number of floating point divide uops retired (x87 and sse, including x87 sqrt). Available PDIST counters: 0,1",
"SampleAfterValue": "1000003",
"UMask": "0x40",
"Unit": "cpu_atom"
}
]
@@ -8,6 +8,15 @@
"UMask": "0xf4",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of cycles that the head (oldest load) of the load buffer is stalled due to request buffers full or lock in progress.",
"Counter": "0,1,2,3,4,5,6,7",
"EventCode": "0x05",
"EventName": "LD_HEAD.WCB_FULL",
"SampleAfterValue": "1000003",
"UMask": "0x2",
"Unit": "cpu_atom"
},
{
"BriefDescription": "Counts the number of machine clears due to memory ordering caused by a snoop from an external agent. Does not count internally generated machine clears such as those due to memory disambiguation.",
"Counter": "0,1,2,3,4,5,6,7",

Some files were not shown because too many files have changed in this diff Show More