Commit ac9cd724 authored by Kan Liang's avatar Kan Liang Committed by Arnaldo Carvalho de Melo
Browse files

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: default avatarIan Rogers <irogers@google.com>
Signed-off-by: default avatarKan 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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 76db7aab
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@ struct hybrid_node {
struct pmu_caps {
	int		nr_caps;
	unsigned int    max_branches;
	unsigned int	br_cntr_nr;
	unsigned int	br_cntr_width;

	char            **caps;
	char            *pmu_name;
};
@@ -62,6 +65,8 @@ struct perf_env {
	unsigned long long	total_mem;
	unsigned int		msr_pmu_type;
	unsigned int		max_branches;
	unsigned int		br_cntr_nr;
	unsigned int		br_cntr_width;
	int			kernel_is_64_bit;

	int			nr_cmdline;
+15 −3
Original line number Diff line number Diff line
@@ -3259,7 +3259,9 @@ static int process_compressed(struct feat_fd *ff,
}

static int __process_pmu_caps(struct feat_fd *ff, int *nr_caps,
			      char ***caps, unsigned int *max_branches)
			      char ***caps, unsigned int *max_branches,
			      unsigned int *br_cntr_nr,
			      unsigned int *br_cntr_width)
{
	char *name, *value, *ptr;
	u32 nr_pmu_caps, i;
@@ -3294,6 +3296,12 @@ static int __process_pmu_caps(struct feat_fd *ff, int *nr_caps,
		if (!strcmp(name, "branches"))
			*max_branches = atoi(value);

		if (!strcmp(name, "branch_counter_nr"))
			*br_cntr_nr = atoi(value);

		if (!strcmp(name, "branch_counter_width"))
			*br_cntr_width = atoi(value);

		free(value);
		free(name);
	}
@@ -3318,7 +3326,9 @@ static int process_cpu_pmu_caps(struct feat_fd *ff,
{
	int ret = __process_pmu_caps(ff, &ff->ph->env.nr_cpu_pmu_caps,
				     &ff->ph->env.cpu_pmu_caps,
				     &ff->ph->env.max_branches);
				     &ff->ph->env.max_branches,
				     &ff->ph->env.br_cntr_nr,
				     &ff->ph->env.br_cntr_width);

	if (!ret && !ff->ph->env.cpu_pmu_caps)
		pr_debug("cpu pmu capabilities not available\n");
@@ -3347,7 +3357,9 @@ static int process_pmu_caps(struct feat_fd *ff, void *data __maybe_unused)
	for (i = 0; i < nr_pmu; i++) {
		ret = __process_pmu_caps(ff, &pmu_caps[i].nr_caps,
					 &pmu_caps[i].caps,
					 &pmu_caps[i].max_branches);
					 &pmu_caps[i].max_branches,
					 &pmu_caps[i].br_cntr_nr,
					 &pmu_caps[i].br_cntr_width);
		if (ret)
			goto err;