[PATCH V3 2/5] perf/x86/intel: Track the num of events needs late setup

From: kan . liang
Date: Thu Feb 13 2025 - 16:17:17 EST


From: Kan Liang <kan.liang@xxxxxxxxxxxxxxx>

When a machine supports PEBS v6, perf unconditionally searches the
cpuc->event_list[] for every event and check if the late setup is
required, which is unnecessary.

The late setup is only required for special events, e.g., events support
counters snapshotting feature. Add n_late_setup to track the num of
events that needs the late setup.

Other features, e.g., auto counter reload feature, require the late
setup as well. Add a wrapper, intel_pmu_pebs_late_setup, for the events
that support counters snapshotting feature.

Signed-off-by: Kan Liang <kan.liang@xxxxxxxxxxxxxxx>
---
arch/x86/events/intel/core.c | 14 ++++++++++++++
arch/x86/events/intel/ds.c | 3 +--
arch/x86/events/perf_event.h | 5 +++++
3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 2df05b18ff04..ce04553910ab 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -2609,6 +2609,8 @@ static void intel_pmu_del_event(struct perf_event *event)
intel_pmu_lbr_del(event);
if (event->attr.precise_ip)
intel_pmu_pebs_del(event);
+ if (is_pebs_counter_event_group(event))
+ this_cpu_ptr(&cpu_hw_events)->n_late_setup--;
}

static int icl_set_topdown_event_period(struct perf_event *event)
@@ -2920,12 +2922,24 @@ static void intel_pmu_enable_event(struct perf_event *event)
}
}

+void intel_pmu_late_setup(void)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ if (!cpuc->n_late_setup)
+ return;
+
+ intel_pmu_pebs_late_setup(cpuc);
+}
+
static void intel_pmu_add_event(struct perf_event *event)
{
if (event->attr.precise_ip)
intel_pmu_pebs_add(event);
if (intel_pmu_needs_branch_stack(event))
intel_pmu_lbr_add(event);
+ if (is_pebs_counter_event_group(event))
+ this_cpu_ptr(&cpu_hw_events)->n_late_setup++;
}

/*
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index e8f808905871..df9499d6e4dc 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -1355,9 +1355,8 @@ static void __intel_pmu_pebs_update_cfg(struct perf_event *event,
}


-static void intel_pmu_late_setup(void)
+void intel_pmu_pebs_late_setup(struct cpu_hw_events *cpuc)
{
- struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
struct perf_event *event;
u64 pebs_data_cfg = 0;
int i;
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index f4693409e191..5bf9c117e9ef 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -261,6 +261,7 @@ struct cpu_hw_events {
struct event_constraint *event_constraint[X86_PMC_IDX_MAX];

int n_excl; /* the number of exclusive events */
+ int n_late_setup; /* the num of events needs late setup */

unsigned int txn_flags;
int is_fake;
@@ -1602,6 +1603,8 @@ void intel_pmu_disable_bts(void);

int intel_pmu_drain_bts_buffer(void);

+void intel_pmu_late_setup(void);
+
u64 grt_latency_data(struct perf_event *event, u64 status);

u64 cmt_latency_data(struct perf_event *event, u64 status);
@@ -1658,6 +1661,8 @@ void intel_pmu_pebs_disable_all(void);

void intel_pmu_pebs_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in);

+void intel_pmu_pebs_late_setup(struct cpu_hw_events *cpuc);
+
void intel_pmu_drain_pebs_buffer(void);

void intel_pmu_store_pebs_lbrs(struct lbr_entry *lbr);
--
2.38.1