perf/x86/intel/uncore: Add alias PMU name
authorKan Liang <kan.liang@linux.intel.com>
Wed, 30 Jun 2021 21:08:36 +0000 (14:08 -0700)
committerPeter Zijlstra <peterz@infradead.org>
Fri, 2 Jul 2021 13:58:40 +0000 (15:58 +0200)
A perf PMU may have two PMU names. For example, Intel Sapphire Rapids
server supports the discovery mechanism. Without the platform-specific
support, an uncore PMU is named by a type ID plus a box ID, e.g.,
uncore_type_0_0, because the real name of the uncore PMU cannot be
retrieved from the discovery table. With the platform-specific support
later, perf has the mapping information from a type ID to a specific
uncore unit. Just like the previous platforms, the uncore PMU is named
by the real PMU name, e.g., uncore_cha_0. The user scripts which work
well with the old numeric name may not work anymore.

Add a new attribute "alias" to indicate the old numeric name. The
following userspace perf tool patch will handle both names. The user
scripts should work properly with the updated perf tool.

Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Link: https://lore.kernel.org/r/1625087320-194204-13-git-send-email-kan.liang@linux.intel.com
Documentation/ABI/testing/sysfs-bus-event_source-devices-uncore [new file with mode: 0644]
arch/x86/events/intel/uncore.c
arch/x86/events/intel/uncore.h
arch/x86/events/intel/uncore_snbep.c

diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-uncore b/Documentation/ABI/testing/sysfs-bus-event_source-devices-uncore
new file mode 100644 (file)
index 0000000..b56e8f0
--- /dev/null
@@ -0,0 +1,13 @@
+What:          /sys/bus/event_source/devices/uncore_*/alias
+Date:          June 2021
+KernelVersion: 5.15
+Contact:       Linux kernel mailing list <linux-kernel@vger.kernel.org>
+Description:   Read-only.  An attribute to describe the alias name of
+               the uncore PMU if an alias exists on some platforms.
+               The 'perf(1)' tool should treat both names the same.
+               They both can be used to access the uncore PMU.
+
+               Example:
+
+               $ cat /sys/devices/uncore_cha_2/alias
+               uncore_type_0_2
index b941ceee2289e5dcbf8bcbceec5c6df3bff9e7b7..c72e368dd16413a7c4a1df87a4d3b04631c2f47d 100644 (file)
@@ -842,6 +842,18 @@ static const struct attribute_group uncore_pmu_attr_group = {
        .attrs = uncore_pmu_attrs,
 };
 
+void uncore_get_alias_name(char *pmu_name, struct intel_uncore_pmu *pmu)
+{
+       struct intel_uncore_type *type = pmu->type;
+
+       if (type->num_boxes == 1)
+               sprintf(pmu_name, "uncore_type_%u", type->type_id);
+       else {
+               sprintf(pmu_name, "uncore_type_%u_%d",
+                       type->type_id, type->box_ids[pmu->pmu_idx]);
+       }
+}
+
 static void uncore_get_pmu_name(struct intel_uncore_pmu *pmu)
 {
        struct intel_uncore_type *type = pmu->type;
@@ -851,12 +863,7 @@ static void uncore_get_pmu_name(struct intel_uncore_pmu *pmu)
         * Use uncore_type_&typeid_&boxid as name.
         */
        if (!type->name) {
-               if (type->num_boxes == 1)
-                       sprintf(pmu->name, "uncore_type_%u", type->type_id);
-               else {
-                       sprintf(pmu->name, "uncore_type_%u_%d",
-                               type->type_id, type->box_ids[pmu->pmu_idx]);
-               }
+               uncore_get_alias_name(pmu->name, pmu);
                return;
        }
 
index fa0e938f01418a421ed8094cf98086cf07f66557..b9687980aab6d3d897a3423db71f30c6596167f9 100644 (file)
@@ -561,6 +561,7 @@ struct event_constraint *
 uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event);
 void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event);
 u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx);
+void uncore_get_alias_name(char *pmu_name, struct intel_uncore_pmu *pmu);
 
 extern struct intel_uncore_type *empty_uncore[];
 extern struct intel_uncore_type **uncore_msr_uncores;
index 1b9ab8ed2523dabeab8c604265e05d0c9b2ad543..d0d02e0482549d7fe6c420b891824e08708e8873 100644 (file)
@@ -5587,6 +5587,26 @@ static const struct attribute_group spr_uncore_chabox_format_group = {
        .attrs = spr_uncore_cha_formats_attr,
 };
 
+static ssize_t alias_show(struct device *dev,
+                         struct device_attribute *attr,
+                         char *buf)
+{
+       struct intel_uncore_pmu *pmu = dev_to_uncore_pmu(dev);
+       char pmu_name[UNCORE_PMU_NAME_LEN];
+
+       uncore_get_alias_name(pmu_name, pmu);
+       return sysfs_emit(buf, "%s\n", pmu_name);
+}
+
+static DEVICE_ATTR_RO(alias);
+
+static struct attribute *uncore_alias_attrs[] = {
+       &dev_attr_alias.attr,
+       NULL
+};
+
+ATTRIBUTE_GROUPS(uncore_alias);
+
 static struct intel_uncore_type spr_uncore_chabox = {
        .name                   = "cha",
        .event_mask             = SPR_CHA_PMON_EVENT_MASK,
@@ -5594,6 +5614,7 @@ static struct intel_uncore_type spr_uncore_chabox = {
        .num_shared_regs        = 1,
        .ops                    = &spr_uncore_chabox_ops,
        .format_group           = &spr_uncore_chabox_format_group,
+       .attr_update            = uncore_alias_groups,
 };
 
 static struct intel_uncore_type spr_uncore_iio = {
@@ -5601,6 +5622,7 @@ static struct intel_uncore_type spr_uncore_iio = {
        .event_mask             = SNBEP_PMON_RAW_EVENT_MASK,
        .event_mask_ext         = SNR_IIO_PMON_RAW_EVENT_MASK_EXT,
        .format_group           = &snr_uncore_iio_format_group,
+       .attr_update            = uncore_alias_groups,
 };
 
 static struct attribute *spr_uncore_raw_formats_attr[] = {
@@ -5620,7 +5642,8 @@ static const struct attribute_group spr_uncore_raw_format_group = {
 #define SPR_UNCORE_COMMON_FORMAT()                             \
        .event_mask             = SNBEP_PMON_RAW_EVENT_MASK,    \
        .event_mask_ext         = SPR_RAW_EVENT_MASK_EXT,       \
-       .format_group           = &spr_uncore_raw_format_group
+       .format_group           = &spr_uncore_raw_format_group, \
+       .attr_update            = uncore_alias_groups
 
 static struct intel_uncore_type spr_uncore_irp = {
        SPR_UNCORE_COMMON_FORMAT(),
@@ -5635,6 +5658,7 @@ static struct intel_uncore_type spr_uncore_m2pcie = {
 
 static struct intel_uncore_type spr_uncore_pcu = {
        .name                   = "pcu",
+       .attr_update            = uncore_alias_groups,
 };
 
 static void spr_uncore_mmio_enable_event(struct intel_uncore_box *box,
@@ -5760,6 +5784,8 @@ static void uncore_type_customized_copy(struct intel_uncore_type *to_type,
                to_type->event_descs = from_type->event_descs;
        if (from_type->format_group)
                to_type->format_group = from_type->format_group;
+       if (from_type->attr_update)
+               to_type->attr_update = from_type->attr_update;
 }
 
 static struct intel_uncore_type **