From 2b72cec9eef19d73c2a4a3e603004fdf2d93d9e6 Mon Sep 17 00:00:00 2001 From: K Prateek Nayak Date: Wed, 17 May 2023 22:57:41 +0530 Subject: [PATCH] perf: Extract building cache level for a CPU into separate function build_caches() builds the complete cache topology of the system by iterating over all CPU, building and comparing cache levels of each CPU, keeping only the unique ones at the end. Extract the unit that build the cache levels for a single CPU into a separate function. Expose this function, and the MAX_CACHE_LVL value to be used elsewhere in perf too. Signed-off-by: K Prateek Nayak Acked-by: Ian Rogers Cc: Alexander Shishkin Cc: Ananth Narayan Cc: Gautham Shenoy Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Sandipan Das Cc: Stephane Eranian Cc: Wen Pu Link: https://lore.kernel.org/r/20230517172745.5833-2-kprateek.nayak@amd.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/header.c | 64 +++++++++++++++++++++++++--------------- tools/perf/util/header.h | 4 +++ 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 276870221ce0..560871736764 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1213,38 +1213,54 @@ static void cpu_cache_level__fprintf(FILE *out, struct cpu_cache_level *c) fprintf(out, "L%d %-15s %8s [%s]\n", c->level, c->type, c->size, c->map); } -#define MAX_CACHE_LVL 4 +/* + * Build caches levels for a particular CPU from the data in + * /sys/devices/system/cpu/cpu/cache/ + * The cache level data is stored in caches[] from index at + * *cntp. + */ +int build_caches_for_cpu(u32 cpu, struct cpu_cache_level caches[], u32 *cntp) +{ + u16 level; + + for (level = 0; level < MAX_CACHE_LVL; level++) { + struct cpu_cache_level c; + int err; + u32 i; + + err = cpu_cache_level__read(&c, cpu, level); + if (err < 0) + return err; + + if (err == 1) + break; + + for (i = 0; i < *cntp; i++) { + if (cpu_cache_level__cmp(&c, &caches[i])) + break; + } + + if (i == *cntp) { + caches[*cntp] = c; + *cntp = *cntp + 1; + } else + cpu_cache_level__free(&c); + } + + return 0; +} static int build_caches(struct cpu_cache_level caches[], u32 *cntp) { - u32 i, cnt = 0; - u32 nr, cpu; - u16 level; + u32 nr, cpu, cnt = 0; nr = cpu__max_cpu().cpu; for (cpu = 0; cpu < nr; cpu++) { - for (level = 0; level < MAX_CACHE_LVL; level++) { - struct cpu_cache_level c; - int err; + int ret = build_caches_for_cpu(cpu, caches, &cnt); - err = cpu_cache_level__read(&c, cpu, level); - if (err < 0) - return err; - - if (err == 1) - break; - - for (i = 0; i < cnt; i++) { - if (cpu_cache_level__cmp(&c, &caches[i])) - break; - } - - if (i == cnt) - caches[cnt++] = c; - else - cpu_cache_level__free(&c); - } + if (ret) + return ret; } *cntp = cnt; return 0; diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 59eeb4a32ac5..7c16a250e738 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -179,7 +179,11 @@ int do_write(struct feat_fd *fd, const void *buf, size_t size); int write_padded(struct feat_fd *fd, const void *bf, size_t count, size_t count_aligned); +#define MAX_CACHE_LVL 4 + int is_cpu_online(unsigned int cpu); +int build_caches_for_cpu(u32 cpu, struct cpu_cache_level caches[], u32 *cntp); + /* * arch specific callback */