Skip to content

Commit

Permalink
perf/x86/intel: Use cache cpu-type for hybrid PMU selection
Browse files Browse the repository at this point in the history
get_this_hybrid_cpu_type() misses a case when cpu-type is populated
regardless of X86_FEATURE_HYBRID_CPU. This is particularly true for hybrid
variants that have P or E cores fused off.

Instead use the cpu-type cached in struct x86_topology, as it does not rely
on hybrid feature to enumerate cpu-type. This can also help avoid the
model-specific fixup get_hybrid_cpu_type(). Also replace the
get_this_hybrid_cpu_native_id() with its cached value in struct
x86_topology.

While at it, remove enum hybrid_cpu_type as it serves no purpose when we
have the exact cpu-types defined in enum intel_cpu_type. Also rename
atom_native_id to intel_native_id and move it to intel-family.h where
intel_cpu_type lives.

Suggested-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
Link: https://lore.kernel.org/r/20241211-add-cpu-type-v5-3-2ae010f50370@linux.intel.com
  • Loading branch information
Pawan Gupta authored and Ingo Molnar committed Feb 27, 2025
1 parent b52aaee commit c4a8b71
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 28 deletions.
19 changes: 10 additions & 9 deletions arch/x86/events/intel/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -4606,9 +4606,9 @@ static int adl_hw_config(struct perf_event *event)
return -EOPNOTSUPP;
}

static enum hybrid_cpu_type adl_get_hybrid_cpu_type(void)
static enum intel_cpu_type adl_get_hybrid_cpu_type(void)
{
return HYBRID_INTEL_CORE;
return INTEL_CPU_TYPE_CORE;
}

static inline bool erratum_hsw11(struct perf_event *event)
Expand Down Expand Up @@ -4953,7 +4953,8 @@ static void intel_pmu_check_hybrid_pmus(struct x86_hybrid_pmu *pmu)

static struct x86_hybrid_pmu *find_hybrid_pmu_for_cpu(void)
{
u8 cpu_type = get_this_hybrid_cpu_type();
struct cpuinfo_x86 *c = &cpu_data(smp_processor_id());
enum intel_cpu_type cpu_type = c->topo.intel_type;
int i;

/*
Expand All @@ -4962,7 +4963,7 @@ static struct x86_hybrid_pmu *find_hybrid_pmu_for_cpu(void)
* on it. There should be a fixup function provided for these
* troublesome CPUs (->get_hybrid_cpu_type).
*/
if (cpu_type == HYBRID_INTEL_NONE) {
if (cpu_type == INTEL_CPU_TYPE_UNKNOWN) {
if (x86_pmu.get_hybrid_cpu_type)
cpu_type = x86_pmu.get_hybrid_cpu_type();
else
Expand All @@ -4979,16 +4980,16 @@ static struct x86_hybrid_pmu *find_hybrid_pmu_for_cpu(void)
enum hybrid_pmu_type pmu_type = x86_pmu.hybrid_pmu[i].pmu_type;
u32 native_id;

if (cpu_type == HYBRID_INTEL_CORE && pmu_type == hybrid_big)
if (cpu_type == INTEL_CPU_TYPE_CORE && pmu_type == hybrid_big)
return &x86_pmu.hybrid_pmu[i];
if (cpu_type == HYBRID_INTEL_ATOM) {
if (cpu_type == INTEL_CPU_TYPE_ATOM) {
if (x86_pmu.num_hybrid_pmus == 2 && pmu_type == hybrid_small)
return &x86_pmu.hybrid_pmu[i];

native_id = get_this_hybrid_cpu_native_id();
if (native_id == skt_native_id && pmu_type == hybrid_small)
native_id = c->topo.intel_native_model_id;
if (native_id == INTEL_ATOM_SKT_NATIVE_ID && pmu_type == hybrid_small)
return &x86_pmu.hybrid_pmu[i];
if (native_id == cmt_native_id && pmu_type == hybrid_tiny)
if (native_id == INTEL_ATOM_CMT_NATIVE_ID && pmu_type == hybrid_tiny)
return &x86_pmu.hybrid_pmu[i];
}
}
Expand Down
19 changes: 1 addition & 18 deletions arch/x86/events/perf_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -669,18 +669,6 @@ enum {
#define PERF_PEBS_DATA_SOURCE_GRT_MAX 0x10
#define PERF_PEBS_DATA_SOURCE_GRT_MASK (PERF_PEBS_DATA_SOURCE_GRT_MAX - 1)

/*
* CPUID.1AH.EAX[31:0] uniquely identifies the microarchitecture
* of the core. Bits 31-24 indicates its core type (Core or Atom)
* and Bits [23:0] indicates the native model ID of the core.
* Core type and native model ID are defined in below enumerations.
*/
enum hybrid_cpu_type {
HYBRID_INTEL_NONE,
HYBRID_INTEL_ATOM = 0x20,
HYBRID_INTEL_CORE = 0x40,
};

#define X86_HYBRID_PMU_ATOM_IDX 0
#define X86_HYBRID_PMU_CORE_IDX 1
#define X86_HYBRID_PMU_TINY_IDX 2
Expand All @@ -697,11 +685,6 @@ enum hybrid_pmu_type {
hybrid_big_small_tiny = hybrid_big | hybrid_small_tiny,
};

enum atom_native_id {
cmt_native_id = 0x2, /* Crestmont */
skt_native_id = 0x3, /* Skymont */
};

struct x86_hybrid_pmu {
struct pmu pmu;
const char *name;
Expand Down Expand Up @@ -994,7 +977,7 @@ struct x86_pmu {
*/
int num_hybrid_pmus;
struct x86_hybrid_pmu *hybrid_pmu;
enum hybrid_cpu_type (*get_hybrid_cpu_type) (void);
enum intel_cpu_type (*get_hybrid_cpu_type) (void);
};

struct x86_perf_task_context_opt {
Expand Down
15 changes: 14 additions & 1 deletion arch/x86/include/asm/intel-family.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,23 @@
/* Family 19 */
#define INTEL_PANTHERCOVE_X IFM(19, 0x01) /* Diamond Rapids */

/* CPU core types */
/*
* Intel CPU core types
*
* CPUID.1AH.EAX[31:0] uniquely identifies the microarchitecture
* of the core. Bits 31-24 indicates its core type (Core or Atom)
* and Bits [23:0] indicates the native model ID of the core.
* Core type and native model ID are defined in below enumerations.
*/
enum intel_cpu_type {
INTEL_CPU_TYPE_UNKNOWN,
INTEL_CPU_TYPE_ATOM = 0x20,
INTEL_CPU_TYPE_CORE = 0x40,
};

enum intel_native_id {
INTEL_ATOM_CMT_NATIVE_ID = 0x2, /* Crestmont */
INTEL_ATOM_SKT_NATIVE_ID = 0x3, /* Skymont */
};

#endif /* _ASM_X86_INTEL_FAMILY_H */

0 comments on commit c4a8b71

Please sign in to comment.