linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1
@ 2021-04-27  7:01 Jin Yao
  2021-04-27  7:01 ` [PATCH v6 01/26] tools headers uapi: Update tools's copy of linux/perf_event.h Jin Yao
                   ` (26 more replies)
  0 siblings, 27 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

AlderLake uses a hybrid architecture utilizing Golden Cove cores
(core cpu) and Gracemont cores (atom cpu). Each cpu has dedicated
event list. Some events are available on core cpu, some events
are available on atom cpu and some events can be available on both.

Kernel exports new pmus "cpu_core" and "cpu_atom" through sysfs:
/sys/devices/cpu_core
/sys/devices/cpu_atom

cat /sys/devices/cpu_core/cpus
0-15

cat /sys/devices/cpu_atom/cpus
16-23

In this example, core cpus are 0-15 and atom cpus are 16-23.

To enable a core only event or atom only event:

        cpu_core/<event name>/
or
        cpu_atom/<event name>/

Count the 'cycles' event on core cpus.

  # perf stat -e cpu_core/cycles/ -a -- sleep 1

   Performance counter stats for 'system wide':

      12,853,951,349      cpu_core/cycles/

         1.002581249 seconds time elapsed

If one event is available on both atom cpu and core cpu, two events
are created automatically.

  # perf stat -e cycles -a -- sleep 1

   Performance counter stats for 'system wide':

      12,856,467,438      cpu_core/cycles/
       6,404,634,785      cpu_atom/cycles/

         1.002453013 seconds time elapsed

Group is supported if the events are from same pmu, otherwise a warning
is displayed and disable grouping automatically.

  # perf stat -e '{cpu_core/cycles/,cpu_core/instructions/}' -a -- sleep 1

   Performance counter stats for 'system wide':

      12,863,866,968      cpu_core/cycles/
         554,795,017      cpu_core/instructions/

         1.002616117 seconds time elapsed

  # perf stat -e '{cpu_core/cycles/,cpu_atom/instructions/}' -a -- sleep 1
  WARNING: events in group from different hybrid PMUs!
  WARNING: grouped events cpus do not match, disabling group:
    anon group { cpu_core/cycles/, cpu_atom/instructions/ }

   Performance counter stats for 'system wide':

           6,283,970      cpu_core/cycles/
             765,635      cpu_atom/instructions/

         1.003959036 seconds time elapsed

Note that, since the whole patchset for AlderLake hybrid support is very
large (40+ patches). For simplicity, it's splitted into several patch
series.

The patch series 1 only supports the basic functionality. The advanced
supports for perf-c2c/perf-mem/topdown/metrics/topology header and others
will be added in follow-up patch series.

The perf tool codes can also be found at:
https://github.com/yaoj/perf.git

Note that, this patch series is based on tmp.perf/core branch.

v6:
---
- Rebase to tmp.perf/core branch.

- A minor update in v6 patch series.

  In '[PATCH v6 18/26] perf tests: Add hybrid cases for 'Parse event
  definition strings' test', we add a test case for cache events with
  pmu prefix.

  No other updates.

v5:
---
- Now Liang Kan's patch series for AlderLake perf core support has been
  upstreamed. So the interface for perf tool part will not be changed.

- '[PATCH v5 12/26] perf parse-events: Support event inside hybrid pmu',
   check the head_config list has only one term and if yes then do the
   second parsing. We drop the 'parsed' param and make parse_events__with_hybrid_pmu
   return 0 when we find some event.

   Move 'evsel->use_config_name = true;' to the patch
   '[PATCH v5 07/26] perf stat: Uniquify hybrid event name'.

- '[PATCH v5 14/26] perf stat: Add default hybrid events',
   do the same way like when topdown calls parse events for checking
   result and displayt the error.

- '[PATCH v5 15/26] perf stat: Filter out unmatched aggregation for hybrid event',
   use Jiri's code to filter, which is much simpler than original.

- Some perf test minor updates.

v4:
---
- In Liang Kan's patch:
  '[PATCH V6 21/25] perf: Extend PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE',
  the user interface for hardware events and cache events are changed, so
  perf tool patches are changed as well.

- Fix an issue when atom CPUs are offlined. "/sys/bus/event_source/devices/cpu_atom/cpus"
  exists but the content is empty. For this case, we can't enable the cpu_atom
  PMU. '[PATCH v4 05/25] perf pmu: Save detected hybrid pmus to a global pmu list'

- Define 'ret' variable for return value in patch
  '[PATCH v4 09/25] perf parse-events: Create two hybrid cache events'

- Directly return add_raw_hybrid() in patch
  '[PATCH v4 10/25] perf parse-events: Create two hybrid raw events'

- Drop the patch 'perf pmu: Support 'cycles' and 'branches' inside
  hybrid PMU'.

- Separate '[PATCH v3 12/27] perf parse-events: Support no alias assigned event
  inside hybrid PMU' into two patches:
  '[PATCH v4 11/25] perf parse-events: Compare with hybrid pmu name'
  '[PATCH v4 12/25] perf parse-events: Support event inside hybrid pmu'.
  And these two patches are improved according to Jiri's comments.

v3:
---
- Drop 'perf evlist: Hybrid event uses its own cpus'. This patch is wide
  and actually it's not very necessary. The current perf framework has
  processed the cpus for evsel well even for hybrid evsel. So this patch can
  be dropped.

- Drop 'perf evsel: Adjust hybrid event and global event mixed group'.
  The patch is a bit tricky and hard to understand. In v3, we will disable
  grouping when the group members are from different PMUs. So this patch
  would be not necessary.

- Create parse-events-hybrid.c/parse-events-hybrid.h and evlist-hybrid.c/evlist-hybrid.h.
  Move hybrid related codes to these files.

- Create a new patch 'perf pmu: Support 'cycles' and 'branches' inside hybrid PMU' to
  support 'cycles' and 'branches' inside PMU.

- Create a new patch 'perf record: Uniquify hybrid event name' to tell user the
  pmu which the event belongs to for perf-record.

- If group members are from different hybrid PMUs, shows warning and disable
  grouping.

- Other refining and refactoring.

v2:
---
- Drop kernel patches (Kan posted the series "Add Alder Lake support for perf (kernel)" separately).
- Drop the patches for perf-c2c/perf-mem/topdown/metrics/topology header supports,
  which will be added in series 2 or series 3.
- Simplify the arguments of __perf_pmu__new_alias() by passing
  the 'struct pme_event' pointer.
- Check sysfs validity before access.
- Use pmu style event name, such as "cpu_core/cycles/".
- Move command output two chars to the right.
- Move pmu hybrid functions to new created pmu-hybrid.c/pmu-hybrid.h.
  This is to pass the perf test python case.

Jin Yao (26):
  tools headers uapi: Update tools's copy of linux/perf_event.h
  perf jevents: Support unit value "cpu_core" and "cpu_atom"
  perf pmu: Simplify arguments of __perf_pmu__new_alias
  perf pmu: Save pmu name
  perf pmu: Save detected hybrid pmus to a global pmu list
  perf pmu: Add hybrid helper functions
  perf stat: Uniquify hybrid event name
  perf parse-events: Create two hybrid hardware events
  perf parse-events: Create two hybrid cache events
  perf parse-events: Create two hybrid raw events
  perf parse-events: Compare with hybrid pmu name
  perf parse-events: Support event inside hybrid pmu
  perf record: Create two hybrid 'cycles' events by default
  perf stat: Add default hybrid events
  perf stat: Filter out unmatched aggregation for hybrid event
  perf stat: Warn group events from different hybrid PMU
  perf record: Uniquify hybrid event name
  perf tests: Add hybrid cases for 'Parse event definition strings' test
  perf tests: Add hybrid cases for 'Roundtrip evsel->name' test
  perf tests: Skip 'Setup struct perf_event_attr' test for hybrid
  perf tests: Support 'Track with sched_switch' test for hybrid
  perf tests: Support 'Parse and process metrics' test for hybrid
  perf tests: Support 'Session topology' test for hybrid
  perf tests: Support 'Convert perf time to TSC' test for hybrid
  perf tests: Skip 'perf stat metrics (shadow stat) test' for hybrid
  perf Documentation: Document intel-hybrid support

 include/uapi/linux/perf_event.h            |  15 ++
 tools/include/uapi/linux/perf_event.h      |  15 ++
 tools/perf/Documentation/intel-hybrid.txt  | 214 +++++++++++++++++++++
 tools/perf/Documentation/perf-record.txt   |   1 +
 tools/perf/Documentation/perf-stat.txt     |   2 +
 tools/perf/builtin-record.c                |  47 ++++-
 tools/perf/builtin-stat.c                  |  36 ++++
 tools/perf/pmu-events/jevents.c            |   2 +
 tools/perf/tests/attr.c                    |   4 +
 tools/perf/tests/evsel-roundtrip-name.c    |  19 +-
 tools/perf/tests/parse-events.c            | 171 ++++++++++++++++
 tools/perf/tests/parse-metric.c            |   8 +-
 tools/perf/tests/perf-time-to-tsc.c        |  12 ++
 tools/perf/tests/shell/stat+shadow_stat.sh |   3 +
 tools/perf/tests/switch-tracking.c         |   6 +-
 tools/perf/tests/topology.c                |  13 +-
 tools/perf/util/Build                      |   3 +
 tools/perf/util/evlist-hybrid.c            |  88 +++++++++
 tools/perf/util/evlist-hybrid.h            |  14 ++
 tools/perf/util/evlist.c                   |   5 +-
 tools/perf/util/evsel.c                    |  12 +-
 tools/perf/util/evsel.h                    |   4 +-
 tools/perf/util/parse-events-hybrid.c      | 178 +++++++++++++++++
 tools/perf/util/parse-events-hybrid.h      |  23 +++
 tools/perf/util/parse-events.c             |  97 +++++++++-
 tools/perf/util/parse-events.h             |   9 +-
 tools/perf/util/parse-events.y             |   9 +-
 tools/perf/util/pmu-hybrid.c               |  89 +++++++++
 tools/perf/util/pmu-hybrid.h               |  22 +++
 tools/perf/util/pmu.c                      |  64 ++++--
 tools/perf/util/pmu.h                      |   7 +
 tools/perf/util/python-ext-sources         |   2 +
 tools/perf/util/stat-display.c             |  18 +-
 33 files changed, 1162 insertions(+), 50 deletions(-)
 create mode 100644 tools/perf/Documentation/intel-hybrid.txt
 create mode 100644 tools/perf/util/evlist-hybrid.c
 create mode 100644 tools/perf/util/evlist-hybrid.h
 create mode 100644 tools/perf/util/parse-events-hybrid.c
 create mode 100644 tools/perf/util/parse-events-hybrid.h
 create mode 100644 tools/perf/util/pmu-hybrid.c
 create mode 100644 tools/perf/util/pmu-hybrid.h

-- 
2.17.1


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v6 01/26] tools headers uapi: Update tools's copy of linux/perf_event.h
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27 19:24   ` Arnaldo Carvalho de Melo
  2021-04-27  7:01 ` [PATCH v6 02/26] perf jevents: Support unit value "cpu_core" and "cpu_atom" Jin Yao
                   ` (25 subsequent siblings)
  26 siblings, 1 reply; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

To get the changes in:

Liang Kan's patch
[PATCH V6 21/25] perf: Extend PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE

Kan's patch is upstreamed yet but perf/core branch doesn't have it
at this moment. But next perf tool patches need this interface for
hybrid support.

This patch can be removed after Kan's patch is merged in perf/core
branch.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v6:
 - No update.

v5:
 - Update the commit message to mention that Kan's patch is
   upstreamed but not merged to perf/core branch.

v4:
 - Updated by Kan's latest patch,
   '[PATCH V6 21/25] perf: Extend PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE'

 include/uapi/linux/perf_event.h       | 15 +++++++++++++++
 tools/include/uapi/linux/perf_event.h | 15 +++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index ad15e40d7f5d..14332f4cf816 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -37,6 +37,21 @@ enum perf_type_id {
 	PERF_TYPE_MAX,				/* non-ABI */
 };
 
+/*
+ * attr.config layout for type PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE
+ * PERF_TYPE_HARDWARE:			0xEEEEEEEE000000AA
+ *					AA: hardware event ID
+ *					EEEEEEEE: PMU type ID
+ * PERF_TYPE_HW_CACHE:			0xEEEEEEEE00DDCCBB
+ *					BB: hardware cache ID
+ *					CC: hardware cache op ID
+ *					DD: hardware cache op result ID
+ *					EEEEEEEE: PMU type ID
+ * If the PMU type ID is 0, the PERF_TYPE_RAW will be applied.
+ */
+#define PERF_PMU_TYPE_SHIFT		32
+#define PERF_HW_EVENT_MASK		0xffffffff
+
 /*
  * Generalized performance event event_id types, used by the
  * attr.event_id parameter of the sys_perf_event_open()
diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
index ad15e40d7f5d..14332f4cf816 100644
--- a/tools/include/uapi/linux/perf_event.h
+++ b/tools/include/uapi/linux/perf_event.h
@@ -37,6 +37,21 @@ enum perf_type_id {
 	PERF_TYPE_MAX,				/* non-ABI */
 };
 
+/*
+ * attr.config layout for type PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE
+ * PERF_TYPE_HARDWARE:			0xEEEEEEEE000000AA
+ *					AA: hardware event ID
+ *					EEEEEEEE: PMU type ID
+ * PERF_TYPE_HW_CACHE:			0xEEEEEEEE00DDCCBB
+ *					BB: hardware cache ID
+ *					CC: hardware cache op ID
+ *					DD: hardware cache op result ID
+ *					EEEEEEEE: PMU type ID
+ * If the PMU type ID is 0, the PERF_TYPE_RAW will be applied.
+ */
+#define PERF_PMU_TYPE_SHIFT		32
+#define PERF_HW_EVENT_MASK		0xffffffff
+
 /*
  * Generalized performance event event_id types, used by the
  * attr.event_id parameter of the sys_perf_event_open()
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 02/26] perf jevents: Support unit value "cpu_core" and "cpu_atom"
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
  2021-04-27  7:01 ` [PATCH v6 01/26] tools headers uapi: Update tools's copy of linux/perf_event.h Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 03/26] perf pmu: Simplify arguments of __perf_pmu__new_alias Jin Yao
                   ` (24 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

For some Intel platforms, such as Alderlake, which is a hybrid platform
and it consists of atom cpu and core cpu. Each cpu has dedicated event
list. Part of events are available on core cpu, part of events are
available on atom cpu.

The kernel exports new cpu pmus: cpu_core and cpu_atom. The event in
json is added with a new field "Unit" to indicate which pmu the event
is available on.

For example, one event in cache.json,

    {
        "BriefDescription": "Counts the number of load ops retired that",
        "CollectPEBSRecord": "2",
        "Counter": "0,1,2,3",
        "EventCode": "0xd2",
        "EventName": "MEM_LOAD_UOPS_RETIRED_MISC.MMIO",
        "PEBScounters": "0,1,2,3",
        "SampleAfterValue": "1000003",
        "UMask": "0x80",
        "Unit": "cpu_atom"
    },

The unit "cpu_atom" indicates this event is only available on "cpu_atom".

In generated pmu-events.c, we can see:

{
        .name = "mem_load_uops_retired_misc.mmio",
        .event = "period=1000003,umask=0x80,event=0xd2",
        .desc = "Counts the number of load ops retired that. Unit: cpu_atom ",
        .topic = "cache",
        .pmu = "cpu_atom",
},

But if without this patch, the "uncore_" prefix is added before "cpu_atom",
such as:
        .pmu = "uncore_cpu_atom"

That would be a wrong pmu.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v6:
 - No change.

 tools/perf/pmu-events/jevents.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index 33aa3c885eaf..ed4f0bd72e5a 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -285,6 +285,8 @@ static struct map {
 	{ "imx8_ddr", "imx8_ddr" },
 	{ "L3PMC", "amd_l3" },
 	{ "DFPMC", "amd_df" },
+	{ "cpu_core", "cpu_core" },
+	{ "cpu_atom", "cpu_atom" },
 	{}
 };
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 03/26] perf pmu: Simplify arguments of __perf_pmu__new_alias
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
  2021-04-27  7:01 ` [PATCH v6 01/26] tools headers uapi: Update tools's copy of linux/perf_event.h Jin Yao
  2021-04-27  7:01 ` [PATCH v6 02/26] perf jevents: Support unit value "cpu_core" and "cpu_atom" Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 04/26] perf pmu: Save pmu name Jin Yao
                   ` (23 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

Simplify the arguments of __perf_pmu__new_alias() by passing
the whole 'struct pme_event' pointer.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v6:
 - No change.

 tools/perf/util/pmu.c | 36 ++++++++++++++++--------------------
 1 file changed, 16 insertions(+), 20 deletions(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 286d5e415bdc..8214def7b0f0 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -306,18 +306,25 @@ static bool perf_pmu_merge_alias(struct perf_pmu_alias *newalias,
 }
 
 static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
-				 char *desc, char *val,
-				 char *long_desc, char *topic,
-				 char *unit, char *perpkg,
-				 char *metric_expr,
-				 char *metric_name,
-				 char *deprecated)
+				 char *desc, char *val, struct pmu_event *pe)
 {
 	struct parse_events_term *term;
 	struct perf_pmu_alias *alias;
 	int ret;
 	int num;
 	char newval[256];
+	char *long_desc = NULL, *topic = NULL, *unit = NULL, *perpkg = NULL,
+	     *metric_expr = NULL, *metric_name = NULL, *deprecated = NULL;
+
+	if (pe) {
+		long_desc = (char *)pe->long_desc;
+		topic = (char *)pe->topic;
+		unit = (char *)pe->unit;
+		perpkg = (char *)pe->perpkg;
+		metric_expr = (char *)pe->metric_expr;
+		metric_name = (char *)pe->metric_name;
+		deprecated = (char *)pe->deprecated;
+	}
 
 	alias = malloc(sizeof(*alias));
 	if (!alias)
@@ -406,8 +413,7 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI
 	/* Remove trailing newline from sysfs file */
 	strim(buf);
 
-	return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL,
-				     NULL, NULL, NULL, NULL);
+	return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL);
 }
 
 static inline bool pmu_alias_info_file(char *name)
@@ -798,11 +804,7 @@ void pmu_add_cpu_aliases_map(struct list_head *head, struct perf_pmu *pmu,
 		/* need type casts to override 'const' */
 		__perf_pmu__new_alias(head, NULL, (char *)pe->name,
 				(char *)pe->desc, (char *)pe->event,
-				(char *)pe->long_desc, (char *)pe->topic,
-				(char *)pe->unit, (char *)pe->perpkg,
-				(char *)pe->metric_expr,
-				(char *)pe->metric_name,
-				(char *)pe->deprecated);
+				pe);
 	}
 }
 
@@ -869,13 +871,7 @@ static int pmu_add_sys_aliases_iter_fn(struct pmu_event *pe, void *data)
 				      (char *)pe->name,
 				      (char *)pe->desc,
 				      (char *)pe->event,
