[PATCH V7 6/8] perf/tools: Extend branch type classification

Anshuman Khandual posted 8 patches 3 years, 7 months ago
[PATCH V7 6/8] perf/tools: Extend branch type classification
Posted by Anshuman Khandual 3 years, 7 months ago
This updates the perf tool with generic branch type classification with new
ABI extender place holder i.e PERF_BR_EXTEND_ABI, the new 4 bit branch type
field i.e perf_branch_entry.new_type, new generic page fault related branch
types and some arch specific branch types as added earlier in the kernel.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-perf-users@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
 tools/include/uapi/linux/perf_event.h | 16 ++++++++-
 tools/perf/builtin-script.c           |  2 +-
 tools/perf/util/branch.c              | 52 ++++++++++++++++++++++++++-
 tools/perf/util/branch.h              |  6 +++-
 tools/perf/util/session.c             |  2 +-
 5 files changed, 73 insertions(+), 5 deletions(-)

diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
index 146c137ff0c1..0f7c7ce29899 100644
--- a/tools/include/uapi/linux/perf_event.h
+++ b/tools/include/uapi/linux/perf_event.h
@@ -255,9 +255,22 @@ enum {
 	PERF_BR_IRQ		= 12,	/* irq */
 	PERF_BR_SERROR		= 13,	/* system error */
 	PERF_BR_NO_TX		= 14,	/* not in transaction */
+	PERF_BR_EXTEND_ABI	= 15,	/* extend ABI */
 	PERF_BR_MAX,
 };
 
+enum {
+	PERF_BR_NEW_FAULT_ALGN		= 0,    /* Alignment fault */
+	PERF_BR_NEW_FAULT_DATA		= 1,    /* Data fault */
+	PERF_BR_NEW_FAULT_INST		= 2,    /* Inst fault */
+	PERF_BR_NEW_ARCH_1		= 3,    /* Architecture specific */
+	PERF_BR_NEW_ARCH_2		= 4,    /* Architecture specific */
+	PERF_BR_NEW_ARCH_3		= 5,    /* Architecture specific */
+	PERF_BR_NEW_ARCH_4		= 6,    /* Architecture specific */
+	PERF_BR_NEW_ARCH_5		= 7,    /* Architecture specific */
+	PERF_BR_NEW_MAX,
+};
+
 #define PERF_SAMPLE_BRANCH_PLM_ALL \
 	(PERF_SAMPLE_BRANCH_USER|\
 	 PERF_SAMPLE_BRANCH_KERNEL|\
@@ -1375,7 +1388,8 @@ struct perf_branch_entry {
 		abort:1,    /* transaction abort */
 		cycles:16,  /* cycle count to last branch */
 		type:4,     /* branch type */
-		reserved:40;
+		new_type:4, /* additional branch type */
+		reserved:36;
 };
 
 union perf_sample_weight {
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 13580a9c50b8..585171479876 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -877,7 +877,7 @@ static int print_bstack_flags(FILE *fp, struct branch_entry *br)
 		       br->flags.in_tx ? 'X' : '-',
 		       br->flags.abort ? 'A' : '-',
 		       br->flags.cycles,
-		       br->flags.type ? branch_type_name(br->flags.type) : "-");
+		       get_branch_type(br));
 }
 
 static int perf_sample__fprintf_brstack(struct perf_sample *sample,
diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c
index abc673347bee..6d962b0a4532 100644
--- a/tools/perf/util/branch.c
+++ b/tools/perf/util/branch.c
@@ -21,7 +21,10 @@ void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags,
 	if (flags->type == PERF_BR_UNKNOWN || from == 0)
 		return;
 
-	st->counts[flags->type]++;
+	if (flags->type == PERF_BR_EXTEND_ABI)
+		st->new_counts[flags->new_type]++;
+	else
+		st->counts[flags->type]++;
 
 	if (flags->type == PERF_BR_COND) {
 		if (to > from)
@@ -36,6 +39,25 @@ void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags,
 		st->cross_4k++;
 }
 
+const char *branch_new_type_name(int new_type)
+{
+	const char *branch_new_names[PERF_BR_NEW_MAX] = {
+		"FAULT_ALGN",
+		"FAULT_DATA",
+		"FAULT_INST",
+		"ARCH_1",
+		"ARCH_2",
+		"ARCH_3",
+		"ARCH_4",
+		"ARCH_5"
+	};
+
+	if (new_type >= 0 && new_type < PERF_BR_NEW_MAX)
+		return branch_new_names[new_type];
+
+	return NULL;
+}
+
 const char *branch_type_name(int type)
 {
 	const char *branch_names[PERF_BR_MAX] = {
@@ -62,6 +84,17 @@ const char *branch_type_name(int type)
 	return NULL;
 }
 
+const char *get_branch_type(struct branch_entry *e)
+{
+	if (e->flags.type == PERF_BR_UNKNOWN)
+		return "";
+
+	if (e->flags.type == PERF_BR_EXTEND_ABI)
+		return branch_new_type_name(e->flags.new_type);
+
+	return branch_type_name(e->flags.type);
+}
+
 void branch_type_stat_display(FILE *fp, struct branch_type_stat *st)
 {
 	u64 total = 0;
@@ -108,6 +141,15 @@ void branch_type_stat_display(FILE *fp, struct branch_type_stat *st)
 				100.0 *
 				(double)st->counts[i] / (double)total);
 	}
+
+	for (i = 0; i < PERF_BR_NEW_MAX; i++) {
+		if (st->new_counts[i] > 0)
+			fprintf(fp, "\n%8s: %5.1f%%",
+				branch_new_type_name(i),
+				100.0 *
+				(double)st->new_counts[i] / (double)total);
+	}
+
 }
 
 static int count_str_scnprintf(int idx, const char *str, char *bf, int size)
