perf c2c: Introduce c2c_decode_stats function
authorJiri Olsa <jolsa@kernel.org>
Thu, 22 Sep 2016 15:36:30 +0000 (17:36 +0200)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 19 Oct 2016 16:18:31 +0000 (13:18 -0300)
Introducing c2c_decode_stats function, which decodes
data_src data into new struct c2c_stats.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Original-patch-by: Dick Fowles <rfowles@redhat.com>
Original-patch-by: Don Zickus <dzickus@redhat.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Joe Mario <jmario@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1474558645-19956-3-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/mem-events.c
tools/perf/util/mem-events.h

index bbc368e7d1e4f7f9a53a329fac26d28785db9efc..502fcee919736e9ebdf017a262779b86e1ffce77 100644 (file)
@@ -9,6 +9,7 @@
 #include "mem-events.h"
 #include "debug.h"
 #include "symbol.h"
+#include "sort.h"
 
 unsigned int perf_mem_events__loads_ldlat = 30;
 
@@ -268,3 +269,100 @@ int perf_script__meminfo_scnprintf(char *out, size_t sz, struct mem_info *mem_in
 
        return i;
 }
+
+int c2c_decode_stats(struct c2c_stats *stats, struct mem_info *mi)
+{
+       union perf_mem_data_src *data_src = &mi->data_src;
+       u64 daddr  = mi->daddr.addr;
+       u64 op     = data_src->mem_op;
+       u64 lvl    = data_src->mem_lvl;
+       u64 snoop  = data_src->mem_snoop;
+       u64 lock   = data_src->mem_lock;
+       int err = 0;
+
+#define P(a, b) PERF_MEM_##a##_##b
+
+       stats->nr_entries++;
+
+       if (lock & P(LOCK, LOCKED)) stats->locks++;
+
+       if (op & P(OP, LOAD)) {
+               /* load */
+               stats->load++;
+
+               if (!daddr) {
+                       stats->ld_noadrs++;
+                       return -1;
+               }
+
+               if (lvl & P(LVL, HIT)) {
+                       if (lvl & P(LVL, UNC)) stats->ld_uncache++;
+                       if (lvl & P(LVL, IO))  stats->ld_io++;
+                       if (lvl & P(LVL, LFB)) stats->ld_fbhit++;
+                       if (lvl & P(LVL, L1 )) stats->ld_l1hit++;
+                       if (lvl & P(LVL, L2 )) stats->ld_l2hit++;
+                       if (lvl & P(LVL, L3 )) {
+                               if (snoop & P(SNOOP, HITM))
+                                       stats->lcl_hitm++;
+                               else
+                                       stats->ld_llchit++;
+                       }
+
+                       if (lvl & P(LVL, LOC_RAM)) {
+                               stats->lcl_dram++;
+                               if (snoop & P(SNOOP, HIT))
+                                       stats->ld_shared++;
+                               else
+                                       stats->ld_excl++;
+                       }
+
+                       if ((lvl & P(LVL, REM_RAM1)) ||
+                           (lvl & P(LVL, REM_RAM2))) {
+                               stats->rmt_dram++;
+                               if (snoop & P(SNOOP, HIT))
+                                       stats->ld_shared++;
+                               else
+                                       stats->ld_excl++;
+                       }
+               }
+
+               if ((lvl & P(LVL, REM_CCE1)) ||
+                   (lvl & P(LVL, REM_CCE2))) {
+                       if (snoop & P(SNOOP, HIT))
+                               stats->rmt_hit++;
+                       else if (snoop & P(SNOOP, HITM))
+                               stats->rmt_hitm++;
+               }
+
+               if ((lvl & P(LVL, MISS)))
+                       stats->ld_miss++;
+
+       } else if (op & P(OP, STORE)) {
+               /* store */
+               stats->store++;
+
+               if (!daddr) {
+                       stats->st_noadrs++;
+                       return -1;
+               }
+
+               if (lvl & P(LVL, HIT)) {
+                       if (lvl & P(LVL, UNC)) stats->st_uncache++;
+                       if (lvl & P(LVL, L1 )) stats->st_l1hit++;
+               }
+               if (lvl & P(LVL, MISS))
+                       if (lvl & P(LVL, L1)) stats->st_l1miss++;
+       } else {
+               /* unparsable data_src? */
+               stats->noparse++;
+               return -1;
+       }
+
+       if (!mi->daddr.map || !mi->iaddr.map) {
+               stats->nomap++;
+               return -1;
+       }
+
+#undef P
+       return err;
+}
index 7f69bf9d789da77cecd13e432874ca6e689e2a8a..e111a2a2b18f78cf9d0c36a2e7b4fd27ca1f9c7d 100644 (file)
@@ -2,6 +2,10 @@
 #define __PERF_MEM_EVENTS_H
 
 #include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <linux/types.h>
+#include "stat.h"
 
 struct perf_mem_event {
        bool            record;
@@ -33,4 +37,36 @@ int perf_mem__lck_scnprintf(char *out, size_t sz, struct mem_info *mem_info);
 
 int perf_script__meminfo_scnprintf(char *bf, size_t size, struct mem_info *mem_info);
 
+struct c2c_stats {
+       u32     nr_entries;
+
+       u32     locks;               /* count of 'lock' transactions */
+       u32     store;               /* count of all stores in trace */
+       u32     st_uncache;          /* stores to uncacheable address */
+       u32     st_noadrs;           /* cacheable store with no address */
+       u32     st_l1hit;            /* count of stores that hit L1D */
+       u32     st_l1miss;           /* count of stores that miss L1D */
+       u32     load;                /* count of all loads in trace */
+       u32     ld_excl;             /* exclusive loads, rmt/lcl DRAM - snp none/miss */
+       u32     ld_shared;           /* shared loads, rmt/lcl DRAM - snp hit */
+       u32     ld_uncache;          /* loads to uncacheable address */
+       u32     ld_io;               /* loads to io address */
+       u32     ld_miss;             /* loads miss */
+       u32     ld_noadrs;           /* cacheable load with no address */
+       u32     ld_fbhit;            /* count of loads hitting Fill Buffer */
+       u32     ld_l1hit;            /* count of loads that hit L1D */
+       u32     ld_l2hit;            /* count of loads that hit L2D */
+       u32     ld_llchit;           /* count of loads that hit LLC */
+       u32     lcl_hitm;            /* count of loads with local HITM  */
+       u32     rmt_hitm;            /* count of loads with remote HITM */
+       u32     rmt_hit;             /* count of loads with remote hit clean; */
+       u32     lcl_dram;            /* count of loads miss to local DRAM */
+       u32     rmt_dram;            /* count of loads miss to remote DRAM */
+       u32     nomap;               /* count of load/stores with no phys adrs */
+       u32     noparse;             /* count of unparsable data sources */
+};
+
+struct hist_entry;
+int c2c_decode_stats(struct c2c_stats *stats, struct mem_info *mi);
+
 #endif /* __PERF_MEM_EVENTS_H */