From: Ian Rogers <irogers@google.com>
To: andi@firstfloor.org
Cc: acme@kernel.org, ak@kernel.org, ak@linux.intel.com,
linux-perf-users@vger.kernel.org, namhyung@kernel.org,
Ian Rogers <irogers@google.com>
Subject: [PATCH v1 3/7] perf ui browsers: Implement interactive 'M' keystroke to toggle hybrid event merging
Date: Sun, 23 Aug 2026 23:37:40 -0700 [thread overview]
Message-ID: <20260824063744.1533837-4-irogers@google.com> (raw)
In-Reply-To: <20260824063744.1533837-1-irogers@google.com>
Map the 'M' keystroke globally across the interface to toggle boolean state
dynamically rebuilding hybrid core groups independently.
This allows cleanly separating or aggregating hybrid core histograms.
Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
---
tools/perf/ui/browsers/hists.c | 48 +++++++++++++++++++++++++++++-----
tools/perf/util/evsel.c | 12 +++++++++
tools/perf/util/evsel.h | 2 ++
3 files changed, 56 insertions(+), 6 deletions(-)
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index c15874a491b4..07cb06834d0f 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -2840,10 +2840,10 @@ add_script_opt(struct hist_browser *browser,
return n;
j = sprintf(tstr, " in ");
j += timestamp__scnprintf_usec(he->time, tstr + j,
- sizeof tstr - j);
+ sizeof(tstr) - j);
j += sprintf(tstr + j, "-");
timestamp__scnprintf_usec(he->time + symbol_conf.time_quantum,
- tstr + j, sizeof tstr - j);
+ tstr + j, sizeof(tstr) - j);
ret = add_script_opt_2(time_act, time_optstr, thread, sym, tstr);
if (ret > 0) {
time_act->time = he->time;
@@ -3580,8 +3580,11 @@ static int perf_evsel_menu__run(struct evsel_menu *menu,
int delay_secs = hbt ? hbt->refresh : 0;
int key;
- if (ui_browser__show(&menu->b, title,
- "ESC: exit, ENTER|->: Browse histograms") < 0)
+ const char *help_msg = evlist__can_merge_hybrid(evlist) ?
+ "ESC: exit, ENTER|->: Browse histograms, M: Merge hybrid events" :
+ "ESC: exit, ENTER|->: Browse histograms";
+
+ if (ui_browser__show(&menu->b, title, help_msg) < 0)
return -1;
while (1) {
@@ -3636,6 +3639,16 @@ static int perf_evsel_menu__run(struct evsel_menu *menu,
goto out;
case K_ESC:
default:
+ if (key == 'M') {
+ if (evlist__can_merge_hybrid(evlist)) {
+ if (!symbol_conf.hybrid_merge)
+ evlist__merge_hybrid(evlist, true);
+ symbol_conf.hybrid_merge =
+ !symbol_conf.hybrid_merge;
+ ui_browser__hide(&menu->b);
+ return K_RELOAD;
+ }
+ }
continue;
}
case K_LEFT:
@@ -3649,6 +3662,15 @@ static int perf_evsel_menu__run(struct evsel_menu *menu,
case CTRL('c'):
goto out;
default:
+ if (key == 'M') {
+ if (evlist__can_merge_hybrid(evlist)) {
+ if (!symbol_conf.hybrid_merge)
+ evlist__merge_hybrid(evlist, true);
+ symbol_conf.hybrid_merge = !symbol_conf.hybrid_merge;
+ ui_browser__hide(&menu->b);
+ return K_RELOAD;
+ }
+ }
ui_browser__warn_unhandled_hotkey(&menu->b, key, delay_secs, NULL);
continue;
}
@@ -3675,6 +3697,8 @@ static int __evlist__tui_browse_hists(struct evlist *evlist, int nr_entries, con
bool warn_lost_event)
{
struct evsel *pos;
+ int ret;
+
struct evsel_menu menu = {
.b = {
.entries = &evlist__core(evlist)->entries,
@@ -3699,8 +3723,11 @@ static int __evlist__tui_browse_hists(struct evlist *evlist, int nr_entries, con
menu.b.width = line_len;
}
- return perf_evsel_menu__run(&menu, nr_entries, help,
+ ret = perf_evsel_menu__run(&menu, nr_entries, help,
hbt, warn_lost_event);
+
+
+ return ret;
}
static bool evlist__single_entry(struct evlist *evlist)
@@ -3720,10 +3747,14 @@ static bool evlist__single_entry(struct evlist *evlist)
return false;
}
+
int evlist__tui_browse_hists(struct evlist *evlist, const char *help, struct hist_browser_timer *hbt,
float min_pcnt, struct perf_env *env, bool warn_lost_event)
{
int nr_entries = evlist__nr_entries(evlist);
+ int ret;
+
+retry:
if (evlist__single_entry(evlist)) {
single_entry: {
@@ -3747,8 +3778,13 @@ single_entry: {
goto single_entry;
}
- return __evlist__tui_browse_hists(evlist, nr_entries, help, hbt, min_pcnt, env,
+ ret = __evlist__tui_browse_hists(evlist, nr_entries, help, hbt, min_pcnt, env,
warn_lost_event);
+ if (ret == K_RELOAD) {
+ nr_entries = evlist__nr_entries(evlist);
+ goto retry;
+ }
+ return ret;
}
static int block_hists_browser__title(struct hist_browser *browser, char *bf,
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 3f56a0e6f9d6..a4760cfb7582 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -4758,3 +4758,15 @@ void evsel__warn_user_requested_cpus(struct evsel *evsel, struct perf_cpu_map *u
perf_cpu_map__put(intersect);
perf_cpu_map__put(online);
}
+
+struct evsel *evsel__new_dummy(void)
+{
+ struct perf_event_attr attr = {
+ .type = PERF_TYPE_SOFTWARE,
+ .config = PERF_COUNT_SW_DUMMY,
+ .size = sizeof(attr),
+ .freq = 0,
+ .sample_period = 1,
+ };
+ return evsel__new(&attr);
+}
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index d9ecc6628217..6cf07120da9f 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -15,6 +15,8 @@
#include "symbol_conf.h"
+struct evsel *evsel__new_dummy(void);
+
struct bperf_follower_bpf;
struct bperf_leader_bpf;
struct bpf_counter_ops;
--
2.55.0.766.g2966f0265a-goog
next prev parent reply other threads:[~2026-08-24 6:38 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-13 13:25 [PATCH v1] perf top: Merge hybrid common events Andi Kleen
2026-08-13 13:57 ` sashiko-bot
2026-08-17 19:40 ` Ian Rogers
2026-08-18 17:29 ` Andi Kleen
2026-08-19 2:58 ` Ian Rogers
2026-08-19 3:34 ` Andi Kleen
2026-08-19 4:16 ` Ian Rogers
2026-08-19 16:11 ` Andi Kleen
2026-08-19 17:58 ` Ian Rogers
2026-08-19 18:25 ` Andi Kleen
2026-08-19 22:18 ` Ian Rogers
2026-08-24 6:37 ` [PATCH v1 0/7] perf ui: Implement hybrid event merging for heterogeneous systems Ian Rogers
2026-08-24 6:37 ` [PATCH v1 1/7] perf evlist: Implement evlist__can_merge_hybrid using first_wildcard_match Ian Rogers
2026-08-24 6:53 ` sashiko-bot
2026-08-24 22:49 ` Andi Kleen
2026-08-25 4:01 ` Ian Rogers
2026-08-24 6:37 ` [PATCH v1 2/7] perf ui hist: Add support for aggregated total_period and merging entries cleanly Ian Rogers
2026-08-24 6:53 ` sashiko-bot
2026-08-24 6:37 ` Ian Rogers [this message]
2026-08-24 6:49 ` [PATCH v1 3/7] perf ui browsers: Implement interactive 'M' keystroke to toggle hybrid event merging sashiko-bot
2026-08-24 6:37 ` [PATCH v1 4/7] perf tools: Expose opt-in --hybrid-merge Ian Rogers
2026-08-24 6:52 ` sashiko-bot
2026-08-24 22:40 ` Andi Kleen
2026-08-25 3:33 ` Ian Rogers
2026-08-25 22:19 ` Arnaldo Carvalho de Melo
2026-08-24 6:37 ` [PATCH v1 5/7] perf Documentation: Add tip for hybrid event merging Ian Rogers
2026-08-24 6:40 ` sashiko-bot
2026-08-24 6:37 ` [PATCH v1 6/7] perf ui hist: Format group headers iteratively based on proportional visual allocations Ian Rogers
2026-08-24 6:53 ` sashiko-bot
2026-08-24 6:37 ` [PATCH v1 7/7] perf test: Expand top tests for --hybrid-merge Ian Rogers
2026-08-24 6:55 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260824063744.1533837-4-irogers@google.com \
--to=irogers@google.com \
--cc=acme@kernel.org \
--cc=ak@kernel.org \
--cc=ak@linux.intel.com \
--cc=andi@firstfloor.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=namhyung@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox