Skip to content

Commit 950ecdc

Browse files
Kan LiangIngo Molnar
authored andcommitted
perf/x86/intel: Fix broken fixed event constraints extension
Unnecessary multiplexing is triggered when running an "instructions" event on an MTL. perf stat -e cpu_core/instructions/,cpu_core/instructions/ -a sleep 1 Performance counter stats for 'system wide': 115,489,000 cpu_core/instructions/ (50.02%) 127,433,777 cpu_core/instructions/ (49.98%) 1.002294504 seconds time elapsed Linux architectural perf events, e.g., cycles and instructions, usually have dedicated fixed counters. These events also have equivalent events which can be used in the general-purpose counters. The counters are precious. In the intel_pmu_check_event_constraints(), perf check/extend the event constraints of these events. So these events can utilize both fixed counters and general-purpose counters. The following cleanup commit: 97588df ("perf/x86/intel: Add common intel_pmu_init_hybrid()") forgot adding the intel_pmu_check_event_constraints() into update_pmu_cap(). The architectural perf events cannot utilize the general-purpose counters. The code to check and update the counters, event constraints and extra_regs is the same among hybrid systems. Move intel_pmu_check_hybrid_pmus() to init_hybrid_pmu(), and emove the duplicate check in update_pmu_cap(). Fixes: 97588df ("perf/x86/intel: Add common intel_pmu_init_hybrid()") Signed-off-by: Kan Liang <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 97588df commit 950ecdc

File tree

1 file changed

+26
-39
lines changed

1 file changed

+26
-39
lines changed

arch/x86/events/intel/core.c

Lines changed: 26 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4598,6 +4598,13 @@ static void intel_pmu_check_num_counters(int *num_counters,
45984598
int *num_counters_fixed,
45994599
u64 *intel_ctrl, u64 fixed_mask);
46004600

4601+
static void intel_pmu_check_event_constraints(struct event_constraint *event_constraints,
4602+
int num_counters,
4603+
int num_counters_fixed,
4604+
u64 intel_ctrl);
4605+
4606+
static void intel_pmu_check_extra_regs(struct extra_reg *extra_regs);
4607+
46014608
static inline bool intel_pmu_broken_perf_cap(void)
46024609
{
46034610
/* The Perf Metric (Bit 15) is always cleared */
@@ -4618,19 +4625,23 @@ static void update_pmu_cap(struct x86_hybrid_pmu *pmu)
46184625
&eax, &ebx, &ecx, &edx);
46194626
pmu->num_counters = fls(eax);
46204627
pmu->num_counters_fixed = fls(ebx);
4621-
intel_pmu_check_num_counters(&pmu->num_counters, &pmu->num_counters_fixed,
4622-
&pmu->intel_ctrl, ebx);
4623-
pmu->max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, pmu->num_counters);
4624-
pmu->unconstrained = (struct event_constraint)
4625-
__EVENT_CONSTRAINT(0, (1ULL << pmu->num_counters) - 1,
4626-
0, pmu->num_counters, 0, 0);
46274628
}
46284629

46294630

46304631
if (!intel_pmu_broken_perf_cap()) {
46314632
/* Perf Metric (Bit 15) and PEBS via PT (Bit 16) are hybrid enumeration */
46324633
rdmsrl(MSR_IA32_PERF_CAPABILITIES, pmu->intel_cap.capabilities);
46334634
}
4635+
}
4636+
4637+
static void intel_pmu_check_hybrid_pmus(struct x86_hybrid_pmu *pmu)
4638+
{
4639+
intel_pmu_check_num_counters(&pmu->num_counters, &pmu->num_counters_fixed,
4640+
&pmu->intel_ctrl, (1ULL << pmu->num_counters_fixed) - 1);
4641+
pmu->max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, pmu->num_counters);
4642+
pmu->unconstrained = (struct event_constraint)
4643+
__EVENT_CONSTRAINT(0, (1ULL << pmu->num_counters) - 1,
4644+
0, pmu->num_counters, 0, 0);
46344645