-				      (char *)pe->long_desc,
-				      (char *)pe->topic,
-				      (char *)pe->unit,
-				      (char *)pe->perpkg,
-				      (char *)pe->metric_expr,
-				      (char *)pe->metric_name,
-				      (char *)pe->deprecated);
+				      pe);
 	}
 
 	return 0;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 04/26] perf pmu: Save pmu name
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (2 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 03/26] perf pmu: Simplify arguments of __perf_pmu__new_alias Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 05/26] perf pmu: Save detected hybrid pmus to a global pmu list Jin Yao
                   ` (22 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

On hybrid platform, one event is available on one pmu
(such as, available on cpu_core or on cpu_atom).

This patch saves the pmu name to the pmu field of struct perf_pmu_alias.
Then next we can know the pmu which the event can be enabled on.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v4 - v6:
 - No change.

v3:
 - Change pmu to pmu_name in struct perf_pmu_alias.

 tools/perf/util/pmu.c | 10 +++++++++-
 tools/perf/util/pmu.h |  1 +
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 8214def7b0f0..44225838eb03 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -283,6 +283,7 @@ void perf_pmu_free_alias(struct perf_pmu_alias *newalias)
 	zfree(&newalias->str);
 	zfree(&newalias->metric_expr);
 	zfree(&newalias->metric_name);
+	zfree(&newalias->pmu_name);
 	parse_events_terms__purge(&newalias->terms);
 	free(newalias);
 }
@@ -297,6 +298,10 @@ static bool perf_pmu_merge_alias(struct perf_pmu_alias *newalias,
 
 	list_for_each_entry(a, alist, list) {
 		if (!strcasecmp(newalias->name, a->name)) {
+			if (newalias->pmu_name && a->pmu_name &&
+			    !strcasecmp(newalias->pmu_name, a->pmu_name)) {
+				continue;
+			}
 			perf_pmu_update_alias(a, newalias);
 			perf_pmu_free_alias(newalias);
 			return true;
@@ -314,7 +319,8 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
 	int num;
 	char newval[256];
 	char *long_desc = NULL, *topic = NULL, *unit = NULL, *perpkg = NULL,
-	     *metric_expr = NULL, *metric_name = NULL, *deprecated = NULL;
+	     *metric_expr = NULL, *metric_name = NULL, *deprecated = NULL,
+	     *pmu_name = NULL;
 
 	if (pe) {
 		long_desc = (char *)pe->long_desc;
@@ -324,6 +330,7 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
 		metric_expr = (char *)pe->metric_expr;
 		metric_name = (char *)pe->metric_name;
 		deprecated = (char *)pe->deprecated;
+		pmu_name = (char *)pe->pmu;
 	}
 
 	alias = malloc(sizeof(*alias));
@@ -389,6 +396,7 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
 	}
 	alias->per_pkg = perpkg && sscanf(perpkg, "%d", &num) == 1 && num == 1;
 	alias->str = strdup(newval);
+	alias->pmu_name = pmu_name ? strdup(pmu_name) : NULL;
 
 	if (deprecated)
 		alias->deprecated = true;
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 1f1749ba830f..4f100768c264 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -72,6 +72,7 @@ struct perf_pmu_alias {
 	bool deprecated;
 	char *metric_expr;
 	char *metric_name;
+	char *pmu_name;
 };
 
 struct perf_pmu *perf_pmu__find(const char *name);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 05/26] perf pmu: Save detected hybrid pmus to a global pmu list
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (3 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 04/26] perf pmu: Save pmu name Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 06/26] perf pmu: Add hybrid helper functions Jin Yao
                   ` (21 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

We identify the cpu_core pmu and cpu_atom pmu by explicitly
checking following files:

For cpu_core, checks:
"/sys/bus/event_source/devices/cpu_core/cpus"

For cpu_atom, checks:
"/sys/bus/event_source/devices/cpu_atom/cpus"

If the 'cpus' file exists and it has data, the pmu exists.

But in order not to hardcode the "cpu_core" and "cpu_atom",
and make the code in a generic way. So if the path
"/sys/bus/event_source/devices/cpu_xxx/cpus" exists, the hybrid
pmu exists. All the detected hybrid pmus are linked to a
global list 'perf_pmu__hybrid_pmus' and then next we just need
to iterate the list to get all hybrid pmu by using
perf_pmu__for_each_hybrid_pmu.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v5 - v6:
 - No change.

v4:
 - Check if 'cpus' file is empty. If so, don't create pmu.

v3:
 - No functional change.

 tools/perf/util/Build        |  1 +
 tools/perf/util/pmu-hybrid.c | 49 ++++++++++++++++++++++++++++++++++++
 tools/perf/util/pmu-hybrid.h | 18 +++++++++++++
 tools/perf/util/pmu.c        |  9 ++++++-
 tools/perf/util/pmu.h        |  4 +++
 5 files changed, 80 insertions(+), 1 deletion(-)
 create mode 100644 tools/perf/util/pmu-hybrid.c
 create mode 100644 tools/perf/util/pmu-hybrid.h

diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 827d216a780e..45bea9911669 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -69,6 +69,7 @@ perf-y += parse-events-bison.o
 perf-y += pmu.o
 perf-y += pmu-flex.o
 perf-y += pmu-bison.o
+perf-y += pmu-hybrid.o
 perf-y += trace-event-read.o
 perf-y += trace-event-info.o
 perf-y += trace-event-scripting.o
diff --git a/tools/perf/util/pmu-hybrid.c b/tools/perf/util/pmu-hybrid.c
new file mode 100644
index 000000000000..8ed0e6e1776d
--- /dev/null
+++ b/tools/perf/util/pmu-hybrid.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/list.h>
+#include <linux/compiler.h>
+#include <linux/string.h>
+#include <linux/zalloc.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdarg.h>
+#include <locale.h>
+#include <api/fs/fs.h>
+#include "fncache.h"
+#include "pmu-hybrid.h"
+
+LIST_HEAD(perf_pmu__hybrid_pmus);
+
+bool perf_pmu__hybrid_mounted(const char *name)
+{
+	char path[PATH_MAX];
+	const char *sysfs;
+	FILE *file;
+	int n, cpu;
+
+	if (strncmp(name, "cpu_", 4))
+		return false;
+
+	sysfs = sysfs__mountpoint();
+	if (!sysfs)
+		return false;
+
+	snprintf(path, PATH_MAX, CPUS_TEMPLATE_CPU, sysfs, name);
+	if (!file_available(path))
+		return false;
+
+	file = fopen(path, "r");
+	if (!file)
+		return false;
+
+	n = fscanf(file, "%u", &cpu);
+	fclose(file);
+	if (n <= 0)
+		return false;
+
+	return true;
+}
diff --git a/tools/perf/util/pmu-hybrid.h b/tools/perf/util/pmu-hybrid.h
new file mode 100644
index 000000000000..35bed3714438
--- /dev/null
+++ b/tools/perf/util/pmu-hybrid.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PMU_HYBRID_H
+#define __PMU_HYBRID_H
+
+#include <linux/perf_event.h>
+#include <linux/compiler.h>
+#include <linux/list.h>
+#include <stdbool.h>
+#include "pmu.h"
+
+extern struct list_head perf_pmu__hybrid_pmus;
+
+#define perf_pmu__for_each_hybrid_pmu(pmu)	\
+	list_for_each_entry(pmu, &perf_pmu__hybrid_pmus, hybrid_list)
+
+bool perf_pmu__hybrid_mounted(const char *name);
+
+#endif /* __PMU_HYBRID_H */
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 44225838eb03..6e49c7b8ad71 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -25,6 +25,7 @@
 #include "string2.h"
 #include "strbuf.h"
 #include "fncache.h"
+#include "pmu-hybrid.h"
 
 struct perf_pmu perf_pmu__fake;
 
@@ -613,7 +614,6 @@ static struct perf_cpu_map *__pmu_cpumask(const char *path)
  */
 #define SYS_TEMPLATE_ID	"./bus/event_source/devices/%s/identifier"
 #define CPUS_TEMPLATE_UNCORE	"%s/bus/event_source/devices/%s/cpumask"
-#define CPUS_TEMPLATE_CPU	"%s/bus/event_source/devices/%s/cpus"
 
 static struct perf_cpu_map *pmu_cpumask(const char *name)
 {
@@ -645,6 +645,9 @@ static bool pmu_is_uncore(const char *name)
 	char path[PATH_MAX];
 	const char *sysfs;
 
+	if (perf_pmu__hybrid_mounted(name))
+		return false;
+
 	sysfs = sysfs__mountpoint();
 	snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name);
 	return file_available(path);
@@ -951,6 +954,7 @@ static struct perf_pmu *pmu_lookup(const char *name)
 	pmu->is_uncore = pmu_is_uncore(name);
 	if (pmu->is_uncore)
 		pmu->id = pmu_id(name);
+	pmu->is_hybrid = perf_pmu__hybrid_mounted(name);
 	pmu->max_precise = pmu_max_precise(name);
 	pmu_add_cpu_aliases(&aliases, pmu);
 	pmu_add_sys_aliases(&aliases, pmu);
@@ -962,6 +966,9 @@ static struct perf_pmu *pmu_lookup(const char *name)
 	list_splice(&aliases, &pmu->aliases);
 	list_add_tail(&pmu->list, &pmus);
 
+	if (pmu->is_hybrid)
+		list_add_tail(&pmu->hybrid_list, &perf_pmu__hybrid_pmus);
+
 	pmu->default_config = perf_pmu__get_default_config(pmu);
 
 	return pmu;
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 4f100768c264..9a2f89eeab6f 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -5,6 +5,7 @@
 #include <linux/bitmap.h>
 #include <linux/compiler.h>
 #include <linux/perf_event.h>
+#include <linux/list.h>
 #include <stdbool.h>
 #include "parse-events.h"
 #include "pmu-events/pmu-events.h"
@@ -19,6 +20,7 @@ enum {
 
 #define PERF_PMU_FORMAT_BITS 64
 #define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/"
+#define CPUS_TEMPLATE_CPU	"%s/bus/event_source/devices/%s/cpus"
 
 struct perf_event_attr;
 
@@ -34,6 +36,7 @@ struct perf_pmu {
 	__u32 type;
 	bool selectable;
 	bool is_uncore;
+	bool is_hybrid;
 	bool auxtrace;
 	int max_precise;
 	struct perf_event_attr *default_config;
@@ -42,6 +45,7 @@ struct perf_pmu {
 	struct list_head aliases; /* HEAD struct perf_pmu_alias -> list */
 	struct list_head caps;    /* HEAD struct perf_pmu_caps -> list */
 	struct list_head list;    /* ELEM */
+	struct list_head hybrid_list;
 };
 
 extern struct perf_pmu perf_pmu__fake;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 06/26] perf pmu: Add hybrid helper functions
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (4 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 05/26] perf pmu: Save detected hybrid pmus to a global pmu list Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 07/26] perf stat: Uniquify hybrid event name Jin Yao
                   ` (20 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

The functions perf_pmu__is_hybrid and perf_pmu__find_hybrid_pmu
can be used to identify the hybrid platform and return the found
hybrid cpu pmu. All the detected hybrid pmus have been saved in
'perf_pmu__hybrid_pmus' list. So we just need to search this list.

perf_pmu__hybrid_type_to_pmu converts the user specified string
to hybrid pmu name. This is used to support the '--cputype' option
in next patches.

perf_pmu__has_hybrid checks the existing of hybrid pmu. Note that,
we have to define it in pmu.c (make pmu-hybrid.c no more symbol
dependency), otherwise perf test python would be failed.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v4 - v6:
 - No change.

v3:
 - Move perf_pmu__has_hybrid from pmu-hybrid.c to pmu.c. We have to
   add pmu-hybrid.c to python-ext-sources to solve symbol dependency
   issue found in perf test python. For perf_pmu__has_hybrid, it calls
   perf_pmu__scan, which is defined in pmu.c. It's very hard to add
   pmu.c to python-ext-sources, too much symbol dependency here.

 tools/perf/util/pmu-hybrid.c | 40 ++++++++++++++++++++++++++++++++++++
 tools/perf/util/pmu-hybrid.h |  4 ++++
 tools/perf/util/pmu.c        | 11 ++++++++++
 tools/perf/util/pmu.h        |  2 ++
 4 files changed, 57 insertions(+)

diff --git a/tools/perf/util/pmu-hybrid.c b/tools/perf/util/pmu-hybrid.c
index 8ed0e6e1776d..f51ccaac60ee 100644
--- a/tools/perf/util/pmu-hybrid.c
+++ b/tools/perf/util/pmu-hybrid.c
@@ -47,3 +47,43 @@ bool perf_pmu__hybrid_mounted(const char *name)
 
 	return true;
 }
+
+struct perf_pmu *perf_pmu__find_hybrid_pmu(const char *name)
+{
+	struct perf_pmu *pmu;
+
+	if (!name)
+		return NULL;
+
+	perf_pmu__for_each_hybrid_pmu(pmu) {
+		if (!strcmp(name, pmu->name))
+			return pmu;
+	}
+
+	return NULL;
+}
+
+bool perf_pmu__is_hybrid(const char *name)
+{
+	return perf_pmu__find_hybrid_pmu(name) != NULL;
+}
+
+char *perf_pmu__hybrid_type_to_pmu(const char *type)
+{
+	char *pmu_name = NULL;
+
+	if (asprintf(&pmu_name, "cpu_%s", type) < 0)
+		return NULL;
+
+	if (perf_pmu__is_hybrid(pmu_name))
+		return pmu_name;
+
+	/*
+	 * pmu may be not scanned, check the sysfs.
+	 */
+	if (perf_pmu__hybrid_mounted(pmu_name))
+		return pmu_name;
+
+	free(pmu_name);
+	return NULL;
+}
diff --git a/tools/perf/util/pmu-hybrid.h b/tools/perf/util/pmu-hybrid.h
index 35bed3714438..d0fa7bc50a76 100644
--- a/tools/perf/util/pmu-hybrid.h
+++ b/tools/perf/util/pmu-hybrid.h
@@ -15,4 +15,8 @@ extern struct list_head perf_pmu__hybrid_pmus;
 
 bool perf_pmu__hybrid_mounted(const char *name);
 
+struct perf_pmu *perf_pmu__find_hybrid_pmu(const char *name);
+bool perf_pmu__is_hybrid(const char *name);
+char *perf_pmu__hybrid_type_to_pmu(const char *type);
+
 #endif /* __PMU_HYBRID_H */
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 6e49c7b8ad71..88c8ecdc60b0 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -40,6 +40,7 @@ int perf_pmu_parse(struct list_head *list, char *name);
 extern FILE *perf_pmu_in;
 
 static LIST_HEAD(pmus);
+static bool hybrid_scanned;
 
 /*
  * Parse & process all the sysfs attributes located under
@@ -1861,3 +1862,13 @@ void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config,
 		   "'%llx' not supported by kernel)!\n",
 		   name ?: "N/A", buf, config);
 }
+
+bool perf_pmu__has_hybrid(void)
+{
+	if (!hybrid_scanned) {
+		hybrid_scanned = true;
+		perf_pmu__scan(NULL);
+	}
+
+	return !list_empty(&perf_pmu__hybrid_pmus);
+}
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 9a2f89eeab6f..a790ef758171 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -132,4 +132,6 @@ int perf_pmu__caps_parse(struct perf_pmu *pmu);
 void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config,
 				   char *name);
 
+bool perf_pmu__has_hybrid(void);
+
 #endif /* __PMU_H */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 07/26] perf stat: Uniquify hybrid event name
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (5 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 06/26] perf pmu: Add hybrid helper functions Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 08/26] perf parse-events: Create two hybrid hardware events Jin Yao
                   ` (19 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

It would be useful to let user know the pmu which the event belongs to.
perf-stat has supported '--no-merge' option and it can print the pmu
name after the event name, such as:

"cycles [cpu_core]"

Now this option is enabled by default for hybrid platform but change
the format to:

"cpu_core/cycles/"

If user configs the name, we still use the user specified name.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v6:
 - Rebase to tmp.perf/core branch.

v5:
 - Move 'evsel->use_config_name = true;' from
   '[PATCH v5 12/26] perf parse-events: Support event inside hybrid pmu'
   to the patch.

v4:
 - If user configs the name, we still use the user specified name.

v3:
 - No change.

 tools/perf/builtin-stat.c      |  4 ++++
 tools/perf/util/evsel.h        |  1 +
 tools/perf/util/parse-events.c |  3 +++
 tools/perf/util/stat-display.c | 15 +++++++++++++--
 4 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 5ec2190e45cd..835e3696b9ce 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -69,6 +69,7 @@
 #include "util/pfm.h"
 #include "util/bpf_counter.h"
 #include "util/iostat.h"
+#include "util/pmu-hybrid.h"
 #include "asm/bug.h"
 
 #include <linux/time64.h>
@@ -2402,6 +2403,9 @@ int cmd_stat(int argc, const char **argv)
 
 	evlist__check_cpu_maps(evsel_list);
 
+	if (perf_pmu__has_hybrid())
+		stat_config.no_merge = true;
+
 	/*
 	 * Initialize thread_map with comm names,
 	 * so we could print it out on output.
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 8f66cdcb338d..ad74c83bd35b 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -116,6 +116,7 @@ struct evsel {
 	bool			merged_stat;
 	bool			reset_group;
 	bool			errored;
+	bool			use_config_name;
 	struct hashmap		*per_pkg_mask;
 	struct evsel		*leader;
 	struct list_head	config_terms;
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 46ebd269a98d..f4628c886e30 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1567,6 +1567,9 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
 	if (!evsel)
 		return -ENOMEM;
 
+	if (evsel->name)
+		evsel->use_config_name = true;
+
 	evsel->pmu_name = name ? strdup(name) : NULL;
 	evsel->use_uncore_alias = use_uncore_alias;
 	evsel->percore = config_term_percore(&evsel->config_terms);
diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index 98664caef6af..0679129ad05e 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -18,6 +18,7 @@
 #include <api/fs/fs.h>
 #include "util.h"
 #include "iostat.h"
+#include "pmu-hybrid.h"
 
 #define CNTR_NOT_SUPPORTED	"<not supported>"
 #define CNTR_NOT_COUNTED	"<not counted>"
@@ -538,6 +539,7 @@ static void uniquify_event_name(struct evsel *counter)
 {
 	char *new_name;
 	char *config;
+	int ret = 0;
 
 	if (counter->uniquified_name ||
 	    !counter->pmu_name || !strncmp(counter->name, counter->pmu_name,
@@ -552,8 +554,17 @@ static void uniquify_event_name(struct evsel *counter)
 			counter->name = new_name;
 		}
 	} else {
-		if (asprintf(&new_name,
-			     "%s [%s]", counter->name, counter->pmu_name) > 0) {
+		if (perf_pmu__has_hybrid()) {
+			if (!counter->use_config_name) {
+				ret = asprintf(&new_name, "%s/%s/",
+					       counter->pmu_name, counter->name);
+			}
+		} else {
+			ret = asprintf(&new_name, "%s [%s]",
+				       counter->name, counter->pmu_name);
+		}
+
+		if (ret) {
 			free(counter->name);
 			counter->name = new_name;
 		}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 08/26] perf parse-events: Create two hybrid hardware events
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (6 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 07/26] perf stat: Uniquify hybrid event name Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 09/26] perf parse-events: Create two hybrid cache events Jin Yao
                   ` (18 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

Current hardware events has special perf types PERF_TYPE_HARDWARE.
But it doesn't pass the PMU type in the user interface. For a hybrid
system, the perf kernel doesn't know which PMU the events belong to.

So now this type is extended to be PMU aware type. The PMU type ID
is stored at attr.config[63:32].

PMU type ID is retrieved from sysfs.

  root@lkp-adl-d01:/sys/devices/cpu_atom# cat type
  8

  root@lkp-adl-d01:/sys/devices/cpu_core# cat type
  4

When enabling a hybrid hardware event without specified pmu, such as,
'perf stat -e cycles -a', two events are created automatically. One
is for atom, the other is for core.

  # perf stat -e cycles -a -vv -- sleep 1
  Control descriptor is not initialized
  ------------------------------------------------------------
  perf_event_attr:
    size                             120
    config                           0x400000000
    sample_type                      IDENTIFIER
    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
    disabled                         1
    inherit                          1
    exclude_guest                    1
  ------------------------------------------------------------
  sys_perf_event_open: pid -1  cpu 0  group_fd -1  flags 0x8 = 3
  ------------------------------------------------------------
  ...
  ------------------------------------------------------------
  perf_event_attr:
    size                             120
    config                           0x400000000
    sample_type                      IDENTIFIER
    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
    disabled                         1
    inherit                          1
    exclude_guest                    1
  ------------------------------------------------------------
  sys_perf_event_open: pid -1  cpu 15  group_fd -1  flags 0x8 = 19
  ------------------------------------------------------------
  perf_event_attr:
    size                             120
    config                           0x800000000
    sample_type                      IDENTIFIER
    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
    disabled                         1
    inherit                          1
    exclude_guest                    1
  ------------------------------------------------------------
  sys_perf_event_open: pid -1  cpu 16  group_fd -1  flags 0x8 = 20
  ------------------------------------------------------------
  ...
  ------------------------------------------------------------
  perf_event_attr:
    size                             120
    config                           0x800000000
    sample_type                      IDENTIFIER
    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
    disabled                         1
    inherit                          1
    exclude_guest                    1
  ------------------------------------------------------------
  sys_perf_event_open: pid -1  cpu 23  group_fd -1  flags 0x8 = 27
  cycles: 0: 836272 1001525722 1001525722
  cycles: 1: 628564 1001580453 1001580453
  cycles: 2: 872693 1001605997 1001605997
  cycles: 3: 70417 1001641369 1001641369
  cycles: 4: 88593 1001726722 1001726722
  cycles: 5: 470495 1001752993 1001752993
  cycles: 6: 484733 1001840440 1001840440
  cycles: 7: 1272477 1001593105 1001593105
  cycles: 8: 209185 1001608616 1001608616
  cycles: 9: 204391 1001633962 1001633962
  cycles: 10: 264121 1001661745 1001661745
  cycles: 11: 826104 1001689904 1001689904
  cycles: 12: 89935 1001728861 1001728861
  cycles: 13: 70639 1001756757 1001756757
  cycles: 14: 185266 1001784810 1001784810
  cycles: 15: 171094 1001825466 1001825466
  cycles: 0: 129624 1001854843 1001854843
  cycles: 1: 122533 1001840421 1001840421
  cycles: 2: 90055 1001882506 1001882506
  cycles: 3: 139607 1001896463 1001896463
  cycles: 4: 141791 1001907838 1001907838
  cycles: 5: 530927 1001883880 1001883880
  cycles: 6: 143246 1001852529 1001852529
  cycles: 7: 667769 1001872626 1001872626
  cycles: 6744979 16026956922 16026956922
  cycles: 1965552 8014991106 8014991106

   Performance counter stats for 'system wide':

           6,744,979      cpu_core/cycles/
           1,965,552      cpu_atom/cycles/

         1.001882711 seconds time elapsed

0x4 in 0x400000000 indicates the cpu_core pmu.
0x8 in 0x800000000 indicates the cpu_atom pmu.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v5 - v6:
 - No change.

v4:
 - Use PERF_TYPE_HARDWARE (v3 uses PERF_TYPE_HARDWARE_PMU)

v3:
 - Create new parse-events-hybrid.c/parse-events-hybrid.h
 - Refine the code

 tools/perf/util/Build                 |   1 +
 tools/perf/util/parse-events-hybrid.c | 100 ++++++++++++++++++++++++++
 tools/perf/util/parse-events-hybrid.h |  17 +++++
 tools/perf/util/parse-events.c        |  18 +++++
 tools/perf/util/parse-events.h        |   5 ++
 5 files changed, 141 insertions(+)
 create mode 100644 tools/perf/util/parse-events-hybrid.c
 create mode 100644 tools/perf/util/parse-events-hybrid.h

diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 45bea9911669..34fcbf3c3bce 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -23,6 +23,7 @@ perf-y += llvm-utils.o
 perf-y += mmap.o
 perf-y += memswap.o
 perf-y += parse-events.o
+perf-y += parse-events-hybrid.o
 perf-y += perf_regs.o
 perf-y += path.o
 perf-y += print_binary.o
diff --git a/tools/perf/util/parse-events-hybrid.c b/tools/perf/util/parse-events-hybrid.c
new file mode 100644
index 000000000000..8fd7f19a9865
--- /dev/null
+++ b/tools/perf/util/parse-events-hybrid.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/err.h>
+#include <linux/zalloc.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/param.h>
+#include "evlist.h"
+#include "evsel.h"
+#include "parse-events.h"
+#include "parse-events-hybrid.h"
+#include "debug.h"
+#include "pmu.h"
+#include "pmu-hybrid.h"
+#include "perf.h"
+
+static void config_hybrid_attr(struct perf_event_attr *attr,
+			       int type, int pmu_type)
+{
+	/*
+	 * attr.config layout for type PERF_TYPE_HARDWARE and
+	 * PERF_TYPE_HW_CACHE
+	 *
+	 * PERF_TYPE_HARDWARE:                 0xEEEEEEEE000000AA
+	 *                                     AA: hardware event ID
+	 *                                     EEEEEEEE: PMU type ID
+	 * PERF_TYPE_HW_CACHE:                 0xEEEEEEEE00DDCCBB
+	 *                                     BB: hardware cache ID
+	 *                                     CC: hardware cache op ID
+	 *                                     DD: hardware cache op result ID
+	 *                                     EEEEEEEE: PMU type ID
+	 * If the PMU type ID is 0, the PERF_TYPE_RAW will be applied.
+	 */
+	attr->type = type;
+	attr->config = attr->config | ((__u64)pmu_type << PERF_PMU_TYPE_SHIFT);
+}
+
+static int create_event_hybrid(__u32 config_type, int *idx,
+			       struct list_head *list,
+			       struct perf_event_attr *attr, char *name,
+			       struct list_head *config_terms,
+			       struct perf_pmu *pmu)
+{
+	struct evsel *evsel;
+	__u32 type = attr->type;
+	__u64 config = attr->config;
+
+	config_hybrid_attr(attr, config_type, pmu->type);
+	evsel = parse_events__add_event_hybrid(list, idx, attr, name,
+					       pmu, config_terms);
+	if (evsel)
+		evsel->pmu_name = strdup(pmu->name);
+	else
+		return -ENOMEM;
+
+	attr->type = type;
+	attr->config = config;
+	return 0;
+}
+
+static int add_hw_hybrid(struct parse_events_state *parse_state,
+			 struct list_head *list, struct perf_event_attr *attr,
+			 char *name, struct list_head *config_terms)
+{
+	struct perf_pmu *pmu;
+	int ret;
+
+	perf_pmu__for_each_hybrid_pmu(pmu) {
+		ret = create_event_hybrid(PERF_TYPE_HARDWARE,
+					  &parse_state->idx, list, attr, name,
+					  config_terms, pmu);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
+				     struct list_head *list,
+				     struct perf_event_attr *attr,
+				     char *name, struct list_head *config_terms,
+				     bool *hybrid)
+{
+	*hybrid = false;
+	if (attr->type == PERF_TYPE_SOFTWARE)
+		return 0;
+
+	if (!perf_pmu__has_hybrid())
+		return 0;
+
+	*hybrid = true;
+	if (attr->type != PERF_TYPE_RAW) {
+		return add_hw_hybrid(parse_state, list, attr, name,
+				     config_terms);
+	}
+
+	return -1;
+}
diff --git a/tools/perf/util/parse-events-hybrid.h b/tools/perf/util/parse-events-hybrid.h
new file mode 100644
index 000000000000..d81a76978480
--- /dev/null
+++ b/tools/perf/util/parse-events-hybrid.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PERF_PARSE_EVENTS_HYBRID_H
+#define __PERF_PARSE_EVENTS_HYBRID_H
+
+#include <linux/list.h>
+#include <stdbool.h>
+#include <linux/types.h>
+#include <linux/perf_event.h>
+#include <string.h>
+
+int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
+				     struct list_head *list,
+				     struct perf_event_attr *attr,
+				     char *name, struct list_head *config_terms,
+				     bool *hybrid);
+
+#endif /* __PERF_PARSE_EVENTS_HYBRID_H */
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index f4628c886e30..9109f8b03fe7 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -37,6 +37,7 @@
 #include "util/evsel_config.h"
 #include "util/event.h"
 #include "util/pfm.h"
+#include "util/parse-events-hybrid.h"
 #include "perf.h"
 
 #define MAX_NAME_LEN 100
@@ -1419,6 +1420,8 @@ int parse_events_add_numeric(struct parse_events_state *parse_state,
 {
 	struct perf_event_attr attr;
 	LIST_HEAD(config_terms);
+	bool hybrid;
+	int ret;
 
 	memset(&attr, 0, sizeof(attr));
 	attr.type = type;
@@ -1433,6 +1436,12 @@ int parse_events_add_numeric(struct parse_events_state *parse_state,
 			return -ENOMEM;
 	}
 
+	ret = parse_events__add_numeric_hybrid(parse_state, list, &attr,
+					       get_config_name(head_config),
+					       &config_terms, &hybrid);
+	if (hybrid)
+		return ret;
+
 	return add_event(list, &parse_state->idx, &attr,
 			 get_config_name(head_config), &config_terms);
 }
@@ -3194,3 +3203,12 @@ char *parse_events_formats_error_string(char *additional_terms)
 fail:
 	return NULL;
 }
+
+struct evsel *parse_events__add_event_hybrid(struct list_head *list, int *idx,
+					     struct perf_event_attr *attr,
+					     char *name, struct perf_pmu *pmu,
+					     struct list_head *config_terms)
+{
+	return __add_event(list, idx, attr, true, name, pmu,
+			   config_terms, false, NULL);
+}
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index e80c9b74f2f2..c4f2f96304ce 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -263,4 +263,9 @@ static inline bool is_sdt_event(char *str __maybe_unused)
 
 int perf_pmu__test_parse_init(void);
 
+struct evsel *parse_events__add_event_hybrid(struct list_head *list, int *idx,
+					     struct perf_event_attr *attr,
+					     char *name, struct perf_pmu *pmu,
+					     struct list_head *config_terms);
+
 #endif /* __PERF_PARSE_EVENTS_H */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 09/26] perf parse-events: Create two hybrid cache events
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (7 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 08/26] perf parse-events: Create two hybrid hardware events Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 10/26] perf parse-events: Create two hybrid raw events Jin Yao
                   ` (17 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

For cache events, they have pre-defined configs. The kernel needs
to know where the cache event comes from (e.g. from cpu_core pmu
or from cpu_atom pmu). But the perf type PERF_TYPE_HW_CACHE
can't carry pmu information.

Now the type PERF_TYPE_HW_CACHE is extended to be PMU aware type.
The PMU type ID is stored at attr.config[63:32].

When enabling a hybrid cache event without specified pmu, such as,
'perf stat -e LLC-loads -a', two events are created
automatically. One is for atom, the other is for core.

  # perf stat -e LLC-loads -a -vv -- sleep 1
  Control descriptor is not initialized
  ------------------------------------------------------------
  perf_event_attr:
    type                             3
    size                             120
    config                           0x400000002
    sample_type                      IDENTIFIER
    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
    disabled                         1
    inherit                          1
    exclude_guest                    1
  ------------------------------------------------------------
  sys_perf_event_open: pid -1  cpu 0  group_fd -1  flags 0x8 = 3
  ------------------------------------------------------------
  ...
  ------------------------------------------------------------
  perf_event_attr:
    type                             3
    size                             120
    config                           0x400000002
    sample_type                      IDENTIFIER
    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
    disabled                         1
    inherit                          1
    exclude_guest                    1
  ------------------------------------------------------------
  sys_perf_event_open: pid -1  cpu 15  group_fd -1  flags 0x8 = 19
  ------------------------------------------------------------
  perf_event_attr:
    type                             3
    size                             120
    config                           0x800000002
    sample_type                      IDENTIFIER
    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
    disabled                         1
    inherit                          1
    exclude_guest                    1
  ------------------------------------------------------------
  sys_perf_event_open: pid -1  cpu 16  group_fd -1  flags 0x8 = 20
  ------------------------------------------------------------
  ...
  ------------------------------------------------------------
  perf_event_attr:
    type                             3
    size                             120
    config                           0x800000002
    sample_type                      IDENTIFIER
    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
    disabled                         1
    inherit                          1
    exclude_guest                    1
  ------------------------------------------------------------
  sys_perf_event_open: pid -1  cpu 23  group_fd -1  flags 0x8 = 27
  LLC-loads: 0: 1507 1001800280 1001800280
  LLC-loads: 1: 666 1001812250 1001812250
  LLC-loads: 2: 3353 1001813453 1001813453
  LLC-loads: 3: 514 1001848795 1001848795
  LLC-loads: 4: 627 1001952832 1001952832
  LLC-loads: 5: 4399 1001451154 1001451154
  LLC-loads: 6: 1240 1001481052 1001481052
  LLC-loads: 7: 478 1001520348 1001520348
  LLC-loads: 8: 691 1001551236 1001551236
  LLC-loads: 9: 310 1001578945 1001578945
  LLC-loads: 10: 1018 1001594354 1001594354
  LLC-loads: 11: 3656 1001622355 1001622355
  LLC-loads: 12: 882 1001661416 1001661416
  LLC-loads: 13: 506 1001693963 1001693963
  LLC-loads: 14: 3547 1001721013 1001721013
  LLC-loads: 15: 1399 1001734818 1001734818
  LLC-loads: 0: 1314 1001793826 1001793826
  LLC-loads: 1: 2857 1001752764 1001752764
  LLC-loads: 2: 646 1001830694 1001830694
  LLC-loads: 3: 1612 1001864861 1001864861
  LLC-loads: 4: 2244 1001912381 1001912381
  LLC-loads: 5: 1255 1001943889 1001943889
  LLC-loads: 6: 4624 1002021109 1002021109
  LLC-loads: 7: 2703 1001959302 1001959302
  LLC-loads: 24793 16026838264 16026838264
  LLC-loads: 17255 8015078826 8015078826

   Performance counter stats for 'system wide':

              24,793      cpu_core/LLC-loads/
              17,255      cpu_atom/LLC-loads/

         1.001970988 seconds time elapsed

0x4 in 0x400000002 indicates the cpu_core pmu.
0x8 in 0x800000002 indicates the cpu_atom pmu.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v5 - v6:
 - No change.

v4:
 - Use PERF_TYPE_HW_CACHE (v3 uses PERF_TYPE_HW_CACHE_PMU)
 - Define 'ret' variable for return value.

v3:
 - Raw event creation is moved to parse-events-hybrid.c.

 tools/perf/util/parse-events-hybrid.c | 23 +++++++++++++++++++++++
 tools/perf/util/parse-events-hybrid.h |  5 +++++
 tools/perf/util/parse-events.c        | 10 +++++++++-
 3 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/parse-events-hybrid.c b/tools/perf/util/parse-events-hybrid.c
index 8fd7f19a9865..7a7e065d2b5f 100644
--- a/tools/perf/util/parse-events-hybrid.c
+++ b/tools/perf/util/parse-events-hybrid.c
@@ -98,3 +98,26 @@ int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
 
 	return -1;
 }
+
+int parse_events__add_cache_hybrid(struct list_head *list, int *idx,
+				   struct perf_event_attr *attr, char *name,
+				   struct list_head *config_terms,
+				   bool *hybrid)
+{
+	struct perf_pmu *pmu;
+	int ret;
+
+	*hybrid = false;
+	if (!perf_pmu__has_hybrid())
+		return 0;
+
+	*hybrid = true;
+	perf_pmu__for_each_hybrid_pmu(pmu) {
+		ret = create_event_hybrid(PERF_TYPE_HW_CACHE, idx, list,
+					  attr, name, config_terms, pmu);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
diff --git a/tools/perf/util/parse-events-hybrid.h b/tools/perf/util/parse-events-hybrid.h
index d81a76978480..9ad33cd0cef4 100644
--- a/tools/perf/util/parse-events-hybrid.h
+++ b/tools/perf/util/parse-events-hybrid.h
@@ -14,4 +14,9 @@ int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
 				     char *name, struct list_head *config_terms,
 				     bool *hybrid);
 
+int parse_events__add_cache_hybrid(struct list_head *list, int *idx,
+				   struct perf_event_attr *attr, char *name,
+				   struct list_head *config_terms,
+				   bool *hybrid);
+
 #endif /* __PERF_PARSE_EVENTS_HYBRID_H */
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 9109f8b03fe7..c228bf5c7d88 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -460,7 +460,8 @@ int parse_events_add_cache(struct list_head *list, int *idx,
 	char name[MAX_NAME_LEN], *config_name;
 	int cache_type = -1, cache_op = -1, cache_result = -1;
 	char *op_result[2] = { op_result1, op_result2 };
-	int i, n;
+	int i, n, ret;
+	bool hybrid;
 
 	/*
 	 * No fallback - if we cannot get a clear cache type
@@ -520,6 +521,13 @@ int parse_events_add_cache(struct list_head *list, int *idx,
 		if (get_config_terms(head_config, &config_terms))
 			return -ENOMEM;
 	}
+
+	ret = parse_events__add_cache_hybrid(list, idx, &attr,
+					     config_name ? : name, &config_terms,
+					     &hybrid);
+	if (hybrid)
+		return ret;
+
 	return add_event(list, idx, &attr, config_name ? : name, &config_terms);
 }
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 10/26] perf parse-events: Create two hybrid raw events
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (8 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 09/26] perf parse-events: Create two hybrid cache events Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 11/26] perf parse-events: Compare with hybrid pmu name Jin Yao
                   ` (16 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

On hybrid platform, same raw event is possible to be available
on both cpu_core pmu and cpu_atom pmu. It's supported to create
two raw events for one event encoding. For raw events, the
attr.type is PMU type.

  # perf stat -e r3c -a -vv -- sleep 1
  Control descriptor is not initialized
  ------------------------------------------------------------
  perf_event_attr:
    type                             4
    size                             120
    config                           0x3c
    sample_type                      IDENTIFIER
    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
    disabled                         1
    inherit                          1
    exclude_guest                    1
  ------------------------------------------------------------
  sys_perf_event_open: pid -1  cpu 0  group_fd -1  flags 0x8 = 3
  ------------------------------------------------------------
  ...
  ------------------------------------------------------------
  perf_event_attr:
    type                             4
    size                             120
    config                           0x3c
    sample_type                      IDENTIFIER
    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
    disabled                         1
    inherit                          1
    exclude_guest                    1
  ------------------------------------------------------------
  sys_perf_event_open: pid -1  cpu 15  group_fd -1  flags 0x8 = 19
  ------------------------------------------------------------
  perf_event_attr:
    type                             8
    size                             120
    config                           0x3c
    sample_type                      IDENTIFIER
    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
    disabled                         1
    inherit                          1
    exclude_guest                    1
  ------------------------------------------------------------
  sys_perf_event_open: pid -1  cpu 16  group_fd -1  flags 0x8 = 20
  ------------------------------------------------------------
  ...
  ------------------------------------------------------------
  perf_event_attr:
    type                             8
    size                             120
    config                           0x3c
    sample_type                      IDENTIFIER
    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
    disabled                         1
    inherit                          1
    exclude_guest                    1
  ------------------------------------------------------------
  sys_perf_event_open: pid -1  cpu 23  group_fd -1  flags 0x8 = 27
  r3c: 0: 434449 1001412521 1001412521
  r3c: 1: 173162 1001482031 1001482031
  r3c: 2: 231710 1001524974 1001524974
  r3c: 3: 110012 1001563523 1001563523
  r3c: 4: 191517 1001593221 1001593221
  r3c: 5: 956458 1001628147 1001628147
  r3c: 6: 416969 1001715626 1001715626
  r3c: 7: 1047527 1001596650 1001596650
  r3c: 8: 103877 1001633520 1001633520
  r3c: 9: 70571 1001637898 1001637898
  r3c: 10: 550284 1001714398 1001714398
  r3c: 11: 1257274 1001738349 1001738349
  r3c: 12: 107797 1001801432 1001801432
  r3c: 13: 67471 1001836281 1001836281
  r3c: 14: 286782 1001923161 1001923161
  r3c: 15: 815509 1001952550 1001952550
  r3c: 0: 95994 1002071117 1002071117
  r3c: 1: 105570 1002142438 1002142438
  r3c: 2: 115921 1002189147 1002189147
  r3c: 3: 72747 1002238133 1002238133
  r3c: 4: 103519 1002276753 1002276753
  r3c: 5: 121382 1002315131 1002315131
  r3c: 6: 80298 1002248050 1002248050
  r3c: 7: 466790 1002278221 1002278221
  r3c: 6821369 16026754282 16026754282
  r3c: 1162221 8017758990 8017758990

   Performance counter stats for 'system wide':

           6,821,369      cpu_core/r3c/
           1,162,221      cpu_atom/r3c/

         1.002289965 seconds time elapsed

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v5 - v6:
 - No change.

v4:
 - Directly return add_raw_hybrid().

v3:
 - Raw event creation is moved to parse-events-hybrid.c.

 tools/perf/util/parse-events-hybrid.c | 38 ++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/parse-events-hybrid.c b/tools/perf/util/parse-events-hybrid.c
index 7a7e065d2b5f..e27b747080e1 100644
--- a/tools/perf/util/parse-events-hybrid.c
+++ b/tools/perf/util/parse-events-hybrid.c
@@ -77,6 +77,41 @@ static int add_hw_hybrid(struct parse_events_state *parse_state,
 	return 0;
 }
 
+static int create_raw_event_hybrid(int *idx, struct list_head *list,
+				   struct perf_event_attr *attr, char *name,
+				   struct list_head *config_terms,
+				   struct perf_pmu *pmu)
+{
+	struct evsel *evsel;
+
+	attr->type = pmu->type;
+	evsel = parse_events__add_event_hybrid(list, idx, attr, name,
+					       pmu, config_terms);
+	if (evsel)
+		evsel->pmu_name = strdup(pmu->name);
+	else
+		return -ENOMEM;
+
+	return 0;
+}
+
+static int add_raw_hybrid(struct parse_events_state *parse_state,
+			  struct list_head *list, struct perf_event_attr *attr,
+			  char *name, struct list_head *config_terms)
+{
+	struct perf_pmu *pmu;
+	int ret;
+
+	perf_pmu__for_each_hybrid_pmu(pmu) {
+		ret = create_raw_event_hybrid(&parse_state->idx, list, attr,
+					      name, config_terms, pmu);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
 				     struct list_head *list,
 				     struct perf_event_attr *attr,
@@ -96,7 +131,8 @@ int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
 				     config_terms);
 	}
 
-	return -1;
+	return add_raw_hybrid(parse_state, list, attr, name,
+			      config_terms);
 }
 
 int parse_events__add_cache_hybrid(struct list_head *list, int *idx,
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 11/26] perf parse-events: Compare with hybrid pmu name
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (9 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 10/26] perf parse-events: Create two hybrid raw events Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 12/26] perf parse-events: Support event inside hybrid pmu Jin Yao
                   ` (15 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

On hybrid platform, user may want to enable event only on one pmu.
Following syntax will be supported:

cpu_core/<event>/
cpu_atom/<event>/

For hardware event, hardware cache event and raw event, two events
are created by default. We pass the specified pmu name in parse_state
and it would be checked before event creation. So next only the
event with the specified pmu would be created.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v5 - v6:
 - No change.

v4:
 - New in v4.

 tools/perf/util/parse-events-hybrid.c | 21 ++++++++++++++++++++-
 tools/perf/util/parse-events-hybrid.h |  3 ++-
 tools/perf/util/parse-events.c        |  5 +++--
 tools/perf/util/parse-events.h        |  4 +++-
 tools/perf/util/parse-events.y        |  9 ++++++---
 5 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/parse-events-hybrid.c b/tools/perf/util/parse-events-hybrid.c
index e27b747080e1..10160ab126f9 100644
--- a/tools/perf/util/parse-events-hybrid.c
+++ b/tools/perf/util/parse-events-hybrid.c
@@ -59,6 +59,15 @@ static int create_event_hybrid(__u32 config_type, int *idx,
 	return 0;
 }
 
+static int pmu_cmp(struct parse_events_state *parse_state,
+		   struct perf_pmu *pmu)
+{
+	if (!parse_state->hybrid_pmu_name)
+		return 0;
+
+	return strcmp(parse_state->hybrid_pmu_name, pmu->name);
+}
+
 static int add_hw_hybrid(struct parse_events_state *parse_state,
 			 struct list_head *list, struct perf_event_attr *attr,
 			 char *name, struct list_head *config_terms)
@@ -67,6 +76,9 @@ static int add_hw_hybrid(struct parse_events_state *parse_state,
 	int ret;
 
 	perf_pmu__for_each_hybrid_pmu(pmu) {
+		if (pmu_cmp(parse_state, pmu))
+			continue;
+
 		ret = create_event_hybrid(PERF_TYPE_HARDWARE,
 					  &parse_state->idx, list, attr, name,
 					  config_terms, pmu);
@@ -103,6 +115,9 @@ static int add_raw_hybrid(struct parse_events_state *parse_state,
 	int ret;
 
 	perf_pmu__for_each_hybrid_pmu(pmu) {
+		if (pmu_cmp(parse_state, pmu))
+			continue;
+
 		ret = create_raw_event_hybrid(&parse_state->idx, list, attr,
 					      name, config_terms, pmu);
 		if (ret)
@@ -138,7 +153,8 @@ int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
 int parse_events__add_cache_hybrid(struct list_head *list, int *idx,
 				   struct perf_event_attr *attr, char *name,
 				   struct list_head *config_terms,
-				   bool *hybrid)
+				   bool *hybrid,
+				   struct parse_events_state *parse_state)
 {
 	struct perf_pmu *pmu;
 	int ret;
@@ -149,6 +165,9 @@ int parse_events__add_cache_hybrid(struct list_head *list, int *idx,
 
 	*hybrid = true;
 	perf_pmu__for_each_hybrid_pmu(pmu) {
+		if (pmu_cmp(parse_state, pmu))
+			continue;
+
 		ret = create_event_hybrid(PERF_TYPE_HW_CACHE, idx, list,
 					  attr, name, config_terms, pmu);
 		if (ret)
diff --git a/tools/perf/util/parse-events-hybrid.h b/tools/perf/util/parse-events-hybrid.h
index 9ad33cd0cef4..f33bd67aa851 100644
--- a/tools/perf/util/parse-events-hybrid.h
+++ b/tools/perf/util/parse-events-hybrid.h
@@ -17,6 +17,7 @@ int parse_events__add_numeric_hybrid(struct parse_events_state *parse_state,
 int parse_events__add_cache_hybrid(struct list_head *list, int *idx,
 				   struct perf_event_attr *attr, char *name,
 				   struct list_head *config_terms,
-				   bool *hybrid);
+				   bool *hybrid,
+				   struct parse_events_state *parse_state);
 
 #endif /* __PERF_PARSE_EVENTS_HYBRID_H */
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index c228bf5c7d88..6236513e6369 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -453,7 +453,8 @@ static int config_attr(struct perf_event_attr *attr,
 int parse_events_add_cache(struct list_head *list, int *idx,
 			   char *type, char *op_result1, char *op_result2,
 			   struct parse_events_error *err,
-			   struct list_head *head_config)
+			   struct list_head *head_config,
+			   struct parse_events_state *parse_state)
 {
 	struct perf_event_attr attr;
 	LIST_HEAD(config_terms);
@@ -524,7 +525,7 @@ int parse_events_add_cache(struct list_head *list, int *idx,
 
 	ret = parse_events__add_cache_hybrid(list, idx, &attr,
 					     config_name ? : name, &config_terms,
-					     &hybrid);
+					     &hybrid, parse_state);
 	if (hybrid)
 		return ret;
 
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index c4f2f96304ce..bf6e41aa9b6a 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -138,6 +138,7 @@ struct parse_events_state {
 	struct list_head	  *terms;
 	int			   stoken;
 	struct perf_pmu		  *fake_pmu;
+	char			  *hybrid_pmu_name;
 };
 
 void parse_events__handle_error(struct parse_events_error *err, int idx,
@@ -188,7 +189,8 @@ int parse_events_add_tool(struct parse_events_state *parse_state,
 int parse_events_add_cache(struct list_head *list, int *idx,
 			   char *type, char *op_result1, char *op_result2,
 			   struct parse_events_error *error,
-			   struct list_head *head_config);
+			   struct list_head *head_config,
+			   struct parse_events_state *parse_state);
 int parse_events_add_breakpoint(struct list_head *list, int *idx,
 				u64 addr, char *type, u64 len);
 int parse_events_add_pmu(struct parse_events_state *parse_state,
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index d57ac86ce7ca..aba12a4d488e 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -454,7 +454,8 @@ PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_e
 
 	list = alloc_list();
 	ABORT_ON(!list);
-	err = parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6);
+	err = parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6,
+				     parse_state);
 	parse_events_terms__delete($6);
 	free($1);
 	free($3);
@@ -475,7 +476,8 @@ PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT opt_event_config
 
 	list = alloc_list();
 	ABORT_ON(!list);
-	err = parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4);
+	err = parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4,
+				     parse_state);
 	parse_events_terms__delete($4);
 	free($1);
 	free($3);
@@ -495,7 +497,8 @@ PE_NAME_CACHE_TYPE opt_event_config
 
 	list = alloc_list();
 	ABORT_ON(!list);
-	err = parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2);
+	err = parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2,
+				     parse_state);
 	parse_events_terms__delete($2);
 	free($1);
 	if (err) {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 12/26] perf parse-events: Support event inside hybrid pmu
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (10 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 11/26] perf parse-events: Compare with hybrid pmu name Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 13/26] perf record: Create two hybrid 'cycles' events by default Jin Yao
                   ` (14 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

On hybrid platform, user may want to enable events on one pmu.

Following syntax are supported:

cpu_core/<event>/
cpu_atom/<event>/

But the syntax doesn't work for cache event.

Before:

  # perf stat -e cpu_core/LLC-loads/ -a -- sleep 1
  event syntax error: 'cpu_core/LLC-loads/'
                                \___ unknown term 'LLC-loads' for pmu 'cpu_core'

Cache events are a bit complex. We can't create aliases for them.
We use another solution. For example, if we use "cpu_core/LLC-loads/",
in parse_events_add_pmu(), term->config is "LLC-loads".

Then we create a new parser to scan "LLC-loads". The
parse_events_add_cache() would be called during parsing.
The parse_state->hybrid_pmu_name is used to identify the pmu
where the event should be enabled on.

After:

  # perf stat -e cpu_core/LLC-loads/ -a -- sleep 1

   Performance counter stats for 'system wide':

              24,593      cpu_core/LLC-loads/

         1.003911601 seconds time elapsed

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v6:
 - No change.

v5:
 - Check the head_config list has only one term and if yes then
   do the second parsing. We drop the 'parsed' param and make
   parse_events__with_hybrid_pmu return 0 when we find some event.

   Move 'evsel->use_config_name = true;' to the patch
   '[PATCH v5 07/26] perf stat: Uniquify hybrid event name'.

v4:
 - New in v4.

 tools/perf/util/parse-events.c | 63 ++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 6236513e6369..4dad14265b81 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -38,6 +38,7 @@
 #include "util/event.h"
 #include "util/pfm.h"
 #include "util/parse-events-hybrid.h"
+#include "util/pmu-hybrid.h"
 #include "perf.h"
 
 #define MAX_NAME_LEN 100
@@ -48,6 +49,9 @@ extern int parse_events_debug;
 int parse_events_parse(void *parse_state, void *scanner);
 static int get_config_terms(struct list_head *head_config,
 			    struct list_head *head_terms __maybe_unused);
+static int parse_events__with_hybrid_pmu(struct parse_events_state *parse_state,
+					 const char *str, char *pmu_name,
+					 struct list_head *list);
 
 static struct perf_pmu_event_symbol *perf_pmu_events_list;
 /*
@@ -1474,6 +1478,33 @@ static bool config_term_percore(struct list_head *config_terms)
 	return false;
 }
 
+static int parse_events__inside_hybrid_pmu(struct parse_events_state *parse_state,
+					   struct list_head *list, char *name,
+					   struct list_head *head_config)
+{
+	struct parse_events_term *term;
+	int ret = -1;
+
+	if (parse_state->fake_pmu || !head_config || list_empty(head_config) ||
+	    !perf_pmu__is_hybrid(name)) {
+		return -1;
+	}
+
+	/*
+	 * More than one term in list.
+	 */
+	if (head_config->next && head_config->next->next != head_config)
+		return -1;
+
+	term = list_first_entry(head_config, struct parse_events_term, list);
+	if (term && term->config && strcmp(term->config, "event")) {
+		ret = parse_events__with_hybrid_pmu(parse_state, term->config,
+						    name, list);
+	}
+
+	return ret;
+}
+
 int parse_events_add_pmu(struct parse_events_state *parse_state,
 			 struct list_head *list, char *name,
 			 struct list_head *head_config,
@@ -1567,6 +1598,11 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
 	if (pmu->default_config && get_config_chgs(pmu, head_config, &config_terms))
 		return -ENOMEM;
 
+	if (!parse_events__inside_hybrid_pmu(parse_state, list, name,
+					     head_config)) {
+		return 0;
+	}
+
 	if (!parse_state->fake_pmu && perf_pmu__config(pmu, &attr, head_config, parse_state->error)) {
 		struct evsel_config_term *pos, *tmp;
 
@@ -2189,6 +2225,33 @@ int parse_events_terms(struct list_head *terms, const char *str)
 	return ret;
 }
 
+static int parse_events__with_hybrid_pmu(struct parse_events_state *parse_state,
+					 const char *str, char *pmu_name,
+					 struct list_head *list)
+{
+	struct parse_events_state ps = {
+		.list            = LIST_HEAD_INIT(ps.list),
+		.stoken          = PE_START_EVENTS,
+		.hybrid_pmu_name = pmu_name,
+		.idx             = parse_state->idx,
+	};
+	int ret;
+
+	ret = parse_events__scanner(str, &ps);
+	perf_pmu__parse_cleanup();
+
+	if (!ret) {
+		if (!list_empty(&ps.list)) {
+			list_splice(&ps.list, list);
+			parse_state->idx = ps.idx;
+			return 0;
+		} else
+			return -1;
+	}
+
+	return ret;
+}
+
 int __parse_events(struct evlist *evlist, const char *str,
 		   struct parse_events_error *err, struct perf_pmu *fake_pmu)
 {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 13/26] perf record: Create two hybrid 'cycles' events by default
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (11 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 12/26] perf parse-events: Support event inside hybrid pmu Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 14/26] perf stat: Add default hybrid events Jin Yao
                   ` (13 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

When evlist is empty, for example no '-e' specified in perf record,
one default 'cycles' event is added to evlist.

While on hybrid platform, it needs to create two default 'cycles'
events. One is for cpu_core, the other is for cpu_atom.

This patch actually calls evsel__new_cycles() two times to create
two 'cycles' events.

  # ./perf record -vv -a -- sleep 1
  ...
  ------------------------------------------------------------
  perf_event_attr:
    size                             120
    config                           0x400000000
    { sample_period, sample_freq }   4000
    sample_type                      IP|TID|TIME|ID|CPU|PERIOD
    read_format                      ID
    disabled                         1
    inherit                          1
    freq                             1
    precise_ip                       3
    sample_id_all                    1
    exclude_guest                    1
  ------------------------------------------------------------
  sys_perf_event_open: pid -1  cpu 0  group_fd -1  flags 0x8 = 5
  sys_perf_event_open: pid -1  cpu 1  group_fd -1  flags 0x8 = 6
  sys_perf_event_open: pid -1  cpu 2  group_fd -1  flags 0x8 = 7
  sys_perf_event_open: pid -1  cpu 3  group_fd -1  flags 0x8 = 9
  sys_perf_event_open: pid -1  cpu 4  group_fd -1  flags 0x8 = 10
  sys_perf_event_open: pid -1  cpu 5  group_fd -1  flags 0x8 = 11
  sys_perf_event_open: pid -1  cpu 6  group_fd -1  flags 0x8 = 12
  sys_perf_event_open: pid -1  cpu 7  group_fd -1  flags 0x8 = 13
  sys_perf_event_open: pid -1  cpu 8  group_fd -1  flags 0x8 = 14
  sys_perf_event_open: pid -1  cpu 9  group_fd -1  flags 0x8 = 15
  sys_perf_event_open: pid -1  cpu 10  group_fd -1  flags 0x8 = 16
  sys_perf_event_open: pid -1  cpu 11  group_fd -1  flags 0x8 = 17
  sys_perf_event_open: pid -1  cpu 12  group_fd -1  flags 0x8 = 18
  sys_perf_event_open: pid -1  cpu 13  group_fd -1  flags 0x8 = 19
  sys_perf_event_open: pid -1  cpu 14  group_fd -1  flags 0x8 = 20
  sys_perf_event_open: pid -1  cpu 15  group_fd -1  flags 0x8 = 21
  ------------------------------------------------------------
  perf_event_attr:
    size                             120
    config                           0x800000000
    { sample_period, sample_freq }   4000
    sample_type                      IP|TID|TIME|ID|CPU|PERIOD
    read_format                      ID
    disabled                         1
    inherit                          1
    freq                             1
    precise_ip                       3
    sample_id_all                    1
    exclude_guest                    1
  ------------------------------------------------------------
  sys_perf_event_open: pid -1  cpu 16  group_fd -1  flags 0x8 = 22
  sys_perf_event_open: pid -1  cpu 17  group_fd -1  flags 0x8 = 23
  sys_perf_event_open: pid -1  cpu 18  group_fd -1  flags 0x8 = 24
  sys_perf_event_open: pid -1  cpu 19  group_fd -1  flags 0x8 = 25
  sys_perf_event_open: pid -1  cpu 20  group_fd -1  flags 0x8 = 26
  sys_perf_event_open: pid -1  cpu 21  group_fd -1  flags 0x8 = 27
  sys_perf_event_open: pid -1  cpu 22  group_fd -1  flags 0x8 = 28
  sys_perf_event_open: pid -1  cpu 23  group_fd -1  flags 0x8 = 29
  ------------------------------------------------------------

We have to create evlist-hybrid.c otherwise due to the symbol
dependency the perf test python would be failed.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v5 - v6:
 - No change.

v4:
 - Use PERF_TYPE_HARDWARE (v3 uses PERF_TYPE_HARDWARE_PMU).

v3:
 - Move the major code to new created evlist-hybrid.c.

 tools/perf/builtin-record.c     | 19 +++++++++++----
 tools/perf/util/Build           |  1 +
 tools/perf/util/evlist-hybrid.c | 41 +++++++++++++++++++++++++++++++++
 tools/perf/util/evlist-hybrid.h | 12 ++++++++++
 tools/perf/util/evlist.c        |  5 +++-
 tools/perf/util/evsel.c         |  6 ++---
 tools/perf/util/evsel.h         |  2 +-
 7 files changed, 77 insertions(+), 9 deletions(-)
 create mode 100644 tools/perf/util/evlist-hybrid.c
 create mode 100644 tools/perf/util/evlist-hybrid.h

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 5fb9665a2ec2..6af46c6a4fd8 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -47,6 +47,8 @@
 #include "util/util.h"
 #include "util/pfm.h"
 #include "util/clockid.h"
+#include "util/pmu-hybrid.h"
+#include "util/evlist-hybrid.h"
 #include "asm/bug.h"
 #include "perf.h"
 
@@ -2790,10 +2792,19 @@ int cmd_record(int argc, const char **argv)
 	if (record.opts.overwrite)
 		record.opts.tail_synthesize = true;
 
-	if (rec->evlist->core.nr_entries == 0 &&
-	    __evlist__add_default(rec->evlist, !record.opts.no_samples) < 0) {
-		pr_err("Not enough memory for event selector list\n");
-		goto out;
+	if (rec->evlist->core.nr_entries == 0) {
+		if (perf_pmu__has_hybrid()) {
+			err = evlist__add_default_hybrid(rec->evlist,
+							 !record.opts.no_samples);
+		} else {
+			err = __evlist__add_default(rec->evlist,
+						    !record.opts.no_samples);
+		}
+
+		if (err < 0) {
+			pr_err("Not enough memory for event selector list\n");
+			goto out;
+		}
 	}
 
 	if (rec->opts.target.tid && !rec->opts.no_inherit_set)
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 34fcbf3c3bce..8c0d9f368ebc 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -10,6 +10,7 @@ perf-y += db-export.o
 perf-y += env.o
 perf-y += event.o
 perf-y += evlist.o
+perf-y += evlist-hybrid.o
 perf-y += sideband_evlist.o
 perf-y += evsel.o
 perf-y += evsel_fprintf.o
diff --git a/tools/perf/util/evlist-hybrid.c b/tools/perf/util/evlist-hybrid.c
new file mode 100644
index 000000000000..e11998526f2e
--- /dev/null
+++ b/tools/perf/util/evlist-hybrid.c
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <errno.h>
+#include <inttypes.h>
+#include "cpumap.h"
+#include "evlist.h"
+#include "evsel.h"
+#include "../perf.h"
+#include "util/pmu-hybrid.h"
+#include "util/evlist-hybrid.h"
+#include <unistd.h>
+#include <stdlib.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <perf/evlist.h>
+#include <perf/evsel.h>
+#include <perf/cpumap.h>
+
+int evlist__add_default_hybrid(struct evlist *evlist, bool precise)
+{
+	struct evsel *evsel;
+	struct perf_pmu *pmu;
+	__u64 config;
+	struct perf_cpu_map *cpus;
+
+	perf_pmu__for_each_hybrid_pmu(pmu) {
+		config = PERF_COUNT_HW_CPU_CYCLES |
+			 ((__u64)pmu->type << PERF_PMU_TYPE_SHIFT);
+		evsel = evsel__new_cycles(precise, PERF_TYPE_HARDWARE,
+					  config);
+		if (!evsel)
+			return -ENOMEM;
+
+		cpus = perf_cpu_map__get(pmu->cpus);
+		evsel->core.cpus = cpus;
+		evsel->core.own_cpus = perf_cpu_map__get(cpus);
+		evsel->pmu_name = strdup(pmu->name);
+		evlist__add(evlist, evsel);
+	}
+
+	return 0;
+}
diff --git a/tools/perf/util/evlist-hybrid.h b/tools/perf/util/evlist-hybrid.h
new file mode 100644
index 000000000000..e25861649d8f
--- /dev/null
+++ b/tools/perf/util/evlist-hybrid.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PERF_EVLIST_HYBRID_H
+#define __PERF_EVLIST_HYBRID_H
+
+#include <linux/compiler.h>
+#include <linux/kernel.h>
+#include "evlist.h"
+#include <unistd.h>
+
+int evlist__add_default_hybrid(struct evlist *evlist, bool precise);
+
+#endif /* __PERF_EVLIST_HYBRID_H */
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index e71041c89010..6e5c41528c7d 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -26,6 +26,7 @@
 #include "util/string2.h"
 #include "util/perf_api_probe.h"
 #include "util/evsel_fprintf.h"
+#include "util/evlist-hybrid.h"
 #include <signal.h>
 #include <unistd.h>
 #include <sched.h>
@@ -248,8 +249,10 @@ void evlist__set_leader(struct evlist *evlist)
 
 int __evlist__add_default(struct evlist *evlist, bool precise)
 {
-	struct evsel *evsel = evsel__new_cycles(precise);
+	struct evsel *evsel;
 
+	evsel = evsel__new_cycles(precise, PERF_TYPE_HARDWARE,
+				  PERF_COUNT_HW_CPU_CYCLES);
 	if (evsel == NULL)
 		return -ENOMEM;
 
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 080ddcfefbcd..0fc9555a2ac4 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -295,11 +295,11 @@ static bool perf_event_can_profile_kernel(void)
 	return perf_event_paranoid_check(1);
 }
 
-struct evsel *evsel__new_cycles(bool precise)
+struct evsel *evsel__new_cycles(bool precise, __u32 type, __u64 config)
 {
 	struct perf_event_attr attr = {
-		.type	= PERF_TYPE_HARDWARE,
-		.config	= PERF_COUNT_HW_CPU_CYCLES,
+		.type	= type,
+		.config	= config,
 		.exclude_kernel	= !perf_event_can_profile_kernel(),
 	};
 	struct evsel *evsel;
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index ad74c83bd35b..a9cc9563ac59 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -221,7 +221,7 @@ static inline struct evsel *evsel__newtp(const char *sys, const char *name)
 	return evsel__newtp_idx(sys, name, 0);
 }
 
-struct evsel *evsel__new_cycles(bool precise);
+struct evsel *evsel__new_cycles(bool precise, __u32 type, __u64 config);
 
 struct tep_event *event_format__new(const char *sys, const char *name);
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 14/26] perf stat: Add default hybrid events
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (12 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 13/26] perf record: Create two hybrid 'cycles' events by default Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 15/26] perf stat: Filter out unmatched aggregation for hybrid event Jin Yao
                   ` (12 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

Previously if '-e' is not specified in perf stat, some software events
and hardware events are added to evlist by default.

Before:

  # perf stat -a -- sleep 1

   Performance counter stats for 'system wide':

           24,044.40 msec cpu-clock                 #   23.946 CPUs utilized
                  99      context-switches          #    4.117 /sec
                  24      cpu-migrations            #    0.998 /sec
                   3      page-faults               #    0.125 /sec
           7,000,244      cycles                    #    0.000 GHz
           2,955,024      instructions              #    0.42  insn per cycle
             608,941      branches                  #   25.326 K/sec
              31,991      branch-misses             #    5.25% of all branches

         1.004106859 seconds time elapsed

Among the events, cycles, instructions, branches and branch-misses
are hardware events.

One hybrid platform, two hardware events are created for one
hardware event.

cpu_core/cycles/,
cpu_atom/cycles/,
cpu_core/instructions/,
cpu_atom/instructions/,
cpu_core/branches/,
cpu_atom/branches/,
cpu_core/branch-misses/,
cpu_atom/branch-misses/

These events would be added to evlist on hybrid platform.

Since parse_events() has been supported to create two hardware events
for one event on hybrid platform, so we just use parse_events(evlist,
"cycles,instructions,branches,branch-misses") to create the default
events and add them to evlist.

After:

  # perf stat -a -- sleep 1

   Performance counter stats for 'system wide':

           24,043.99 msec cpu-clock                 #   23.991 CPUs utilized
                 139      context-switches          #    5.781 /sec
                  25      cpu-migrations            #    1.040 /sec
                   6      page-faults               #    0.250 /sec
          10,381,751      cpu_core/cycles/          #  431.782 K/sec
           1,264,216      cpu_atom/cycles/          #   52.579 K/sec
           3,406,958      cpu_core/instructions/    #  141.697 K/sec
             414,588      cpu_atom/instructions/    #   17.243 K/sec
             705,149      cpu_core/branches/        #   29.327 K/sec
              82,358      cpu_atom/branches/        #    3.425 K/sec
              40,821      cpu_core/branch-misses/   #    1.698 K/sec
               9,086      cpu_atom/branch-misses/   #  377.891 /sec

         1.002228863 seconds time elapsed

We can see two events are created for one hardware event.

One TODO is, the shadow stats looks a bit different, now it's just
'M/sec'.

The perf_stat__update_shadow_stats and perf_stat__print_shadow_stats
need to be improved in future if we want to get the original shadow
stats.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v6:
 - No change.

v5:
 - Do the same way like when topdown calls parse events for checking
   result and displayt the error.

v4:
 - No change.

 tools/perf/builtin-stat.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 835e3696b9ce..42e60764ad8d 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1639,6 +1639,12 @@ static int add_default_attributes(void)
   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS	},
   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES		},
 