@@ -123,6 +165,9 @@ int branch_type_str(struct branch_type_stat *st, char *bf, int size)
 	for (i = 0; i < PERF_BR_MAX; i++)
 		total += st->counts[i];
 
+	for (i = 0; i < PERF_BR_NEW_MAX; i++)
+		total += st->new_counts[i];
+
 	if (total == 0)
 		return 0;
 
@@ -140,6 +185,11 @@ int branch_type_str(struct branch_type_stat *st, char *bf, int size)
 			printed += count_str_scnprintf(j++, branch_type_name(i), bf + printed, size - printed);
 	}
 
+	for (i = 0; i < PERF_BR_NEW_MAX; i++) {
+		if (st->new_counts[i] > 0)
+			printed += count_str_scnprintf(j++, branch_new_type_name(i), bf + printed, size - printed);
+	}
+
 	if (st->cross_4k > 0)
 		printed += count_str_scnprintf(j++, "CROSS_4K", bf + printed, size - printed);
 
diff --git a/tools/perf/util/branch.h b/tools/perf/util/branch.h
index 17b2ccc61094..8d251b35428a 100644
--- a/tools/perf/util/branch.h
+++ b/tools/perf/util/branch.h
@@ -24,7 +24,8 @@ struct branch_flags {
 			u64 abort:1;
 			u64 cycles:16;
 			u64 type:4;
-			u64 reserved:40;
+			u64 new_type:4;
+			u64 reserved:36;
 		};
 	};
 };
