diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 9b5083630a56..e4e3f1432622 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -287,7 +287,7 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report struct perf_evsel *evsel = hists_to_evsel(hists); char buf[512]; size_t size = sizeof(buf); - int socket = hists->socket_filter; + int socked_id = hists->socket_filter; if (symbol_conf.filter_relative) { nr_samples = hists->stats.nr_non_filtered_samples; @@ -329,8 +329,8 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report } else ret += fprintf(fp, "\n# Event count (approx.): %" PRIu64, nr_events); - if (socket > -1) - ret += fprintf(fp, "\n# Processor Socket: %d", socket); + if (socked_id > -1) + ret += fprintf(fp, "\n# Processor Socket: %d", socked_id); return ret + fprintf(fp, "\n#\n"); } diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 792dcf55cbe1..380e9080991e 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -1261,7 +1261,7 @@ static int hists__browser_title(struct hists *hists, int printed; const struct dso *dso = hists->dso_filter; const struct thread *thread = hists->thread_filter; - int socket = hists->socket_filter; + int socket_id = hists->socket_filter; unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE]; u64 nr_events = hists->stats.total_period; struct perf_evsel *evsel = hists_to_evsel(hists); @@ -1315,9 +1315,9 @@ static int hists__browser_title(struct hists *hists, if (dso) printed += scnprintf(bf + printed, size - printed, ", DSO: %s", dso->short_name); - if (socket > -1) + if (socket_id > -1) printed += scnprintf(bf + printed, size - printed, - ", Processor Socket: %d", socket); + ", Processor Socket: %d", socket_id); if (!is_report_browser(hbt)) { struct perf_top *top = hbt->arg; @@ -1429,6 +1429,7 @@ struct popup_action { struct thread *thread; struct dso *dso; struct map_symbol ms; + int socket; int (*fn)(struct hist_browser *browser, struct popup_action *act); }; @@ -1676,6 +1677,41 @@ add_exit_opt(struct hist_browser *browser __maybe_unused, return 1; } +static int +do_zoom_socket(struct hist_browser *browser, struct popup_action *act) +{ + if (browser->hists->socket_filter > -1) { + pstack__remove(browser->pstack, &browser->hists->socket_filter); + browser->hists->socket_filter = -1; + perf_hpp__set_elide(HISTC_SOCKET, false); + } else { + browser->hists->socket_filter = act->socket; + perf_hpp__set_elide(HISTC_SOCKET, true); + pstack__push(browser->pstack, &browser->hists->socket_filter); + } + + hists__filter_by_socket(browser->hists); + hist_browser__reset(browser); + return 0; +} + +static int +add_socket_opt(struct hist_browser *browser, struct popup_action *act, + char **optstr, int socket_id) +{ + if (socket_id < 0) + return 0; + + if (asprintf(optstr, "Zoom %s Processor Socket %d", + (browser->hists->socket_filter > -1) ? "out of" : "into", + socket_id) < 0) + return 0; + + act->socket = socket_id; + act->fn = do_zoom_socket; + return 1; +} + static void hist_browser__update_nr_entries(struct hist_browser *hb) { u64 nr_entries = 0; @@ -1729,6 +1765,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, "E Expand all callchains\n" \ "F Toggle percentage of filtered entries\n" \ "H Display column headers\n" \ + "S Zoom into current Processor Socket\n" \ /* help messages are sorted by lexical order of the hotkey */ const char report_help[] = HIST_BROWSER_HELP_COMMON @@ -1759,7 +1796,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, hist_browser__update_nr_entries(browser); } - browser->pstack = pstack__new(2); + browser->pstack = pstack__new(3); if (browser->pstack == NULL) goto out; @@ -1778,6 +1815,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, struct thread *thread = NULL; struct dso *dso = NULL; int choice = 0; + int socked_id = -1; nr_options = 0; @@ -1786,6 +1824,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, if (browser->he_selection != NULL) { thread = hist_browser__selected_thread(browser); dso = browser->selection->map ? browser->selection->map->dso : NULL; + socked_id = browser->he_selection->socket; } switch (key) { case K_TAB: @@ -1828,6 +1867,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, actions->thread = thread; do_zoom_thread(browser, actions); continue; + case 'S': + actions->socket = socked_id; + do_zoom_socket(browser, actions); + continue; case '/': if (ui_browser__input_window("Symbol to show", "Please enter the name of symbol you want to see", @@ -1903,9 +1946,11 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, * Ditto for thread below. */ do_zoom_dso(browser, actions); - } - if (top == &browser->hists->thread_filter) + } else if (top == &browser->hists->thread_filter) { do_zoom_thread(browser, actions); + } else if (top == &browser->hists->socket_filter) { + do_zoom_socket(browser, actions); + } continue; } case 'q': @@ -1973,7 +2018,9 @@ skip_annotation: nr_options += add_map_opt(browser, &actions[nr_options], &options[nr_options], browser->selection->map); - + nr_options += add_socket_opt(browser, &actions[nr_options], + &options[nr_options], + socked_id); /* perf script support */ if (browser->he_selection) { nr_options += add_script_opt(browser, diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 5d78ae879017..b3567a25f0c4 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -1310,6 +1310,25 @@ static bool hists__filter_entry_by_socket(struct hists *hists, return false; } +void hists__filter_by_socket(struct hists *hists) +{ + struct rb_node *nd; + + hists->stats.nr_non_filtered_samples = 0; + + hists__reset_filter_stats(hists); + hists__reset_col_len(hists); + + for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { + struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); + + if (hists__filter_entry_by_socket(hists, h)) + continue; + + hists__remove_entry_filter(hists, h, HIST_FILTER__SOCKET); + } +} + void events_stats__inc(struct events_stats *stats, u32 type) { ++stats->nr_events[0]; diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index ef682f210923..4d6aa1dbdaee 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -147,6 +147,7 @@ size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp); void hists__filter_by_dso(struct hists *hists); void hists__filter_by_thread(struct hists *hists); void hists__filter_by_symbol(struct hists *hists); +void hists__filter_by_socket(struct hists *hists); static inline bool hists__has_filter(struct hists *hists) {