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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.