Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf header: Support num and width of branch counters

To support the branch counters feature, the information of the maximum
number of supported counters and the width of the counters is exposed in
the sysfs caps folder. The perf tool can use the information to parse
the logged counters in each branch.

Store the information in the perf_env for later usage.

Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexey Bayduraev <alexey.v.bayduraev@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tinghao Zhang <tinghao.zhang@intel.com>
Link: https://lore.kernel.org/r/20231025201626.3000228-7-kan.liang@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Kan Liang and committed by
Arnaldo Carvalho de Melo
ac9cd724 76db7aab

+20 -3
+5
tools/perf/util/env.h
··· 46 46 struct pmu_caps { 47 47 int nr_caps; 48 48 unsigned int max_branches; 49 + unsigned int br_cntr_nr; 50 + unsigned int br_cntr_width; 51 + 49 52 char **caps; 50 53 char *pmu_name; 51 54 }; ··· 65 62 unsigned long long total_mem; 66 63 unsigned int msr_pmu_type; 67 64 unsigned int max_branches; 65 + unsigned int br_cntr_nr; 66 + unsigned int br_cntr_width; 68 67 int kernel_is_64_bit; 69 68 70 69 int nr_cmdline;
+15 -3
tools/perf/util/header.c
··· 3259 3259 } 3260 3260 3261 3261 static int __process_pmu_caps(struct feat_fd *ff, int *nr_caps, 3262 - char ***caps, unsigned int *max_branches) 3262 + char ***caps, unsigned int *max_branches, 3263 + unsigned int *br_cntr_nr, 3264 + unsigned int *br_cntr_width) 3263 3265 { 3264 3266 char *name, *value, *ptr; 3265 3267 u32 nr_pmu_caps, i; ··· 3296 3294 if (!strcmp(name, "branches")) 3297 3295 *max_branches = atoi(value); 3298 3296 3297 + if (!strcmp(name, "branch_counter_nr")) 3298 + *br_cntr_nr = atoi(value); 3299 + 3300 + if (!strcmp(name, "branch_counter_width")) 3301 + *br_cntr_width = atoi(value); 3302 + 3299 3303 free(value); 3300 3304 free(name); 3301 3305 } ··· 3326 3318 { 3327 3319 int ret = __process_pmu_caps(ff, &ff->ph->env.nr_cpu_pmu_caps, 3328 3320 &ff->ph->env.cpu_pmu_caps, 3329 - &ff->ph->env.max_branches); 3321 + &ff->ph->env.max_branches, 3322 + &ff->ph->env.br_cntr_nr, 3323 + &ff->ph->env.br_cntr_width); 3330 3324 3331 3325 if (!ret && !ff->ph->env.cpu_pmu_caps) 3332 3326 pr_debug("cpu pmu capabilities not available\n"); ··· 3357 3347 for (i = 0; i < nr_pmu; i++) { 3358 3348 ret = __process_pmu_caps(ff, &pmu_caps[i].nr_caps, 3359 3349 &pmu_caps[i].caps, 3360 - &pmu_caps[i].max_branches); 3350 + &pmu_caps[i].max_branches, 3351 + &pmu_caps[i].br_cntr_nr, 3352 + &pmu_caps[i].br_cntr_width); 3361 3353 if (ret) 3362 3354 goto err; 3363 3355