+};
+	struct perf_event_attr default_sw_attrs[] = {
+  { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK		},
+  { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES	},
+  { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS		},
+  { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS		},
 };
 
 /*
@@ -1876,6 +1882,28 @@ static int add_default_attributes(void)
 	}
 
 	if (!evsel_list->core.nr_entries) {
+		if (perf_pmu__has_hybrid()) {
+			const char *hybrid_str = "cycles,instructions,branches,branch-misses";
+
+			if (target__has_cpu(&target))
+				default_sw_attrs[0].config = PERF_COUNT_SW_CPU_CLOCK;
+
+			if (evlist__add_default_attrs(evsel_list,
+						      default_sw_attrs) < 0) {
+				return -1;
+			}
+
+			err = parse_events(evsel_list, hybrid_str, &errinfo);
+			if (err) {
+				fprintf(stderr,
+					"Cannot set up hybrid events %s: %d\n",
+					hybrid_str, err);
+				parse_events_print_error(&errinfo, hybrid_str);
+				return -1;
+			}
+			return err;
+		}
+
 		if (target__has_cpu(&target))
 			default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK;
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 15/26] perf stat: Filter out unmatched aggregation for hybrid event
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (13 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 14/26] perf stat: Add default hybrid events Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 16/26] perf stat: Warn group events from different hybrid PMU Jin Yao
                   ` (11 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

perf-stat has supported some aggregation modes, such as --per-core,
--per-socket and etc. While for hybrid event, it may only available
on part of cpus. So for --per-core, we need to filter out the
unavailable cores, for --per-socket, filter out the unavailable
sockets, and so on.

Before:

  # perf stat --per-core -e cpu_core/cycles/ -a -- sleep 1

   Performance counter stats for 'system wide':

  S0-D0-C0           2            479,530      cpu_core/cycles/
  S0-D0-C4           2            175,007      cpu_core/cycles/
  S0-D0-C8           2            166,240      cpu_core/cycles/
  S0-D0-C12          2            704,673      cpu_core/cycles/
  S0-D0-C16          2            865,835      cpu_core/cycles/
  S0-D0-C20          2          2,958,461      cpu_core/cycles/
  S0-D0-C24          2            163,988      cpu_core/cycles/
  S0-D0-C28          2            164,729      cpu_core/cycles/
  S0-D0-C32          0      <not counted>      cpu_core/cycles/
  S0-D0-C33          0      <not counted>      cpu_core/cycles/
  S0-D0-C34          0      <not counted>      cpu_core/cycles/
  S0-D0-C35          0      <not counted>      cpu_core/cycles/
  S0-D0-C36          0      <not counted>      cpu_core/cycles/
  S0-D0-C37          0      <not counted>      cpu_core/cycles/
  S0-D0-C38          0      <not counted>      cpu_core/cycles/
  S0-D0-C39          0      <not counted>      cpu_core/cycles/

         1.003597211 seconds time elapsed

After:

  # perf stat --per-core -e cpu_core/cycles/ -a -- sleep 1

   Performance counter stats for 'system wide':

  S0-D0-C0           2            210,428      cpu_core/cycles/
  S0-D0-C4           2            444,830      cpu_core/cycles/
  S0-D0-C8           2            435,241      cpu_core/cycles/
  S0-D0-C12          2            423,976      cpu_core/cycles/
  S0-D0-C16          2            859,350      cpu_core/cycles/
  S0-D0-C20          2          1,559,589      cpu_core/cycles/
  S0-D0-C24          2            163,924      cpu_core/cycles/
  S0-D0-C28          2            376,610      cpu_core/cycles/

         1.003621290 seconds time elapsed

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Co-developed-by: Jiri Olsa <jolsa@redhat.com>
---
v6:
 - No change.

v5:
 - Use Jiri's code, which is much simpler than original.

v4:
 - No change.

 tools/perf/util/stat-display.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index 0679129ad05e..a76fff5e7d83 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -667,6 +667,9 @@ static void print_counter_aggrdata(struct perf_stat_config *config,
 	if (!collect_data(config, counter, aggr_cb, &ad))
 		return;
 
+	if (perf_pmu__has_hybrid() && ad.ena == 0)
+		return;
+
 	nr = ad.nr;
 	ena = ad.ena;
 	run = ad.run;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 16/26] perf stat: Warn group events from different hybrid PMU
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (14 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 15/26] perf stat: Filter out unmatched aggregation for hybrid event Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 17/26] perf record: Uniquify hybrid event name Jin Yao
                   ` (10 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

If a group has events which are from different hybrid PMUs,
shows a warning:

"WARNING: events in group from different hybrid PMUs!"

This is to remind the user not to put the core event and atom
event into one group.

Next, just disable grouping.

  # perf stat -e "{cpu_core/cycles/,cpu_atom/cycles/}" -a -- sleep 1
  WARNING: events in group from different hybrid PMUs!
  WARNING: grouped events cpus do not match, disabling group:
    anon group { cpu_core/cycles/, cpu_atom/cycles/ }

   Performance counter stats for 'system wide':

           5,438,125      cpu_core/cycles/
           3,914,586      cpu_atom/cycles/

         1.004250966 seconds time elapsed

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v4 - v6:
 - No change.

 tools/perf/builtin-stat.c          |  4 +++
 tools/perf/util/evlist-hybrid.c    | 47 ++++++++++++++++++++++++++++++
 tools/perf/util/evlist-hybrid.h    |  2 ++
 tools/perf/util/evsel.c            |  6 ++++
 tools/perf/util/evsel.h            |  1 +
 tools/perf/util/python-ext-sources |  2 ++
 6 files changed, 62 insertions(+)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 42e60764ad8d..5a830ae09418 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -48,6 +48,7 @@
 #include "util/pmu.h"
 #include "util/event.h"
 #include "util/evlist.h"
+#include "util/evlist-hybrid.h"
 #include "util/evsel.h"
 #include "util/debug.h"
 #include "util/color.h"
@@ -243,6 +244,9 @@ static void evlist__check_cpu_maps(struct evlist *evlist)
 	struct evsel *evsel, *pos, *leader;
 	char buf[1024];
 
+	if (evlist__has_hybrid(evlist))
+		evlist__warn_hybrid_group(evlist);
+
 	evlist__for_each_entry(evlist, evsel) {
 		leader = evsel->leader;
 
diff --git a/tools/perf/util/evlist-hybrid.c b/tools/perf/util/evlist-hybrid.c
index e11998526f2e..db3f5fbdebe1 100644
--- a/tools/perf/util/evlist-hybrid.c
+++ b/tools/perf/util/evlist-hybrid.c
@@ -7,6 +7,7 @@
 #include "../perf.h"
 #include "util/pmu-hybrid.h"
 #include "util/evlist-hybrid.h"
+#include "debug.h"
 #include <unistd.h>
 #include <stdlib.h>
 #include <linux/err.h>
@@ -39,3 +40,49 @@ int evlist__add_default_hybrid(struct evlist *evlist, bool precise)
 
 	return 0;
 }
+
+static bool group_hybrid_conflict(struct evsel *leader)
+{
+	struct evsel *pos, *prev = NULL;
+
+	for_each_group_evsel(pos, leader) {
+		if (!evsel__is_hybrid(pos))
+			continue;
+
+		if (prev && strcmp(prev->pmu_name, pos->pmu_name))
+			return true;
+
+		prev = pos;
+	}
+
+	return false;
+}
+
+void evlist__warn_hybrid_group(struct evlist *evlist)
+{
+	struct evsel *evsel;
+
+	evlist__for_each_entry(evlist, evsel) {
+		if (evsel__is_group_leader(evsel) &&
+		    evsel->core.nr_members > 1 &&
+		    group_hybrid_conflict(evsel)) {
+			pr_warning("WARNING: events in group from "
+				   "different hybrid PMUs!\n");
+			return;
+		}
+	}
+}
+
+bool evlist__has_hybrid(struct evlist *evlist)
+{
+	struct evsel *evsel;
+
+	evlist__for_each_entry(evlist, evsel) {
+		if (evsel->pmu_name &&
+		    perf_pmu__is_hybrid(evsel->pmu_name)) {
+			return true;
+		}
+	}
+
+	return false;
+}
diff --git a/tools/perf/util/evlist-hybrid.h b/tools/perf/util/evlist-hybrid.h
index e25861649d8f..19f74b4c340a 100644
--- a/tools/perf/util/evlist-hybrid.h
+++ b/tools/perf/util/evlist-hybrid.h
@@ -8,5 +8,7 @@
 #include <unistd.h>
 
 int evlist__add_default_hybrid(struct evlist *evlist, bool precise);
+void evlist__warn_hybrid_group(struct evlist *evlist);
+bool evlist__has_hybrid(struct evlist *evlist);
 
 #endif /* __PERF_EVLIST_HYBRID_H */
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 0fc9555a2ac4..4a3cd1b5bb33 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -47,6 +47,7 @@
 #include "memswap.h"
 #include "util.h"
 #include "hashmap.h"
