diff options
Diffstat (limited to 'tools/perf/util/mem-events.c')
-rw-r--r-- | tools/perf/util/mem-events.c | 90 |
1 files changed, 48 insertions, 42 deletions
diff --git a/tools/perf/util/mem-events.c b/tools/perf/util/mem-events.c index b3a91093069a..ed1ee4b05356 100644 --- a/tools/perf/util/mem-events.c +++ b/tools/perf/util/mem-events.c @@ -295,6 +295,7 @@ static const char * const mem_lvl[] = { }; static const char * const mem_lvlnum[] = { + [PERF_MEM_LVLNUM_UNC] = "Uncached", [PERF_MEM_LVLNUM_CXL] = "CXL", [PERF_MEM_LVLNUM_IO] = "I/O", [PERF_MEM_LVLNUM_ANY_CACHE] = "Any cache", @@ -343,66 +344,71 @@ static int perf_mem__op_scnprintf(char *out, size_t sz, struct mem_info *mem_inf int perf_mem__lvl_scnprintf(char *out, size_t sz, struct mem_info *mem_info) { - size_t i, l = 0; - u64 m = PERF_MEM_LVL_NA; - u64 hit, miss; + union perf_mem_data_src data_src; int printed = 0; - - if (mem_info) - m = mem_info->data_src.mem_lvl; + size_t l = 0; + size_t i; + int lvl; + char hit_miss[5] = {0}; sz -= 1; /* -1 for null termination */ out[0] = '\0'; - hit = m & PERF_MEM_LVL_HIT; - miss = m & PERF_MEM_LVL_MISS; + if (!mem_info) + goto na; - /* already taken care of */ - m &= ~(PERF_MEM_LVL_HIT|PERF_MEM_LVL_MISS); + data_src = mem_info->data_src; - if (mem_info && mem_info->data_src.mem_remote) { - strcat(out, "Remote "); - l += 7; - } + if (data_src.mem_lvl & PERF_MEM_LVL_HIT) + memcpy(hit_miss, "hit", 3); + else if (data_src.mem_lvl & PERF_MEM_LVL_MISS) + memcpy(hit_miss, "miss", 4); - /* - * Incase mem_hops field is set, we can skip printing data source via - * PERF_MEM_LVL namespace. - */ - if (mem_info && mem_info->data_src.mem_hops) { - l += scnprintf(out + l, sz - l, "%s ", mem_hops[mem_info->data_src.mem_hops]); - } else { - for (i = 0; m && i < ARRAY_SIZE(mem_lvl); i++, m >>= 1) { - if (!(m & 0x1)) - continue; - if (printed++) { - strcat(out, " or "); - l += 4; - } - l += scnprintf(out + l, sz - l, mem_lvl[i]); + lvl = data_src.mem_lvl_num; + if (lvl && lvl != PERF_MEM_LVLNUM_NA) { + if (data_src.mem_remote) { + strcat(out, "Remote "); + l += 7; } + + if (data_src.mem_hops) + l += scnprintf(out + l, sz - l, "%s ", mem_hops[data_src.mem_hops]); + + if (mem_lvlnum[lvl]) + l += scnprintf(out + l, sz - l, mem_lvlnum[lvl]); + else + l += scnprintf(out + l, sz - l, "L%d", lvl); + + l += scnprintf(out + l, sz - l, " %s", hit_miss); + return l; } - if (mem_info && mem_info->data_src.mem_lvl_num) { - int lvl = mem_info->data_src.mem_lvl_num; + lvl = data_src.mem_lvl; + if (!lvl) + goto na; + + lvl &= ~(PERF_MEM_LVL_NA | PERF_MEM_LVL_HIT | PERF_MEM_LVL_MISS); + if (!lvl) + goto na; + + for (i = 0; lvl && i < ARRAY_SIZE(mem_lvl); i++, lvl >>= 1) { + if (!(lvl & 0x1)) + continue; if (printed++) { strcat(out, " or "); l += 4; } - if (mem_lvlnum[lvl]) - l += scnprintf(out + l, sz - l, mem_lvlnum[lvl]); - else - l += scnprintf(out + l, sz - l, "L%d", lvl); + l += scnprintf(out + l, sz - l, mem_lvl[i]); } - if (l == 0) - l += scnprintf(out + l, sz - l, "N/A"); - if (hit) - l += scnprintf(out + l, sz - l, " hit"); - if (miss) - l += scnprintf(out + l, sz - l, " miss"); + if (printed) { + l += scnprintf(out + l, sz - l, " %s", hit_miss); + return l; + } - return l; +na: + strcat(out, "N/A"); + return 3; } static const char * const snoop_access[] = { |