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.

So the kernel introduces a new type 'PERF_TYPE_HW_CACHE_PMU'.

The new attr.config layout for PERF_TYPE_HW_CACHE_PMU is

0xDD00CCBBAA
AA: hardware cache ID
BB: hardware cache op ID
CC: hardware cache op result ID
DD: PMU type ID

Similar as hardware event, PMU type ID is retrieved from sysfs.

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

  # ./perf stat -e L1-dcache-loads -vv -a -- sleep 1
  Control descriptor is not initialized
  ------------------------------------------------------------
  perf_event_attr:
    type                             7
    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:
    type                             7
    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 1  group_fd -1  flags 0x8 = 4
  ------------------------------------------------------------

  ......

  ------------------------------------------------------------
  perf_event_attr:
    type                             7
    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:
    type                             7
    size                             120
    config                           0xa00000000
    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                             7
    size                             120
    config                           0xa00000000
    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 17  group_fd -1  flags 0x8 = 21
  ------------------------------------------------------------

  ......

  ------------------------------------------------------------
  perf_event_attr:
    type                             7
    size                             120
    config                           0xa00000000
    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
  L1-dcache-loads: 0: 12071 1001549888 1001549888
  L1-dcache-loads: 1: 12704 1001602818 1001602818
  L1-dcache-loads: 2: 21560 1001687258 1001687258
  L1-dcache-loads: 3: 8104 1001727825 1001727825
  L1-dcache-loads: 4: 7855 1001738995 1001738995
  L1-dcache-loads: 5: 7714 1001766241 1001766241
  L1-dcache-loads: 6: 7704 1001790333 1001790333
  L1-dcache-loads: 7: 58026 1001826950 1001826950
  L1-dcache-loads: 8: 107639 1001641286 1001641286
  L1-dcache-loads: 9: 67013 1001682357 1001682357
  L1-dcache-loads: 10: 17137 1001700068 1001700068
  L1-dcache-loads: 11: 86449 1001696907 1001696907
  L1-dcache-loads: 12: 7723 1001716599 1001716599
  L1-dcache-loads: 13: 10211 1001743285 1001743285
  L1-dcache-loads: 14: 13023 1001765343 1001765343
  L1-dcache-loads: 15: 8991 1001788673 1001788673
  L1-dcache-loads: 0: 240163 1001800830 1001800830
  L1-dcache-loads: 1: 7454 1001773983 1001773983
  L1-dcache-loads: 2: 32323 1001686339 1001686339
  L1-dcache-loads: 3: 11039 1001732430 1001732430
  L1-dcache-loads: 4: 52867 1001753753 1001753753
  L1-dcache-loads: 5: 7481 1001756879 1001756879
  L1-dcache-loads: 6: 7471 1001814616 1001814616
  L1-dcache-loads: 7: 29627 1001815092 1001815092
  L1-dcache-loads: 453924 16027424826 16027424826
  L1-dcache-loads: 388425 8014133922 8014133922

   Performance counter stats for 'system wide':

             453,924      cpu_core/L1-dcache-loads/
             388,425      cpu_atom/L1-dcache-loads/

         1.003644499 seconds time elapsed

type 7 is PERF_TYPE_HW_CACHE_PMU.
0x4 in 0x400000000 indicates the cpu_core pmu.
0xa in 0xa00000000 indicates the cpu_atom pmu.

Signed-off-by: Jin Yao <yao....@linux.intel.com>
---
v3:
 - Hybrid cache 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        |  8 ++++++++
 3 files changed, 36 insertions(+)

diff --git a/tools/perf/util/parse-events-hybrid.c 
b/tools/perf/util/parse-events-hybrid.c
index bd48563596e0..ff2909bfbf86 100644
--- a/tools/perf/util/parse-events-hybrid.c
+++ b/tools/perf/util/parse-events-hybrid.c
@@ -95,3 +95,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_PMU, 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 1bbd0ba92ba7..3692fa3c964a 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -458,6 +458,7 @@ int parse_events_add_cache(struct list_head *list, int *idx,
        int cache_type = -1, cache_op = -1, cache_result = -1;
        char *op_result[2] = { op_result1, op_result2 };
        int i, n;
+       bool hybrid;
 
        /*
         * No fallback - if we cannot get a clear cache type
@@ -517,6 +518,13 @@ int parse_events_add_cache(struct list_head *list, int 
*idx,
                if (get_config_terms(head_config, &config_terms))
                        return -ENOMEM;
        }
+
+       i = parse_events__add_cache_hybrid(list, idx, &attr,
+                                          config_name ? : name, &config_terms,
+                                          &hybrid);
+       if (hybrid)
+               return i;
+
        return add_event(list, idx, &attr, config_name ? : name, &config_terms);
 }
 
-- 
2.17.1

Reply via email to