+#include "pmu-hybrid.h"
 #include "../perf-sys.h"
 #include "util/parse-branch-options.h"
 #include <internal/xyarray.h>
@@ -2819,3 +2820,8 @@ void evsel__zero_per_pkg(struct evsel *evsel)
 		hashmap__clear(evsel->per_pkg_mask);
 	}
 }
+
+bool evsel__is_hybrid(struct evsel *evsel)
+{
+	return evsel->pmu_name && perf_pmu__is_hybrid(evsel->pmu_name);
+}
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index a9cc9563ac59..75cf5dbfe208 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -462,4 +462,5 @@ struct perf_env *evsel__env(struct evsel *evsel);
 int evsel__store_ids(struct evsel *evsel, struct evlist *evlist);
 
 void evsel__zero_per_pkg(struct evsel *evsel);
+bool evsel__is_hybrid(struct evsel *evsel);
 #endif /* __PERF_EVSEL_H */
diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources
index 845dd46e3c61..d7c976671e3a 100644
--- a/tools/perf/util/python-ext-sources
+++ b/tools/perf/util/python-ext-sources
@@ -37,3 +37,5 @@ util/units.c
 util/affinity.c
 util/rwsem.c
 util/hashmap.c
+util/pmu-hybrid.c
+util/fncache.c
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 17/26] perf record: Uniquify hybrid event name
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (15 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 16/26] perf stat: Warn group events from different hybrid PMU Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 18/26] perf tests: Add hybrid cases for 'Parse event definition strings' test Jin Yao
                   ` (9 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

For perf-record, it would be useful to tell user the pmu which the
event belongs to.

For example,

  # perf record -a -- sleep 1
  # perf report

  # To display the perf.data header info, please use --header/--header-only options.
  #
  #
  # Total Lost Samples: 0
  #
  # Samples: 106  of event 'cpu_core/cycles/'
  # Event count (approx.): 22043448
  #
  # Overhead  Command       Shared Object            Symbol
  # ........  ............  .......................  ............................
  #
  ...

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v4 - v6:
 - No change.

 tools/perf/builtin-record.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 6af46c6a4fd8..3337b5f93336 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -1605,6 +1605,32 @@ static void hit_auxtrace_snapshot_trigger(struct record *rec)
 	}
 }
 
+static void record__uniquify_name(struct record *rec)
+{
+	struct evsel *pos;
+	struct evlist *evlist = rec->evlist;
+	char *new_name;
+	int ret;
+
+	if (!perf_pmu__has_hybrid())
+		return;
+
+	evlist__for_each_entry(evlist, pos) {
+		if (!evsel__is_hybrid(pos))
+			continue;
+
+		if (strchr(pos->name, '/'))
+			continue;
+
+		ret = asprintf(&new_name, "%s/%s/",
+			       pos->pmu_name, pos->name);
+		if (ret) {
+			free(pos->name);
+			pos->name = new_name;
+		}
+	}
+}
+
 static int __cmd_record(struct record *rec, int argc, const char **argv)
 {
 	int err;
@@ -1709,6 +1735,8 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
 	if (data->is_pipe && rec->evlist->core.nr_entries == 1)
 		rec->opts.sample_id = true;
 
+	record__uniquify_name(rec);
+
 	if (record__open(rec) != 0) {
 		err = -1;
 		goto out_child;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 18/26] perf tests: Add hybrid cases for 'Parse event definition strings' test
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (16 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 17/26] perf record: Uniquify hybrid event name Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 19/26] perf tests: Add hybrid cases for 'Roundtrip evsel->name' test Jin Yao
                   ` (8 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

Add basic hybrid test cases for 'Parse event definition strings' test.

  # perf test 6
   6: Parse event definition strings                                  : Ok

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v6:
 - Add test case for parsing cache events with pmu prefix.

v5:
 - No change.

 tools/perf/tests/parse-events.c | 171 ++++++++++++++++++++++++++++++++
 1 file changed, 171 insertions(+)

diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index 026c54743311..0f113b2b36a3 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -1512,6 +1512,124 @@ static int test__all_tracepoints(struct evlist *evlist)
 	return test__checkevent_tracepoint_multi(evlist);
 }
 
