[Devel] [PATCH RHEL7 COMMIT] Revert "ms/perf/x86/intel: make reusable LBR initialization code"
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Oct 3 18:38:13 MSK 2019
The commit is pushed to "branch-rh7-3.10.0-957.27.2.vz7.107.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-957.27.2.vz7.107.13
------>
commit a8ba9c64e89a12ef7fb4befdfa737e6dd1ddfde8
Author: Jan Dakinevich <jan.dakinevich at virtuozzo.com>
Date: Thu Oct 3 18:38:11 2019 +0300
Revert "ms/perf/x86/intel: make reusable LBR initialization code"
This reverts commit 59528e58cb39978b4b7c7a2ba57a1ba25749456e.
Signed-off-by: Jan Dakinevich <jan.dakinevich at virtuozzo.com>
---
arch/x86/events/core.c | 6 +-
arch/x86/events/intel/core.c | 55 +++++---
arch/x86/events/intel/lbr.c | 275 +++++++++++++-------------------------
arch/x86/events/perf_event.h | 27 +++-
arch/x86/include/asm/perf_event.h | 11 --
5 files changed, 157 insertions(+), 217 deletions(-)
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index ae062afc3032..a2a9294988c4 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -365,7 +365,7 @@ int x86_add_exclusive(unsigned int what)
* When lbr_pt_coexist we allow PT to coexist with either LBR or BTS.
* LBR and BTS are still mutually exclusive.
*/
- if (x86_pmu.lbr.pt_coexist && what == x86_lbr_exclusive_pt)
+ if (x86_pmu.lbr_pt_coexist && what == x86_lbr_exclusive_pt)
return 0;
if (!atomic_inc_not_zero(&x86_pmu.lbr_exclusive[what])) {
@@ -388,7 +388,7 @@ int x86_add_exclusive(unsigned int what)
void x86_del_exclusive(unsigned int what)
{
- if (x86_pmu.lbr.pt_coexist && what == x86_lbr_exclusive_pt)
+ if (x86_pmu.lbr_pt_coexist && what == x86_lbr_exclusive_pt)
return;
atomic_dec(&x86_pmu.lbr_exclusive[what]);
@@ -493,7 +493,7 @@ int x86_pmu_max_precise(void)
precise++;
/* Support for IP fixup */
- if (x86_pmu.lbr.nr || x86_pmu.intel_cap.pebs_format >= 2)
+ if (x86_pmu.lbr_nr || x86_pmu.intel_cap.pebs_format >= 2)
precise++;
if (x86_pmu.pebs_prec_dist)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 094a43249f89..0a98b9a24f38 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -2123,7 +2123,7 @@ static void intel_pmu_reset(void)
}
/* Reset LBRs and LBR freezing */
- if (x86_pmu.lbr.nr) {
+ if (x86_pmu.lbr_nr) {
update_debugctlmsr(get_debugctlmsr() &
~(DEBUGCTLMSR_FREEZE_LBRS_ON_PMI|DEBUGCTLMSR_LBR));
}
@@ -3207,7 +3207,7 @@ static int intel_pmu_cpu_prepare(int cpu)
{
struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
- if (x86_pmu.extra_regs || x86_pmu.lbr.sel_map) {
+ if (x86_pmu.extra_regs || x86_pmu.lbr_sel_map) {
cpuc->shared_regs = allocate_shared_regs(cpu);
if (!cpuc->shared_regs)
goto err;
@@ -3300,7 +3300,7 @@ static void intel_pmu_cpu_starting(int cpu)
cpuc->shared_regs->refcnt++;
}
- if (x86_pmu.lbr.sel_map)
+ if (x86_pmu.lbr_sel_map)
cpuc->lbr_sel = &cpuc->shared_regs->regs[EXTRA_REG_LBR];
if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) {
@@ -3746,7 +3746,7 @@ static ssize_t branches_show(struct device *cdev,
struct device_attribute *attr,
char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d\n", x86_pmu.lbr.nr);
+ return snprintf(buf, PAGE_SIZE, "%d\n", x86_pmu.lbr_nr);
}
static DEVICE_ATTR_RO(branches);
@@ -3848,8 +3848,6 @@ __init int intel_pmu_init(void)
intel_ds_init();
- intel_pmu_lbr_init();
-
x86_add_quirk(intel_arch_events_quirk); /* Install first, so it runs last */
/*
@@ -3869,6 +3867,8 @@ __init int intel_pmu_init(void)
memcpy(hw_cache_event_ids, core2_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
+ intel_pmu_lbr_init_core();
+
x86_pmu.event_constraints = intel_core2_event_constraints;
x86_pmu.pebs_constraints = intel_core2_pebs_event_constraints;
pr_cont("Core2 events, ");
@@ -3883,6 +3883,8 @@ __init int intel_pmu_init(void)
memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
sizeof(hw_cache_extra_regs));
+ intel_pmu_lbr_init_nhm();
+
x86_pmu.event_constraints = intel_nehalem_event_constraints;
x86_pmu.pebs_constraints = intel_nehalem_pebs_event_constraints;
x86_pmu.enable_all = intel_pmu_nhm_enable_all;
@@ -3914,6 +3916,8 @@ __init int intel_pmu_init(void)
memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
+ intel_pmu_lbr_init_atom();
+
x86_pmu.event_constraints = intel_gen_event_constraints;
x86_pmu.pebs_constraints = intel_atom_pebs_event_constraints;
x86_pmu.pebs_aliases = intel_pebs_aliases_core2;
@@ -3931,6 +3935,8 @@ __init int intel_pmu_init(void)
memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
sizeof(hw_cache_extra_regs));
+ intel_pmu_lbr_init_slm();
+
x86_pmu.event_constraints = intel_slm_event_constraints;
x86_pmu.pebs_constraints = intel_slm_pebs_event_constraints;
x86_pmu.extra_regs = intel_slm_extra_regs;
@@ -3947,6 +3953,8 @@ __init int intel_pmu_init(void)
memcpy(hw_cache_extra_regs, glm_hw_cache_extra_regs,
sizeof(hw_cache_extra_regs));
+ intel_pmu_lbr_init_skl();
+
x86_pmu.event_constraints = intel_slm_event_constraints;
x86_pmu.pebs_constraints = intel_glm_pebs_event_constraints;
x86_pmu.extra_regs = intel_glm_extra_regs;
@@ -3957,6 +3965,7 @@ __init int intel_pmu_init(void)
*/
x86_pmu.pebs_aliases = NULL;
x86_pmu.pebs_prec_dist = true;
+ x86_pmu.lbr_pt_coexist = true;
x86_pmu.flags |= PMU_FL_HAS_RSP_1;
x86_pmu.cpu_events = glm_events_attrs;
extra_attr = slm_format_attr;
@@ -3970,6 +3979,8 @@ __init int intel_pmu_init(void)
memcpy(hw_cache_extra_regs, glp_hw_cache_extra_regs,
sizeof(hw_cache_extra_regs));
+ intel_pmu_lbr_init_skl();
+
x86_pmu.event_constraints = intel_slm_event_constraints;
x86_pmu.pebs_constraints = intel_glp_pebs_event_constraints;
x86_pmu.extra_regs = intel_glm_extra_regs;
@@ -3979,6 +3990,7 @@ __init int intel_pmu_init(void)
*/
x86_pmu.pebs_aliases = NULL;
x86_pmu.pebs_prec_dist = true;
+ x86_pmu.lbr_pt_coexist = true;
x86_pmu.flags |= PMU_FL_HAS_RSP_1;
x86_pmu.get_event_constraints = glp_get_event_constraints;
x86_pmu.cpu_events = glm_events_attrs;
@@ -3997,6 +4009,8 @@ __init int intel_pmu_init(void)
memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
sizeof(hw_cache_extra_regs));
+ intel_pmu_lbr_init_nhm();
+
x86_pmu.event_constraints = intel_westmere_event_constraints;
x86_pmu.enable_all = intel_pmu_nhm_enable_all;
x86_pmu.pebs_constraints = intel_westmere_pebs_event_constraints;
@@ -4027,6 +4041,8 @@ __init int intel_pmu_init(void)
memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
sizeof(hw_cache_extra_regs));
+ intel_pmu_lbr_init_snb();
+
x86_pmu.event_constraints = intel_snb_event_constraints;
x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints;
x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
@@ -4066,6 +4082,8 @@ __init int intel_pmu_init(void)
memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
sizeof(hw_cache_extra_regs));
+ intel_pmu_lbr_init_snb();
+
x86_pmu.event_constraints = intel_ivb_event_constraints;
x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints;
x86_pmu.pebs_aliases = intel_pebs_aliases_ivb;
@@ -4100,6 +4118,8 @@ __init int intel_pmu_init(void)
memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids));
memcpy(hw_cache_extra_regs, hsw_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
+ intel_pmu_lbr_init_hsw();
+
x86_pmu.event_constraints = intel_hsw_event_constraints;
x86_pmu.pebs_constraints = intel_hsw_pebs_event_constraints;
x86_pmu.extra_regs = intel_snbep_extra_regs;
@@ -4112,6 +4132,7 @@ __init int intel_pmu_init(void)
x86_pmu.hw_config = hsw_hw_config;
x86_pmu.get_event_constraints = hsw_get_event_constraints;
x86_pmu.cpu_events = get_hsw_events_attrs();
+ x86_pmu.lbr_double_abort = true;
extra_attr = boot_cpu_has(X86_FEATURE_RTM) ?
hsw_format_attr : nhm_format_attr;
pr_cont("Haswell events, ");
@@ -4136,6 +4157,8 @@ __init int intel_pmu_init(void)
hw_cache_extra_regs[C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = HSW_DEMAND_WRITE|
BDW_L3_MISS_LOCAL|HSW_SNOOP_DRAM;
+ intel_pmu_lbr_init_hsw();
+
x86_pmu.event_constraints = intel_bdw_event_constraints;
x86_pmu.pebs_constraints = intel_bdw_pebs_event_constraints;
x86_pmu.extra_regs = intel_snbep_extra_regs;
@@ -4161,6 +4184,7 @@ __init int intel_pmu_init(void)
slm_hw_cache_event_ids, sizeof(hw_cache_event_ids));
memcpy(hw_cache_extra_regs,
knl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
+ intel_pmu_lbr_init_knl();
x86_pmu.event_constraints = intel_slm_event_constraints;
x86_pmu.pebs_constraints = intel_slm_pebs_event_constraints;
@@ -4182,6 +4206,7 @@ __init int intel_pmu_init(void)
x86_pmu.late_ack = true;
memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
+ intel_pmu_lbr_init_skl();
x86_pmu.event_constraints = intel_skl_event_constraints;
x86_pmu.pebs_constraints = intel_skl_pebs_event_constraints;
@@ -4269,19 +4294,19 @@ __init int intel_pmu_init(void)
* Check all LBT MSR here.
* Disable LBR access if any LBR MSRs can not be accessed.
*/
- if (x86_pmu.lbr.nr && !check_msr(x86_pmu.lbr.tos, 0x3UL))
- x86_pmu.lbr.nr = 0;
- for (i = 0; i < x86_pmu.lbr.nr; i++) {
- if (!(check_msr(x86_pmu.lbr.from + i, 0xffffUL) &&
- check_msr(x86_pmu.lbr.to + i, 0xffffUL)))
- x86_pmu.lbr.nr = 0;
+ if (x86_pmu.lbr_nr && !check_msr(x86_pmu.lbr_tos, 0x3UL))
+ x86_pmu.lbr_nr = 0;
+ for (i = 0; i < x86_pmu.lbr_nr; i++) {
+ if (!(check_msr(x86_pmu.lbr_from + i, 0xffffUL) &&
+ check_msr(x86_pmu.lbr_to + i, 0xffffUL)))
+ x86_pmu.lbr_nr = 0;
}
x86_pmu.caps_attrs = intel_pmu_caps_attrs;
- if (x86_pmu.lbr.nr) {
+ if (x86_pmu.lbr_nr) {
x86_pmu.caps_attrs = merge_attr(x86_pmu.caps_attrs, lbr_attrs);
- pr_cont("%d-deep LBR, ", x86_pmu.lbr.nr);
+ pr_cont("%d-deep LBR, ", x86_pmu.lbr_nr);
}
/*
@@ -4294,7 +4319,7 @@ __init int intel_pmu_init(void)
er->extra_msr_access = check_msr(er->msr, 0x11UL);
/* Disable LBR select mapping */
if ((er->idx == EXTRA_REG_LBR) && !er->extra_msr_access)
- x86_pmu.lbr.sel_map = NULL;
+ x86_pmu.lbr_sel_map = NULL;
}
}
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index bbb541552211..b01ad77d87dd 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -4,7 +4,6 @@
#include <asm/perf_event.h>
#include <asm/msr.h>
#include <asm/insn.h>
-#include <asm/intel-family.h>
#include "../perf_event.h"
@@ -165,7 +164,7 @@ static void __intel_pmu_lbr_enable(bool pmi)
* did not change.
*/
if (cpuc->lbr_sel)
- lbr_select = cpuc->lbr_sel->config & x86_pmu.lbr.sel_mask;
+ lbr_select = cpuc->lbr_sel->config & x86_pmu.lbr_sel_mask;
if (!pmi && cpuc->lbr_sel)
wrmsrl(MSR_LBR_SELECT, lbr_select);
@@ -194,17 +193,17 @@ static void intel_pmu_lbr_reset_32(void)
{
int i;
- for (i = 0; i < x86_pmu.lbr.nr; i++)
- wrmsrl(x86_pmu.lbr.from + i, 0);
+ for (i = 0; i < x86_pmu.lbr_nr; i++)
+ wrmsrl(x86_pmu.lbr_from + i, 0);
}
static void intel_pmu_lbr_reset_64(void)
{
int i;
- for (i = 0; i < x86_pmu.lbr.nr; i++) {
- wrmsrl(x86_pmu.lbr.from + i, 0);
- wrmsrl(x86_pmu.lbr.to + i, 0);
+ for (i = 0; i < x86_pmu.lbr_nr; i++) {
+ wrmsrl(x86_pmu.lbr_from + i, 0);
+ wrmsrl(x86_pmu.lbr_to + i, 0);
if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
wrmsrl(MSR_LBR_INFO_0 + i, 0);
}
@@ -212,7 +211,7 @@ static void intel_pmu_lbr_reset_64(void)
void intel_pmu_lbr_reset(void)
{
- if (!x86_pmu.lbr.nr)
+ if (!x86_pmu.lbr_nr)
return;
if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
@@ -228,7 +227,7 @@ static inline u64 intel_pmu_lbr_tos(void)
{
u64 tos;
- rdmsrl(x86_pmu.lbr.tos, tos);
+ rdmsrl(x86_pmu.lbr_tos, tos);
return tos;
}
@@ -249,12 +248,12 @@ static void __intel_pmu_lbr_restore(struct x86_perf_task_context *task_ctx)
return;
}
- mask = x86_pmu.lbr.nr - 1;
+ mask = x86_pmu.lbr_nr - 1;
tos = intel_pmu_lbr_tos();
for (i = 0; i < tos; i++) {
lbr_idx = (tos - i) & mask;
- wrmsrl(x86_pmu.lbr.from + lbr_idx, task_ctx->lbr_from[i]);
- wrmsrl(x86_pmu.lbr.to + lbr_idx, task_ctx->lbr_to[i]);
+ wrmsrl(x86_pmu.lbr_from + lbr_idx, task_ctx->lbr_from[i]);
+ wrmsrl(x86_pmu.lbr_to + lbr_idx, task_ctx->lbr_to[i]);
if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
wrmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]);
}
@@ -272,12 +271,12 @@ static void __intel_pmu_lbr_save(struct x86_perf_task_context *task_ctx)
return;
}
- mask = x86_pmu.lbr.nr - 1;
+ mask = x86_pmu.lbr_nr - 1;
tos = intel_pmu_lbr_tos();
for (i = 0; i < tos; i++) {
lbr_idx = (tos - i) & mask;
- rdmsrl(x86_pmu.lbr.from + lbr_idx, task_ctx->lbr_from[i]);
- rdmsrl(x86_pmu.lbr.to + lbr_idx, task_ctx->lbr_to[i]);
+ rdmsrl(x86_pmu.lbr_from + lbr_idx, task_ctx->lbr_from[i]);
+ rdmsrl(x86_pmu.lbr_to + lbr_idx, task_ctx->lbr_to[i]);
if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_INFO)
rdmsrl(MSR_LBR_INFO_0 + lbr_idx, task_ctx->lbr_info[i]);
}
@@ -326,7 +325,7 @@ void intel_pmu_lbr_add(struct perf_event *event)
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct x86_perf_task_context *task_ctx;
- if (!x86_pmu.lbr.nr)
+ if (!x86_pmu.lbr_nr)
return;
cpuc->br_sel = event->hw.branch_reg.reg;
@@ -365,7 +364,7 @@ void intel_pmu_lbr_del(struct perf_event *event)
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct x86_perf_task_context *task_ctx;
- if (!x86_pmu.lbr.nr)
+ if (!x86_pmu.lbr_nr)
return;
if (branch_user_callstack(cpuc->br_sel) &&
@@ -397,11 +396,11 @@ void intel_pmu_lbr_disable_all(void)
static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)
{
- unsigned long mask = x86_pmu.lbr.nr - 1;
+ unsigned long mask = x86_pmu.lbr_nr - 1;
u64 tos = intel_pmu_lbr_tos();
int i;
- for (i = 0; i < x86_pmu.lbr.nr; i++) {
+ for (i = 0; i < x86_pmu.lbr_nr; i++) {
unsigned long lbr_idx = (tos - i) & mask;
union {
struct {
@@ -411,7 +410,7 @@ static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)
u64 lbr;
} msr_lastbranch;
- rdmsrl(x86_pmu.lbr.from + lbr_idx, msr_lastbranch.lbr);
+ rdmsrl(x86_pmu.lbr_from + lbr_idx, msr_lastbranch.lbr);
cpuc->lbr_entries[i].from = msr_lastbranch.from;
cpuc->lbr_entries[i].to = msr_lastbranch.to;
@@ -434,12 +433,12 @@ static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)
static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
{
bool need_info = false;
- unsigned long mask = x86_pmu.lbr.nr - 1;
+ unsigned long mask = x86_pmu.lbr_nr - 1;
int lbr_format = x86_pmu.intel_cap.lbr_format;
u64 tos = intel_pmu_lbr_tos();
int i;
int out = 0;
- int num = x86_pmu.lbr.nr;
+ int num = x86_pmu.lbr_nr;
if (cpuc->lbr_sel) {
need_info = !(cpuc->lbr_sel->config & LBR_NO_INFO);
@@ -454,8 +453,8 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
u16 cycles = 0;
int lbr_flags = lbr_desc[lbr_format];
- rdmsrl(x86_pmu.lbr.from + lbr_idx, from);
- rdmsrl(x86_pmu.lbr.to + lbr_idx, to);
+ rdmsrl(x86_pmu.lbr_from + lbr_idx, from);
+ rdmsrl(x86_pmu.lbr_to + lbr_idx, to);
if (lbr_format == LBR_FORMAT_INFO && need_info) {
u64 info;
@@ -497,7 +496,7 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
* If the abort just happened outside the window
* the extra entry cannot be removed.
*/
- if (abort && x86_pmu.lbr.double_abort && out > 0)
+ if (abort && x86_pmu.lbr_double_abort && out > 0)
out--;
cpuc->lbr_entries[out].from = from;
@@ -613,7 +612,7 @@ static int intel_pmu_setup_hw_lbr_filter(struct perf_event *event)
if (!(br_type & (1ULL << i)))
continue;
- v = x86_pmu.lbr.sel_map[i];
+ v = x86_pmu.lbr_sel_map[i];
if (v == LBR_NOT_SUPP)
return -EOPNOTSUPP;
@@ -631,7 +630,7 @@ static int intel_pmu_setup_hw_lbr_filter(struct perf_event *event)
* But the 10th bit LBR_CALL_STACK does not operate
* in suppress mode.
*/
- reg->config = mask ^ (x86_pmu.lbr.sel_mask & ~LBR_CALL_STACK);
+ reg->config = mask ^ (x86_pmu.lbr_sel_mask & ~LBR_CALL_STACK);
if ((br_type & PERF_SAMPLE_BRANCH_NO_CYCLES) &&
(br_type & PERF_SAMPLE_BRANCH_NO_FLAGS) &&
@@ -648,7 +647,7 @@ int intel_pmu_setup_lbr_filter(struct perf_event *event)
/*
* no LBR on this PMU
*/
- if (!x86_pmu.lbr.nr)
+ if (!x86_pmu.lbr_nr)
return -EOPNOTSUPP;
/*
@@ -661,7 +660,7 @@ int intel_pmu_setup_lbr_filter(struct perf_event *event)
/*
* setup HW LBR filter, if any
*/
- if (x86_pmu.lbr.sel_map)
+ if (x86_pmu.lbr_sel_map)
ret = intel_pmu_setup_hw_lbr_filter(event);
return ret;
@@ -991,12 +990,12 @@ static const int hsw_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
};
/* core */
-static void intel_pmu_lbr_init_core(struct x86_pmu_lbr *lbr)
+void __init intel_pmu_lbr_init_core(void)
{
- lbr->nr = 4;
- lbr->tos = MSR_LBR_TOS;
- lbr->from = MSR_LBR_CORE_FROM;
- lbr->to = MSR_LBR_CORE_TO;
+ x86_pmu.lbr_nr = 4;
+ x86_pmu.lbr_tos = MSR_LBR_TOS;
+ x86_pmu.lbr_from = MSR_LBR_CORE_FROM;
+ x86_pmu.lbr_to = MSR_LBR_CORE_TO;
/*
* SW branch filter usage:
@@ -1005,15 +1004,15 @@ static void intel_pmu_lbr_init_core(struct x86_pmu_lbr *lbr)
}
/* nehalem/westmere */
-static void intel_pmu_lbr_init_nhm(struct x86_pmu_lbr *lbr)
+void __init intel_pmu_lbr_init_nhm(void)
{
- lbr->nr = 16;
- lbr->tos = MSR_LBR_TOS;
- lbr->from = MSR_LBR_NHM_FROM;
- lbr->to = MSR_LBR_NHM_TO;
+ x86_pmu.lbr_nr = 16;
+ x86_pmu.lbr_tos = MSR_LBR_TOS;
+ x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
+ x86_pmu.lbr_to = MSR_LBR_NHM_TO;
- lbr->sel_mask = LBR_SEL_MASK;
- lbr->sel_map = nhm_lbr_sel_map;
+ x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
+ x86_pmu.lbr_sel_map = nhm_lbr_sel_map;
/*
* SW branch filter usage:
@@ -1025,15 +1024,15 @@ static void intel_pmu_lbr_init_nhm(struct x86_pmu_lbr *lbr)
}
/* sandy bridge */
-static void intel_pmu_lbr_init_snb(struct x86_pmu_lbr *lbr)
+void __init intel_pmu_lbr_init_snb(void)
{
- lbr->nr = 16;
- lbr->tos = MSR_LBR_TOS;
- lbr->from = MSR_LBR_NHM_FROM;
- lbr->to = MSR_LBR_NHM_TO;
+ x86_pmu.lbr_nr = 16;
+ x86_pmu.lbr_tos = MSR_LBR_TOS;
+ x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
+ x86_pmu.lbr_to = MSR_LBR_NHM_TO;
- lbr->sel_mask = LBR_SEL_MASK;
- lbr->sel_map = snb_lbr_sel_map;
+ x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
+ x86_pmu.lbr_sel_map = snb_lbr_sel_map;
/*
* SW branch filter usage:
@@ -1044,27 +1043,27 @@ static void intel_pmu_lbr_init_snb(struct x86_pmu_lbr *lbr)
}
/* haswell */
-static void intel_pmu_lbr_init_hsw(struct x86_pmu_lbr *lbr)
+void intel_pmu_lbr_init_hsw(void)
{
- lbr->nr = 16;
- lbr->tos = MSR_LBR_TOS;
- lbr->from = MSR_LBR_NHM_FROM;
- lbr->to = MSR_LBR_NHM_TO;
+ x86_pmu.lbr_nr = 16;
+ x86_pmu.lbr_tos = MSR_LBR_TOS;
+ x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
+ x86_pmu.lbr_to = MSR_LBR_NHM_TO;
- lbr->sel_mask = LBR_SEL_MASK;
- lbr->sel_map = hsw_lbr_sel_map;
+ x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
+ x86_pmu.lbr_sel_map = hsw_lbr_sel_map;
}
/* skylake */
-static void intel_pmu_lbr_init_skl(struct x86_pmu_lbr *lbr)
+__init void intel_pmu_lbr_init_skl(void)
{
- lbr->nr = 32;
- lbr->tos = MSR_LBR_TOS;
- lbr->from = MSR_LBR_NHM_FROM;
- lbr->to = MSR_LBR_NHM_TO;
+ x86_pmu.lbr_nr = 32;
+ x86_pmu.lbr_tos = MSR_LBR_TOS;
+ x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
+ x86_pmu.lbr_to = MSR_LBR_NHM_TO;
- lbr->sel_mask = LBR_SEL_MASK;
- lbr->sel_map = hsw_lbr_sel_map;
+ x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
+ x86_pmu.lbr_sel_map = hsw_lbr_sel_map;
/*
* SW branch filter usage:
@@ -1075,12 +1074,23 @@ static void intel_pmu_lbr_init_skl(struct x86_pmu_lbr *lbr)
}
/* atom */
-static void intel_pmu_lbr_init_atom(struct x86_pmu_lbr *lbr)
+void __init intel_pmu_lbr_init_atom(void)
{
- lbr->nr = 8;
- lbr->tos = MSR_LBR_TOS;
- lbr->from = MSR_LBR_CORE_FROM;
- lbr->to = MSR_LBR_CORE_TO;
+ /*
+ * only models starting at stepping 10 seems
+ * to have an operational LBR which can freeze
+ * on PMU interrupt
+ */
+ if (boot_cpu_data.x86_model == 28
+ && boot_cpu_data.x86_mask < 10) {
+ pr_cont("LBR disabled due to erratum");
+ return;
+ }
+
+ x86_pmu.lbr_nr = 8;
+ x86_pmu.lbr_tos = MSR_LBR_TOS;
+ x86_pmu.lbr_from = MSR_LBR_CORE_FROM;
+ x86_pmu.lbr_to = MSR_LBR_CORE_TO;
/*
* SW branch filter usage:
@@ -1089,132 +1099,31 @@ static void intel_pmu_lbr_init_atom(struct x86_pmu_lbr *lbr)
}
/* slm */
-static void intel_pmu_lbr_init_slm(struct x86_pmu_lbr *lbr)
+void __init intel_pmu_lbr_init_slm(void)
{
- lbr->nr = 8;
- lbr->tos = MSR_LBR_TOS;
- lbr->from = MSR_LBR_CORE_FROM;
- lbr->to = MSR_LBR_CORE_TO;
+ x86_pmu.lbr_nr = 8;
+ x86_pmu.lbr_tos = MSR_LBR_TOS;
+ x86_pmu.lbr_from = MSR_LBR_CORE_FROM;
+ x86_pmu.lbr_to = MSR_LBR_CORE_TO;
- lbr->sel_mask = LBR_SEL_MASK;
- lbr->sel_map = nhm_lbr_sel_map;
+ x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
+ x86_pmu.lbr_sel_map = nhm_lbr_sel_map;
/*
* SW branch filter usage:
* - compensate for lack of HW filter
*/
+ pr_cont("8-deep LBR, ");
}
/* Knights Landing */
-static void intel_pmu_lbr_init_knl(struct x86_pmu_lbr *lbr)
-{
- lbr->nr = 8;
- lbr->tos = MSR_LBR_TOS;
- lbr->from = MSR_LBR_NHM_FROM;
- lbr->to = MSR_LBR_NHM_TO;
-
- lbr->sel_mask = LBR_SEL_MASK;
- lbr->sel_map = snb_lbr_sel_map;
-}
-
-static void __intel_pmu_lbr_fill(struct x86_pmu_lbr *lbr, u8 family, u8 model)
+void intel_pmu_lbr_init_knl(void)
{
- bool apply_tweaks = lbr == &x86_pmu.lbr;
+ x86_pmu.lbr_nr = 8;
+ x86_pmu.lbr_tos = MSR_LBR_TOS;
+ x86_pmu.lbr_from = MSR_LBR_NHM_FROM;
+ x86_pmu.lbr_to = MSR_LBR_NHM_TO;
- memset(lbr, 0, sizeof(struct x86_pmu_lbr));
-
- if (family != 0x6)
- return;
-
- switch (model) {
- case INTEL_FAM6_CORE_YONAH:
- break;
- case INTEL_FAM6_CORE2_MEROM:
- case INTEL_FAM6_CORE2_MEROM_L:
- case INTEL_FAM6_CORE2_PENRYN:
- case INTEL_FAM6_CORE2_DUNNINGTON:
- intel_pmu_lbr_init_core(lbr);
- break;
- case INTEL_FAM6_NEHALEM:
- case INTEL_FAM6_NEHALEM_EP:
- case INTEL_FAM6_NEHALEM_EX:
- case INTEL_FAM6_WESTMERE:
- case INTEL_FAM6_WESTMERE_EP:
- case INTEL_FAM6_WESTMERE_EX:
- intel_pmu_lbr_init_nhm(lbr);
- break;
- case INTEL_FAM6_ATOM_BONNELL:
- case INTEL_FAM6_ATOM_BONNELL_MID:
- case INTEL_FAM6_ATOM_SALTWELL_MID:
- case INTEL_FAM6_ATOM_SALTWELL_TABLET:
- case INTEL_FAM6_ATOM_SALTWELL:
- /*
- * only models starting at stepping 10 seems
- * to have an operational LBR which can freeze
- * on PMU interrupt
- */
- if (apply_tweaks &&
- boot_cpu_data.x86_model == INTEL_FAM6_ATOM_BONNELL &&
- boot_cpu_data.x86_mask < 10) {
- pr_cont("LBR disabled due to erratum");
- return;
- }
- intel_pmu_lbr_init_atom(lbr);
- break;
- case INTEL_FAM6_ATOM_SILVERMONT:
- case INTEL_FAM6_ATOM_SILVERMONT_X:
- case INTEL_FAM6_ATOM_AIRMONT:
- intel_pmu_lbr_init_slm(lbr);
- break;
- case INTEL_FAM6_ATOM_GOLDMONT:
- case INTEL_FAM6_ATOM_GOLDMONT_X:
- case INTEL_FAM6_ATOM_GOLDMONT_PLUS:
- lbr->pt_coexist = true;
- case INTEL_FAM6_SKYLAKE_MOBILE:
- case INTEL_FAM6_SKYLAKE_DESKTOP:
- case INTEL_FAM6_SKYLAKE_X:
- case INTEL_FAM6_KABYLAKE_MOBILE:
- case INTEL_FAM6_KABYLAKE_DESKTOP:
- intel_pmu_lbr_init_skl(lbr);
- break;
- case INTEL_FAM6_SANDYBRIDGE:
- case INTEL_FAM6_SANDYBRIDGE_X:
- case INTEL_FAM6_IVYBRIDGE:
- case INTEL_FAM6_IVYBRIDGE_X:
- intel_pmu_lbr_init_snb(lbr);
- break;
- case INTEL_FAM6_HASWELL_CORE:
- case INTEL_FAM6_HASWELL_X:
- case INTEL_FAM6_HASWELL_ULT:
- case INTEL_FAM6_HASWELL_GT3E:
- lbr->double_abort = true;
- case INTEL_FAM6_BROADWELL_CORE:
- case INTEL_FAM6_BROADWELL_XEON_D:
- case INTEL_FAM6_BROADWELL_GT3E:
- case INTEL_FAM6_BROADWELL_X:
- /*
- * OpenVZ kernel doesn't have Goldmont Plus CPU PMU support
- */
- if (apply_tweaks &&
- boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT_PLUS)
- return;
- intel_pmu_lbr_init_hsw(lbr);
- break;
- case INTEL_FAM6_XEON_PHI_KNL:
- case INTEL_FAM6_XEON_PHI_KNM:
- intel_pmu_lbr_init_knl(lbr);
- break;
- }
-}
-
-void __init intel_pmu_lbr_init(void)
-{
- __intel_pmu_lbr_fill(&x86_pmu.lbr, boot_cpu_data.x86,
- boot_cpu_data.x86_model);
-}
-
-void intel_pmu_lbr_fill(struct x86_pmu_lbr *lbr, u8 family, u8 model)
-{
- __intel_pmu_lbr_fill(lbr, family, model);
+ x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
+ x86_pmu.lbr_sel_map = snb_lbr_sel_map;
}
-EXPORT_SYMBOL_GPL(intel_pmu_lbr_fill);
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index 8e465fb7910d..e48949b246cf 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -626,7 +626,12 @@ struct x86_pmu {
/*
* Intel LBR
*/
- struct x86_pmu_lbr lbr;
+ unsigned long lbr_tos, lbr_from, lbr_to; /* MSR base regs */
+ int lbr_nr; /* hardware stack size */
+ u64 lbr_sel_mask; /* LBR_SELECT valid bits */
+ const int *lbr_sel_map; /* lbr_select mappings */
+ bool lbr_double_abort; /* duplicated lbr aborts */
+ bool lbr_pt_coexist; /* (LBR|BTS) may coexist with PT */
/*
* Intel PT/LBR/BTS are exclusive
@@ -696,8 +701,8 @@ extern struct x86_pmu x86_pmu __read_mostly;
static inline bool x86_pmu_has_lbr_callstack(void)
{
- return x86_pmu.lbr.sel_map &&
- x86_pmu.lbr.sel_map[PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT] > 0;
+ return x86_pmu.lbr_sel_map &&
+ x86_pmu.lbr_sel_map[PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT] > 0;
}
DECLARE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
@@ -933,9 +938,21 @@ void intel_pmu_lbr_disable_all(void);
void intel_pmu_lbr_read(void);
-void intel_pmu_lbr_init(void);
+void intel_pmu_lbr_init_core(void);
-void intel_pmu_lbr_fill(struct x86_pmu_lbr *lbr, u8 family, u8 model);
+void intel_pmu_lbr_init_nhm(void);
+
+void intel_pmu_lbr_init_atom(void);
+
+void intel_pmu_lbr_init_slm(void);
+
+void intel_pmu_lbr_init_snb(void);
+
+void intel_pmu_lbr_init_hsw(void);
+
+void intel_pmu_lbr_init_skl(void);
+
+void intel_pmu_lbr_init_knl(void);
void intel_pmu_pebs_data_source_nhm(void);
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index bf9f2086dbbe..f353061bba1d 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -124,15 +124,6 @@ struct x86_pmu_capability {
int events_mask_len;
};
-struct x86_pmu_lbr {
- unsigned long tos, from, to; /* MSR base regs */
- int nr; /* hardware stack size */
- u64 sel_mask; /* LBR_SELECT valid bits */
- const int *sel_map; /* lbr_select mappings */
- bool double_abort; /* duplicated lbr aborts */
- bool pt_coexist; /* (LBR|BTS) may coexist with PT */
-};
-
/*
* Fixed-purpose performance events:
*/
@@ -308,6 +299,4 @@ static inline void perf_check_microcode(void) { }
#define arch_perf_out_copy_user copy_from_user_nmi
-extern void intel_pmu_lbr_fill(struct x86_pmu_lbr *lbr, u8 family, u8 model);
-
#endif /* _ASM_X86_PERF_EVENT_H */
More information about the Devel
mailing list