@@ -72,6 +73,7 @@ static inline struct branch_entry *perf_sample__branch_entries(struct perf_sampl
 struct branch_type_stat {
 	bool	branch_to;
 	u64	counts[PERF_BR_MAX];
+	u64	new_counts[PERF_BR_NEW_MAX];
 	u64	cond_fwd;
 	u64	cond_bwd;
 	u64	cross_4k;
@@ -82,6 +84,8 @@ void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags,
 		       u64 from, u64 to);
 
 const char *branch_type_name(int type);
+const char *branch_new_type_name(int new_type);
+const char *get_branch_type(struct branch_entry *e);
 void branch_type_stat_display(FILE *fp, struct branch_type_stat *st);
 int branch_type_str(struct branch_type_stat *st, char *bf, int bfsize);
 
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 192c9274f7ad..47d5a50e616a 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1180,7 +1180,7 @@ static void branch_stack__printf(struct perf_sample *sample, bool callstack)
 				e->flags.abort ? "A" : " ",
 				e->flags.in_tx ? "T" : " ",
 				(unsigned)e->flags.reserved,
-				e->flags.type ? branch_type_name(e->flags.type) : "");
+				get_branch_type(e));
 		} else {
 			if (i == 0) {
 				printf("..... %2"PRIu64": %016" PRIx64 "\n"
-- 
2.25.1
Re: [PATCH V7 6/8] perf/tools: Extend branch type classification
Posted by Arnaldo Carvalho de Melo 3 years, 7 months ago
Em Wed, Aug 24, 2022 at 10:18:20AM +0530, Anshuman Khandual escreveu:
> This updates the perf tool with generic branch type classification with new
> ABI extender place holder i.e PERF_BR_EXTEND_ABI, the new 4 bit branch type
> field i.e perf_branch_entry.new_type, new generic page fault related branch
> types and some arch specific branch types as added earlier in the kernel.
> 
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> Cc: Jiri Olsa <jolsa@redhat.com>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Will Deacon <will@kernel.org>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-perf-users@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
>  tools/include/uapi/linux/perf_event.h | 16 ++++++++-
>  tools/perf/builtin-script.c           |  2 +-
>  tools/perf/util/branch.c              | 52 ++++++++++++++++++++++++++-
>  tools/perf/util/branch.h              |  6 +++-
>  tools/perf/util/session.c             |  2 +-
>  5 files changed, 73 insertions(+), 5 deletions(-)
> 
> diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
> index 146c137ff0c1..0f7c7ce29899 100644
> --- a/tools/include/uapi/linux/perf_event.h
> +++ b/tools/include/uapi/linux/perf_event.h
> @@ -255,9 +255,22 @@ enum {
>  	PERF_BR_IRQ		= 12,	/* irq */
>  	PERF_BR_SERROR		= 13,	/* system error */
>  	PERF_BR_NO_TX		= 14,	/* not in transaction */
> +	PERF_BR_EXTEND_ABI	= 15,	/* extend ABI */
>  	PERF_BR_MAX,
>  };
>  
> +enum {
> +	PERF_BR_NEW_FAULT_ALGN		= 0,    /* Alignment fault */
> +	PERF_BR_NEW_FAULT_DATA		= 1,    /* Data fault */
> +	PERF_BR_NEW_FAULT_INST		= 2,    /* Inst fault */
> +	PERF_BR_NEW_ARCH_1		= 3,    /* Architecture specific */
> +	PERF_BR_NEW_ARCH_2		= 4,    /* Architecture specific */
> +	PERF_BR_NEW_ARCH_3		= 5,    /* Architecture specific */
> +	PERF_BR_NEW_ARCH_4		= 6,    /* Architecture specific */
> +	PERF_BR_NEW_ARCH_5		= 7,    /* Architecture specific */
> +	PERF_BR_NEW_MAX,
> +};
> +
>  #define PERF_SAMPLE_BRANCH_PLM_ALL \
>  	(PERF_SAMPLE_BRANCH_USER|\
>  	 PERF_SAMPLE_BRANCH_KERNEL|\
> @@ -1375,7 +1388,8 @@ struct perf_branch_entry {
>  		abort:1,    /* transaction abort */
>  		cycles:16,  /* cycle count to last branch */
>  		type:4,     /* branch type */
> -		reserved:40;
> +		new_type:4, /* additional branch type */
> +		reserved:36;
>  };
>  
>  union perf_sample_weight {
> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> index 13580a9c50b8..585171479876 100644
> --- a/tools/perf/builtin-script.c
> +++ b/tools/perf/builtin-script.c
> @@ -877,7 +877,7 @@ static int print_bstack_flags(FILE *fp, struct branch_entry *br)
>  		       br->flags.in_tx ? 'X' : '-',
>  		       br->flags.abort ? 'A' : '-',
>  		       br->flags.cycles,
> -		       br->flags.type ? branch_type_name(br->flags.type) : "-");
> +		       get_branch_type(br));
>  }
>  
>  static int perf_sample__fprintf_brstack(struct perf_sample *sample,
> diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c
> index abc673347bee..6d962b0a4532 100644
> --- a/tools/perf/util/branch.c
> +++ b/tools/perf/util/branch.c
> @@ -21,7 +21,10 @@ void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags,
>  	if (flags->type == PERF_BR_UNKNOWN || from == 0)
>  		return;
>  
> -	st->counts[flags->type]++;
> +	if (flags->type == PERF_BR_EXTEND_ABI)
> +		st->new_counts[flags->new_type]++;
> +	else
> +		st->counts[flags->type]++;
>  
>  	if (flags->type == PERF_BR_COND) {
>  		if (to > from)
> @@ -36,6 +39,25 @@ void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags,
>  		st->cross_4k++;
>  }
>  
> +const char *branch_new_type_name(int new_type)
> +{
> +	const char *branch_new_names[PERF_BR_NEW_MAX] = {
> +		"FAULT_ALGN",
> +		"FAULT_DATA",
> +		"FAULT_INST",
> +		"ARCH_1",
> +		"ARCH_2",
> +		"ARCH_3",
> +		"ARCH_4",
> +		"ARCH_5"
> +	};
> +
> +	if (new_type >= 0 && new_type < PERF_BR_NEW_MAX)
> +		return branch_new_names[new_type];
> +
> +	return NULL;
> +}
> +
>  const char *branch_type_name(int type)
>  {
>  	const char *branch_names[PERF_BR_MAX] = {
> @@ -62,6 +84,17 @@ const char *branch_type_name(int type)
>  	return NULL;
>  }
>  
> +const char *get_branch_type(struct branch_entry *e)
> +{
> +	if (e->flags.type == PERF_BR_UNKNOWN)
> +		return "";
> +
> +	if (e->flags.type == PERF_BR_EXTEND_ABI)
> +		return branch_new_type_name(e->flags.new_type);
> +
> +	return branch_type_name(e->flags.type);
> +}
> +
>  void branch_type_stat_display(FILE *fp, struct branch_type_stat *st)
>  {
>  	u64 total = 0;
> @@ -108,6 +141,15 @@ void branch_type_stat_display(FILE *fp, struct branch_type_stat *st)
>  				100.0 *
>  				(double)st->counts[i] / (double)total);
>  	}
> +
> +	for (i = 0; i < PERF_BR_NEW_MAX; i++) {
> +		if (st->new_counts[i] > 0)
> +			fprintf(fp, "\n%8s: %5.1f%%",
> +				branch_new_type_name(i),
> +				100.0 *
> +				(double)st->new_counts[i] / (double)total);
> +	}
> +

Strange:

  75     8.89 ubuntu:20.04-x-powerpc64el    : FAIL gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04)
        inlined from 'branch_type_stat_display' at util/branch.c:152:4:
    /usr/powerpc64le-linux-gnu/include/bits/stdio2.h:100:10: error: '%8s' directive argument is null [-Werror=format-overflow=]
      100 |   return __fprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt,
          |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      101 |    __va_arg_pack ());
          |    ~~~~~~~~~~~~~~~~~


>  }
>  
>  static int count_str_scnprintf(int idx, const char *str, char *bf, int size)
> @@ -123,6 +165,9 @@ int branch_type_str(struct branch_type_stat *st, char *bf, int size)
>  	for (i = 0; i < PERF_BR_MAX; i++)
>  		total += st->counts[i];
>  
> +	for (i = 0; i < PERF_BR_NEW_MAX; i++)
> +		total += st->new_counts[i];
> +
>  	if (total == 0)
>  		return 0;
>  
> @@ -140,6 +185,11 @@ int branch_type_str(struct branch_type_stat *st, char *bf, int size)
>  			printed += count_str_scnprintf(j++, branch_type_name(i), bf + printed, size - printed);
>  	}
>  
> +	for (i = 0; i < PERF_BR_NEW_MAX; i++) {
> +		if (st->new_counts[i] > 0)
> +			printed += count_str_scnprintf(j++, branch_new_type_name(i), bf + printed, size - printed);
> +	}
> +
>  	if (st->cross_4k > 0)
>  		printed += count_str_scnprintf(j++, "CROSS_4K", bf + printed, size - printed);
>  
> diff --git a/tools/perf/util/branch.h b/tools/perf/util/branch.h
> index 17b2ccc61094..8d251b35428a 100644
> --- a/tools/perf/util/branch.h
> +++ b/tools/perf/util/branch.h
> @@ -24,7 +24,8 @@ struct branch_flags {
>  			u64 abort:1;
>  			u64 cycles:16;
>  			u64 type:4;
> -			u64 reserved:40;
> +			u64 new_type:4;
> +			u64 reserved:36;
>  		};
>  	};
>  };
> @@ -72,6 +73,7 @@ static inline struct branch_entry *perf_sample__branch_entries(struct perf_sampl
>  struct branch_type_stat {
>  	bool	branch_to;
>  	u64	counts[PERF_BR_MAX];
> +	u64	new_counts[PERF_BR_NEW_MAX];
>  	u64	cond_fwd;
>  	u64	cond_bwd;
>  	u64	cross_4k;
> @@ -82,6 +84,8 @@ void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags,
>  		       u64 from, u64 to);
>  
>  const char *branch_type_name(int type);
> +const char *branch_new_type_name(int new_type);
> +const char *get_branch_type(struct branch_entry *e);
>  void branch_type_stat_display(FILE *fp, struct branch_type_stat *st);
>  int branch_type_str(struct branch_type_stat *st, char *bf, int bfsize);
>  
> diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
> index 192c9274f7ad..47d5a50e616a 100644
> --- a/tools/perf/util/session.c
> +++ b/tools/perf/util/session.c
> @@ -1180,7 +1180,7 @@ static void branch_stack__printf(struct perf_sample *sample, bool callstack)
>  				e->flags.abort ? "A" : " ",
>  				e->flags.in_tx ? "T" : " ",
>  				(unsigned)e->flags.reserved,
> -				e->flags.type ? branch_type_name(e->flags.type) : "");
> +				get_branch_type(e));
>  		} else {
>  			if (i == 0) {
>  				printf("..... %2"PRIu64": %016" PRIx64 "\n"
> -- 
> 2.25.1

-- 

- Arnaldo
Re: [PATCH V7 6/8] perf/tools: Extend branch type classification
Posted by Anshuman Khandual 3 years, 7 months ago

On 8/31/22 02:41, Arnaldo Carvalho de Melo wrote:
> Em Wed, Aug 24, 2022 at 10:18:20AM +0530, Anshuman Khandual escreveu:
>> This updates the perf tool with generic branch type classification with new
>> ABI extender place holder i.e PERF_BR_EXTEND_ABI, the new 4 bit branch type
>> field i.e perf_branch_entry.new_type, new generic page fault related branch
>> types and some arch specific branch types as added earlier in the kernel.
>>
>> Cc: Peter Zijlstra <peterz@infradead.org>
>> Cc: Ingo Molnar <mingo@redhat.com>
>> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
>> Cc: Mark Rutland <mark.rutland@arm.com>
>> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
>> Cc: Jiri Olsa <jolsa@redhat.com>
>> Cc: Namhyung Kim <namhyung@kernel.org>
>> Cc: Thomas Gleixner <tglx@linutronix.de>
>> Cc: Will Deacon <will@kernel.org>
>> Cc: linux-arm-kernel@lists.infradead.org
>> Cc: linux-perf-users@vger.kernel.org
>> Cc: linux-kernel@vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
>> ---
>>  tools/include/uapi/linux/perf_event.h | 16 ++++++++-
>>  tools/perf/builtin-script.c           |  2 +-
>>  tools/perf/util/branch.c              | 52 ++++++++++++++++++++++++++-
>>  tools/perf/util/branch.h              |  6 +++-
>>  tools/perf/util/session.c             |  2 +-
>>  5 files changed, 73 insertions(+), 5 deletions(-)
>>
>> diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
>> index 146c137ff0c1..0f7c7ce29899 100644
>> --- a/tools/include/uapi/linux/perf_event.h
>> +++ b/tools/include/uapi/linux/perf_event.h
>> @@ -255,9 +255,22 @@ enum {
>>  	PERF_BR_IRQ		= 12,	/* irq */
>>  	PERF_BR_SERROR		= 13,	/* system error */
>>  	PERF_BR_NO_TX		= 14,	/* not in transaction */
>> +	PERF_BR_EXTEND_ABI	= 15,	/* extend ABI */
>>  	PERF_BR_MAX,
>>  };
>>  
>> +enum {
>> +	PERF_BR_NEW_FAULT_ALGN		= 0,    /* Alignment fault */
>> +	PERF_BR_NEW_FAULT_DATA		= 1,    /* Data fault */
>> +	PERF_BR_NEW_FAULT_INST		= 2,    /* Inst fault */
>> +	PERF_BR_NEW_ARCH_1		= 3,    /* Architecture specific */
>> +	PERF_BR_NEW_ARCH_2		= 4,    /* Architecture specific */
>> +	PERF_BR_NEW_ARCH_3		= 5,    /* Architecture specific */
>> +	PERF_BR_NEW_ARCH_4		= 6,    /* Architecture specific */
>> +	PERF_BR_NEW_ARCH_5		= 7,    /* Architecture specific */
>> +	PERF_BR_NEW_MAX,
>> +};
>> +
>>  #define PERF_SAMPLE_BRANCH_PLM_ALL \
>>  	(PERF_SAMPLE_BRANCH_USER|\
>>  	 PERF_SAMPLE_BRANCH_KERNEL|\
>> @@ -1375,7 +1388,8 @@ struct perf_branch_entry {
>>  		abort:1,    /* transaction abort */
>>  		cycles:16,  /* cycle count to last branch */
>>  		type:4,     /* branch type */
>> -		reserved:40;
>> +		new_type:4, /* additional branch type */
>> +		reserved:36;
>>  };
>>  
>>  union perf_sample_weight {
>> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
>> index 13580a9c50b8..585171479876 100644
>> --- a/tools/perf/builtin-script.c
>> +++ b/tools/perf/builtin-script.c
>> @@ -877,7 +877,7 @@ static int print_bstack_flags(FILE *fp, struct branch_entry *br)
>>  		       br->flags.in_tx ? 'X' : '-',
>>  		       br->flags.abort ? 'A' : '-',
>>  		       br->flags.cycles,
>> -		       br->flags.type ? branch_type_name(br->flags.type) : "-");
>> +		       get_branch_type(br));
>>  }
>>  
>>  static int perf_sample__fprintf_brstack(struct perf_sample *sample,
>> diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c
>> index abc673347bee..6d962b0a4532 100644
>> --- a/tools/perf/util/branch.c
>> +++ b/tools/perf/util/branch.c
>> @@ -21,7 +21,10 @@ void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags,
>>  	if (flags->type == PERF_BR_UNKNOWN || from == 0)
>>  		return;
>>  
>> -	st->counts[flags->type]++;
>> +	if (flags->type == PERF_BR_EXTEND_ABI)
>> +		st->new_counts[flags->new_type]++;
>> +	else
>> +		st->counts[flags->type]++;
>>  
>>  	if (flags->type == PERF_BR_COND) {
>>  		if (to > from)
>> @@ -36,6 +39,25 @@ void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags,
>>  		st->cross_4k++;
>>  }
>>  
>> +const char *branch_new_type_name(int new_type)
>> +{
>> +	const char *branch_new_names[PERF_BR_NEW_MAX] = {
>> +		"FAULT_ALGN",
>> +		"FAULT_DATA",
>> +		"FAULT_INST",
>> +		"ARCH_1",
>> +		"ARCH_2",
>> +		"ARCH_3",
>> +		"ARCH_4",
>> +		"ARCH_5"
>> +	};
>> +
>> +	if (new_type >= 0 && new_type < PERF_BR_NEW_MAX)
>> +		return branch_new_names[new_type];
>> +
>> +	return NULL;
>> +}
>> +
>>  const char *branch_type_name(int type)
>>  {
>>  	const char *branch_names[PERF_BR_MAX] = {
>> @@ -62,6 +84,17 @@ const char *branch_type_name(int type)
>>  	return NULL;
>>  }
>>  
>> +const char *get_branch_type(struct branch_entry *e)
>> +{
>> +	if (e->flags.type == PERF_BR_UNKNOWN)
>> +		return "";
>> +
>> +	if (e->flags.type == PERF_BR_EXTEND_ABI)
>> +		return branch_new_type_name(e->flags.new_type);
>> +
>> +	return branch_type_name(e->flags.type);
>> +}
>> +
>>  void branch_type_stat_display(FILE *fp, struct branch_type_stat *st)
>>  {
>>  	u64 total = 0;
>> @@ -108,6 +141,15 @@ void branch_type_stat_display(FILE *fp, struct branch_type_stat *st)
>>  				100.0 *
>>  				(double)st->counts[i] / (double)total);
>>  	}
>> +
>> +	for (i = 0; i < PERF_BR_NEW_MAX; i++) {
>> +		if (st->new_counts[i] > 0)
>> +			fprintf(fp, "\n%8s: %5.1f%%",
>> +				branch_new_type_name(i),
>> +				100.0 *
>> +				(double)st->new_counts[i] / (double)total);
>> +	}
>> +
> Strange:
> 
>   75     8.89 ubuntu:20.04-x-powerpc64el    : FAIL gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04)
>         inlined from 'branch_type_stat_display' at util/branch.c:152:4:
>     /usr/powerpc64le-linux-gnu/include/bits/stdio2.h:100:10: error: '%8s' directive argument is null [-Werror=format-overflow=]
>       100 |   return __fprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt,
>           |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>       101 |    __va_arg_pack ());
>           |    ~~~~~~~~~~~~~~~~~
> 

Indeed. But this new code block here looks exact same like the previous and existing one
i.e with branch_new_name() and PERF_BR_NEW_MAX. The complain is that - '%8s' directive
argument is NULL. This warning might just be a false positive [1], because of a compiler
problem on powerpc64el ? But please do let me know if something needs to be changed here
to avoid this warning.

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90036

- Anshuman
Re: [PATCH V7 6/8] perf/tools: Extend branch type classification
Posted by Arnaldo Carvalho de Melo 3 years, 7 months ago
Em Thu, Sep 01, 2022 at 10:37:24AM +0530, Anshuman Khandual escreveu:
> 
> 
> On 8/31/22 02:41, Arnaldo Carvalho de Melo wrote:
> > Em Wed, Aug 24, 2022 at 10:18:20AM +0530, Anshuman Khandual escreveu:
> >> This updates the perf tool with generic branch type classification with new
> >> ABI extender place holder i.e PERF_BR_EXTEND_ABI, the new 4 bit branch type
> >> field i.e perf_branch_entry.new_type, new generic page fault related branch
> >> types and some arch specific branch types as added earlier in the kernel.
> >>
> >> Cc: Peter Zijlstra <peterz@infradead.org>
> >> Cc: Ingo Molnar <mingo@redhat.com>
> >> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> >> Cc: Mark Rutland <mark.rutland@arm.com>
> >> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> >> Cc: Jiri Olsa <jolsa@redhat.com>
> >> Cc: Namhyung Kim <namhyung@kernel.org>
> >> Cc: Thomas Gleixner <tglx@linutronix.de>
> >> Cc: Will Deacon <will@kernel.org>
> >> Cc: linux-arm-kernel@lists.infradead.org
> >> Cc: linux-perf-users@vger.kernel.org
> >> Cc: linux-kernel@vger.kernel.org
> >> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> >> ---
> >>  tools/include/uapi/linux/perf_event.h | 16 ++++++++-
> >>  tools/perf/builtin-script.c           |  2 +-
> >>  tools/perf/util/branch.c              | 52 ++++++++++++++++++++++++++-
> >>  tools/perf/util/branch.h              |  6 +++-
> >>  tools/perf/util/session.c             |  2 +-
> >>  5 files changed, 73 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
> >> index 146c137ff0c1..0f7c7ce29899 100644
> >> --- a/tools/include/uapi/linux/perf_event.h
> >> +++ b/tools/include/uapi/linux/perf_event.h
> >> @@ -255,9 +255,22 @@ enum {
> >>  	PERF_BR_IRQ		= 12,	/* irq */
> >>  	PERF_BR_SERROR		= 13,	/* system error */
> >>  	PERF_BR_NO_TX		= 14,	/* not in transaction */
> >> +	PERF_BR_EXTEND_ABI	= 15,	/* extend ABI */
> >>  	PERF_BR_MAX,
> >>  };
> >>  
> >> +enum {
> >> +	PERF_BR_NEW_FAULT_ALGN		= 0,    /* Alignment fault */
> >> +	PERF_BR_NEW_FAULT_DATA		= 1,    /* Data fault */
> >> +	PERF_BR_NEW_FAULT_INST		= 2,    /* Inst fault */
> >> +	PERF_BR_NEW_ARCH_1		= 3,    /* Architecture specific */
> >> +	PERF_BR_NEW_ARCH_2		= 4,    /* Architecture specific */
> >> +	PERF_BR_NEW_ARCH_3		= 5,    /* Architecture specific */
> >> +	PERF_BR_NEW_ARCH_4		= 6,    /* Architecture specific */
> >> +	PERF_BR_NEW_ARCH_5		= 7,    /* Architecture specific */
> >> +	PERF_BR_NEW_MAX,
> >> +};
> >> +
> >>  #define PERF_SAMPLE_BRANCH_PLM_ALL \
> >>  	(PERF_SAMPLE_BRANCH_USER|\
> >>  	 PERF_SAMPLE_BRANCH_KERNEL|\
> >> @@ -1375,7 +1388,8 @@ struct perf_branch_entry {
> >>  		abort:1,    /* transaction abort */
> >>  		cycles:16,  /* cycle count to last branch */
> >>  		type:4,     /* branch type */
> >> -		reserved:40;
> >> +		new_type:4, /* additional branch type */
> >> +		reserved:36;
> >>  };
> >>  
> >>  union perf_sample_weight {
> >> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> >> index 13580a9c50b8..585171479876 100644
> >> --- a/tools/perf/builtin-script.c
> >> +++ b/tools/perf/builtin-script.c
> >> @@ -877,7 +877,7 @@ static int print_bstack_flags(FILE *fp, struct branch_entry *br)
> >>  		       br->flags.in_tx ? 'X' : '-',
> >>  		       br->flags.abort ? 'A' : '-',
> >>  		       br->flags.cycles,
> >> -		       br->flags.type ? branch_type_name(br->flags.type) : "-");
> >> +		       get_branch_type(br));
> >>  }
> >>  
> >>  static int perf_sample__fprintf_brstack(struct perf_sample *sample,
> >> diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c
> >> index abc673347bee..6d962b0a4532 100644
> >> --- a/tools/perf/util/branch.c
> >> +++ b/tools/perf/util/branch.c
> >> @@ -21,7 +21,10 @@ void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags,
> >>  	if (flags->type == PERF_BR_UNKNOWN || from == 0)
> >>  		return;
> >>  
> >> -	st->counts[flags->type]++;
> >> +	if (flags->type == PERF_BR_EXTEND_ABI)
> >> +		st->new_counts[flags->new_type]++;
> >> +	else
> >> +		st->counts[flags->type]++;
> >>  
> >>  	if (flags->type == PERF_BR_COND) {
> >>  		if (to > from)
> >> @@ -36,6 +39,25 @@ void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags,
> >>  		st->cross_4k++;
> >>  }
> >>  
> >> +const char *branch_new_type_name(int new_type)
> >> +{
> >> +	const char *branch_new_names[PERF_BR_NEW_MAX] = {
> >> +		"FAULT_ALGN",
> >> +		"FAULT_DATA",
> >> +		"FAULT_INST",
> >> +		"ARCH_1",
> >> +		"ARCH_2",
> >> +		"ARCH_3",
> >> +		"ARCH_4",
> >> +		"ARCH_5"
> >> +	};
> >> +
> >> +	if (new_type >= 0 && new_type < PERF_BR_NEW_MAX)
> >> +		return branch_new_names[new_type];
> >> +
> >> +	return NULL;
> >> +}
> >> +
> >>  const char *branch_type_name(int type)
> >>  {
> >>  	const char *branch_names[PERF_BR_MAX] = {
> >> @@ -62,6 +84,17 @@ const char *branch_type_name(int type)
> >>  	return NULL;
> >>  }
> >>  
> >> +const char *get_branch_type(struct branch_entry *e)
> >> +{
> >> +	if (e->flags.type == PERF_BR_UNKNOWN)
> >> +		return "";
> >> +
> >> +	if (e->flags.type == PERF_BR_EXTEND_ABI)
> >> +		return branch_new_type_name(e->flags.new_type);
> >> +
> >> +	return branch_type_name(e->flags.type);
> >> +}
> >> +
> >>  void branch_type_stat_display(FILE *fp, struct branch_type_stat *st)
> >>  {
> >>  	u64 total = 0;
> >> @@ -108,6 +141,15 @@ void branch_type_stat_display(FILE *fp, struct branch_type_stat *st)
> >>  				100.0 *
> >>  				(double)st->counts[i] / (double)total);
> >>  	}
> >> +
> >> +	for (i = 0; i < PERF_BR_NEW_MAX; i++) {
> >> +		if (st->new_counts[i] > 0)
> >> +			fprintf(fp, "\n%8s: %5.1f%%",
> >> +				branch_new_type_name(i),
> >> +				100.0 *
> >> +				(double)st->new_counts[i] / (double)total);
> >> +	}
> >> +
> > Strange:
> > 
> >   75     8.89 ubuntu:20.04-x-powerpc64el    : FAIL gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04)
> >         inlined from 'branch_type_stat_display' at util/branch.c:152:4:
> >     /usr/powerpc64le-linux-gnu/include/bits/stdio2.h:100:10: error: '%8s' directive argument is null [-Werror=format-overflow=]
> >       100 |   return __fprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt,
> >           |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >       101 |    __va_arg_pack ());
> >           |    ~~~~~~~~~~~~~~~~~
> > 
> 
> Indeed. But this new code block here looks exact same like the previous and existing one
> i.e with branch_new_name() and PERF_BR_NEW_MAX. The complain is that - '%8s' directive
> argument is NULL. This warning might just be a false positive [1], because of a compiler
> problem on powerpc64el ? But please do let me know if something needs to be changed here
> to avoid this warning.
> 
> [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90036
> 

So, I tried not returning NULL in the functions that are ultimately
called, but that didn't help, so I'll try just disabling that specific
warning for this specific file.

The patch that didn't help is below.

- Arnaldo

commit 07c96060c410db6d10dbbdffb22bb46afebfe2c0
Author: Arnaldo Carvalho de Melo <acme@redhat.com>
Date:   Wed Aug 31 13:26:22 2022 -0300

    perf branch: Don't return NULL on function that is used in a %s printf format
    
    To address this warning:
    
      In file included from /usr/include/stdio.h:866,
                       from /home/sfr/next/next/tools/perf/util/branch.h:9,
                       from util/branch.c:2:
      In function 'fprintf',
          inlined from 'branch_type_stat_display' at util/branch.c:152:4:
      /usr/include/powerpc64le-linux-gnu/bits/stdio2.h:105:10: error: '%8s' directive argument is null [-Werror=format-overflow=]
        105 |   return __fprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt,
            |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        106 |                         __va_arg_pack ());
            |                         ~~~~~~~~~~~~~~~~~
      cc1: all warnings being treated as errors
    
    Fixes: 9781e500dcb87eeb ("perf branch: Extend branch type classification")
    Cc: Anshuman Khandual <anshuman.khandual@arm.com>
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c
index d40776c44b060b7e..f30366999f01e5e7 100644
--- a/tools/perf/util/branch.c
+++ b/tools/perf/util/branch.c
@@ -68,7 +68,7 @@ const char *branch_new_type_name(int new_type)
 	if (new_type >= 0 && new_type < PERF_BR_NEW_MAX)
 		return branch_new_names[new_type];
 