+static int test__hybrid_hw_event_with_pmu(struct evlist *evlist)
+{
+	struct evsel *evsel = evlist__first(evlist);
+
+	TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type);
+	TEST_ASSERT_VAL("wrong config", 0x3c == evsel->core.attr.config);
+	return 0;
+}
+
+static int test__hybrid_hw_group_event(struct evlist *evlist)
+{
+	struct evsel *evsel, *leader;
+
+	evsel = leader = evlist__first(evlist);
+	TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type);
+	TEST_ASSERT_VAL("wrong config", 0x3c == evsel->core.attr.config);
+	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
+
+	evsel = evsel__next(evsel);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type);
+	TEST_ASSERT_VAL("wrong config", 0xc0 == evsel->core.attr.config);
+	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
+	return 0;
+}
+
+static int test__hybrid_sw_hw_group_event(struct evlist *evlist)
+{
+	struct evsel *evsel, *leader;
+
+	evsel = leader = evlist__first(evlist);
+	TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->core.attr.type);
+	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
+
+	evsel = evsel__next(evsel);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type);
+	TEST_ASSERT_VAL("wrong config", 0x3c == evsel->core.attr.config);
+	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
+	return 0;
+}
+
+static int test__hybrid_hw_sw_group_event(struct evlist *evlist)
+{
+	struct evsel *evsel, *leader;
+
+	evsel = leader = evlist__first(evlist);
+	TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type);
+	TEST_ASSERT_VAL("wrong config", 0x3c == evsel->core.attr.config);
+	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
+
+	evsel = evsel__next(evsel);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->core.attr.type);
+	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
+	return 0;
+}
+
+static int test__hybrid_group_modifier1(struct evlist *evlist)
+{
+	struct evsel *evsel, *leader;
+
+	evsel = leader = evlist__first(evlist);
+	TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type);
+	TEST_ASSERT_VAL("wrong config", 0x3c == evsel->core.attr.config);
+	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
+	TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user);
+	TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->core.attr.exclude_kernel);
+
+	evsel = evsel__next(evsel);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type);
+	TEST_ASSERT_VAL("wrong config", 0xc0 == evsel->core.attr.config);
+	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
+	TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user);
+	TEST_ASSERT_VAL("wrong exclude_kernel", evsel->core.attr.exclude_kernel);
+	return 0;
+}
+
+static int test__hybrid_raw1(struct evlist *evlist)
+{
+	struct evsel *evsel = evlist__first(evlist);
+
+	TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type);
+	TEST_ASSERT_VAL("wrong config", 0x1a == evsel->core.attr.config);
+
+	/* The type of second event is randome value */
+	evsel = evsel__next(evsel);
+	TEST_ASSERT_VAL("wrong config", 0x1a == evsel->core.attr.config);
+	return 0;
+}
+
+static int test__hybrid_raw2(struct evlist *evlist)
+{
+	struct evsel *evsel = evlist__first(evlist);
+
+	TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type);
+	TEST_ASSERT_VAL("wrong config", 0x1a == evsel->core.attr.config);
+	return 0;
+}
+
+static int test__hybrid_cache_event(struct evlist *evlist)
+{
+	struct evsel *evsel = evlist__first(evlist);
+
+	TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->core.attr.type);
+	TEST_ASSERT_VAL("wrong config", 0x2 == (evsel->core.attr.config & 0xffffffff));
+
+	evsel = evsel__next(evsel);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->core.attr.type);
+	TEST_ASSERT_VAL("wrong config", 0x10002 == (evsel->core.attr.config & 0xffffffff));
+	return 0;
+}
+
 struct evlist_test {
 	const char *name;
 	__u32 type;
@@ -1868,6 +1986,54 @@ static struct terms_test test__terms[] = {
 	},
 };
 
