Skip to content

Commit 556a7c0

Browse files
Kan LiangPeter Zijlstra
authored andcommitted
perf/x86/intel: Hide Topdown metrics events if the feature is not enumerated
The below error is observed on Ice Lake VM. $ perf stat Error: The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (slots). /bin/dmesg | grep -i perf may provide additional information. In a virtualization env, the Topdown metrics and the slots event haven't been supported yet. The guest CPUID doesn't enumerate them. However, the current kernel unconditionally exposes the slots event and the Topdown metrics events to sysfs, which misleads the perf tool and triggers the error. Hide the perf-metrics topdown events and the slots event if the perf-metrics feature is not enumerated. The big core of a hybrid platform can also supports the perf-metrics feature. Fix the hybrid platform as well. Closes: https://lore.kernel.org/lkml/CAM9d7cj8z+ryyzUHR+P1Dcpot2jjW+Qcc4CPQpfafTXN=LEU0Q@mail.gmail.com/ Reported-by: Dongli Zhang <dongli.zhang@oracle.com> Signed-off-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Tested-by: Dongli Zhang <dongli.zhang@oracle.com> Link: https://lkml.kernel.org/r/20240708193336.1192217-2-kan.liang@linux.intel.com
1 parent a5a6ff3 commit 556a7c0

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

arch/x86/events/intel/core.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5830,8 +5830,22 @@ exra_is_visible(struct kobject *kobj, struct attribute *attr, int i)
58305830
return x86_pmu.version >= 2 ? attr->mode : 0;
58315831
}
58325832

5833+
static umode_t
5834+
td_is_visible(struct kobject *kobj, struct attribute *attr, int i)
5835+
{
5836+
/*
5837+
* Hide the perf metrics topdown events
5838+
* if the feature is not enumerated.
5839+
*/
5840+
if (x86_pmu.num_topdown_events)
5841+
return x86_pmu.intel_cap.perf_metrics ? attr->mode : 0;
5842+
5843+
return attr->mode;
5844+
}
5845+
58335846
static struct attribute_group group_events_td = {
58345847
.name = "events",
5848+
.is_visible = td_is_visible,
58355849
};
58365850

58375851
static struct attribute_group group_events_mem = {
@@ -6057,9 +6071,27 @@ static umode_t hybrid_format_is_visible(struct kobject *kobj,
60576071
return (cpu >= 0) && (pmu->pmu_type & pmu_attr->pmu_type) ? attr->mode : 0;
60586072
}
60596073

6074+
static umode_t hybrid_td_is_visible(struct kobject *kobj,
6075+
struct attribute *attr, int i)
6076+
{
6077+
struct device *dev = kobj_to_dev(kobj);
6078+
struct x86_hybrid_pmu *pmu =
6079+
container_of(dev_get_drvdata(dev), struct x86_hybrid_pmu, pmu);
6080+
6081+
if (!is_attr_for_this_pmu(kobj, attr))
6082+
return 0;
6083+
6084+
6085+
/* Only the big core supports perf metrics */
6086+
if (pmu->pmu_type == hybrid_big)
6087+
return pmu->intel_cap.perf_metrics ? attr->mode : 0;
6088+
6089+
return attr->mode;
6090+
}
6091+
60606092
static struct attribute_group hybrid_group_events_td = {
60616093
.name = "events",
6062-
.is_visible = hybrid_events_is_visible,
6094+
.is_visible = hybrid_td_is_visible,
60636095
};
60646096

60656097
static struct attribute_group hybrid_group_events_mem = {

0 commit comments

Comments
 (0)