-	return NULL;
+	return "<<INVALID>>";
 }
 
 const char *branch_type_name(int type)
@@ -94,7 +94,7 @@ const char *branch_type_name(int type)
 	if (type >= 0 && type < PERF_BR_MAX)
 		return branch_names[type];
 
-	return NULL;
+	return "<<INVALID>>";
 }
 
 const char *get_branch_type(struct branch_entry *e)
Re: [PATCH V7 6/8] perf/tools: Extend branch type classification
Posted by Arnaldo Carvalho de Melo 3 years, 7 months ago
Em Fri, Sep 02, 2022 at 02:31:34PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Thu, Sep 01, 2022 at 10:37:24AM +0530, Anshuman Khandual escreveu:
> > On 8/31/22 02:41, Arnaldo Carvalho de Melo wrote:
> > > Strange:
> > > 
> > >   75     8.89 ubuntu:20.04-x-powerpc64el    : FAIL gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04)
> > >         inlined from 'branch_type_stat_display' at util/branch.c:152:4:
> > >     /usr/powerpc64le-linux-gnu/include/bits/stdio2.h:100:10: error: '%8s' directive argument is null [-Werror=format-overflow=]
> > >       100 |   return __fprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt,
> > >           |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > >       101 |    __va_arg_pack ());
> > >           |    ~~~~~~~~~~~~~~~~~
> > > 
> > 
> > Indeed. But this new code block here looks exact same like the previous and existing one
> > i.e with branch_new_name() and PERF_BR_NEW_MAX. The complain is that - '%8s' directive
> > argument is NULL. This warning might just be a false positive [1], because of a compiler
> > problem on powerpc64el ? But please do let me know if something needs to be changed here
> > to avoid this warning.
> > 
> > [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90036
> > 
> 
> So, I tried not returning NULL in the functions that are ultimately
> called, but that didn't help, so I'll try just disabling that specific
> warning for this specific file.

Got it building:

    23.68 ubuntu:20.04-x-powerpc64el    : Ok   powerpc64le-linux-gnu-gcc (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0
BUILD_TARBALL_HEAD=b0f700972d9d0c9b8e73f69ccf0e56d74c580d71

With:

From b0f700972d9d0c9b8e73f69ccf0e56d74c580d71 Mon Sep 17 00:00:00 2001
From: Arnaldo Carvalho de Melo <acme@redhat.com>
Date: Fri, 2 Sep 2022 14:35:26 -0300
Subject: [PATCH 1/1] perf build: Avoid false positive with
 -Werror=format-overflow= with gcc 10.3.0 on powerpc

When building with gcc 10.3.0 on powerpc this is happening:

   75     8.89 ubuntu:20.04-x-powerpc64el    : FAIL gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04)
         inlined from 'branch_type_stat_display' at util/branch.c:152:4:
     /usr/powerpc64le-linux-gnu/include/bits/stdio2.h:100:10: error: '%8s' directive argument is null [-Werror=format-overflow=]
       100 |   return __fprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt,
           |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       101 |    __va_arg_pack ());
           |    ~~~~~~~~~~~~~~~~~