+static struct evlist_test test__hybrid_events[] = {
+	{
+		.name  = "cpu_core/cpu-cycles/",
+		.check = test__hybrid_hw_event_with_pmu,
+		.id    = 0,
+	},
+	{
+		.name  = "{cpu_core/cpu-cycles/,cpu_core/instructions/}",
+		.check = test__hybrid_hw_group_event,
+		.id    = 1,
+	},
+	{
+		.name  = "{cpu-clock,cpu_core/cpu-cycles/}",
+		.check = test__hybrid_sw_hw_group_event,
+		.id    = 2,
+	},
+	{
+		.name  = "{cpu_core/cpu-cycles/,cpu-clock}",
+		.check = test__hybrid_hw_sw_group_event,
+		.id    = 3,
+	},
+	{
+		.name  = "{cpu_core/cpu-cycles/k,cpu_core/instructions/u}",
+		.check = test__hybrid_group_modifier1,
+		.id    = 4,
+	},
+	{
+		.name  = "r1a",
+		.check = test__hybrid_raw1,
+		.id    = 5,
+	},
+	{
+		.name  = "cpu_core/r1a/",
+		.check = test__hybrid_raw2,
+		.id    = 6,
+	},
+	{
+		.name  = "cpu_core/config=10,config1,config2=3,period=1000/u",
+		.check = test__checkevent_pmu,
+		.id    = 7,
+	},
+	{
+		.name  = "cpu_core/LLC-loads/,cpu_atom/LLC-load-misses/",
+		.check = test__hybrid_cache_event,
+		.id    = 8,
+	},
+};
+
 static int test_event(struct evlist_test *e)
 {
 	struct parse_events_error err;
@@ -2035,6 +2201,11 @@ do {							\
 		ret2 = ret1;				\
 } while (0)
 
+	if (perf_pmu__has_hybrid()) {
+		TEST_EVENTS(test__hybrid_events);
+		return ret2;
+	}
+
 	TEST_EVENTS(test__events);
 
 	if (test_pmu())
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 19/26] perf tests: Add hybrid cases for 'Roundtrip evsel->name' test
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (17 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 18/26] perf tests: Add hybrid cases for 'Parse event definition strings' test Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 20/26] perf tests: Skip 'Setup struct perf_event_attr' test for hybrid Jin Yao
                   ` (7 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

Since for one hw event, two hybrid events are created.

For example,

evsel->idx      evsel__name(evsel)
0               cycles
1               cycles
2               instructions
3               instructions
...

So for comparing the evsel name on hybrid, the evsel->idx
needs to be divided by 2.

  # ./perf test 14
  14: Roundtrip evsel->name                                           : Ok

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v6:
 - No change.

 tools/perf/tests/evsel-roundtrip-name.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c
index f7f3e5b4c180..b74cf80d1f10 100644
--- a/tools/perf/tests/evsel-roundtrip-name.c
+++ b/tools/perf/tests/evsel-roundtrip-name.c
@@ -4,6 +4,7 @@
 #include "parse-events.h"
 #include "tests.h"
 #include "debug.h"
+#include "pmu.h"
 #include <errno.h>
 #include <linux/kernel.h>
 
@@ -62,7 +63,8 @@ static int perf_evsel__roundtrip_cache_name_test(void)
 	return ret;
 }
 
-static int __perf_evsel__name_array_test(const char *names[], int nr_names)
+static int __perf_evsel__name_array_test(const char *names[], int nr_names,
+					 int distance)
 {
 	int i, err;
 	struct evsel *evsel;
@@ -82,9 +84,9 @@ static int __perf_evsel__name_array_test(const char *names[], int nr_names)
 
 	err = 0;
 	evlist__for_each_entry(evlist, evsel) {
-		if (strcmp(evsel__name(evsel), names[evsel->idx])) {
+		if (strcmp(evsel__name(evsel), names[evsel->idx / distance])) {
 			--err;
-			pr_debug("%s != %s\n", evsel__name(evsel), names[evsel->idx]);
+			pr_debug("%s != %s\n", evsel__name(evsel), names[evsel->idx / distance]);
 		}
 	}
 
@@ -93,18 +95,21 @@ static int __perf_evsel__name_array_test(const char *names[], int nr_names)
 	return err;
 }
 
-#define perf_evsel__name_array_test(names) \
-	__perf_evsel__name_array_test(names, ARRAY_SIZE(names))
+#define perf_evsel__name_array_test(names, distance) \
+	__perf_evsel__name_array_test(names, ARRAY_SIZE(names), distance)
 
 int test__perf_evsel__roundtrip_name_test(struct test *test __maybe_unused, int subtest __maybe_unused)
 {
 	int err = 0, ret = 0;
 
-	err = perf_evsel__name_array_test(evsel__hw_names);
+	if (perf_pmu__has_hybrid())
+		return perf_evsel__name_array_test(evsel__hw_names, 2);
+
+	err = perf_evsel__name_array_test(evsel__hw_names, 1);
 	if (err)
 		ret = err;
 
-	err = __perf_evsel__name_array_test(evsel__sw_names, PERF_COUNT_SW_DUMMY + 1);
+	err = __perf_evsel__name_array_test(evsel__sw_names, PERF_COUNT_SW_DUMMY + 1, 1);
 	if (err)
 		ret = err;
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 20/26] perf tests: Skip 'Setup struct perf_event_attr' test for hybrid
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (18 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 19/26] perf tests: Add hybrid cases for 'Roundtrip evsel->name' test Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 21/26] perf tests: Support 'Track with sched_switch' " Jin Yao
                   ` (6 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

For hybrid, the attr.type consists of pmu type id + original type.
There will be much changes for this test. Now we temporarily
skip this test case and TODO in future.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v6:
 - No change.

v5:
 - Since it's skip the test case, return TEST_SKIP.

 tools/perf/tests/attr.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c
index dd39ce9b0277..9b40a25376ae 100644
--- a/tools/perf/tests/attr.c
+++ b/tools/perf/tests/attr.c
@@ -34,6 +34,7 @@
 #include "event.h"
 #include "util.h"
 #include "tests.h"
+#include "pmu.h"
 
 #define ENV "PERF_TEST_ATTR"
 
@@ -184,6 +185,9 @@ int test__attr(struct test *test __maybe_unused, int subtest __maybe_unused)
 	char path_dir[PATH_MAX];
 	char *exec_path;
 
+	if (perf_pmu__has_hybrid())
+		return TEST_SKIP;
+
 	/* First try development tree tests. */
 	if (!lstat("./tests", &st))
 		return run_dir("./tests", "./perf");
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 21/26] perf tests: Support 'Track with sched_switch' test for hybrid
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (19 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 20/26] perf tests: Skip 'Setup struct perf_event_attr' test for hybrid Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 22/26] perf tests: Support 'Parse and process metrics' " Jin Yao
                   ` (5 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

Since for "cycles:u' on hybrid platform, it creates two "cycles".
So the number of events in evlist is not expected in next test
steps. Now we just use one event "cpu_core/cycles:u/" for hybrid.

  # ./perf test 35
  35: Track with sched_switch                                         : Ok

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v6:
 - No change.

v5:
 - Drop the variable 'hybrid' and use 'if (perf_pmu__has_hybrid())'
   directly.

 tools/perf/tests/switch-tracking.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c
index 3ebaa758df77..62c0ec21aaa8 100644
--- a/tools/perf/tests/switch-tracking.c
+++ b/tools/perf/tests/switch-tracking.c
@@ -18,6 +18,7 @@
 #include "record.h"
 #include "tests.h"
 #include "util/mmap.h"
+#include "pmu.h"
 
 static int spin_sleep(void)
 {
@@ -371,7 +372,10 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_
 	cpu_clocks_evsel = evlist__last(evlist);
 
 	/* Second event */
-	err = parse_events(evlist, "cycles:u", NULL);
+	if (perf_pmu__has_hybrid())
+		err = parse_events(evlist, "cpu_core/cycles/u", NULL);
+	else
+		err = parse_events(evlist, "cycles:u", NULL);
 	if (err) {
 		pr_debug("Failed to parse event cycles:u\n");
 		goto out_err;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 22/26] perf tests: Support 'Parse and process metrics' test for hybrid
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (20 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 21/26] perf tests: Support 'Track with sched_switch' " Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 23/26] perf tests: Support 'Session topology' " Jin Yao
                   ` (4 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

Some events are not supported. Only pick up some cases for hybrid.

  # ./perf test 68
  68: Parse and process metrics                                       : Ok

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v6:
 - No change.

v5:
 - Remove the perf_pmu_scan() since it's called in
   perf_pmu__has_hybrid() yet.

 tools/perf/tests/parse-metric.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metric.c
index 4968c4106254..4f6f4904e852 100644
--- a/tools/perf/tests/parse-metric.c
+++ b/tools/perf/tests/parse-metric.c
@@ -11,6 +11,7 @@
 #include "debug.h"
 #include "expr.h"
 #include "stat.h"
+#include "pmu.h"
 
 static struct pmu_event pme_test[] = {
 {
@@ -372,10 +373,13 @@ int test__parse_metric(struct test *test __maybe_unused, int subtest __maybe_unu
 {
 	TEST_ASSERT_VAL("IPC failed", test_ipc() == 0);
 	TEST_ASSERT_VAL("frontend failed", test_frontend() == 0);
-	TEST_ASSERT_VAL("cache_miss_cycles failed", test_cache_miss_cycles() == 0);
 	TEST_ASSERT_VAL("DCache_L2 failed", test_dcache_l2() == 0);
 	TEST_ASSERT_VAL("recursion fail failed", test_recursion_fail() == 0);
-	TEST_ASSERT_VAL("test metric group", test_metric_group() == 0);
 	TEST_ASSERT_VAL("Memory bandwidth", test_memory_bandwidth() == 0);
+
+	if (!perf_pmu__has_hybrid()) {
+		TEST_ASSERT_VAL("cache_miss_cycles failed", test_cache_miss_cycles() == 0);
+		TEST_ASSERT_VAL("test metric group", test_metric_group() == 0);
+	}
 	return 0;
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 23/26] perf tests: Support 'Session topology' test for hybrid
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (21 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 22/26] perf tests: Support 'Parse and process metrics' " Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 24/26] perf tests: Support 'Convert perf time to TSC' " Jin Yao
                   ` (3 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

Force to create one event "cpu_core/cycles/" by default,
otherwise in evlist__valid_sample_type, the checking of
'if (evlist->core.nr_entries == 1)' would be failed.

  # ./perf test 41
  41: Session topology                                                : Ok

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v6:
 - No change.

v5:
 - Add "TEST_ASSERT_VAL session->evlist".

 tools/perf/tests/topology.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
index 050489807a47..ec4e3b21b831 100644
--- a/tools/perf/tests/topology.c
+++ b/tools/perf/tests/topology.c
@@ -8,6 +8,7 @@
 #include "session.h"
 #include "evlist.h"
 #include "debug.h"
+#include "pmu.h"
 #include <linux/err.h>
 
 #define TEMPL "/tmp/perf-test-XXXXXX"
@@ -40,8 +41,16 @@ static int session_write_header(char *path)
 	session = perf_session__new(&data, false, NULL);
 	TEST_ASSERT_VAL("can't get session", !IS_ERR(session));
 
-	session->evlist = evlist__new_default();
-	TEST_ASSERT_VAL("can't get evlist", session->evlist);
+	if (!perf_pmu__has_hybrid()) {
+		session->evlist = evlist__new_default();
+		TEST_ASSERT_VAL("can't get evlist", session->evlist);
+	} else {
+		struct parse_events_error err;
+
+		session->evlist = evlist__new();
+		TEST_ASSERT_VAL("can't get evlist", session->evlist);
+		parse_events(session->evlist, "cpu_core/cycles/", &err);
+	}
 
 	perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY);
 	perf_header__set_feat(&session->header, HEADER_NRCPUS);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 24/26] perf tests: Support 'Convert perf time to TSC' test for hybrid
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (22 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 23/26] perf tests: Support 'Session topology' " Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 25/26] perf tests: Skip 'perf stat metrics (shadow stat) test' " Jin Yao
                   ` (2 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

Since for "cycles:u' on hybrid platform, it creates two "cycles".
So the second evsel in evlist also needs initialization.

With this patch,

  # ./perf test 71
  71: Convert perf time to TSC                                        : Ok

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v6:
 - No change.

v5:
 - Drop the variable 'hybrid' and use 'if (perf_pmu__has_hybrid())'.

 tools/perf/tests/perf-time-to-tsc.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
index 680c3cffb128..85d75b9b25a1 100644
--- a/tools/perf/tests/perf-time-to-tsc.c
+++ b/tools/perf/tests/perf-time-to-tsc.c
@@ -20,6 +20,7 @@
 #include "tsc.h"
 #include "mmap.h"
 #include "tests.h"
+#include "pmu.h"
 
 #define CHECK__(x) {				\
 	while ((x) < 0) {			\
@@ -88,6 +89,17 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe
 	evsel->core.attr.disabled = 1;
 	evsel->core.attr.enable_on_exec = 0;
 
+	/*
+	 * For hybrid "cycles:u", it creates two events.
+	 * Init the second evsel here.
+	 */
+	if (perf_pmu__has_hybrid()) {
+		evsel = evsel__next(evsel);
+		evsel->core.attr.comm = 1;
+		evsel->core.attr.disabled = 1;
+		evsel->core.attr.enable_on_exec = 0;
+	}
+
 	CHECK__(evlist__open(evlist));
 
 	CHECK__(evlist__mmap(evlist, UINT_MAX));
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 25/26] perf tests: Skip 'perf stat metrics (shadow stat) test' for hybrid
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (23 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 24/26] perf tests: Support 'Convert perf time to TSC' " Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27  7:01 ` [PATCH v6 26/26] perf Documentation: Document intel-hybrid support Jin Yao
  2021-04-27 12:50 ` [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jiri Olsa
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

Currently we don't support shadow stat for hybrid.

  root@ssp-pwrt-002:~# ./perf stat -e cycles,instructions -a -- sleep 1

   Performance counter stats for 'system wide':

      12,883,109,591      cpu_core/cycles/
       6,405,163,221      cpu_atom/cycles/
         555,553,778      cpu_core/instructions/
         841,158,734      cpu_atom/instructions/

         1.002644773 seconds time elapsed

Now there is no shadow stat 'insn per cycle' reported. We will support
it later and now just skip the 'perf stat metrics (shadow stat) test'.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v6:
 - No change.

 tools/perf/tests/shell/stat+shadow_stat.sh | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/perf/tests/shell/stat+shadow_stat.sh b/tools/perf/tests/shell/stat+shadow_stat.sh
index ebebd3596cf9..e6e35fc6c882 100755
--- a/tools/perf/tests/shell/stat+shadow_stat.sh
+++ b/tools/perf/tests/shell/stat+shadow_stat.sh
@@ -7,6 +7,9 @@ set -e
 # skip if system-wide mode is forbidden
 perf stat -a true > /dev/null 2>&1 || exit 2
 
+# skip if on hybrid platform
+perf stat -a -e cycles sleep 1 2>&1 | grep -e cpu_core && exit 2
+
 test_global_aggr()
 {
 	perf stat -a --no-big-num -e cycles,instructions sleep 1  2>&1 | \
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v6 26/26] perf Documentation: Document intel-hybrid support
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (24 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 25/26] perf tests: Skip 'perf stat metrics (shadow stat) test' " Jin Yao
@ 2021-04-27  7:01 ` Jin Yao
  2021-04-27 12:50 ` [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jiri Olsa
  26 siblings, 0 replies; 35+ messages in thread
From: Jin Yao @ 2021-04-27  7:01 UTC (permalink / raw)
  To: acme, jolsa, peterz, mingo, alexander.shishkin
  Cc: Linux-kernel, ak, kan.liang, yao.jin, Jin Yao

Add some words and examples to help understanding of
Intel hybrid perf support.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
v6:
 - No change.

 tools/perf/Documentation/intel-hybrid.txt | 214 ++++++++++++++++++++++
 tools/perf/Documentation/perf-record.txt  |   1 +
 tools/perf/Documentation/perf-stat.txt    |   2 +
 3 files changed, 217 insertions(+)
 create mode 100644 tools/perf/Documentation/intel-hybrid.txt

diff --git a/tools/perf/Documentation/intel-hybrid.txt b/tools/perf/Documentation/intel-hybrid.txt
new file mode 100644
index 000000000000..07f0aa3bf682
--- /dev/null
+++ b/tools/perf/Documentation/intel-hybrid.txt
@@ -0,0 +1,214 @@
+Intel hybrid support
+--------------------
+Support for Intel hybrid events within perf tools.
+
+For some Intel platforms, such as AlderLake, which is hybrid platform and
+it consists of atom cpu and core cpu. Each cpu has dedicated event list.
+Part of events are available on core cpu, part of events are available
+on atom cpu and even part of events are available on both.
+
+Kernel exports two new cpu pmus via sysfs:
+/sys/devices/cpu_core
+/sys/devices/cpu_atom
+
+The 'cpus' files are created under the directories. For example,
+
+cat /sys/devices/cpu_core/cpus
+0-15
+
+cat /sys/devices/cpu_atom/cpus
+16-23
+
+It indicates cpu0-cpu15 are core cpus and cpu16-cpu23 are atom cpus.
+
+Quickstart
+
+List hybrid event
+-----------------
+
+As before, use perf-list to list the symbolic event.
+
+perf list
+
+inst_retired.any
+	[Fixed Counter: Counts the number of instructions retired. Unit: cpu_atom]
+inst_retired.any
+	[Number of instructions retired. Fixed Counter - architectural event. Unit: cpu_core]
+
+The 'Unit: xxx' is added to brief description to indicate which pmu
+the event is belong to. Same event name but with different pmu can
+be supported.
+
+Enable hybrid event with a specific pmu
+---------------------------------------
+
+To enable a core only event or atom only event, following syntax is supported:
+
+	cpu_core/<event name>/
+or
+	cpu_atom/<event name>/
+
+For example, count the 'cycles' event on core cpus.
+
+	perf stat -e cpu_core/cycles/
+
+Create two events for one hardware event automatically
+------------------------------------------------------
+
+When creating one event and the event is available on both atom and core,
+two events are created automatically. One is for atom, the other is for
+core. Most of hardware events and cache events are available on both
+cpu_core and cpu_atom.
+
+For hardware events, they have pre-defined configs (e.g. 0 for cycles).
+But on hybrid platform, kernel needs to know where the event comes from
+(from atom or from core). The original perf event type PERF_TYPE_HARDWARE
+can't carry pmu information. So now this type is extended to be PMU aware
+type. The PMU type ID is stored at attr.config[63:32].
+
+PMU type ID is retrieved from sysfs.
+/sys/devices/cpu_atom/type
+/sys/devices/cpu_core/type
+
+The new attr.config layout for PERF_TYPE_HARDWARE:
+
+PERF_TYPE_HARDWARE:                 0xEEEEEEEE000000AA
+                                    AA: hardware event ID
+                                    EEEEEEEE: PMU type ID
+
+Cache event is similar. The type PERF_TYPE_HW_CACHE is extended to be
+PMU aware type. The PMU type ID is stored at attr.config[63:32].
+
+The new attr.config layout for PERF_TYPE_HW_CACHE:
+
+PERF_TYPE_HW_CACHE:                 0xEEEEEEEE00DDCCBB
+                                    BB: hardware cache ID
+                                    CC: hardware cache op ID
+                                    DD: hardware cache op result ID
+                                    EEEEEEEE: PMU type ID
+
+When enabling a hardware event without specified pmu, such as,
+perf stat -e cycles -a (use system-wide in this example), two events
+are created automatically.
+
+  ------------------------------------------------------------
+  perf_event_attr:
+    size                             120
+    config                           0x400000000
+    sample_type                      IDENTIFIER
+    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
+    disabled                         1
+    inherit                          1
+    exclude_guest                    1
+  ------------------------------------------------------------
+
+and
+
+  ------------------------------------------------------------
+  perf_event_attr:
+    size                             120
+    config                           0x800000000
+    sample_type                      IDENTIFIER
+    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
+    disabled                         1
+    inherit                          1
+    exclude_guest                    1
+  ------------------------------------------------------------
+
+type 0 is PERF_TYPE_HARDWARE.
+0x4 in 0x400000000 indicates it's cpu_core pmu.
+0x8 in 0x800000000 indicates it's cpu_atom pmu (atom pmu type id is random).
+
+The kernel creates 'cycles' (0x400000000) on cpu0-cpu15 (core cpus),
+and create 'cycles' (0x800000000) on cpu16-cpu23 (atom cpus).
+
+For perf-stat result, it displays two events:
+
+ Performance counter stats for 'system wide':
+
+           6,744,979      cpu_core/cycles/
+           1,965,552      cpu_atom/cycles/
+
+The first 'cycles' is core event, the second 'cycles' is atom event.
+
+Thread mode example:
+--------------------
+
+perf-stat reports the scaled counts for hybrid event and with a percentage
+displayed. The percentage is the event's running time/enabling time.
+
+One example, 'triad_loop' runs on cpu16 (atom core), while we can see the
+scaled value for core cycles is 160,444,092 and the percentage is 0.47%.
+
+perf stat -e cycles -- taskset -c 16 ./triad_loop
+
+As previous, two events are created.
+
+------------------------------------------------------------
+perf_event_attr:
+  size                             120
+  config                           0x400000000
+  sample_type                      IDENTIFIER
+  read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
+  disabled                         1
+  inherit                          1
+  enable_on_exec                   1
+  exclude_guest                    1
+------------------------------------------------------------
+
+and
+
+------------------------------------------------------------
+perf_event_attr:
+  size                             120
+  config                           0x800000000
+  sample_type                      IDENTIFIER
+  read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
+  disabled                         1
+  inherit                          1
+  enable_on_exec                   1
+  exclude_guest                    1
+------------------------------------------------------------
+
+ Performance counter stats for 'taskset -c 16 ./triad_loop':
+
+       233,066,666      cpu_core/cycles/                                              (0.43%)
+       604,097,080      cpu_atom/cycles/                                              (99.57%)
+
+perf-record:
+------------
+
+If there is no '-e' specified in perf record, on hybrid platform,
+it creates two default 'cycles' and adds them to event list. One
+is for core, the other is for atom.
+
+perf-stat:
+----------
+
+If there is no '-e' specified in perf stat, on hybrid platform,
+besides of software events, following events are created and
+added to event list in order.
+
+cpu_core/cycles/,
+cpu_atom/cycles/,
+cpu_core/instructions/,
+cpu_atom/instructions/,
+cpu_core/branches/,
+cpu_atom/branches/,
+cpu_core/branch-misses/,
+cpu_atom/branch-misses/
+
+Of course, both perf-stat and perf-record support to enable
+hybrid event with a specific pmu.
+
+e.g.
+perf stat -e cpu_core/cycles/
+perf stat -e cpu_atom/cycles/
+perf stat -e cpu_core/r1a/
+perf stat -e cpu_atom/L1-icache-loads/
+perf stat -e cpu_core/cycles/,cpu_atom/instructions/
+perf stat -e '{cpu_core/cycles/,cpu_core/instructions/}'
+
+But '{cpu_core/cycles/,cpu_atom/instructions/}' will return
+warning and disable grouping, because the pmus in group are
+not matched (cpu_core vs. cpu_atom).
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index f3161c9673e9..d71bac847936 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -695,6 +695,7 @@ measurements:
  wait -n ${perf_pid}
  exit $?
 
+include::intel-hybrid.txt[]
 
 SEE ALSO
 --------
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index f10e24da23e9..45c2467e4eb2 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -552,6 +552,8 @@ The fields are in this order:
 
 Additional metrics may be printed with all earlier fields being empty.
 
+include::intel-hybrid.txt[]
+
 SEE ALSO
 --------
 linkperf:perf-top[1], linkperf:perf-list[1]
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1
  2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
                   ` (25 preceding siblings ...)
  2021-04-27  7:01 ` [PATCH v6 26/26] perf Documentation: Document intel-hybrid support Jin Yao
@ 2021-04-27 12:50 ` Jiri Olsa
  2021-04-27 13:14   ` Arnaldo Carvalho de Melo
  2021-04-28  1:57   ` Jin, Yao
  26 siblings, 2 replies; 35+ messages in thread
From: Jiri Olsa @ 2021-04-27 12:50 UTC (permalink / raw)
  To: Jin Yao
  Cc: acme, jolsa, peterz, mingo, alexander.shishkin, Linux-kernel, ak,
	kan.liang, yao.jin

On Tue, Apr 27, 2021 at 03:01:13PM +0800, Jin Yao wrote:
> AlderLake uses a hybrid architecture utilizing Golden Cove cores
> (core cpu) and Gracemont cores (atom cpu). Each cpu has dedicated
> event list. Some events are available on core cpu, some events
> are available on atom cpu and some events can be available on both.
> 
> Kernel exports new pmus "cpu_core" and "cpu_atom" through sysfs:
> /sys/devices/cpu_core
> /sys/devices/cpu_atom
> 
> cat /sys/devices/cpu_core/cpus
> 0-15
> 
> cat /sys/devices/cpu_atom/cpus
> 16-23
> 
> In this example, core cpus are 0-15 and atom cpus are 16-23.
> 
> To enable a core only event or atom only event:
> 
>         cpu_core/<event name>/
> or
>         cpu_atom/<event name>/
> 
> Count the 'cycles' event on core cpus.
> 
>   # perf stat -e cpu_core/cycles/ -a -- sleep 1
> 
>    Performance counter stats for 'system wide':
> 
>       12,853,951,349      cpu_core/cycles/
> 
>          1.002581249 seconds time elapsed
> 
> If one event is available on both atom cpu and core cpu, two events
> are created automatically.
> 
>   # perf stat -e cycles -a -- sleep 1
> 
>    Performance counter stats for 'system wide':
> 
>       12,856,467,438      cpu_core/cycles/
>        6,404,634,785      cpu_atom/cycles/
> 
>          1.002453013 seconds time elapsed
> 
> Group is supported if the events are from same pmu, otherwise a warning
> is displayed and disable grouping automatically.
> 
>   # perf stat -e '{cpu_core/cycles/,cpu_core/instructions/}' -a -- sleep 1
> 
>    Performance counter stats for 'system wide':
> 
>       12,863,866,968      cpu_core/cycles/
>          554,795,017      cpu_core/instructions/
> 
>          1.002616117 seconds time elapsed
> 
>   # perf stat -e '{cpu_core/cycles/,cpu_atom/instructions/}' -a -- sleep 1
>   WARNING: events in group from different hybrid PMUs!
>   WARNING: grouped events cpus do not match, disabling group:
>     anon group { cpu_core/cycles/, cpu_atom/instructions/ }
> 
>    Performance counter stats for 'system wide':
> 
>            6,283,970      cpu_core/cycles/
>              765,635      cpu_atom/instructions/
> 
>          1.003959036 seconds time elapsed
> 
> Note that, since the whole patchset for AlderLake hybrid support is very
> large (40+ patches). For simplicity, it's splitted into several patch
> series.
> 
> The patch series 1 only supports the basic functionality. The advanced
> supports for perf-c2c/perf-mem/topdown/metrics/topology header and others
> will be added in follow-up patch series.
> 
> The perf tool codes can also be found at:
> https://github.com/yaoj/perf.git

hi,
did you update the branch for v6? I think I can't see
the new update there

thanks,
jirka

> 
> Note that, this patch series is based on tmp.perf/core branch.
> 
> v6:
> ---
> - Rebase to tmp.perf/core branch.
> 
> - A minor update in v6 patch series.
> 
>   In '[PATCH v6 18/26] perf tests: Add hybrid cases for 'Parse event
>   definition strings' test', we add a test case for cache events with
>   pmu prefix.
> 
>   No other updates.
> 
> v5:
> ---
> - Now Liang Kan's patch series for AlderLake perf core support has been
>   upstreamed. So the interface for perf tool part will not be changed.
> 
> - '[PATCH v5 12/26] perf parse-events: Support event inside hybrid pmu',
>    check the head_config list has only one term and if yes then do the
>    second parsing. We drop the 'parsed' param and make parse_events__with_hybrid_pmu
>    return 0 when we find some event.
> 
>    Move 'evsel->use_config_name = true;' to the patch
>    '[PATCH v5 07/26] perf stat: Uniquify hybrid event name'.
> 
> - '[PATCH v5 14/26] perf stat: Add default hybrid events',
>    do the same way like when topdown calls parse events for checking
>    result and displayt the error.
> 
> - '[PATCH v5 15/26] perf stat: Filter out unmatched aggregation for hybrid event',
>    use Jiri's code to filter, which is much simpler than original.
> 
> - Some perf test minor updates.
> 
> v4:
> ---
> - In Liang Kan's patch:
>   '[PATCH V6 21/25] perf: Extend PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE',
>   the user interface for hardware events and cache events are changed, so
>   perf tool patches are changed as well.
> 
> - Fix an issue when atom CPUs are offlined. "/sys/bus/event_source/devices/cpu_atom/cpus"
>   exists but the content is empty. For this case, we can't enable the cpu_atom
>   PMU. '[PATCH v4 05/25] perf pmu: Save detected hybrid pmus to a global pmu list'
> 
> - Define 'ret' variable for return value in patch
>   '[PATCH v4 09/25] perf parse-events: Create two hybrid cache events'
> 
> - Directly return add_raw_hybrid() in patch
>   '[PATCH v4 10/25] perf parse-events: Create two hybrid raw events'
> 
> - Drop the patch 'perf pmu: Support 'cycles' and 'branches' inside
>   hybrid PMU'.
> 
> - Separate '[PATCH v3 12/27] perf parse-events: Support no alias assigned event
>   inside hybrid PMU' into two patches:
>   '[PATCH v4 11/25] perf parse-events: Compare with hybrid pmu name'
>   '[PATCH v4 12/25] perf parse-events: Support event inside hybrid pmu'.
>   And these two patches are improved according to Jiri's comments.
> 
> v3:
> ---
> - Drop 'perf evlist: Hybrid event uses its own cpus'. This patch is wide
>   and actually it's not very necessary. The current perf framework has
>   processed the cpus for evsel well even for hybrid evsel. So this patch can
>   be dropped.
> 
> - Drop 'perf evsel: Adjust hybrid event and global event mixed group'.
>   The patch is a bit tricky and hard to understand. In v3, we will disable
>   grouping when the group members are from different PMUs. So this patch
>   would be not necessary.
> 
> - Create parse-events-hybrid.c/parse-events-hybrid.h and evlist-hybrid.c/evlist-hybrid.h.
>   Move hybrid related codes to these files.
> 
> - Create a new patch 'perf pmu: Support 'cycles' and 'branches' inside hybrid PMU' to
>   support 'cycles' and 'branches' inside PMU.
> 
> - Create a new patch 'perf record: Uniquify hybrid event name' to tell user the
>   pmu which the event belongs to for perf-record.
> 
> - If group members are from different hybrid PMUs, shows warning and disable
>   grouping.
> 
> - Other refining and refactoring.
> 
> v2:
> ---
> - Drop kernel patches (Kan posted the series "Add Alder Lake support for perf (kernel)" separately).
> - Drop the patches for perf-c2c/perf-mem/topdown/metrics/topology header supports,
>   which will be added in series 2 or series 3.
> - Simplify the arguments of __perf_pmu__new_alias() by passing
>   the 'struct pme_event' pointer.
> - Check sysfs validity before access.
> - Use pmu style event name, such as "cpu_core/cycles/".
> - Move command output two chars to the right.
> - Move pmu hybrid functions to new created pmu-hybrid.c/pmu-hybrid.h.
>   This is to pass the perf test python case.
> 
> Jin Yao (26):
>   tools headers uapi: Update tools's copy of linux/perf_event.h
>   perf jevents: Support unit value "cpu_core" and "cpu_atom"
>   perf pmu: Simplify arguments of __perf_pmu__new_alias
>   perf pmu: Save pmu name
>   perf pmu: Save detected hybrid pmus to a global pmu list
>   perf pmu: Add hybrid helper functions
>   perf stat: Uniquify hybrid event name
>   perf parse-events: Create two hybrid hardware events
>   perf parse-events: Create two hybrid cache events
>   perf parse-events: Create two hybrid raw events
>   perf parse-events: Compare with hybrid pmu name
>   perf parse-events: Support event inside hybrid pmu
>   perf record: Create two hybrid 'cycles' events by default
>   perf stat: Add default hybrid events
>   perf stat: Filter out unmatched aggregation for hybrid event
>   perf stat: Warn group events from different hybrid PMU
>   perf record: Uniquify hybrid event name
>   perf tests: Add hybrid cases for 'Parse event definition strings' test
>   perf tests: Add hybrid cases for 'Roundtrip evsel->name' test
>   perf tests: Skip 'Setup struct perf_event_attr' test for hybrid
>   perf tests: Support 'Track with sched_switch' test for hybrid
>   perf tests: Support 'Parse and process metrics' test for hybrid
>   perf tests: Support 'Session topology' test for hybrid
>   perf tests: Support 'Convert perf time to TSC' test for hybrid
>   perf tests: Skip 'perf stat metrics (shadow stat) test' for hybrid
>   perf Documentation: Document intel-hybrid support
> 
>  include/uapi/linux/perf_event.h            |  15 ++
>  tools/include/uapi/linux/perf_event.h      |  15 ++
>  tools/perf/Documentation/intel-hybrid.txt  | 214 +++++++++++++++++++++
>  tools/perf/Documentation/perf-record.txt   |   1 +
>  tools/perf/Documentation/perf-stat.txt     |   2 +
>  tools/perf/builtin-record.c                |  47 ++++-
>  tools/perf/builtin-stat.c                  |  36 ++++
>  tools/perf/pmu-events/jevents.c            |   2 +
>  tools/perf/tests/attr.c                    |   4 +
>  tools/perf/tests/evsel-roundtrip-name.c    |  19 +-
>  tools/perf/tests/parse-events.c            | 171 ++++++++++++++++
>  tools/perf/tests/parse-metric.c            |   8 +-
>  tools/perf/tests/perf-time-to-tsc.c        |  12 ++
>  tools/perf/tests/shell/stat+shadow_stat.sh |   3 +
>  tools/perf/tests/switch-tracking.c         |   6 +-
>  tools/perf/tests/topology.c                |  13 +-
>  tools/perf/util/Build                      |   3 +
>  tools/perf/util/evlist-hybrid.c            |  88 +++++++++
>  tools/perf/util/evlist-hybrid.h            |  14 ++
>  tools/perf/util/evlist.c                   |   5 +-
>  tools/perf/util/evsel.c                    |  12 +-
>  tools/perf/util/evsel.h                    |   4 +-
>  tools/perf/util/parse-events-hybrid.c      | 178 +++++++++++++++++
>  tools/perf/util/parse-events-hybrid.h      |  23 +++
>  tools/perf/util/parse-events.c             |  97 +++++++++-
>  tools/perf/util/parse-events.h             |   9 +-
>  tools/perf/util/parse-events.y             |   9 +-
>  tools/perf/util/pmu-hybrid.c               |  89 +++++++++
>  tools/perf/util/pmu-hybrid.h               |  22 +++
>  tools/perf/util/pmu.c                      |  64 ++++--
>  tools/perf/util/pmu.h                      |   7 +
>  tools/perf/util/python-ext-sources         |   2 +
>  tools/perf/util/stat-display.c             |  18 +-
>  33 files changed, 1162 insertions(+), 50 deletions(-)
>  create mode 100644 tools/perf/Documentation/intel-hybrid.txt
>  create mode 100644 tools/perf/util/evlist-hybrid.c
>  create mode 100644 tools/perf/util/evlist-hybrid.h
>  create mode 100644 tools/perf/util/parse-events-hybrid.c
>  create mode 100644 tools/perf/util/parse-events-hybrid.h
>  create mode 100644 tools/perf/util/pmu-hybrid.c
>  create mode 100644 tools/perf/util/pmu-hybrid.h
> 
> -- 
> 2.17.1
> 


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1
  2021-04-27 12:50 ` [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jiri Olsa
@ 2021-04-27 13:14   ` Arnaldo Carvalho de Melo
  2021-04-28  1:57   ` Jin, Yao
  1 sibling, 0 replies; 35+ messages in thread
From: Arnaldo Carvalho de Melo @ 2021-04-27 13:14 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Jin Yao, jolsa, peterz, mingo, alexander.shishkin, Linux-kernel,
	ak, kan.liang, yao.jin

Em Tue, Apr 27, 2021 at 02:50:17PM +0200, Jiri Olsa escreveu:
> On Tue, Apr 27, 2021 at 03:01:13PM +0800, Jin Yao wrote:
> > AlderLake uses a hybrid architecture utilizing Golden Cove cores
> > (core cpu) and Gracemont cores (atom cpu). Each cpu has dedicated
> > event list. Some events are available on core cpu, some events
> > are available on atom cpu and some events can be available on both.
> > 
> > Kernel exports new pmus "cpu_core" and "cpu_atom" through sysfs:
> > /sys/devices/cpu_core
> > /sys/devices/cpu_atom
> > 
> > cat /sys/devices/cpu_core/cpus
> > 0-15
> > 
> > cat /sys/devices/cpu_atom/cpus
> > 16-23
> > 
> > In this example, core cpus are 0-15 and atom cpus are 16-23.
> > 
> > To enable a core only event or atom only event:
> > 
> >         cpu_core/<event name>/
> > or
> >         cpu_atom/<event name>/
> > 
> > Count the 'cycles' event on core cpus.
> > 
> >   # perf stat -e cpu_core/cycles/ -a -- sleep 1
> > 
> >    Performance counter stats for 'system wide':
> > 
> >       12,853,951,349      cpu_core/cycles/
> > 
> >          1.002581249 seconds time elapsed
> > 
> > If one event is available on both atom cpu and core cpu, two events
> > are created automatically.
> > 
> >   # perf stat -e cycles -a -- sleep 1
> > 
> >    Performance counter stats for 'system wide':
> > 
> >       12,856,467,438      cpu_core/cycles/
> >        6,404,634,785      cpu_atom/cycles/
> > 
> >          1.002453013 seconds time elapsed
> > 
> > Group is supported if the events are from same pmu, otherwise a warning
> > is displayed and disable grouping automatically.
> > 
> >   # perf stat -e '{cpu_core/cycles/,cpu_core/instructions/}' -a -- sleep 1
> > 
> >    Performance counter stats for 'system wide':
> > 
> >       12,863,866,968      cpu_core/cycles/
> >          554,795,017      cpu_core/instructions/
> > 
> >          1.002616117 seconds time elapsed
> > 
> >   # perf stat -e '{cpu_core/cycles/,cpu_atom/instructions/}' -a -- sleep 1
> >   WARNING: events in group from different hybrid PMUs!
> >   WARNING: grouped events cpus do not match, disabling group:
> >     anon group { cpu_core/cycles/, cpu_atom/instructions/ }
> > 
> >    Performance counter stats for 'system wide':
> > 
> >            6,283,970      cpu_core/cycles/
> >              765,635      cpu_atom/instructions/
> > 
> >          1.003959036 seconds time elapsed
> > 
> > Note that, since the whole patchset for AlderLake hybrid support is very
> > large (40+ patches). For simplicity, it's splitted into several patch
> > series.
> > 
> > The patch series 1 only supports the basic functionality. The advanced
> > supports for perf-c2c/perf-mem/topdown/metrics/topology header and others
> > will be added in follow-up patch series.
> > 
> > The perf tool codes can also be found at:
> > https://github.com/yaoj/perf.git
> 
> hi,
> did you update the branch for v6? I think I can't see
> the new update there

I'm putting it in my tmp.perf/core while I'm testing it and you
reviewing, I'll  do some reviewing as well, now it applied ok:

[acme@five perf]$        git am ./v6_20210427_yao_jin_perf_tool_alderlake_hybrid_support_series_1.mbx
Applying: tools headers uapi: Update tools's copy of linux/perf_event.h
Applying: perf jevents: Support unit value "cpu_core" and "cpu_atom"
Applying: perf pmu: Simplify arguments of __perf_pmu__new_alias
Applying: perf pmu: Save pmu name
Applying: perf pmu: Save detected hybrid pmus to a global pmu list
Applying: perf pmu: Add hybrid helper functions
Applying: perf stat: Uniquify hybrid event name
Applying: perf parse-events: Create two hybrid hardware events
Applying: perf parse-events: Create two hybrid cache events
Applying: perf parse-events: Create two hybrid raw events
Applying: perf parse-events: Compare with hybrid pmu name
Applying: perf parse-events: Support event inside hybrid pmu
Applying: perf record: Create two hybrid 'cycles' events by default
Applying: perf stat: Add default hybrid events
Applying: perf stat: Filter out unmatched aggregation for hybrid event
Applying: perf stat: Warn group events from different hybrid PMU
Applying: perf record: Uniquify hybrid event name
Applying: perf tests: Add hybrid cases for 'Parse event definition strings' test
Applying: perf tests: Add hybrid cases for 'Roundtrip evsel->name' test
Applying: perf tests: Skip 'Setup struct perf_event_attr' test for hybrid
Applying: perf tests: Support 'Track with sched_switch' test for hybrid
Applying: perf tests: Support 'Parse and process metrics' test for hybrid
Applying: perf tests: Support 'Session topology' test for hybrid
Applying: perf tests: Support 'Convert perf time to TSC' test for hybrid
Applying: perf tests: Skip 'perf stat metrics (shadow stat) test' for hybrid
Applying: perf Documentation: Document intel-hybrid support
[acme@five perf]$

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 01/26] tools headers uapi: Update tools's copy of linux/perf_event.h
  2021-04-27  7:01 ` [PATCH v6 01/26] tools headers uapi: Update tools's copy of linux/perf_event.h Jin Yao
@ 2021-04-27 19:24   ` Arnaldo Carvalho de Melo
  2021-04-28  1:18     ` Jin, Yao
  0 siblings, 1 reply; 35+ messages in thread
From: Arnaldo Carvalho de Melo @ 2021-04-27 19:24 UTC (permalink / raw)
  To: Jin Yao
  Cc: jolsa, peterz, mingo, alexander.shishkin, Linux-kernel, ak,
	kan.liang, yao.jin

Em Tue, Apr 27, 2021 at 03:01:14PM +0800, Jin Yao escreveu:
> To get the changes in:
> 
> Liang Kan's patch
> [PATCH V6 21/25] perf: Extend PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE
> 
> Kan's patch is upstreamed yet but perf/core branch doesn't have it
> at this moment. But next perf tool patches need this interface for
> hybrid support.
> 
> This patch can be removed after Kan's patch is merged in perf/core
> branch.

Nope, it is already in tip/perf/core as:

  55bcf6ef314ae8ba ("perf: Extend PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE")

And your patch, the one below, shouldn't include the kernel file, i.e. include/uapi/linux/perf_event.h
as tooling only uses the one in tools/include/uapi/linux/perf_event.h.

Leave the perf tool build warning there, as soon as both acme/perf/core
and tip/perf/core hit torvalds/master, all gets solved.

So I'm removing it here in addition to updating the commit log message.

Ah good news, the test builds passed in all my test build containers.

I'll refresh tmp.perf/core once I update these messages, etc. So that we
can continue from there in case you need to respin a v7.

Thanks,

- Arnaldo.


 
> Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
> ---
> v6:
>  - No update.
> 
> v5:
>  - Update the commit message to mention that Kan's patch is
>    upstreamed but not merged to perf/core branch.
> 
> v4:
>  - Updated by Kan's latest patch,
>    '[PATCH V6 21/25] perf: Extend PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE'
> 
>  include/uapi/linux/perf_event.h       | 15 +++++++++++++++
>  tools/include/uapi/linux/perf_event.h | 15 +++++++++++++++
>  2 files changed, 30 insertions(+)
> 
> diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
> index ad15e40d7f5d..14332f4cf816 100644
> --- a/include/uapi/linux/perf_event.h
> +++ b/include/uapi/linux/perf_event.h
> @@ -37,6 +37,21 @@ enum perf_type_id {
>  	PERF_TYPE_MAX,				/* non-ABI */
>  };
>  
> +/*
> + * attr.config layout for type PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE
> + * PERF_TYPE_HARDWARE:			0xEEEEEEEE000000AA
> + *					AA: hardware event ID
> + *					EEEEEEEE: PMU type ID
> + * PERF_TYPE_HW_CACHE:			0xEEEEEEEE00DDCCBB
> + *					BB: hardware cache ID
> + *					CC: hardware cache op ID
> + *					DD: hardware cache op result ID
> + *					EEEEEEEE: PMU type ID
> + * If the PMU type ID is 0, the PERF_TYPE_RAW will be applied.
> + */
> +#define PERF_PMU_TYPE_SHIFT		32
> +#define PERF_HW_EVENT_MASK		0xffffffff
> +
>  /*
>   * Generalized performance event event_id types, used by the
>   * attr.event_id parameter of the sys_perf_event_open()
> diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
> index ad15e40d7f5d..14332f4cf816 100644
> --- a/tools/include/uapi/linux/perf_event.h
> +++ b/tools/include/uapi/linux/perf_event.h
> @@ -37,6 +37,21 @@ enum perf_type_id {
>  	PERF_TYPE_MAX,				/* non-ABI */
>  };
>  
> +/*
> + * attr.config layout for type PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE
> + * PERF_TYPE_HARDWARE:			0xEEEEEEEE000000AA
> + *					AA: hardware event ID
> + *					EEEEEEEE: PMU type ID
> + * PERF_TYPE_HW_CACHE:			0xEEEEEEEE00DDCCBB
> + *					BB: hardware cache ID
> + *					CC: hardware cache op ID
> + *					DD: hardware cache op result ID
> + *					EEEEEEEE: PMU type ID
> + * If the PMU type ID is 0, the PERF_TYPE_RAW will be applied.
> + */
> +#define PERF_PMU_TYPE_SHIFT		32
> +#define PERF_HW_EVENT_MASK		0xffffffff
> +
>  /*
>   * Generalized performance event event_id types, used by the
>   * attr.event_id parameter of the sys_perf_event_open()
> -- 
> 2.17.1
> 

-- 

- Arnaldo

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 01/26] tools headers uapi: Update tools's copy of linux/perf_event.h
  2021-04-27 19:24   ` Arnaldo Carvalho de Melo
@ 2021-04-28  1:18     ` Jin, Yao
  0 siblings, 0 replies; 35+ messages in thread
From: Jin, Yao @ 2021-04-28  1:18 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: jolsa, peterz, mingo, alexander.shishkin, Linux-kernel, ak,
	kan.liang, yao.jin

Hi Arnaldo,

On 4/28/2021 3:24 AM, Arnaldo Carvalho de Melo wrote:
> Em Tue, Apr 27, 2021 at 03:01:14PM +0800, Jin Yao escreveu:
>> To get the changes in:
>>
>> Liang Kan's patch
>> [PATCH V6 21/25] perf: Extend PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE
>>
>> Kan's patch is upstreamed yet but perf/core branch doesn't have it
>> at this moment. But next perf tool patches need this interface for
>> hybrid support.
>>
>> This patch can be removed after Kan's patch is merged in perf/core
>> branch.
> 
> Nope, it is already in tip/perf/core as:
> 
>    55bcf6ef314ae8ba ("perf: Extend PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE")
> 

Oh, the perf/core mentioned here just means the "perf/core" from acme/linux.git. Sorry, I didn't say 
this clearly. I guess it will be merged to acme/linux.git at some window.

> And your patch, the one below, shouldn't include the kernel file, i.e. include/uapi/linux/perf_event.h
> as tooling only uses the one in tools/include/uapi/linux/perf_event.h.
> 

Yes, my fault. I only need to update the tools/include/uapi/linux/perf_event.h. You have helped me 
to update the commit 7ad6382ef375 ("tools headers uapi: Update tools's copy of linux/perf_event.h") 
in tmp.perf/core. Thanks so much!

> Leave the perf tool build warning there, as soon as both acme/perf/core
> and tip/perf/core hit torvalds/master, all gets solved.
> 
> So I'm removing it here in addition to updating the commit log message.
> 

Thanks again!

> Ah good news, the test builds passed in all my test build containers.
>

Great! :)

> I'll refresh tmp.perf/core once I update these messages, etc. So that we
> can continue from there in case you need to respin a v7.
> 

I've seen the patches have been applied in tmp.perf/core now, thanks! If we need v7, we can continue 
from tmp.perf/core.

Thanks
Jin Yao

> Thanks,
> 
> - Arnaldo.
> 
> 
>   
>> Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
>> ---
>> v6:
>>   - No update.
>>
>> v5:
>>   - Update the commit message to mention that Kan's patch is
>>     upstreamed but not merged to perf/core branch.
>>
>> v4:
>>   - Updated by Kan's latest patch,
>>     '[PATCH V6 21/25] perf: Extend PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE'
>>
>>   include/uapi/linux/perf_event.h       | 15 +++++++++++++++
>>   tools/include/uapi/linux/perf_event.h | 15 +++++++++++++++
>>   2 files changed, 30 insertions(+)
>>
>> diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
>> index ad15e40d7f5d..14332f4cf816 100644
>> --- a/include/uapi/linux/perf_event.h
>> +++ b/include/uapi/linux/perf_event.h
>> @@ -37,6 +37,21 @@ enum perf_type_id {
>>   	PERF_TYPE_MAX,				/* non-ABI */
>>   };
>>   
>> +/*
>> + * attr.config layout for type PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE
>> + * PERF_TYPE_HARDWARE:			0xEEEEEEEE000000AA
>> + *					AA: hardware event ID
>> + *					EEEEEEEE: PMU type ID
>> + * PERF_TYPE_HW_CACHE:			0xEEEEEEEE00DDCCBB
>> + *					BB: hardware cache ID
>> + *					CC: hardware cache op ID
>> + *					DD: hardware cache op result ID
>> + *					EEEEEEEE: PMU type ID
>> + * If the PMU type ID is 0, the PERF_TYPE_RAW will be applied.
>> + */
>> +#define PERF_PMU_TYPE_SHIFT		32
>> +#define PERF_HW_EVENT_MASK		0xffffffff
>> +
>>   /*
>>    * Generalized performance event event_id types, used by the
>>    * attr.event_id parameter of the sys_perf_event_open()
>> diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
>> index ad15e40d7f5d..14332f4cf816 100644
>> --- a/tools/include/uapi/linux/perf_event.h
>> +++ b/tools/include/uapi/linux/perf_event.h
>> @@ -37,6 +37,21 @@ enum perf_type_id {
>>   	PERF_TYPE_MAX,				/* non-ABI */
>>   };
>>   
>> +/*
>> + * attr.config layout for type PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE
>> + * PERF_TYPE_HARDWARE:			0xEEEEEEEE000000AA
>> + *					AA: hardware event ID
>> + *					EEEEEEEE: PMU type ID
>> + * PERF_TYPE_HW_CACHE:			0xEEEEEEEE00DDCCBB
>> + *					BB: hardware cache ID
>> + *					CC: hardware cache op ID
>> + *					DD: hardware cache op result ID
>> + *					EEEEEEEE: PMU type ID
>> + * If the PMU type ID is 0, the PERF_TYPE_RAW will be applied.
>> + */
>> +#define PERF_PMU_TYPE_SHIFT		32
>> +#define PERF_HW_EVENT_MASK		0xffffffff
>> +
>>   /*
>>    * Generalized performance event event_id types, used by the
>>    * attr.event_id parameter of the sys_perf_event_open()
>> -- 
>> 2.17.1
>>
> 

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1
  2021-04-27 12:50 ` [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jiri Olsa
  2021-04-27 13:14   ` Arnaldo Carvalho de Melo
@ 2021-04-28  1:57   ` Jin, Yao
  2021-04-28  7:28     ` Jiri Olsa
  1 sibling, 1 reply; 35+ messages in thread
From: Jin, Yao @ 2021-04-28  1:57 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: acme, jolsa, peterz, mingo, alexander.shishkin, Linux-kernel, ak,
	kan.liang, yao.jin

Hi Jiri,

On 4/27/2021 8:50 PM, Jiri Olsa wrote:
> On Tue, Apr 27, 2021 at 03:01:13PM +0800, Jin Yao wrote:
>> AlderLake uses a hybrid architecture utilizing Golden Cove cores
>> (core cpu) and Gracemont cores (atom cpu). Each cpu has dedicated
>> event list. Some events are available on core cpu, some events
>> are available on atom cpu and some events can be available on both.
>>
>> Kernel exports new pmus "cpu_core" and "cpu_atom" through sysfs:
>> /sys/devices/cpu_core
>> /sys/devices/cpu_atom
>>
>> cat /sys/devices/cpu_core/cpus
>> 0-15
>>
>> cat /sys/devices/cpu_atom/cpus
>> 16-23
>>
>> In this example, core cpus are 0-15 and atom cpus are 16-23.
>>
>> To enable a core only event or atom only event:
>>
>>          cpu_core/<event name>/
>> or
>>          cpu_atom/<event name>/
>>
>> Count the 'cycles' event on core cpus.
>>
>>    # perf stat -e cpu_core/cycles/ -a -- sleep 1
>>
>>     Performance counter stats for 'system wide':
>>
>>        12,853,951,349      cpu_core/cycles/
>>
>>           1.002581249 seconds time elapsed
>>
>> If one event is available on both atom cpu and core cpu, two events
>> are created automatically.
>>
>>    # perf stat -e cycles -a -- sleep 1
>>
>>     Performance counter stats for 'system wide':
>>
>>        12,856,467,438      cpu_core/cycles/
>>         6,404,634,785      cpu_atom/cycles/
>>
>>           1.002453013 seconds time elapsed
>>
>> Group is supported if the events are from same pmu, otherwise a warning
>> is displayed and disable grouping automatically.
>>
>>    # perf stat -e '{cpu_core/cycles/,cpu_core/instructions/}' -a -- sleep 1
>>
>>     Performance counter stats for 'system wide':
>>
>>        12,863,866,968      cpu_core/cycles/
>>           554,795,017      cpu_core/instructions/
>>
>>           1.002616117 seconds time elapsed
>>
>>    # perf stat -e '{cpu_core/cycles/,cpu_atom/instructions/}' -a -- sleep 1
>>    WARNING: events in group from different hybrid PMUs!
>>    WARNING: grouped events cpus do not match, disabling group:
>>      anon group { cpu_core/cycles/, cpu_atom/instructions/ }
>>
>>     Performance counter stats for 'system wide':
>>
>>             6,283,970      cpu_core/cycles/
>>               765,635      cpu_atom/instructions/
>>
>>           1.003959036 seconds time elapsed
>>
>> Note that, since the whole patchset for AlderLake hybrid support is very
>> large (40+ patches). For simplicity, it's splitted into several patch
>> series.
>>
>> The patch series 1 only supports the basic functionality. The advanced
>> supports for perf-c2c/perf-mem/topdown/metrics/topology header and others
>> will be added in follow-up patch series.
>>
>> The perf tool codes can also be found at:
>> https://github.com/yaoj/perf.git
> 
> hi,
> did you update the branch for v6? I think I can't see
> the new update there
> 
> thanks,
> jirka
> 

I just pushed the latest updates to https://github.com/yaoj/perf.git. Sorry it's getting late.

Actually it's Arnaldo's tmp.perf/core branch. Arnaldo has applied the patch series on tmp.perf/core 
and with an update on "[PATCH v6 01/26] tools headers uapi: Update tools's copy of
  linux/perf_event.h".

If there are more comments which need to be addressed, we will start from tmp.perf/core for v7.

Thanks
Jin Yao

>>
>> Note that, this patch series is based on tmp.perf/core branch.
>>
>> v6:
>> ---
>> - Rebase to tmp.perf/core branch.
>>
>> - A minor update in v6 patch series.
>>
>>    In '[PATCH v6 18/26] perf tests: Add hybrid cases for 'Parse event
>>    definition strings' test', we add a test case for cache events with
>>    pmu prefix.
>>
>>    No other updates.
>>
>> v5:
>> ---
>> - Now Liang Kan's patch series for AlderLake perf core support has been
>>    upstreamed. So the interface for perf tool part will not be changed.
>>
>> - '[PATCH v5 12/26] perf parse-events: Support event inside hybrid pmu',
>>     check the head_config list has only one term and if yes then do the
>>     second parsing. We drop the 'parsed' param and make parse_events__with_hybrid_pmu
>>     return 0 when we find some event.
>>
>>     Move 'evsel->use_config_name = true;' to the patch
>>     '[PATCH v5 07/26] perf stat: Uniquify hybrid event name'.
>>
>> - '[PATCH v5 14/26] perf stat: Add default hybrid events',
>>     do the same way like when topdown calls parse events for checking
>>     result and displayt the error.
>>
>> - '[PATCH v5 15/26] perf stat: Filter out unmatched aggregation for hybrid event',
>>     use Jiri's code to filter, which is much simpler than original.
>>
>> - Some perf test minor updates.
>>
>> v4:
>> ---
>> - In Liang Kan's patch:
>>    '[PATCH V6 21/25] perf: Extend PERF_TYPE_HARDWARE and PERF_TYPE_HW_CACHE',
>>    the user interface for hardware events and cache events are changed, so
>>    perf tool patches are changed as well.
>>
>> - Fix an issue when atom CPUs are offlined. "/sys/bus/event_source/devices/cpu_atom/cpus"
>>    exists but the content is empty. For this case, we can't enable the cpu_atom
>>    PMU. '[PATCH v4 05/25] perf pmu: Save detected hybrid pmus to a global pmu list'
>>
>> - Define 'ret' variable for return value in patch
>>    '[PATCH v4 09/25] perf parse-events: Create two hybrid cache events'
>>
>> - Directly return add_raw_hybrid() in patch
>>    '[PATCH v4 10/25] perf parse-events: Create two hybrid raw events'
>>
>> - Drop the patch 'perf pmu: Support 'cycles' and 'branches' inside
>>    hybrid PMU'.
>>
>> - Separate '[PATCH v3 12/27] perf parse-events: Support no alias assigned event
>>    inside hybrid PMU' into two patches:
>>    '[PATCH v4 11/25] perf parse-events: Compare with hybrid pmu name'
>>    '[PATCH v4 12/25] perf parse-events: Support event inside hybrid pmu'.
>>    And these two patches are improved according to Jiri's comments.
>>
>> v3:
>> ---
>> - Drop 'perf evlist: Hybrid event uses its own cpus'. This patch is wide
>>    and actually it's not very necessary. The current perf framework has
>>    processed the cpus for evsel well even for hybrid evsel. So this patch can
>>    be dropped.
>>
>> - Drop 'perf evsel: Adjust hybrid event and global event mixed group'.
>>    The patch is a bit tricky and hard to understand. In v3, we will disable
>>    grouping when the group members are from different PMUs. So this patch
>>    would be not necessary.
>>
>> - Create parse-events-hybrid.c/parse-events-hybrid.h and evlist-hybrid.c/evlist-hybrid.h.
>>    Move hybrid related codes to these files.
>>
>> - Create a new patch 'perf pmu: Support 'cycles' and 'branches' inside hybrid PMU' to
>>    support 'cycles' and 'branches' inside PMU.
>>
>> - Create a new patch 'perf record: Uniquify hybrid event name' to tell user the
>>    pmu which the event belongs to for perf-record.
>>
>> - If group members are from different hybrid PMUs, shows warning and disable
>>    grouping.
>>
>> - Other refining and refactoring.
>>
>> v2:
>> ---
>> - Drop kernel patches (Kan posted the series "Add Alder Lake support for perf (kernel)" separately).
>> - Drop the patches for perf-c2c/perf-mem/topdown/metrics/topology header supports,
>>    which will be added in series 2 or series 3.
>> - Simplify the arguments of __perf_pmu__new_alias() by passing
>>    the 'struct pme_event' pointer.
>> - Check sysfs validity before access.
>> - Use pmu style event name, such as "cpu_core/cycles/".
>> - Move command output two chars to the right.
>> - Move pmu hybrid functions to new created pmu-hybrid.c/pmu-hybrid.h.
>>    This is to pass the perf test python case.
>>
>> Jin Yao (26):
>>    tools headers uapi: Update tools's copy of linux/perf_event.h
>>    perf jevents: Support unit value "cpu_core" and "cpu_atom"
>>    perf pmu: Simplify arguments of __perf_pmu__new_alias
>>    perf pmu: Save pmu name
>>    perf pmu: Save detected hybrid pmus to a global pmu list
>>    perf pmu: Add hybrid helper functions
>>    perf stat: Uniquify hybrid event name
>>    perf parse-events: Create two hybrid hardware events
>>    perf parse-events: Create two hybrid cache events
>>    perf parse-events: Create two hybrid raw events
>>    perf parse-events: Compare with hybrid pmu name
>>    perf parse-events: Support event inside hybrid pmu
>>    perf record: Create two hybrid 'cycles' events by default
>>    perf stat: Add default hybrid events
>>    perf stat: Filter out unmatched aggregation for hybrid event
>>    perf stat: Warn group events from different hybrid PMU
>>    perf record: Uniquify hybrid event name
>>    perf tests: Add hybrid cases for 'Parse event definition strings' test
>>    perf tests: Add hybrid cases for 'Roundtrip evsel->name' test
>>    perf tests: Skip 'Setup struct perf_event_attr' test for hybrid
>>    perf tests: Support 'Track with sched_switch' test for hybrid
>>    perf tests: Support 'Parse and process metrics' test for hybrid
>>    perf tests: Support 'Session topology' test for hybrid
>>    perf tests: Support 'Convert perf time to TSC' test for hybrid
>>    perf tests: Skip 'perf stat metrics (shadow stat) test' for hybrid
>>    perf Documentation: Document intel-hybrid support
>>
>>   include/uapi/linux/perf_event.h            |  15 ++
>>   tools/include/uapi/linux/perf_event.h      |  15 ++
>>   tools/perf/Documentation/intel-hybrid.txt  | 214 +++++++++++++++++++++
>>   tools/perf/Documentation/perf-record.txt   |   1 +
>>   tools/perf/Documentation/perf-stat.txt     |   2 +
>>   tools/perf/builtin-record.c                |  47 ++++-
>>   tools/perf/builtin-stat.c                  |  36 ++++
>>   tools/perf/pmu-events/jevents.c            |   2 +
>>   tools/perf/tests/attr.c                    |   4 +
>>   tools/perf/tests/evsel-roundtrip-name.c    |  19 +-
>>   tools/perf/tests/parse-events.c            | 171 ++++++++++++++++
>>   tools/perf/tests/parse-metric.c            |   8 +-
>>   tools/perf/tests/perf-time-to-tsc.c        |  12 ++
>>   tools/perf/tests/shell/stat+shadow_stat.sh |   3 +
>>   tools/perf/tests/switch-tracking.c         |   6 +-
>>   tools/perf/tests/topology.c                |  13 +-
>>   tools/perf/util/Build                      |   3 +
>>   tools/perf/util/evlist-hybrid.c            |  88 +++++++++
>>   tools/perf/util/evlist-hybrid.h            |  14 ++
>>   tools/perf/util/evlist.c                   |   5 +-
>>   tools/perf/util/evsel.c                    |  12 +-
>>   tools/perf/util/evsel.h                    |   4 +-
>>   tools/perf/util/parse-events-hybrid.c      | 178 +++++++++++++++++
>>   tools/perf/util/parse-events-hybrid.h      |  23 +++
>>   tools/perf/util/parse-events.c             |  97 +++++++++-
>>   tools/perf/util/parse-events.h             |   9 +-
>>   tools/perf/util/parse-events.y             |   9 +-
>>   tools/perf/util/pmu-hybrid.c               |  89 +++++++++
>>   tools/perf/util/pmu-hybrid.h               |  22 +++
>>   tools/perf/util/pmu.c                      |  64 ++++--
>>   tools/perf/util/pmu.h                      |   7 +
>>   tools/perf/util/python-ext-sources         |   2 +
>>   tools/perf/util/stat-display.c             |  18 +-
>>   33 files changed, 1162 insertions(+), 50 deletions(-)
>>   create mode 100644 tools/perf/Documentation/intel-hybrid.txt
>>   create mode 100644 tools/perf/util/evlist-hybrid.c
>>   create mode 100644 tools/perf/util/evlist-hybrid.h
>>   create mode 100644 tools/perf/util/parse-events-hybrid.c
>>   create mode 100644 tools/perf/util/parse-events-hybrid.h
>>   create mode 100644 tools/perf/util/pmu-hybrid.c
>>   create mode 100644 tools/perf/util/pmu-hybrid.h
>>
>> -- 
>> 2.17.1
>>
> 

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1
  2021-04-28  1:57   ` Jin, Yao
@ 2021-04-28  7:28     ` Jiri Olsa
  2021-04-28  8:01       ` Jin, Yao
  2021-04-28 13:44       ` Arnaldo Carvalho de Melo
  0 siblings, 2 replies; 35+ messages in thread
From: Jiri Olsa @ 2021-04-28  7:28 UTC (permalink / raw)
  To: Jin, Yao
  Cc: acme, jolsa, peterz, mingo, alexander.shishkin, Linux-kernel, ak,
	kan.liang, yao.jin

On Wed, Apr 28, 2021 at 09:57:40AM +0800, Jin, Yao wrote:

SNIP

> > >           1.003959036 seconds time elapsed
> > > 
> > > Note that, since the whole patchset for AlderLake hybrid support is very
> > > large (40+ patches). For simplicity, it's splitted into several patch
> > > series.
> > > 
> > > The patch series 1 only supports the basic functionality. The advanced
> > > supports for perf-c2c/perf-mem/topdown/metrics/topology header and others
> > > will be added in follow-up patch series.
> > > 
> > > The perf tool codes can also be found at:
> > > https://github.com/yaoj/perf.git
> > 
> > hi,
> > did you update the branch for v6? I think I can't see
> > the new update there
> > 
> > thanks,
> > jirka
> > 
> 
> I just pushed the latest updates to https://github.com/yaoj/perf.git. Sorry it's getting late.
> 
> Actually it's Arnaldo's tmp.perf/core branch. Arnaldo has applied the patch
> series on tmp.perf/core and with an update on "[PATCH v6 01/26] tools
> headers uapi: Update tools's copy of
>  linux/perf_event.h".

np, I used Arnaldo's branch for review

> 
> If there are more comments which need to be addressed, we will start from tmp.perf/core for v7.
> 
> Thanks
> Jin Yao
> 
> > > 
> > > Note that, this patch series is based on tmp.perf/core branch.
> > > 
> > > v6:
> > > ---
> > > - Rebase to tmp.perf/core branch.
> > > 
> > > - A minor update in v6 patch series.
> > > 
> > >    In '[PATCH v6 18/26] perf tests: Add hybrid cases for 'Parse event
> > >    definition strings' test', we add a test case for cache events with
> > >    pmu prefix.
> > > 
> > >    No other updates.

I can't test the functionality, but apart from that all seems fine
and non-hybrid stuff keeps working ;-)

Reviewed-by: Jiri Olsa <jolsa@kernel.org>

thanks,
jirka


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1
  2021-04-28  7:28     ` Jiri Olsa
@ 2021-04-28  8:01       ` Jin, Yao
  2021-04-28 13:44       ` Arnaldo Carvalho de Melo
  1 sibling, 0 replies; 35+ messages in thread
From: Jin, Yao @ 2021-04-28  8:01 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: acme, jolsa, peterz, mingo, alexander.shishkin, Linux-kernel, ak,
	kan.liang, yao.jin

Hi Jiri,

On 4/28/2021 3:28 PM, Jiri Olsa wrote:
> I can't test the functionality, but apart from that all seems fine
> and non-hybrid stuff keeps working;-)
> 
> Reviewed-by: Jiri Olsa<jolsa@kernel.org>
> 
> thanks,
> jirka

Thanks so much for your review! It's really very helpful for improving the patchset quality, thanks!

I'm now preparing follow-up patchsets, which are to support the hybrid PMU topology 
header/perf-c2c/perf-mem/topdown/metrics.

For simplicity and easy to review, I will post them one by one.

Thanks
Jin Yao


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1
  2021-04-28  7:28     ` Jiri Olsa
  2021-04-28  8:01       ` Jin, Yao
@ 2021-04-28 13:44       ` Arnaldo Carvalho de Melo
  1 sibling, 0 replies; 35+ messages in thread
From: Arnaldo Carvalho de Melo @ 2021-04-28 13:44 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Jin, Yao, jolsa, peterz, mingo, alexander.shishkin, Linux-kernel,
	ak, kan.liang, yao.jin

Em Wed, Apr 28, 2021 at 09:28:31AM +0200, Jiri Olsa escreveu:
> On Wed, Apr 28, 2021 at 09:57:40AM +0800, Jin, Yao wrote:
> 
> SNIP
> 
> > > >           1.003959036 seconds time elapsed
> > > > 
> > > > Note that, since the whole patchset for AlderLake hybrid support is very
> > > > large (40+ patches). For simplicity, it's splitted into several patch
> > > > series.
> > > > 
> > > > The patch series 1 only supports the basic functionality. The advanced
> > > > supports for perf-c2c/perf-mem/topdown/metrics/topology header and others
> > > > will be added in follow-up patch series.
> > > > 
> > > > The perf tool codes can also be found at:
> > > > https://github.com/yaoj/perf.git
> > > 
> > > hi,
> > > did you update the branch for v6? I think I can't see
> > > the new update there
> > > 
> > > thanks,
> > > jirka
> > > 
> > 
> > I just pushed the latest updates to https://github.com/yaoj/perf.git. Sorry it's getting late.
> > 
> > Actually it's Arnaldo's tmp.perf/core branch. Arnaldo has applied the patch
> > series on tmp.perf/core and with an update on "[PATCH v6 01/26] tools
> > headers uapi: Update tools's copy of
> >  linux/perf_event.h".
> 
> np, I used Arnaldo's branch for review
> 
> > 
> > If there are more comments which need to be addressed, we will start from tmp.perf/core for v7.
> > 
> > Thanks
> > Jin Yao
> > 
> > > > 
> > > > Note that, this patch series is based on tmp.perf/core branch.
> > > > 
> > > > v6:
> > > > ---
> > > > - Rebase to tmp.perf/core branch.
> > > > 
> > > > - A minor update in v6 patch series.
> > > > 
> > > >    In '[PATCH v6 18/26] perf tests: Add hybrid cases for 'Parse event
> > > >    definition strings' test', we add a test case for cache events with
> > > >    pmu prefix.
> > > > 
> > > >    No other updates.
> 
> I can't test the functionality, but apart from that all seems fine
> and non-hybrid stuff keeps working ;-)
> 
> Reviewed-by: Jiri Olsa <jolsa@kernel.org>

Thanks, added it to the series.

- Arnaldo

^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2021-04-28 13:45 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-27  7:01 [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jin Yao
2021-04-27  7:01 ` [PATCH v6 01/26] tools headers uapi: Update tools's copy of linux/perf_event.h Jin Yao
2021-04-27 19:24   ` Arnaldo Carvalho de Melo
2021-04-28  1:18     ` Jin, Yao
2021-04-27  7:01 ` [PATCH v6 02/26] perf jevents: Support unit value "cpu_core" and "cpu_atom" Jin Yao
2021-04-27  7:01 ` [PATCH v6 03/26] perf pmu: Simplify arguments of __perf_pmu__new_alias Jin Yao
2021-04-27  7:01 ` [PATCH v6 04/26] perf pmu: Save pmu name Jin Yao
2021-04-27  7:01 ` [PATCH v6 05/26] perf pmu: Save detected hybrid pmus to a global pmu list Jin Yao
2021-04-27  7:01 ` [PATCH v6 06/26] perf pmu: Add hybrid helper functions Jin Yao
2021-04-27  7:01 ` [PATCH v6 07/26] perf stat: Uniquify hybrid event name Jin Yao
2021-04-27  7:01 ` [PATCH v6 08/26] perf parse-events: Create two hybrid hardware events Jin Yao
2021-04-27  7:01 ` [PATCH v6 09/26] perf parse-events: Create two hybrid cache events Jin Yao
2021-04-27  7:01 ` [PATCH v6 10/26] perf parse-events: Create two hybrid raw events Jin Yao
2021-04-27  7:01 ` [PATCH v6 11/26] perf parse-events: Compare with hybrid pmu name Jin Yao
2021-04-27  7:01 ` [PATCH v6 12/26] perf parse-events: Support event inside hybrid pmu Jin Yao
2021-04-27  7:01 ` [PATCH v6 13/26] perf record: Create two hybrid 'cycles' events by default Jin Yao
2021-04-27  7:01 ` [PATCH v6 14/26] perf stat: Add default hybrid events Jin Yao
2021-04-27  7:01 ` [PATCH v6 15/26] perf stat: Filter out unmatched aggregation for hybrid event Jin Yao
2021-04-27  7:01 ` [PATCH v6 16/26] perf stat: Warn group events from different hybrid PMU Jin Yao
2021-04-27  7:01 ` [PATCH v6 17/26] perf record: Uniquify hybrid event name Jin Yao
2021-04-27  7:01 ` [PATCH v6 18/26] perf tests: Add hybrid cases for 'Parse event definition strings' test Jin Yao
2021-04-27  7:01 ` [PATCH v6 19/26] perf tests: Add hybrid cases for 'Roundtrip evsel->name' test Jin Yao
2021-04-27  7:01 ` [PATCH v6 20/26] perf tests: Skip 'Setup struct perf_event_attr' test for hybrid Jin Yao
2021-04-27  7:01 ` [PATCH v6 21/26] perf tests: Support 'Track with sched_switch' " Jin Yao
2021-04-27  7:01 ` [PATCH v6 22/26] perf tests: Support 'Parse and process metrics' " Jin Yao
2021-04-27  7:01 ` [PATCH v6 23/26] perf tests: Support 'Session topology' " Jin Yao
2021-04-27  7:01 ` [PATCH v6 24/26] perf tests: Support 'Convert perf time to TSC' " Jin Yao
2021-04-27  7:01 ` [PATCH v6 25/26] perf tests: Skip 'perf stat metrics (shadow stat) test' " Jin Yao
2021-04-27  7:01 ` [PATCH v6 26/26] perf Documentation: Document intel-hybrid support Jin Yao
2021-04-27 12:50 ` [PATCH v6 00/26] perf tool: AlderLake hybrid support series 1 Jiri Olsa
2021-04-27 13:14   ` Arnaldo Carvalho de Melo
2021-04-28  1:57   ` Jin, Yao
2021-04-28  7:28     ` Jiri Olsa
2021-04-28  8:01       ` Jin, Yao
2021-04-28 13:44       ` Arnaldo Carvalho de Melo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).