1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 2ce1e22b0SJiri Olsa #include <stddef.h> 3ce1e22b0SJiri Olsa #include <stdlib.h> 4ce1e22b0SJiri Olsa #include <string.h> 5ce1e22b0SJiri Olsa #include <errno.h> 654fbad54SJiri Olsa #include <sys/types.h> 754fbad54SJiri Olsa #include <sys/stat.h> 854fbad54SJiri Olsa #include <unistd.h> 954fbad54SJiri Olsa #include <api/fs/fs.h> 10877a7a11SArnaldo Carvalho de Melo #include <linux/kernel.h> 11acbe613eSJiri Olsa #include "mem-events.h" 12ce1e22b0SJiri Olsa #include "debug.h" 130c877d75SJiri Olsa #include "symbol.h" 14aadddd68SJiri Olsa #include "sort.h" 15acbe613eSJiri Olsa 16b0d745b3SJiri Olsa unsigned int perf_mem_events__loads_ldlat = 30; 17b0d745b3SJiri Olsa 1854fbad54SJiri Olsa #define E(t, n, s) { .tag = t, .name = n, .sysfs_name = s } 19acbe613eSJiri Olsa 20acbe613eSJiri Olsa struct perf_mem_event perf_mem_events[PERF_MEM_EVENTS__MAX] = { 21b0d745b3SJiri Olsa E("ldlat-loads", "cpu/mem-loads,ldlat=%u/P", "mem-loads"), 2254fbad54SJiri Olsa E("ldlat-stores", "cpu/mem-stores/P", "mem-stores"), 23acbe613eSJiri Olsa }; 2454fbad54SJiri Olsa #undef E 25acbe613eSJiri Olsa 26acbe613eSJiri Olsa #undef E 27ce1e22b0SJiri Olsa 28b0d745b3SJiri Olsa static char mem_loads_name[100]; 29b0d745b3SJiri Olsa static bool mem_loads_name__init; 30b0d745b3SJiri Olsa 312ba7ac58SJiri Olsa char *perf_mem_events__name(int i) 322ba7ac58SJiri Olsa { 33b0d745b3SJiri Olsa if (i == PERF_MEM_EVENTS__LOAD) { 34b0d745b3SJiri Olsa if (!mem_loads_name__init) { 35b0d745b3SJiri Olsa mem_loads_name__init = true; 36b0d745b3SJiri Olsa scnprintf(mem_loads_name, sizeof(mem_loads_name), 37b0d745b3SJiri Olsa perf_mem_events[i].name, 38b0d745b3SJiri Olsa perf_mem_events__loads_ldlat); 39b0d745b3SJiri Olsa } 40b0d745b3SJiri Olsa return mem_loads_name; 41b0d745b3SJiri Olsa } 42b0d745b3SJiri Olsa 432ba7ac58SJiri Olsa return (char *)perf_mem_events[i].name; 442ba7ac58SJiri Olsa } 452ba7ac58SJiri Olsa 46ce1e22b0SJiri Olsa int perf_mem_events__parse(const char *str) 47ce1e22b0SJiri Olsa { 48ce1e22b0SJiri Olsa char *tok, *saveptr = NULL; 49ce1e22b0SJiri Olsa bool found = false; 50ce1e22b0SJiri Olsa char *buf; 51ce1e22b0SJiri Olsa int j; 52ce1e22b0SJiri Olsa 53ce1e22b0SJiri Olsa /* We need buffer that we know we can write to. */ 54ce1e22b0SJiri Olsa buf = malloc(strlen(str) + 1); 55ce1e22b0SJiri Olsa if (!buf) 56ce1e22b0SJiri Olsa return -ENOMEM; 57ce1e22b0SJiri Olsa 58ce1e22b0SJiri Olsa strcpy(buf, str); 59ce1e22b0SJiri Olsa 60ce1e22b0SJiri Olsa tok = strtok_r((char *)buf, ",", &saveptr); 61ce1e22b0SJiri Olsa 62ce1e22b0SJiri Olsa while (tok) { 63ce1e22b0SJiri Olsa for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) { 64ce1e22b0SJiri Olsa struct perf_mem_event *e = &perf_mem_events[j]; 65ce1e22b0SJiri Olsa 66ce1e22b0SJiri Olsa if (strstr(e->tag, tok)) 67ce1e22b0SJiri Olsa e->record = found = true; 68ce1e22b0SJiri Olsa } 69ce1e22b0SJiri Olsa 70ce1e22b0SJiri Olsa tok = strtok_r(NULL, ",", &saveptr); 71ce1e22b0SJiri Olsa } 72ce1e22b0SJiri Olsa 73ce1e22b0SJiri Olsa free(buf); 74ce1e22b0SJiri Olsa 75ce1e22b0SJiri Olsa if (found) 76ce1e22b0SJiri Olsa return 0; 77ce1e22b0SJiri Olsa 78ce1e22b0SJiri Olsa pr_err("failed: event '%s' not found, use '-e list' to get list of available events\n", str); 79ce1e22b0SJiri Olsa return -1; 80ce1e22b0SJiri Olsa } 8154fbad54SJiri Olsa 8254fbad54SJiri Olsa int perf_mem_events__init(void) 8354fbad54SJiri Olsa { 8454fbad54SJiri Olsa const char *mnt = sysfs__mount(); 8554fbad54SJiri Olsa bool found = false; 8654fbad54SJiri Olsa int j; 8754fbad54SJiri Olsa 8854fbad54SJiri Olsa if (!mnt) 8954fbad54SJiri Olsa return -ENOENT; 9054fbad54SJiri Olsa 9154fbad54SJiri Olsa for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) { 9254fbad54SJiri Olsa char path[PATH_MAX]; 9354fbad54SJiri Olsa struct perf_mem_event *e = &perf_mem_events[j]; 9454fbad54SJiri Olsa struct stat st; 9554fbad54SJiri Olsa 9654fbad54SJiri Olsa scnprintf(path, PATH_MAX, "%s/devices/cpu/events/%s", 9754fbad54SJiri Olsa mnt, e->sysfs_name); 9854fbad54SJiri Olsa 9954fbad54SJiri Olsa if (!stat(path, &st)) 10054fbad54SJiri Olsa e->supported = found = true; 10154fbad54SJiri Olsa } 10254fbad54SJiri Olsa 10354fbad54SJiri Olsa return found ? 0 : -ENOENT; 10454fbad54SJiri Olsa } 1050c877d75SJiri Olsa 1060c877d75SJiri Olsa static const char * const tlb_access[] = { 1070c877d75SJiri Olsa "N/A", 1080c877d75SJiri Olsa "HIT", 1090c877d75SJiri Olsa "MISS", 1100c877d75SJiri Olsa "L1", 1110c877d75SJiri Olsa "L2", 1120c877d75SJiri Olsa "Walker", 1130c877d75SJiri Olsa "Fault", 1140c877d75SJiri Olsa }; 1150c877d75SJiri Olsa 116b1a5fbeaSJiri Olsa int perf_mem__tlb_scnprintf(char *out, size_t sz, struct mem_info *mem_info) 1170c877d75SJiri Olsa { 1180c877d75SJiri Olsa size_t l = 0, i; 1190c877d75SJiri Olsa u64 m = PERF_MEM_TLB_NA; 1200c877d75SJiri Olsa u64 hit, miss; 1210c877d75SJiri Olsa 1220c877d75SJiri Olsa sz -= 1; /* -1 for null termination */ 1230c877d75SJiri Olsa out[0] = '\0'; 1240c877d75SJiri Olsa 1250c877d75SJiri Olsa if (mem_info) 1260c877d75SJiri Olsa m = mem_info->data_src.mem_dtlb; 1270c877d75SJiri Olsa 1280c877d75SJiri Olsa hit = m & PERF_MEM_TLB_HIT; 1290c877d75SJiri Olsa miss = m & PERF_MEM_TLB_MISS; 1300c877d75SJiri Olsa 1310c877d75SJiri Olsa /* already taken care of */ 1320c877d75SJiri Olsa m &= ~(PERF_MEM_TLB_HIT|PERF_MEM_TLB_MISS); 1330c877d75SJiri Olsa 1340c877d75SJiri Olsa for (i = 0; m && i < ARRAY_SIZE(tlb_access); i++, m >>= 1) { 1350c877d75SJiri Olsa if (!(m & 0x1)) 1360c877d75SJiri Olsa continue; 1370c877d75SJiri Olsa if (l) { 1380c877d75SJiri Olsa strcat(out, " or "); 1390c877d75SJiri Olsa l += 4; 1400c877d75SJiri Olsa } 141b1a5fbeaSJiri Olsa l += scnprintf(out + l, sz - l, tlb_access[i]); 1420c877d75SJiri Olsa } 1430c877d75SJiri Olsa if (*out == '\0') 144b1a5fbeaSJiri Olsa l += scnprintf(out, sz - l, "N/A"); 1450c877d75SJiri Olsa if (hit) 146b1a5fbeaSJiri Olsa l += scnprintf(out + l, sz - l, " hit"); 1470c877d75SJiri Olsa if (miss) 148b1a5fbeaSJiri Olsa l += scnprintf(out + l, sz - l, " miss"); 149b1a5fbeaSJiri Olsa 150b1a5fbeaSJiri Olsa return l; 1510c877d75SJiri Olsa } 152071e9a1eSJiri Olsa 153071e9a1eSJiri Olsa static const char * const mem_lvl[] = { 154071e9a1eSJiri Olsa "N/A", 155071e9a1eSJiri Olsa "HIT", 156071e9a1eSJiri Olsa "MISS", 157071e9a1eSJiri Olsa "L1", 158071e9a1eSJiri Olsa "LFB", 159071e9a1eSJiri Olsa "L2", 160071e9a1eSJiri Olsa "L3", 161071e9a1eSJiri Olsa "Local RAM", 162071e9a1eSJiri Olsa "Remote RAM (1 hop)", 163071e9a1eSJiri Olsa "Remote RAM (2 hops)", 164071e9a1eSJiri Olsa "Remote Cache (1 hop)", 165071e9a1eSJiri Olsa "Remote Cache (2 hops)", 166071e9a1eSJiri Olsa "I/O", 167071e9a1eSJiri Olsa "Uncached", 168071e9a1eSJiri Olsa }; 169071e9a1eSJiri Olsa 17052839e65SAndi Kleen static const char * const mem_lvlnum[] = { 17152839e65SAndi Kleen [PERF_MEM_LVLNUM_ANY_CACHE] = "Any cache", 17252839e65SAndi Kleen [PERF_MEM_LVLNUM_LFB] = "LFB", 17352839e65SAndi Kleen [PERF_MEM_LVLNUM_RAM] = "RAM", 17452839e65SAndi Kleen [PERF_MEM_LVLNUM_PMEM] = "PMEM", 17552839e65SAndi Kleen [PERF_MEM_LVLNUM_NA] = "N/A", 17652839e65SAndi Kleen }; 17752839e65SAndi Kleen 17896907563SJiri Olsa int perf_mem__lvl_scnprintf(char *out, size_t sz, struct mem_info *mem_info) 179071e9a1eSJiri Olsa { 180071e9a1eSJiri Olsa size_t i, l = 0; 181071e9a1eSJiri Olsa u64 m = PERF_MEM_LVL_NA; 182071e9a1eSJiri Olsa u64 hit, miss; 18352839e65SAndi Kleen int printed; 184071e9a1eSJiri Olsa 185071e9a1eSJiri Olsa if (mem_info) 186071e9a1eSJiri Olsa m = mem_info->data_src.mem_lvl; 187071e9a1eSJiri Olsa 188071e9a1eSJiri Olsa sz -= 1; /* -1 for null termination */ 189071e9a1eSJiri Olsa out[0] = '\0'; 190071e9a1eSJiri Olsa 191071e9a1eSJiri Olsa hit = m & PERF_MEM_LVL_HIT; 192071e9a1eSJiri Olsa miss = m & PERF_MEM_LVL_MISS; 193071e9a1eSJiri Olsa 194071e9a1eSJiri Olsa /* already taken care of */ 195071e9a1eSJiri Olsa m &= ~(PERF_MEM_LVL_HIT|PERF_MEM_LVL_MISS); 196071e9a1eSJiri Olsa 19752839e65SAndi Kleen 19852839e65SAndi Kleen if (mem_info && mem_info->data_src.mem_remote) { 19952839e65SAndi Kleen strcat(out, "Remote "); 20052839e65SAndi Kleen l += 7; 20152839e65SAndi Kleen } 20252839e65SAndi Kleen 20352839e65SAndi Kleen printed = 0; 204071e9a1eSJiri Olsa for (i = 0; m && i < ARRAY_SIZE(mem_lvl); i++, m >>= 1) { 205071e9a1eSJiri Olsa if (!(m & 0x1)) 206071e9a1eSJiri Olsa continue; 20752839e65SAndi Kleen if (printed++) { 208071e9a1eSJiri Olsa strcat(out, " or "); 209071e9a1eSJiri Olsa l += 4; 210071e9a1eSJiri Olsa } 21196907563SJiri Olsa l += scnprintf(out + l, sz - l, mem_lvl[i]); 212071e9a1eSJiri Olsa } 21352839e65SAndi Kleen 21452839e65SAndi Kleen if (mem_info && mem_info->data_src.mem_lvl_num) { 21552839e65SAndi Kleen int lvl = mem_info->data_src.mem_lvl_num; 21652839e65SAndi Kleen if (printed++) { 21752839e65SAndi Kleen strcat(out, " or "); 21852839e65SAndi Kleen l += 4; 21952839e65SAndi Kleen } 22052839e65SAndi Kleen if (mem_lvlnum[lvl]) 22152839e65SAndi Kleen l += scnprintf(out + l, sz - l, mem_lvlnum[lvl]); 22252839e65SAndi Kleen else 22352839e65SAndi Kleen l += scnprintf(out + l, sz - l, "L%d", lvl); 22452839e65SAndi Kleen } 22552839e65SAndi Kleen 22652839e65SAndi Kleen if (l == 0) 22752839e65SAndi Kleen l += scnprintf(out + l, sz - l, "N/A"); 228071e9a1eSJiri Olsa if (hit) 22996907563SJiri Olsa l += scnprintf(out + l, sz - l, " hit"); 230071e9a1eSJiri Olsa if (miss) 23196907563SJiri Olsa l += scnprintf(out + l, sz - l, " miss"); 23296907563SJiri Olsa 23396907563SJiri Olsa return l; 234071e9a1eSJiri Olsa } 2352c07af13SJiri Olsa 2362c07af13SJiri Olsa static const char * const snoop_access[] = { 2372c07af13SJiri Olsa "N/A", 2382c07af13SJiri Olsa "None", 2392c07af13SJiri Olsa "Hit", 240166ebdd2SAndi Kleen "Miss", 2412c07af13SJiri Olsa "HitM", 2422c07af13SJiri Olsa }; 2432c07af13SJiri Olsa 244149d7507SJiri Olsa int perf_mem__snp_scnprintf(char *out, size_t sz, struct mem_info *mem_info) 2452c07af13SJiri Olsa { 2462c07af13SJiri Olsa size_t i, l = 0; 2472c07af13SJiri Olsa u64 m = PERF_MEM_SNOOP_NA; 2482c07af13SJiri Olsa 2492c07af13SJiri Olsa sz -= 1; /* -1 for null termination */ 2502c07af13SJiri Olsa out[0] = '\0'; 2512c07af13SJiri Olsa 2522c07af13SJiri Olsa if (mem_info) 2532c07af13SJiri Olsa m = mem_info->data_src.mem_snoop; 2542c07af13SJiri Olsa 2552c07af13SJiri Olsa for (i = 0; m && i < ARRAY_SIZE(snoop_access); i++, m >>= 1) { 2562c07af13SJiri Olsa if (!(m & 0x1)) 2572c07af13SJiri Olsa continue; 2582c07af13SJiri Olsa if (l) { 2592c07af13SJiri Olsa strcat(out, " or "); 2602c07af13SJiri Olsa l += 4; 2612c07af13SJiri Olsa } 262149d7507SJiri Olsa l += scnprintf(out + l, sz - l, snoop_access[i]); 2632c07af13SJiri Olsa } 26452839e65SAndi Kleen if (mem_info && 26552839e65SAndi Kleen (mem_info->data_src.mem_snoopx & PERF_MEM_SNOOPX_FWD)) { 26652839e65SAndi Kleen if (l) { 26752839e65SAndi Kleen strcat(out, " or "); 26852839e65SAndi Kleen l += 4; 26952839e65SAndi Kleen } 27052839e65SAndi Kleen l += scnprintf(out + l, sz - l, "Fwd"); 27152839e65SAndi Kleen } 2722c07af13SJiri Olsa 2732c07af13SJiri Olsa if (*out == '\0') 274149d7507SJiri Olsa l += scnprintf(out, sz - l, "N/A"); 275149d7507SJiri Olsa 276149d7507SJiri Olsa return l; 2772c07af13SJiri Olsa } 27869a77275SJiri Olsa 2798b0819c8SJiri Olsa int perf_mem__lck_scnprintf(char *out, size_t sz, struct mem_info *mem_info) 28069a77275SJiri Olsa { 28169a77275SJiri Olsa u64 mask = PERF_MEM_LOCK_NA; 2828b0819c8SJiri Olsa int l; 28369a77275SJiri Olsa 28469a77275SJiri Olsa if (mem_info) 28569a77275SJiri Olsa mask = mem_info->data_src.mem_lock; 28669a77275SJiri Olsa 28769a77275SJiri Olsa if (mask & PERF_MEM_LOCK_NA) 2888b0819c8SJiri Olsa l = scnprintf(out, sz, "N/A"); 28969a77275SJiri Olsa else if (mask & PERF_MEM_LOCK_LOCKED) 2908b0819c8SJiri Olsa l = scnprintf(out, sz, "Yes"); 29169a77275SJiri Olsa else 2928b0819c8SJiri Olsa l = scnprintf(out, sz, "No"); 2938b0819c8SJiri Olsa 2948b0819c8SJiri Olsa return l; 29569a77275SJiri Olsa } 296c19ac912SJiri Olsa 297c19ac912SJiri Olsa int perf_script__meminfo_scnprintf(char *out, size_t sz, struct mem_info *mem_info) 298c19ac912SJiri Olsa { 299c19ac912SJiri Olsa int i = 0; 300c19ac912SJiri Olsa 301c19ac912SJiri Olsa i += perf_mem__lvl_scnprintf(out, sz, mem_info); 302c19ac912SJiri Olsa i += scnprintf(out + i, sz - i, "|SNP "); 303c19ac912SJiri Olsa i += perf_mem__snp_scnprintf(out + i, sz - i, mem_info); 304c19ac912SJiri Olsa i += scnprintf(out + i, sz - i, "|TLB "); 305c19ac912SJiri Olsa i += perf_mem__tlb_scnprintf(out + i, sz - i, mem_info); 306c19ac912SJiri Olsa i += scnprintf(out + i, sz - i, "|LCK "); 307c19ac912SJiri Olsa i += perf_mem__lck_scnprintf(out + i, sz - i, mem_info); 308c19ac912SJiri Olsa 309c19ac912SJiri Olsa return i; 310c19ac912SJiri Olsa } 311aadddd68SJiri Olsa 312aadddd68SJiri Olsa int c2c_decode_stats(struct c2c_stats *stats, struct mem_info *mi) 313aadddd68SJiri Olsa { 314aadddd68SJiri Olsa union perf_mem_data_src *data_src = &mi->data_src; 315aadddd68SJiri Olsa u64 daddr = mi->daddr.addr; 316aadddd68SJiri Olsa u64 op = data_src->mem_op; 317aadddd68SJiri Olsa u64 lvl = data_src->mem_lvl; 318aadddd68SJiri Olsa u64 snoop = data_src->mem_snoop; 319aadddd68SJiri Olsa u64 lock = data_src->mem_lock; 32012c15302SJiri Olsa /* 32112c15302SJiri Olsa * Skylake might report unknown remote level via this 32212c15302SJiri Olsa * bit, consider it when evaluating remote HITMs. 32312c15302SJiri Olsa */ 32412c15302SJiri Olsa bool mrem = data_src->mem_remote; 325aadddd68SJiri Olsa int err = 0; 326aadddd68SJiri Olsa 327dba8ab93SJiri Olsa #define HITM_INC(__f) \ 328dba8ab93SJiri Olsa do { \ 329dba8ab93SJiri Olsa stats->__f++; \ 330dba8ab93SJiri Olsa stats->tot_hitm++; \ 331dba8ab93SJiri Olsa } while (0) 332dba8ab93SJiri Olsa 333aadddd68SJiri Olsa #define P(a, b) PERF_MEM_##a##_##b 334aadddd68SJiri Olsa 335aadddd68SJiri Olsa stats->nr_entries++; 336aadddd68SJiri Olsa 337aadddd68SJiri Olsa if (lock & P(LOCK, LOCKED)) stats->locks++; 338aadddd68SJiri Olsa 339aadddd68SJiri Olsa if (op & P(OP, LOAD)) { 340aadddd68SJiri Olsa /* load */ 341aadddd68SJiri Olsa stats->load++; 342aadddd68SJiri Olsa 343aadddd68SJiri Olsa if (!daddr) { 344aadddd68SJiri Olsa stats->ld_noadrs++; 345aadddd68SJiri Olsa return -1; 346aadddd68SJiri Olsa } 347aadddd68SJiri Olsa 348aadddd68SJiri Olsa if (lvl & P(LVL, HIT)) { 349aadddd68SJiri Olsa if (lvl & P(LVL, UNC)) stats->ld_uncache++; 350aadddd68SJiri Olsa if (lvl & P(LVL, IO)) stats->ld_io++; 351aadddd68SJiri Olsa if (lvl & P(LVL, LFB)) stats->ld_fbhit++; 352aadddd68SJiri Olsa if (lvl & P(LVL, L1 )) stats->ld_l1hit++; 353aadddd68SJiri Olsa if (lvl & P(LVL, L2 )) stats->ld_l2hit++; 354aadddd68SJiri Olsa if (lvl & P(LVL, L3 )) { 355aadddd68SJiri Olsa if (snoop & P(SNOOP, HITM)) 356dba8ab93SJiri Olsa HITM_INC(lcl_hitm); 357aadddd68SJiri Olsa else 358aadddd68SJiri Olsa stats->ld_llchit++; 359aadddd68SJiri Olsa } 360aadddd68SJiri Olsa 361aadddd68SJiri Olsa if (lvl & P(LVL, LOC_RAM)) { 362aadddd68SJiri Olsa stats->lcl_dram++; 363aadddd68SJiri Olsa if (snoop & P(SNOOP, HIT)) 364aadddd68SJiri Olsa stats->ld_shared++; 365aadddd68SJiri Olsa else 366aadddd68SJiri Olsa stats->ld_excl++; 367aadddd68SJiri Olsa } 368aadddd68SJiri Olsa 369aadddd68SJiri Olsa if ((lvl & P(LVL, REM_RAM1)) || 37012c15302SJiri Olsa (lvl & P(LVL, REM_RAM2)) || 37112c15302SJiri Olsa mrem) { 372aadddd68SJiri Olsa stats->rmt_dram++; 373aadddd68SJiri Olsa if (snoop & P(SNOOP, HIT)) 374aadddd68SJiri Olsa stats->ld_shared++; 375aadddd68SJiri Olsa else 376aadddd68SJiri Olsa stats->ld_excl++; 377aadddd68SJiri Olsa } 378aadddd68SJiri Olsa } 379aadddd68SJiri Olsa 380aadddd68SJiri Olsa if ((lvl & P(LVL, REM_CCE1)) || 38112c15302SJiri Olsa (lvl & P(LVL, REM_CCE2)) || 38212c15302SJiri Olsa mrem) { 383aadddd68SJiri Olsa if (snoop & P(SNOOP, HIT)) 384aadddd68SJiri Olsa stats->rmt_hit++; 385aadddd68SJiri Olsa else if (snoop & P(SNOOP, HITM)) 386dba8ab93SJiri Olsa HITM_INC(rmt_hitm); 387aadddd68SJiri Olsa } 388aadddd68SJiri Olsa 389aadddd68SJiri Olsa if ((lvl & P(LVL, MISS))) 390aadddd68SJiri Olsa stats->ld_miss++; 391aadddd68SJiri Olsa 392aadddd68SJiri Olsa } else if (op & P(OP, STORE)) { 393aadddd68SJiri Olsa /* store */ 394aadddd68SJiri Olsa stats->store++; 395aadddd68SJiri Olsa 396aadddd68SJiri Olsa if (!daddr) { 397aadddd68SJiri Olsa stats->st_noadrs++; 398aadddd68SJiri Olsa return -1; 399aadddd68SJiri Olsa } 400aadddd68SJiri Olsa 401aadddd68SJiri Olsa if (lvl & P(LVL, HIT)) { 402aadddd68SJiri Olsa if (lvl & P(LVL, UNC)) stats->st_uncache++; 403aadddd68SJiri Olsa if (lvl & P(LVL, L1 )) stats->st_l1hit++; 404aadddd68SJiri Olsa } 405aadddd68SJiri Olsa if (lvl & P(LVL, MISS)) 406aadddd68SJiri Olsa if (lvl & P(LVL, L1)) stats->st_l1miss++; 407aadddd68SJiri Olsa } else { 408aadddd68SJiri Olsa /* unparsable data_src? */ 409aadddd68SJiri Olsa stats->noparse++; 410aadddd68SJiri Olsa return -1; 411aadddd68SJiri Olsa } 412aadddd68SJiri Olsa 413aadddd68SJiri Olsa if (!mi->daddr.map || !mi->iaddr.map) { 414aadddd68SJiri Olsa stats->nomap++; 415aadddd68SJiri Olsa return -1; 416aadddd68SJiri Olsa } 417aadddd68SJiri Olsa 418aadddd68SJiri Olsa #undef P 419dba8ab93SJiri Olsa #undef HITM_INC 420aadddd68SJiri Olsa return err; 421aadddd68SJiri Olsa } 4220a9a24ccSJiri Olsa 4230a9a24ccSJiri Olsa void c2c_add_stats(struct c2c_stats *stats, struct c2c_stats *add) 4240a9a24ccSJiri Olsa { 4250a9a24ccSJiri Olsa stats->nr_entries += add->nr_entries; 4260a9a24ccSJiri Olsa 4270a9a24ccSJiri Olsa stats->locks += add->locks; 4280a9a24ccSJiri Olsa stats->store += add->store; 4290a9a24ccSJiri Olsa stats->st_uncache += add->st_uncache; 4300a9a24ccSJiri Olsa stats->st_noadrs += add->st_noadrs; 4310a9a24ccSJiri Olsa stats->st_l1hit += add->st_l1hit; 4320a9a24ccSJiri Olsa stats->st_l1miss += add->st_l1miss; 4330a9a24ccSJiri Olsa stats->load += add->load; 4340a9a24ccSJiri Olsa stats->ld_excl += add->ld_excl; 4350a9a24ccSJiri Olsa stats->ld_shared += add->ld_shared; 4360a9a24ccSJiri Olsa stats->ld_uncache += add->ld_uncache; 4370a9a24ccSJiri Olsa stats->ld_io += add->ld_io; 4380a9a24ccSJiri Olsa stats->ld_miss += add->ld_miss; 4390a9a24ccSJiri Olsa stats->ld_noadrs += add->ld_noadrs; 4400a9a24ccSJiri Olsa stats->ld_fbhit += add->ld_fbhit; 4410a9a24ccSJiri Olsa stats->ld_l1hit += add->ld_l1hit; 4420a9a24ccSJiri Olsa stats->ld_l2hit += add->ld_l2hit; 4430a9a24ccSJiri Olsa stats->ld_llchit += add->ld_llchit; 4440a9a24ccSJiri Olsa stats->lcl_hitm += add->lcl_hitm; 4450a9a24ccSJiri Olsa stats->rmt_hitm += add->rmt_hitm; 446dba8ab93SJiri Olsa stats->tot_hitm += add->tot_hitm; 4470a9a24ccSJiri Olsa stats->rmt_hit += add->rmt_hit; 4480a9a24ccSJiri Olsa stats->lcl_dram += add->lcl_dram; 4490a9a24ccSJiri Olsa stats->rmt_dram += add->rmt_dram; 4500a9a24ccSJiri Olsa stats->nomap += add->nomap; 4510a9a24ccSJiri Olsa stats->noparse += add->noparse; 4520a9a24ccSJiri Olsa } 453