[PATCH] perf callchain: Remove unused callchain_branch_counts

linux@treblig.org posted 1 patch 1 month, 3 weeks ago
tools/perf/util/callchain.c | 71 -------------------------------------
tools/perf/util/callchain.h |  4 ---
2 files changed, 75 deletions(-)
[PATCH] perf callchain: Remove unused callchain_branch_counts
Posted by linux@treblig.org 1 month, 3 weeks ago
From: "Dr. David Alan Gilbert" <linux@treblig.org>

callchain_branch_counts() was added in 2016 by commit
3dd029ef9401 ("perf report: Calculate and return the branch flag counting")
but unused.

Remove it and it's helpers.

Signed-off-by: Dr. David Alan Gilbert <linux@treblig.org>
---
 tools/perf/util/callchain.c | 71 -------------------------------------
 tools/perf/util/callchain.h |  4 ---
 2 files changed, 75 deletions(-)

diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 0c7564747a14..11435b72afbe 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -1266,77 +1266,6 @@ int callchain_node__fprintf_value(struct callchain_node *node,
 	return 0;
 }
 
-static void callchain_counts_value(struct callchain_node *node,
-				   u64 *branch_count, u64 *predicted_count,
-				   u64 *abort_count, u64 *cycles_count)
-{
-	struct callchain_list *clist;
-
-	list_for_each_entry(clist, &node->val, list) {
-		if (branch_count)
-			*branch_count += clist->branch_count;
-
-		if (predicted_count)
-			*predicted_count += clist->predicted_count;
-
-		if (abort_count)
-			*abort_count += clist->abort_count;
-
-		if (cycles_count)
-			*cycles_count += clist->cycles_count;
-	}
-}
-
-static int callchain_node_branch_counts_cumul(struct callchain_node *node,
-					      u64 *branch_count,
-					      u64 *predicted_count,
-					      u64 *abort_count,
-					      u64 *cycles_count)
-{
-	struct callchain_node *child;
-	struct rb_node *n;
-
-	n = rb_first(&node->rb_root_in);
-	while (n) {
-		child = rb_entry(n, struct callchain_node, rb_node_in);
-		n = rb_next(n);
-
-		callchain_node_branch_counts_cumul(child, branch_count,
-						   predicted_count,
-						   abort_count,
-						   cycles_count);
-
-		callchain_counts_value(child, branch_count,
-				       predicted_count, abort_count,
-				       cycles_count);
-	}
-
-	return 0;
-}
-
-int callchain_branch_counts(struct callchain_root *root,
-			    u64 *branch_count, u64 *predicted_count,
-			    u64 *abort_count, u64 *cycles_count)
-{
-	if (branch_count)
-		*branch_count = 0;
-
-	if (predicted_count)
-		*predicted_count = 0;
-
-	if (abort_count)
-		*abort_count = 0;
-
-	if (cycles_count)
-		*cycles_count = 0;
-
-	return callchain_node_branch_counts_cumul(&root->node,
-						  branch_count,
-						  predicted_count,
-						  abort_count,
-						  cycles_count);
-}
-
 static int count_pri64_printf(int idx, const char *str, u64 value, char *bf, int bfsize)
 {
 	return scnprintf(bf, bfsize, "%s%s:%" PRId64 "", (idx) ? " " : " (", str, value);
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 86ed9e4d04f9..d7741fa9e9de 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -298,10 +298,6 @@ void free_callchain(struct callchain_root *root);
 void decay_callchain(struct callchain_root *root);
 int callchain_node__make_parent_list(struct callchain_node *node);
 
-int callchain_branch_counts(struct callchain_root *root,
-			    u64 *branch_count, u64 *predicted_count,
-			    u64 *abort_count, u64 *cycles_count);
-
 void callchain_param_setup(u64 sample_type, const char *arch);
 
 bool callchain_cnode_matched(struct callchain_node *base_cnode,
-- 
2.46.2
Re: [PATCH] perf callchain: Remove unused callchain_branch_counts
Posted by Namhyung Kim 1 month, 2 weeks ago
On Sun, Oct 06, 2024 at 02:22:04AM +0100, linux@treblig.org wrote:
> From: "Dr. David Alan Gilbert" <linux@treblig.org>
> 
> callchain_branch_counts() was added in 2016 by commit
> 3dd029ef9401 ("perf report: Calculate and return the branch flag counting")
> but unused.
> 
> Remove it and it's helpers.

Kan, are you ok with this?

Thanks,
Namhyung

> 
> Signed-off-by: Dr. David Alan Gilbert <linux@treblig.org>
> ---
>  tools/perf/util/callchain.c | 71 -------------------------------------
>  tools/perf/util/callchain.h |  4 ---
>  2 files changed, 75 deletions(-)
> 
> diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
> index 0c7564747a14..11435b72afbe 100644
> --- a/tools/perf/util/callchain.c
> +++ b/tools/perf/util/callchain.c
> @@ -1266,77 +1266,6 @@ int callchain_node__fprintf_value(struct callchain_node *node,
>  	return 0;
>  }
>  
> -static void callchain_counts_value(struct callchain_node *node,
> -				   u64 *branch_count, u64 *predicted_count,
> -				   u64 *abort_count, u64 *cycles_count)
> -{
> -	struct callchain_list *clist;
> -
> -	list_for_each_entry(clist, &node->val, list) {
> -		if (branch_count)
> -			*branch_count += clist->branch_count;
> -
> -		if (predicted_count)
> -			*predicted_count += clist->predicted_count;
> -
> -		if (abort_count)
> -			*abort_count += clist->abort_count;
> -
> -		if (cycles_count)
> -			*cycles_count += clist->cycles_count;
> -	}
> -}
> -
> -static int callchain_node_branch_counts_cumul(struct callchain_node *node,
> -					      u64 *branch_count,
> -					      u64 *predicted_count,
> -					      u64 *abort_count,
> -					      u64 *cycles_count)
> -{
> -	struct callchain_node *child;
> -	struct rb_node *n;
> -
> -	n = rb_first(&node->rb_root_in);
> -	while (n) {
> -		child = rb_entry(n, struct callchain_node, rb_node_in);
> -		n = rb_next(n);
> -
> -		callchain_node_branch_counts_cumul(child, branch_count,
> -						   predicted_count,
> -						   abort_count,
> -						   cycles_count);
> -
> -		callchain_counts_value(child, branch_count,
> -				       predicted_count, abort_count,
> -				       cycles_count);
> -	}
> -
> -	return 0;
> -}
> -
> -int callchain_branch_counts(struct callchain_root *root,
> -			    u64 *branch_count, u64 *predicted_count,
> -			    u64 *abort_count, u64 *cycles_count)
> -{
> -	if (branch_count)
> -		*branch_count = 0;
> -
> -	if (predicted_count)
> -		*predicted_count = 0;
> -
> -	if (abort_count)
> -		*abort_count = 0;
> -
> -	if (cycles_count)
> -		*cycles_count = 0;
> -
> -	return callchain_node_branch_counts_cumul(&root->node,
> -						  branch_count,
> -						  predicted_count,
> -						  abort_count,
> -						  cycles_count);
> -}
> -
>  static int count_pri64_printf(int idx, const char *str, u64 value, char *bf, int bfsize)
>  {
>  	return scnprintf(bf, bfsize, "%s%s:%" PRId64 "", (idx) ? " " : " (", str, value);
> diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
> index 86ed9e4d04f9..d7741fa9e9de 100644
> --- a/tools/perf/util/callchain.h
> +++ b/tools/perf/util/callchain.h
> @@ -298,10 +298,6 @@ void free_callchain(struct callchain_root *root);
>  void decay_callchain(struct callchain_root *root);
>  int callchain_node__make_parent_list(struct callchain_node *node);
>  
> -int callchain_branch_counts(struct callchain_root *root,
> -			    u64 *branch_count, u64 *predicted_count,
> -			    u64 *abort_count, u64 *cycles_count);
> -
>  void callchain_param_setup(u64 sample_type, const char *arch);
>  
>  bool callchain_cnode_matched(struct callchain_node *base_cnode,
> -- 
> 2.46.2
>
Re: [PATCH] perf callchain: Remove unused callchain_branch_counts
Posted by Liang, Kan 1 month, 2 weeks ago

On 2024-10-09 1:30 a.m., Namhyung Kim wrote:
> On Sun, Oct 06, 2024 at 02:22:04AM +0100, linux@treblig.org wrote:
>> From: "Dr. David Alan Gilbert" <linux@treblig.org>
>>
>> callchain_branch_counts() was added in 2016 by commit
>> 3dd029ef9401 ("perf report: Calculate and return the branch flag counting")
>> but unused.

It seems the original patchset was not well organized. This function is
actually used by the last patch of the series.
https://lore.kernel.org/lkml/1477876794-30749-7-git-send-email-yao.jin@linux.intel.com/

But for some reason, the last patch was not merged. I think Andi gave
the Acked-by for the whole series. It might be just accidentally missed.

I think the missed feature is still useful.
We will redo the test and re-post it.

Thanks,
Kan

>>
>> Remove it and it's helpers.
> 
> Kan, are you ok with this?
> 
> Thanks,
> Namhyung
> 
>>
>> Signed-off-by: Dr. David Alan Gilbert <linux@treblig.org>
>> ---
>>  tools/perf/util/callchain.c | 71 -------------------------------------
>>  tools/perf/util/callchain.h |  4 ---
>>  2 files changed, 75 deletions(-)
>>
>> diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
>> index 0c7564747a14..11435b72afbe 100644
>> --- a/tools/perf/util/callchain.c
>> +++ b/tools/perf/util/callchain.c
>> @@ -1266,77 +1266,6 @@ int callchain_node__fprintf_value(struct callchain_node *node,
>>  	return 0;
>>  }
>>  
>> -static void callchain_counts_value(struct callchain_node *node,
>> -				   u64 *branch_count, u64 *predicted_count,
>> -				   u64 *abort_count, u64 *cycles_count)
>> -{
>> -	struct callchain_list *clist;
>> -
>> -	list_for_each_entry(clist, &node->val, list) {
>> -		if (branch_count)
>> -			*branch_count += clist->branch_count;
>> -
>> -		if (predicted_count)
>> -			*predicted_count += clist->predicted_count;
>> -
>> -		if (abort_count)
>> -			*abort_count += clist->abort_count;
>> -
>> -		if (cycles_count)
>> -			*cycles_count += clist->cycles_count;
>> -	}
>> -}
>> -
>> -static int callchain_node_branch_counts_cumul(struct callchain_node *node,
>> -					      u64 *branch_count,
>> -					      u64 *predicted_count,
>> -					      u64 *abort_count,
>> -					      u64 *cycles_count)
>> -{
>> -	struct callchain_node *child;
>> -	struct rb_node *n;
>> -
>> -	n = rb_first(&node->rb_root_in);
>> -	while (n) {
>> -		child = rb_entry(n, struct callchain_node, rb_node_in);
>> -		n = rb_next(n);
>> -
>> -		callchain_node_branch_counts_cumul(child, branch_count,
>> -						   predicted_count,
>> -						   abort_count,
>> -						   cycles_count);
>> -
>> -		callchain_counts_value(child, branch_count,
>> -				       predicted_count, abort_count,
>> -				       cycles_count);
>> -	}
>> -
>> -	return 0;
>> -}
>> -
>> -int callchain_branch_counts(struct callchain_root *root,
>> -			    u64 *branch_count, u64 *predicted_count,
>> -			    u64 *abort_count, u64 *cycles_count)
>> -{
>> -	if (branch_count)
>> -		*branch_count = 0;
>> -
>> -	if (predicted_count)
>> -		*predicted_count = 0;
>> -
>> -	if (abort_count)
>> -		*abort_count = 0;
>> -
>> -	if (cycles_count)
>> -		*cycles_count = 0;
>> -
>> -	return callchain_node_branch_counts_cumul(&root->node,
>> -						  branch_count,
>> -						  predicted_count,
>> -						  abort_count,
>> -						  cycles_count);
>> -}
>> -
>>  static int count_pri64_printf(int idx, const char *str, u64 value, char *bf, int bfsize)
>>  {
>>  	return scnprintf(bf, bfsize, "%s%s:%" PRId64 "", (idx) ? " " : " (", str, value);
>> diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
>> index 86ed9e4d04f9..d7741fa9e9de 100644
>> --- a/tools/perf/util/callchain.h
>> +++ b/tools/perf/util/callchain.h
>> @@ -298,10 +298,6 @@ void free_callchain(struct callchain_root *root);
>>  void decay_callchain(struct callchain_root *root);
>>  int callchain_node__make_parent_list(struct callchain_node *node);
>>  
>> -int callchain_branch_counts(struct callchain_root *root,
>> -			    u64 *branch_count, u64 *predicted_count,
>> -			    u64 *abort_count, u64 *cycles_count);
>> -
>>  void callchain_param_setup(u64 sample_type, const char *arch);
>>  
>>  bool callchain_cnode_matched(struct callchain_node *base_cnode,
>> -- 
>> 2.46.2
>>
>
Re: [PATCH] perf callchain: Remove unused callchain_branch_counts
Posted by Namhyung Kim 1 month, 2 weeks ago
On Wed, Oct 09, 2024 at 11:27:16AM -0400, Liang, Kan wrote:
> 
> 
> On 2024-10-09 1:30 a.m., Namhyung Kim wrote:
> > On Sun, Oct 06, 2024 at 02:22:04AM +0100, linux@treblig.org wrote:
> >> From: "Dr. David Alan Gilbert" <linux@treblig.org>
> >>
> >> callchain_branch_counts() was added in 2016 by commit
> >> 3dd029ef9401 ("perf report: Calculate and return the branch flag counting")
> >> but unused.
> 
> It seems the original patchset was not well organized. This function is
> actually used by the last patch of the series.
> https://lore.kernel.org/lkml/1477876794-30749-7-git-send-email-yao.jin@linux.intel.com/
> 
> But for some reason, the last patch was not merged. I think Andi gave
> the Acked-by for the whole series. It might be just accidentally missed.
> 
> I think the missed feature is still useful.
> We will redo the test and re-post it.
 
Great, thanks for taking care of this.
Namhyung
[PATCH] perf report: Display columns Predicted/Abort/Cycles in --branch-history
Posted by Thomas Falcon 1 month, 2 weeks ago
The original commit message:

"
Use current sort mechanism but the real .se_cmp() just returns 0 so
that new columns "Predicted", "Abort" and "Cycles" are created in display
but actually these keys are not the sort keys.

For example:

Overhead  Source:Line   Symbol    Shared Object  Predicted  Abort  Cycles
........  ............  ........  .............  .........  .....  ......

  38.25%  div.c:45      [.] main  div            97.6%      0      3
"

Update missed commit from series "perf report: Show branch flags/cycles
in --branch-history callgraph view" to apply to current repository so that
new columns described above are visible.

Link to original series:
https://lore.kernel.org/lkml/1477876794-30749-1-git-send-email-yao.jin@linux.intel.com/

Reported-by: Dr. David Alan Gilbert <linux@treblig.org>
Suggested-by: Kan Liang <kan.liang@linux.intel.com>
Co-developed-by: Jin Yao <yao.jin@linux.intel.com>
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Tested-by: Thomas Falcon <thomas.falcon@intel.com>
Signed-off-by: Thomas Falcon <thomas.falcon@intel.com>
---
 tools/perf/Documentation/perf-report.txt |   8 ++
 tools/perf/builtin-report.c              |   6 +-
 tools/perf/util/hist.c                   |   3 +
 tools/perf/util/hist.h                   |   3 +
 tools/perf/util/sort.c                   | 113 ++++++++++++++++++++++-
 tools/perf/util/sort.h                   |   3 +
 6 files changed, 134 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 7c66d81ab978..87f864519406 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -391,6 +391,14 @@ OPTIONS
 	This allows to examine the path the program took to each sample.
 	The data collection must have used -b (or -j) and -g.
 
+	Also show with some branch flags that can be:
+	- Predicted: display the average percentage of predicated branches.
+		     (predicated number / total number)
+	- Abort: display the number of tsx aborted branches.
+	- Cycles: cycles in basic block.
+
+	- iterations: display the average number of iterations in callchain list.
+
 --addr2line=<path>::
         Path to addr2line binary.
 
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 5dc17ffee27a..36b344e39dd6 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -1271,6 +1271,10 @@ static int process_attr(const struct perf_tool *tool __maybe_unused,
 	return 0;
 }
 
+#define CALLCHAIN_BRANCH_SORT_ORDER	\
+	"srcline,symbol,dso,callchain_branch_predicted," \
+	"callchain_branch_abort,callchain_branch_cycles"
+
 int cmd_report(int argc, const char **argv)
 {
 	struct perf_session *session;
@@ -1639,7 +1643,7 @@ int cmd_report(int argc, const char **argv)
 		symbol_conf.use_callchain = true;
 		callchain_register_param(&callchain_param);
 		if (sort_order == NULL)
-			sort_order = "srcline,symbol,dso";
+			sort_order = CALLCHAIN_BRANCH_SORT_ORDER;
 	}
 
 	if (report.mem_mode) {
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index f387e85a0087..fff134565801 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -218,6 +218,9 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
 	hists__new_col_len(hists, HISTC_LOCAL_P_STAGE_CYC, 13);
 	hists__new_col_len(hists, HISTC_GLOBAL_P_STAGE_CYC, 13);
 	hists__new_col_len(hists, HISTC_ADDR, BITS_PER_LONG / 4 + 2);
+	hists__new_col_len(hists, HISTC_CALLCHAIN_BRANCH_PREDICTED, 9);
+	hists__new_col_len(hists, HISTC_CALLCHAIN_BRANCH_ABORT, 5);
+	hists__new_col_len(hists, HISTC_CALLCHAIN_BRANCH_CYCLES, 6);
 
 	if (symbol_conf.nanosecs)
 		hists__new_col_len(hists, HISTC_TIME, 16);
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 7d7ae94b4b31..1131056924d9 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -87,6 +87,9 @@ enum hist_column {
 	HISTC_TYPE_OFFSET,
 	HISTC_SYMBOL_OFFSET,
 	HISTC_TYPE_CACHELINE,
+	HISTC_CALLCHAIN_BRANCH_PREDICTED,
+	HISTC_CALLCHAIN_BRANCH_ABORT,
+	HISTC_CALLCHAIN_BRANCH_CYCLES,
 	HISTC_NR_COLS, /* Last entry */
 };
 
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 013020f33ece..168c488f0178 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -677,6 +677,102 @@ struct sort_entry sort_sym_ipc_null = {
 	.se_width_idx	= HISTC_SYMBOL_IPC,
 };
 
+/* --sort callchain_branch_predicted */
+
+static int64_t
+sort__callchain_branch_predicted_cmp(struct hist_entry *left __maybe_unused,
+				     struct hist_entry *right __maybe_unused)
+{
+	return 0;
+}
+
+static int hist_entry__callchain_branch_predicted_snprintf(
+	struct hist_entry *he, char *bf, size_t size, unsigned int width)
+{
+	u64 branch_count, predicted_count;
+	double percent = 0.0;
+	char str[32];
+
+	callchain_branch_counts(he->callchain, &branch_count,
+				&predicted_count, NULL, NULL);
+
+	if (branch_count)
+		percent = predicted_count * 100.0 / branch_count;
+
+	snprintf(str, sizeof(str), "%.1f%%", percent);
+	return repsep_snprintf(bf, size, "%-*.*s", width, width, str);
+}
+
+struct sort_entry sort_callchain_branch_predicted = {
+	.se_header	= "Predicted",
+	.se_cmp		= sort__callchain_branch_predicted_cmp,
+	.se_snprintf	= hist_entry__callchain_branch_predicted_snprintf,
+	.se_width_idx	= HISTC_CALLCHAIN_BRANCH_PREDICTED,
+};
+
+/* --sort callchain_branch_abort */
+
+static int64_t
+sort__callchain_branch_abort_cmp(struct hist_entry *left __maybe_unused,
+				 struct hist_entry *right __maybe_unused)
+{
+	return 0;
+}
+
+static int hist_entry__callchain_branch_abort_snprintf(struct hist_entry *he,
+						       char *bf, size_t size,
+						       unsigned int width)
+{
+	u64 branch_count, abort_count;
+	char str[32];
+
+	callchain_branch_counts(he->callchain, &branch_count,
+				NULL, &abort_count, NULL);
+
+	snprintf(str, sizeof(str), "%" PRId64, abort_count);
+	return repsep_snprintf(bf, size, "%-*.*s", width, width, str);
+}
+
+struct sort_entry sort_callchain_branch_abort = {
+	.se_header	= "Abort",
+	.se_cmp		= sort__callchain_branch_abort_cmp,
+	.se_snprintf	= hist_entry__callchain_branch_abort_snprintf,
+	.se_width_idx	= HISTC_CALLCHAIN_BRANCH_ABORT,
+};
+
+/* --sort callchain_branch_cycles */
+
+static int64_t
+sort__callchain_branch_cycles_cmp(struct hist_entry *left __maybe_unused,
+				  struct hist_entry *right __maybe_unused)
+{
+	return 0;
+}
+
+static int hist_entry__callchain_branch_cycles_snprintf(struct hist_entry *he,
+							char *bf, size_t size,
+							unsigned int width)
+{
+	u64 branch_count, cycles_count, cycles = 0;
+	char str[32];
+
+	callchain_branch_counts(he->callchain, &branch_count,
+				NULL, NULL, &cycles_count);
+
+	if (branch_count)
+		cycles = cycles_count / branch_count;
+
+	snprintf(str, sizeof(str), "%" PRId64 "", cycles);
+	return repsep_snprintf(bf, size, "%-*.*s", width, width, str);
+}
+
+struct sort_entry sort_callchain_branch_cycles = {
+	.se_header	= "Cycles",
+	.se_cmp		= sort__callchain_branch_cycles_cmp,
+	.se_snprintf	= hist_entry__callchain_branch_cycles_snprintf,
+	.se_width_idx	= HISTC_CALLCHAIN_BRANCH_CYCLES,
+};
+
 /* --sort srcfile */
 
 static char no_srcfile[1];
@@ -2456,6 +2552,15 @@ static struct sort_dimension bstack_sort_dimensions[] = {
 	DIM(SORT_SYM_IPC, "ipc_lbr", sort_sym_ipc),
 	DIM(SORT_ADDR_FROM, "addr_from", sort_addr_from),
 	DIM(SORT_ADDR_TO, "addr_to", sort_addr_to),
+	DIM(SORT_CALLCHAIN_BRANCH_PREDICTED,
+		"callchain_branch_predicted",
+		sort_callchain_branch_predicted),
+	DIM(SORT_CALLCHAIN_BRANCH_ABORT,
+		"callchain_branch_abort",
+		sort_callchain_branch_abort),
+	DIM(SORT_CALLCHAIN_BRANCH_CYCLES,
+		"callchain_branch_cycles",
+		sort_callchain_branch_cycles)
 };
 
 #undef DIM
@@ -3484,7 +3589,13 @@ int sort_dimension__add(struct perf_hpp_list *list, const char *tok,
 		if (!sd->name || strncasecmp(tok, sd->name, strlen(tok)))
 			continue;
 
-		if (sort__mode != SORT_MODE__BRANCH)
+		if ((sort__mode != SORT_MODE__BRANCH) &&
+			strncasecmp(tok, "callchain_branch_predicted",
+				    strlen(tok)) &&
+			strncasecmp(tok, "callchain_branch_abort",
+				    strlen(tok)) &&
+			strncasecmp(tok, "callchain_branch_cycles",
+				    strlen(tok)))
 			return -EINVAL;
 
 		if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to)
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 9ff68c6786e7..a8572574e168 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -88,6 +88,9 @@ enum sort_type {
 	SORT_SYM_IPC,
 	SORT_ADDR_FROM,
 	SORT_ADDR_TO,
+	SORT_CALLCHAIN_BRANCH_PREDICTED,
+	SORT_CALLCHAIN_BRANCH_ABORT,
+	SORT_CALLCHAIN_BRANCH_CYCLES,
 
 	/* memory mode specific sort keys */
 	__SORT_MEMORY_MODE,
-- 
2.47.0
Re: [PATCH] perf report: Display columns Predicted/Abort/Cycles in --branch-history
Posted by Namhyung Kim 1 month, 2 weeks ago
On Thu, 10 Oct 2024 13:40:46 -0500, Thomas Falcon wrote:
> The original commit message:
> 
> "
> Use current sort mechanism but the real .se_cmp() just returns 0 so
> that new columns "Predicted", "Abort" and "Cycles" are created in display
> but actually these keys are not the sort keys.
> 
> [...]

Applied to perf-tools-next, thanks!

Best regards,
Namhyung
Re: [PATCH] perf callchain: Remove unused callchain_branch_counts
Posted by Dr. David Alan Gilbert 1 month, 2 weeks ago
* Liang, Kan (kan.liang@linux.intel.com) wrote:
> 
> 
> On 2024-10-09 1:30 a.m., Namhyung Kim wrote:
> > On Sun, Oct 06, 2024 at 02:22:04AM +0100, linux@treblig.org wrote:
> >> From: "Dr. David Alan Gilbert" <linux@treblig.org>
> >>
> >> callchain_branch_counts() was added in 2016 by commit
> >> 3dd029ef9401 ("perf report: Calculate and return the branch flag counting")
> >> but unused.
> 
> It seems the original patchset was not well organized. This function is
> actually used by the last patch of the series.
> https://lore.kernel.org/lkml/1477876794-30749-7-git-send-email-yao.jin@linux.intel.com/
> 
> But for some reason, the last patch was not merged. I think Andi gave
> the Acked-by for the whole series. It might be just accidentally missed.

OK, that'll be the 4th time this deadcode series has found missing calls
to functions!

> I think the missed feature is still useful.
> We will redo the test and re-post it.

OK, great.

Dave

> Thanks,
> Kan
> 
> >>
> >> Remove it and it's helpers.
> > 
> > Kan, are you ok with this?
> > 
> > Thanks,
> > Namhyung
> > 
> >>
> >> Signed-off-by: Dr. David Alan Gilbert <linux@treblig.org>
> >> ---
> >>  tools/perf/util/callchain.c | 71 -------------------------------------
> >>  tools/perf/util/callchain.h |  4 ---
> >>  2 files changed, 75 deletions(-)
> >>
> >> diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
> >> index 0c7564747a14..11435b72afbe 100644
> >> --- a/tools/perf/util/callchain.c
> >> +++ b/tools/perf/util/callchain.c
> >> @@ -1266,77 +1266,6 @@ int callchain_node__fprintf_value(struct callchain_node *node,
> >>  	return 0;
> >>  }
> >>  
> >> -static void callchain_counts_value(struct callchain_node *node,
> >> -				   u64 *branch_count, u64 *predicted_count,
> >> -				   u64 *abort_count, u64 *cycles_count)
> >> -{
> >> -	struct callchain_list *clist;
> >> -
> >> -	list_for_each_entry(clist, &node->val, list) {
> >> -		if (branch_count)
> >> -			*branch_count += clist->branch_count;
> >> -
> >> -		if (predicted_count)
> >> -			*predicted_count += clist->predicted_count;
> >> -
> >> -		if (abort_count)
> >> -			*abort_count += clist->abort_count;
> >> -
> >> -		if (cycles_count)
> >> -			*cycles_count += clist->cycles_count;
> >> -	}
> >> -}
> >> -
> >> -static int callchain_node_branch_counts_cumul(struct callchain_node *node,
> >> -					      u64 *branch_count,
> >> -					      u64 *predicted_count,
> >> -					      u64 *abort_count,
> >> -					      u64 *cycles_count)
> >> -{
> >> -	struct callchain_node *child;
> >> -	struct rb_node *n;
> >> -
> >> -	n = rb_first(&node->rb_root_in);
> >> -	while (n) {
> >> -		child = rb_entry(n, struct callchain_node, rb_node_in);
> >> -		n = rb_next(n);
> >> -
> >> -		callchain_node_branch_counts_cumul(child, branch_count,
> >> -						   predicted_count,
> >> -						   abort_count,
> >> -						   cycles_count);
> >> -
> >> -		callchain_counts_value(child, branch_count,
> >> -				       predicted_count, abort_count,
> >> -				       cycles_count);
> >> -	}
> >> -
> >> -	return 0;
> >> -}
> >> -
> >> -int callchain_branch_counts(struct callchain_root *root,
> >> -			    u64 *branch_count, u64 *predicted_count,
> >> -			    u64 *abort_count, u64 *cycles_count)
> >> -{
> >> -	if (branch_count)
> >> -		*branch_count = 0;
> >> -
> >> -	if (predicted_count)
> >> -		*predicted_count = 0;
> >> -
> >> -	if (abort_count)
> >> -		*abort_count = 0;
> >> -
> >> -	if (cycles_count)
> >> -		*cycles_count = 0;
> >> -
> >> -	return callchain_node_branch_counts_cumul(&root->node,
> >> -						  branch_count,
> >> -						  predicted_count,
> >> -						  abort_count,
> >> -						  cycles_count);
> >> -}
> >> -
> >>  static int count_pri64_printf(int idx, const char *str, u64 value, char *bf, int bfsize)
> >>  {
> >>  	return scnprintf(bf, bfsize, "%s%s:%" PRId64 "", (idx) ? " " : " (", str, value);
> >> diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
> >> index 86ed9e4d04f9..d7741fa9e9de 100644
> >> --- a/tools/perf/util/callchain.h
> >> +++ b/tools/perf/util/callchain.h
> >> @@ -298,10 +298,6 @@ void free_callchain(struct callchain_root *root);
> >>  void decay_callchain(struct callchain_root *root);
> >>  int callchain_node__make_parent_list(struct callchain_node *node);
> >>  
> >> -int callchain_branch_counts(struct callchain_root *root,
> >> -			    u64 *branch_count, u64 *predicted_count,
> >> -			    u64 *abort_count, u64 *cycles_count);
> >> -
> >>  void callchain_param_setup(u64 sample_type, const char *arch);
> >>  
> >>  bool callchain_cnode_matched(struct callchain_node *base_cnode,
> >> -- 
> >> 2.46.2
> >>
> > 
> 
-- 
 -----Open up your eyes, open up your mind, open up your code -------   
/ Dr. David Alan Gilbert    |       Running GNU/Linux       | Happy  \ 
\        dave @ treblig.org |                               | In Hex /
 \ _________________________|_____ http://www.treblig.org   |_______/
Re: [PATCH] perf callchain: Remove unused callchain_branch_counts
Posted by Namhyung Kim 1 month, 2 weeks ago
On Wed, Oct 09, 2024 at 04:50:53PM +0000, Dr. David Alan Gilbert wrote:
> * Liang, Kan (kan.liang@linux.intel.com) wrote:
> > 
> > 
> > On 2024-10-09 1:30 a.m., Namhyung Kim wrote:
> > > On Sun, Oct 06, 2024 at 02:22:04AM +0100, linux@treblig.org wrote:
> > >> From: "Dr. David Alan Gilbert" <linux@treblig.org>
> > >>
> > >> callchain_branch_counts() was added in 2016 by commit
> > >> 3dd029ef9401 ("perf report: Calculate and return the branch flag counting")
> > >> but unused.
> > 
> > It seems the original patchset was not well organized. This function is
> > actually used by the last patch of the series.
> > https://lore.kernel.org/lkml/1477876794-30749-7-git-send-email-yao.jin@linux.intel.com/
> > 
> > But for some reason, the last patch was not merged. I think Andi gave
> > the Acked-by for the whole series. It might be just accidentally missed.
> 
> OK, that'll be the 4th time this deadcode series has found missing calls
> to functions!

Nice work! :)

Thanks,
Namhyung