[PATCH 06/14] perf c2c: add comparison functions for function view sorting

From: Jiebin Sun

Date: Fri Jun 26 2026 - 03:07:02 EST


Add sort comparison functions for the function view columns:

- cycles_percent_cmp(): compare by weighted HITM cycle count
- iaddr_symbol_cmp(): compare by instruction address
- total_stores_cmp(): compare by store count
- empty_cmp(): no-op comparator for display-only columns

Use overflow-safe (a > b) - (a < b) pattern for unsigned
comparisons in cycles_percent_cmp() and total_stores_cmp().

Signed-off-by: Jiebin Sun <jiebin.sun@xxxxxxxxx>
Cc: Adrian Hunter <adrian.hunter@xxxxxxxxx>
Cc: Alexander Shishkin <alexander.shishkin@xxxxxxxxxxxxxxx>
Cc: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
Cc: Dapeng Mi <dapeng1.mi@xxxxxxxxxxxxxxx>
Cc: Ian Rogers <irogers@xxxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: James Clark <james.clark@xxxxxxxxxx>
Cc: Jiri Olsa <jolsa@xxxxxxxxxx>
Cc: Mark Rutland <mark.rutland@xxxxxxx>
Cc: Namhyung Kim <namhyung@xxxxxxxxxx>
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: Thomas Falcon <thomas.falcon@xxxxxxxxx>
Reviewed-by: Tianyou Li <tianyou.li@xxxxxxxxx>
Reviewed-by: Wangyang Guo <wangyang.guo@xxxxxxxxx>
---
tools/perf/ui/browsers/c2c-function.c | 75 +++++++++++++++++++++++++++
1 file changed, 75 insertions(+)

diff --git a/tools/perf/ui/browsers/c2c-function.c b/tools/perf/ui/browsers/c2c-function.c
index 5393f603c864..172e1aa86eca 100644
--- a/tools/perf/ui/browsers/c2c-function.c
+++ b/tools/perf/ui/browsers/c2c-function.c
@@ -315,6 +315,81 @@ cycles_percent_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
return ret;
}

+/*
+ * cycles_percent_cmp - Comparison function for cycles percentage sorting
+ */
+static __maybe_unused int64_t
+cycles_percent_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
+ struct hist_entry *left, struct hist_entry *right)
+{
+ struct c2c_hist_entry *c2c_left = container_of(left, struct c2c_hist_entry, he);
+ struct c2c_hist_entry *c2c_right = container_of(right, struct c2c_hist_entry, he);
+ u64 cycles_left, cycles_right;
+
+ /* Cycles Percent is only shown for level-1 entries; others compare equal. */
+ if (left->parent_he || right->parent_he)
+ return 0;
+
+ cycles_left = c2c_hist_entry__cycles(c2c_left);
+ cycles_right = c2c_hist_entry__cycles(c2c_right);
+
+ return (cycles_left > cycles_right) - (cycles_left < cycles_right);
+}
+
+/*
+ * iaddr_symbol_cmp - Comparison function for instruction address sorting
+ */
+static __maybe_unused int64_t
+iaddr_symbol_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
+ struct hist_entry *left, struct hist_entry *right)
+{
+ u64 left_iaddr, right_iaddr;
+
+ /* IAddr is hidden for level-3 cacheline entries; they compare equal. */
+ if ((left->parent_he && left->parent_he->parent_he) ||
+ (right->parent_he && right->parent_he->parent_he))
+ return 0;
+
+ left_iaddr = hist_entry__iaddr(left);
+ right_iaddr = hist_entry__iaddr(right);
+
+ /*
+ * Descending by instruction address (same direction as sort__iaddr_cmp(),
+ * which also returns r - l): the expression is +1 when left < right.
+ * Uses hist_entry__iaddr(), which falls back to he->ip when mem_info is
+ * NULL, so it matches what iaddr_symbol_entry() displays.
+ */
+ return (left_iaddr < right_iaddr) - (left_iaddr > right_iaddr);
+}
+
+static __maybe_unused int64_t
+empty_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
+ struct hist_entry *left __maybe_unused,
+ struct hist_entry *right __maybe_unused)
+{
+ return 0;
+}
+
+/*
+ * total_stores_cmp - Comparison function for total stores sorting
+ */
+static __maybe_unused int64_t
+total_stores_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
+ struct hist_entry *left, struct hist_entry *right)
+{
+ struct c2c_hist_entry *c2c_left = container_of(left, struct c2c_hist_entry, he);
+ struct c2c_hist_entry *c2c_right = container_of(right, struct c2c_hist_entry, he);
+ u64 left_store, right_store;
+
+ /* Match total_stores_entry(): L1 sums child stores, L2/L3 use their own. */
+ left_store = left->parent_he ? (u64)c2c_left->stats.store :
+ hist_entry__child_stores(left);
+ right_store = right->parent_he ? (u64)c2c_right->stats.store :
+ hist_entry__child_stores(right);
+
+ return (left_store > right_store) - (left_store < right_store);
+}
+
int perf_c2c__browse_function_view(struct hists *hists __maybe_unused)
{
ui__warning("C2C function view is not implemented yet.\n");
--
2.52.0