[Devel] [PATCH RHEL7 COMMIT] ms/perf/x86/intel: make reusable LBR initialization code, part 1/2
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Oct 3 18:38:14 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 81325a25ac55eaf25a7c26746a4bff4f42c9c1a0
Author: Jan Dakinevich <jan.dakinevich at virtuozzo.com>
Date: Thu Oct 3 18:38:12 2019 +0300
ms/perf/x86/intel: make reusable LBR initialization code, part 1/2
Move LBR information from `struct x86_pmu' to separate structure
`struct x86_pmu_lbr'.
LBR initialization is nailed to perf subsystem and to global
'boot_x86_pmu' structure. To reuse this code and keep these changes
readable the work splited into to parts.
https://jira.sw.ru/browse/PSBM-75679
Signed-off-by: Jan Dakinevich <jan.dakinevich at virtuozzo.com>
---
arch/x86/events/core.c | 6 +-
arch/x86/events/intel/core.c | 58 ++++++-------
arch/x86/events/intel/lbr.c | 172 ++++++++++++++++++--------------------
arch/x86/events/perf_event.h | 27 +++---
arch/x86/include/asm/perf_event.h | 9 ++
5 files changed, 132 insertions(+), 140 deletions(-)
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index a2a9294988c4..ae062afc3032 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 0a98b9a24f38..c0ce9c6b30b6 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);
@@ -3867,7 +3867,7 @@ __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();
+ intel_pmu_lbr_init_core(&x86_pmu.lbr);
x86_pmu.event_constraints = intel_core2_event_constraints;
x86_pmu.pebs_constraints = intel_core2_pebs_event_constraints;
@@ -3883,7 +3883,7 @@ __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();
+ intel_pmu_lbr_init_nhm(&x86_pmu.lbr);
x86_pmu.event_constraints = intel_nehalem_event_constraints;
x86_pmu.pebs_constraints = intel_nehalem_pebs_event_constraints;
@@ -3916,7 +3916,7 @@ __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();
+ intel_pmu_lbr_init_atom(&x86_pmu.lbr);
x86_pmu.event_constraints = intel_gen_event_constraints;
x86_pmu.pebs_constraints = intel_atom_pebs_event_constraints;
@@ -3935,7 +3935,7 @@ __init int intel_pmu_init(void)
memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
sizeof(hw_cache_extra_regs));
- intel_pmu_lbr_init_slm();
+ intel_pmu_lbr_init_slm(&x86_pmu.lbr);
x86_pmu.event_constraints = intel_slm_event_constraints;
x86_pmu.pebs_constraints = intel_slm_pebs_event_constraints;
@@ -3953,7 +3953,7 @@ __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();
+ intel_pmu_lbr_init_skl(&x86_pmu.lbr);
x86_pmu.event_constraints = intel_slm_event_constraints;
x86_pmu.pebs_constraints = intel_glm_pebs_event_constraints;
@@ -3965,7 +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.lbr.pt_coexist = true;
x86_pmu.flags |= PMU_FL_HAS_RSP_1;
x86_pmu.cpu_events = glm_events_attrs;
extra_attr = slm_format_attr;
@@ -3979,7 +3979,7 @@ __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();
+ intel_pmu_lbr_init_skl(&x86_pmu.lbr);
x86_pmu.event_constraints = intel_slm_event_constraints;
x86_pmu.pebs_constraints = intel_glp_pebs_event_constraints;
@@ -3990,7 +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.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;
@@ -4009,7 +4009,7 @@ __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();
+ intel_pmu_lbr_init_nhm(&x86_pmu.lbr);
x86_pmu.event_constraints = intel_westmere_event_constraints;
x86_pmu.enable_all = intel_pmu_nhm_enable_all;
@@ -4041,7 +4041,7 @@ __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();
+ intel_pmu_lbr_init_snb(&x86_pmu.lbr);
x86_pmu.event_constraints = intel_snb_event_constraints;
x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints;
@@ -4082,7 +4082,7 @@ __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();
+ intel_pmu_lbr_init_snb(&x86_pmu.lbr);
x86_pmu.event_constraints = intel_ivb_event_constraints;
x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints;
@@ -4118,7 +4118,7 @@ __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();
+ intel_pmu_lbr_init_hsw(&x86_pmu.lbr);
x86_pmu.event_constraints = intel_hsw_event_constraints;
x86_pmu.pebs_constraints = intel_hsw_pebs_event_constraints;
@@ -4132,7 +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;
+ x86_pmu.lbr.double_abort = true;
extra_attr = boot_cpu_has(X86_FEATURE_RTM) ?
hsw_format_attr : nhm_format_attr;
pr_cont("Haswell events, ");
@@ -4157,7 +4157,7 @@ __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();
+ intel_pmu_lbr_init_hsw(&x86_pmu.lbr);
x86_pmu.event_constraints = intel_bdw_event_constraints;
x86_pmu.pebs_constraints = intel_bdw_pebs_event_constraints;
@@ -4184,7 +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();
+ intel_pmu_lbr_init_knl(&x86_pmu.lbr);
x86_pmu.event_constraints = intel_slm_event_constraints;
x86_pmu.pebs_constraints = intel_slm_pebs_event_constraints;
@@ -4206,7 +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();
+ intel_pmu_lbr_init_skl(&x86_pmu.lbr);
x86_pmu.event_constraints = intel_skl_event_constraints;
x86_pmu.pebs_constraints = intel_skl_pebs_event_constraints;
@@ -4294,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);
}
/*
@@ -4319,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 b01ad77d87dd..ac08ac962b2f 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -164,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);
@@ -193,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);
}
@@ -211,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)
@@ -227,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;
}
@@ -248,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]);
}
@@ -271,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]);
}
@@ -325,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;
@@ -364,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) &&
@@ -396,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 {
@@ -410,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;
@@ -433,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);
@@ -453,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;
@@ -496,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;
@@ -612,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;
@@ -630,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) &&
@@ -647,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;
/*
@@ -660,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;
@@ -990,12 +990,12 @@ static const int hsw_lbr_sel_map[PERF_SAMPLE_BRANCH_MAX_SHIFT] = {
};
/* core */
-void __init intel_pmu_lbr_init_core(void)
+void __init intel_pmu_lbr_init_core(struct x86_pmu_lbr *lbr)
{
- 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;
+ lbr->nr = 4;
+ lbr->tos = MSR_LBR_TOS;
+ lbr->from = MSR_LBR_CORE_FROM;
+ lbr->to = MSR_LBR_CORE_TO;
/*
* SW branch filter usage:
@@ -1004,15 +1004,15 @@ void __init intel_pmu_lbr_init_core(void)
}
/* nehalem/westmere */
-void __init intel_pmu_lbr_init_nhm(void)
+void __init intel_pmu_lbr_init_nhm(struct x86_pmu_lbr *lbr)
{
- 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->nr = 16;
+ lbr->tos = MSR_LBR_TOS;
+ lbr->from = MSR_LBR_NHM_FROM;
+ lbr->to = MSR_LBR_NHM_TO;
- x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
- x86_pmu.lbr_sel_map = nhm_lbr_sel_map;
+ lbr->sel_mask = LBR_SEL_MASK;
+ lbr->sel_map = nhm_lbr_sel_map;
/*
* SW branch filter usage:
@@ -1024,15 +1024,15 @@ void __init intel_pmu_lbr_init_nhm(void)
}
/* sandy bridge */
-void __init intel_pmu_lbr_init_snb(void)
+void __init intel_pmu_lbr_init_snb(struct x86_pmu_lbr *lbr)
{
- 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->nr = 16;
+ lbr->tos = MSR_LBR_TOS;
+ lbr->from = MSR_LBR_NHM_FROM;
+ lbr->to = MSR_LBR_NHM_TO;
- x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
- x86_pmu.lbr_sel_map = snb_lbr_sel_map;
+ lbr->sel_mask = LBR_SEL_MASK;
+ lbr->sel_map = snb_lbr_sel_map;
/*
* SW branch filter usage:
@@ -1043,27 +1043,27 @@ void __init intel_pmu_lbr_init_snb(void)
}
/* haswell */
-void intel_pmu_lbr_init_hsw(void)
+void intel_pmu_lbr_init_hsw(struct x86_pmu_lbr *lbr)
{
- 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->nr = 16;
+ lbr->tos = MSR_LBR_TOS;
+ lbr->from = MSR_LBR_NHM_FROM;
+ lbr->to = MSR_LBR_NHM_TO;
- x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
- x86_pmu.lbr_sel_map = hsw_lbr_sel_map;
+ lbr->sel_mask = LBR_SEL_MASK;
+ lbr->sel_map = hsw_lbr_sel_map;
}
/* skylake */
-__init void intel_pmu_lbr_init_skl(void)
+__init void intel_pmu_lbr_init_skl(struct x86_pmu_lbr *lbr)
{
- 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->nr = 32;
+ lbr->tos = MSR_LBR_TOS;
+ lbr->from = MSR_LBR_NHM_FROM;
+ lbr->to = MSR_LBR_NHM_TO;
- x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
- x86_pmu.lbr_sel_map = hsw_lbr_sel_map;
+ lbr->sel_mask = LBR_SEL_MASK;
+ lbr->sel_map = hsw_lbr_sel_map;
/*
* SW branch filter usage:
@@ -1074,23 +1074,12 @@ __init void intel_pmu_lbr_init_skl(void)
}
/* atom */
-void __init intel_pmu_lbr_init_atom(void)
+void __init intel_pmu_lbr_init_atom(struct x86_pmu_lbr *lbr)
{
- /*
- * 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;
+ lbr->nr = 8;
+ lbr->tos = MSR_LBR_TOS;
+ lbr->from = MSR_LBR_CORE_FROM;
+ lbr->to = MSR_LBR_CORE_TO;
/*
* SW branch filter usage:
@@ -1099,31 +1088,30 @@ void __init intel_pmu_lbr_init_atom(void)
}
/* slm */
-void __init intel_pmu_lbr_init_slm(void)
+void __init intel_pmu_lbr_init_slm(struct x86_pmu_lbr *lbr)
{
- 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->nr = 8;
+ lbr->tos = MSR_LBR_TOS;
+ lbr->from = MSR_LBR_CORE_FROM;
+ lbr->to = MSR_LBR_CORE_TO;
- x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
- x86_pmu.lbr_sel_map = nhm_lbr_sel_map;
+ lbr->sel_mask = LBR_SEL_MASK;
+ lbr->sel_map = nhm_lbr_sel_map;
/*
* SW branch filter usage:
* - compensate for lack of HW filter
*/
- pr_cont("8-deep LBR, ");
}
/* Knights Landing */
-void intel_pmu_lbr_init_knl(void)
+void intel_pmu_lbr_init_knl(struct x86_pmu_lbr *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;
+ lbr->nr = 8;
+ lbr->tos = MSR_LBR_TOS;
+ lbr->from = MSR_LBR_NHM_FROM;
+ lbr->to = MSR_LBR_NHM_TO;
- x86_pmu.lbr_sel_mask = LBR_SEL_MASK;
- x86_pmu.lbr_sel_map = snb_lbr_sel_map;
+ lbr->sel_mask = LBR_SEL_MASK;
+ lbr->sel_map = snb_lbr_sel_map;
}
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index e48949b246cf..e48403278fe5 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -626,12 +626,7 @@ struct x86_pmu {
/*
* Intel 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 */
+ struct x86_pmu_lbr lbr;
/*
* Intel PT/LBR/BTS are exclusive
@@ -701,8 +696,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);
@@ -938,21 +933,21 @@ void intel_pmu_lbr_disable_all(void);
void intel_pmu_lbr_read(void);
-void intel_pmu_lbr_init_core(void);
+void intel_pmu_lbr_init_core(struct x86_pmu_lbr *lbr);
-void intel_pmu_lbr_init_nhm(void);
+void intel_pmu_lbr_init_nhm(struct x86_pmu_lbr *lbr);
-void intel_pmu_lbr_init_atom(void);
+void intel_pmu_lbr_init_atom(struct x86_pmu_lbr *lbr);
-void intel_pmu_lbr_init_slm(void);
+void intel_pmu_lbr_init_slm(struct x86_pmu_lbr *lbr);
-void intel_pmu_lbr_init_snb(void);
+void intel_pmu_lbr_init_snb(struct x86_pmu_lbr *lbr);
-void intel_pmu_lbr_init_hsw(void);
+void intel_pmu_lbr_init_hsw(struct x86_pmu_lbr *lbr);
-void intel_pmu_lbr_init_skl(void);
+void intel_pmu_lbr_init_skl(struct x86_pmu_lbr *lbr);
-void intel_pmu_lbr_init_knl(void);
+void intel_pmu_lbr_init_knl(struct x86_pmu_lbr *lbr);
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 f353061bba1d..440d3ecb0110 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -124,6 +124,15 @@ 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:
*/
More information about the Devel
mailing list