Looks related to:

  [10/11/12/13 Regression] false positive: directive argument is null [-Werror=format-overflow=]
  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90036

So lets disable this just for the util/branch.o file.

Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.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: Robin Murphy <robin.murphy@arm.com>
Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will@kernel.org>
Link: http://lore.kernel.org/lkml/YxI99uLvpgAZjm2r@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/Build | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 8fd6dc8de5210336..20a5524e88a04d44 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -223,6 +223,10 @@ CFLAGS_llvm-utils.o += -DPERF_INCLUDE_DIR="BUILD_STR($(perf_include_dir_SQ))"
 # avoid compiler warnings in 32-bit mode
 CFLAGS_genelf_debug.o  += -Wno-packed
 
+# avoid false positive when building with gcc 10.3.0 on powerpc
+# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90036
+CFLAGS_branch.o += -Wno-format-overflow
+
 $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-flex.h: util/parse-events.l $(OUTPUT)util/parse-events-bison.c
 	$(call rule_mkdir)
 	$(Q)$(call echo-cmd,flex)$(FLEX) -o $(OUTPUT)util/parse-events-flex.c \
-- 
2.37.2
Re: [PATCH V7 6/8] perf/tools: Extend branch type classification
Posted by Anshuman Khandual 3 years, 7 months ago

