[V5,7/8] perf header: Support num and width of branch counters

Message ID 20231025201626.3000228-7-kan.liang@linux.intel.com
State New
Headers
Series [V5,1/8] perf: Add branch stack counters |

Commit Message

Liang, Kan Oct. 25, 2023, 8:16 p.m. UTC
  From: Kan Liang <kan.liang@linux.intel.com>

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.

Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
---

No changes since V4

 tools/perf/util/env.h    |  5 +++++
 tools/perf/util/header.c | 18 +++++++++++++++---
 2 files changed, 20 insertions(+), 3 deletions(-)
  

Comments

Ian Rogers Oct. 26, 2023, 2:10 a.m. UTC | #1
On Wed, Oct 25, 2023 at 1:16 PM <kan.liang@linux.intel.com> wrote:
>
> From: Kan Liang <kan.liang@linux.intel.com>
>
> 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.
>
> Signed-off-by: Kan Liang <kan.liang@linux.intel.com>

Reviewed-by: Ian Rogers <irogers@google.com>

Thanks,
Ian

> ---
>
> No changes since V4
>
>  tools/perf/util/env.h    |  5 +++++
>  tools/perf/util/header.c | 18 +++++++++++++++---
>  2 files changed, 20 insertions(+), 3 deletions(-)
>
> diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
> index 4566c51f2fd9..48d7f8759a2a 100644
> --- a/tools/perf/util/env.h
> +++ b/tools/perf/util/env.h
> @@ -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;
> diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
> index d812e1e371a7..9664062ba835 100644
> --- a/tools/perf/util/header.c
> +++ b/tools/perf/util/header.c
> @@ -3256,7 +3256,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;
> @@ -3291,6 +3293,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);
>         }
> @@ -3315,7 +3323,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");
> @@ -3344,7 +3354,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;
>
> --
> 2.35.1
>
  

Patch

diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index 4566c51f2fd9..48d7f8759a2a 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -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;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index d812e1e371a7..9664062ba835 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -3256,7 +3256,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;
@@ -3291,6 +3293,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);
 	}
@@ -3315,7 +3323,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");
@@ -3344,7 +3354,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;