46354646
if (pmu->intel_cap.perf_metrics)
46364647
pmu->intel_ctrl |= 1ULL << GLOBAL_CTRL_EN_PERF_METRICS;
@@ -4641,6 +4652,13 @@ static void update_pmu_cap(struct x86_hybrid_pmu *pmu)
46414652
pmu->pmu.capabilities |= PERF_PMU_CAP_AUX_OUTPUT;
46424653
else
46434654
pmu->pmu.capabilities |= ~PERF_PMU_CAP_AUX_OUTPUT;
4655+
4656+
intel_pmu_check_event_constraints(pmu->event_constraints,
4657+
pmu->num_counters,
4658+
pmu->num_counters_fixed,
4659+
pmu->intel_ctrl);
4660+
4661+
intel_pmu_check_extra_regs(pmu->extra_regs);
46444662
}
46454663

46464664
static struct x86_hybrid_pmu *find_hybrid_pmu_for_cpu(void)
@@ -4696,6 +4714,8 @@ static bool init_hybrid_pmu(int cpu)
46964714
if (this_cpu_has(X86_FEATURE_ARCH_PERFMON_EXT))
46974715
update_pmu_cap(pmu);
46984716

4717+
intel_pmu_check_hybrid_pmus(pmu);
4718+
46994719
if (!check_hw_exists(&pmu->pmu, pmu->num_counters, pmu->num_counters_fixed))
47004720
return false;
47014721

@@ -5915,36 +5935,6 @@ static void intel_pmu_check_extra_regs(struct extra_reg *extra_regs)
59155935
}
59165936
}
59175937

5918-
static void intel_pmu_check_hybrid_pmus(u64 fixed_mask)
5919-
{
5920-
struct x86_hybrid_pmu *pmu;
5921-
int i;
5922-
5923-
for (i = 0; i < x86_pmu.num_hybrid_pmus; i++) {
5924-
pmu = &x86_pmu.hybrid_pmu[i];
5925-
5926-
intel_pmu_check_num_counters(&pmu->num_counters,
5927-
&pmu->num_counters_fixed,
5928-
&pmu->intel_ctrl,
5929-
fixed_mask);
5930-
5931-
if (pmu->intel_cap.perf_metrics) {
5932-
pmu->intel_ctrl |= 1ULL << GLOBAL_CTRL_EN_PERF_METRICS;
5933-
pmu->intel_ctrl |= INTEL_PMC_MSK_FIXED_SLOTS;
5934-
}
5935-
5936-
if (pmu->intel_cap.pebs_output_pt_available)
5937-
pmu->pmu.capabilities |= PERF_PMU_CAP_AUX_OUTPUT;
5938-
5939-
intel_pmu_check_event_constraints(pmu->event_constraints,
5940-
pmu->num_counters,
5941-
pmu->num_counters_fixed,
5942-
pmu->intel_ctrl);
5943-
5944-
intel_pmu_check_extra_regs(pmu->extra_regs);
5945-
}
5946-
}
5947-
59485938
static const struct { enum hybrid_pmu_type id; char *name; } intel_hybrid_pmu_type_map[] __initconst = {
59495939
{ hybrid_small, "cpu_atom" },
59505940
{ hybrid_big, "cpu_core" },
@@ -6869,9 +6859,6 @@ __init int intel_pmu_init(void)
68696859
if (!is_hybrid() && x86_pmu.intel_cap.perf_metrics)
68706860
x86_pmu.intel_ctrl |= 1ULL << GLOBAL_CTRL_EN_PERF_METRICS;
68716861

6872-
if (is_hybrid() && !boot_cpu_has(X86_FEATURE_ARCH_PERFMON_EXT))
6873-
intel_pmu_check_hybrid_pmus((u64)fixed_mask);
6874-
68756862
if (x86_pmu.intel_cap.pebs_timing_info)
68766863
x86_pmu.flags |= PMU_FL_RETIRE_LATENCY;
68776864

0 commit comments

Comments
 (0)