On 9/2/22 23:16, Arnaldo Carvalho de Melo wrote:
> Em Fri, Sep 02, 2022 at 02:31:34PM -0300, Arnaldo Carvalho de Melo escreveu:
>> Em Thu, Sep 01, 2022 at 10:37:24AM +0530, Anshuman Khandual escreveu:
>>> On 8/31/22 02:41, Arnaldo Carvalho de Melo wrote:
>>>> Strange:
>>>>
>>>>   75     8.89 ubuntu:20.04-x-powerpc64el    : FAIL gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04)
>>>>         inlined from 'branch_type_stat_display' at util/branch.c:152:4:
>>>>     /usr/powerpc64le-linux-gnu/include/bits/stdio2.h:100:10: error: '%8s' directive argument is null [-Werror=format-overflow=]
>>>>       100 |   return __fprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt,
>>>>           |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>       101 |    __va_arg_pack ());
>>>>           |    ~~~~~~~~~~~~~~~~~
>>>>
>>>
>>> Indeed. But this new code block here looks exact same like the previous and existing one
>>> i.e with branch_new_name() and PERF_BR_NEW_MAX. The complain is that - '%8s' directive
>>> argument is NULL. This warning might just be a false positive [1], because of a compiler
>>> problem on powerpc64el ? But please do let me know if something needs to be changed here
>>> to avoid this warning.
>>>
>>> [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90036
>>>
>>
>> So, I tried not returning NULL in the functions that are ultimately
>> called, but that didn't help, so I'll try just disabling that specific
>> warning for this specific file.
> 
> Got it building:

Thanks Arnaldo, I guess all the tool changes in this series, along with this
build will land in linux-next later for more test coverage.

> 
>     23.68 ubuntu:20.04-x-powerpc64el    : Ok   powerpc64le-linux-gnu-gcc (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0
> BUILD_TARBALL_HEAD=b0f700972d9d0c9b8e73f69ccf0e56d74c580d71
> 
> With:
> 
>>From b0f700972d9d0c9b8e73f69ccf0e56d74c580d71 Mon Sep 17 00:00:00 2001
> From: Arnaldo Carvalho de Melo <acme@redhat.com>
> Date: Fri, 2 Sep 2022 14:35:26 -0300
> Subject: [PATCH 1/1] perf build: Avoid false positive with
>  -Werror=format-overflow= with gcc 10.3.0 on powerpc
> 
> When building with gcc 10.3.0 on powerpc this is happening:
> 
>    75     8.89 ubuntu:20.04-x-powerpc64el    : FAIL gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04)
>          inlined from 'branch_type_stat_display' at util/branch.c:152:4:
>      /usr/powerpc64le-linux-gnu/include/bits/stdio2.h:100:10: error: '%8s' directive argument is null [-Werror=format-overflow=]
>        100 |   return __fprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt,
>            |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>        101 |    __va_arg_pack ());
>            |    ~~~~~~~~~~~~~~~~~
> 
> Looks related to:
> 
>   [10/11/12/13 Regression] false positive: directive argument is null [-Werror=format-overflow=]
>   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90036
> 
> So lets disable this just for the util/branch.o file.
> 
> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> Cc: Anshuman Khandual <anshuman.khandual@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: James Clark <james.clark@arm.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: Robin Murphy <robin.murphy@arm.com>
> Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Will Deacon <will@kernel.org>
> Link: http://lore.kernel.org/lkml/YxI99uLvpgAZjm2r@kernel.org
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> ---
>  tools/perf/util/Build | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> index 8fd6dc8de5210336..20a5524e88a04d44 100644
> --- a/tools/perf/util/Build
> +++ b/tools/perf/util/Build
> @@ -223,6 +223,10 @@ CFLAGS_llvm-utils.o += -DPERF_INCLUDE_DIR="BUILD_STR($(perf_include_dir_SQ))"
>  # avoid compiler warnings in 32-bit mode
>  CFLAGS_genelf_debug.o  += -Wno-packed
>  
> +# avoid false positive when building with gcc 10.3.0 on powerpc
> +# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90036
> +CFLAGS_branch.o += -Wno-format-overflow
> +
>  $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-flex.h: util/parse-events.l $(OUTPUT)util/parse-events-bison.c
>  	$(call rule_mkdir)
>  	$(Q)$(call echo-cmd,flex)$(FLEX) -o $(OUTPUT)util/parse-events-flex.c \