Commit 84734b06 authored by Kan Liang's avatar Kan Liang Committed by Arnaldo Carvalho de Melo

perf hists browser: Zoom in/out for processor socket

Currently, users can zoom in/out for threads and dso in 'perf top' and
'perf report'.

This patch extends it for the processor sockets.

'S' is the short key to zoom into current Processor Socket.
Signed-off-by: default avatarKan Liang <kan.liang@intel.com>
Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1441377946-44429-4-git-send-email-kan.liang@intel.com
[ - Made it elide the Socket column when zooming into it,
    just like with the other zoom ops;
  - Make it use browser->pstack, to unzoom level by level;
  - Rename 'socket' variables to 'socket_id' to make it build on
    older systems where it shadows a global glibc declaration ]
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 21394d94
...@@ -287,7 +287,7 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report ...@@ -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); struct perf_evsel *evsel = hists_to_evsel(hists);
char buf[512]; char buf[512];
size_t size = sizeof(buf); size_t size = sizeof(buf);
int socket = hists->socket_filter; int socked_id = hists->socket_filter;
if (symbol_conf.filter_relative) { if (symbol_conf.filter_relative) {
nr_samples = hists->stats.nr_non_filtered_samples; 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 ...@@ -329,8 +329,8 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report
} else } else
ret += fprintf(fp, "\n# Event count (approx.): %" PRIu64, nr_events); ret += fprintf(fp, "\n# Event count (approx.): %" PRIu64, nr_events);
if (socket > -1) if (socked_id > -1)
ret += fprintf(fp, "\n# Processor Socket: %d", socket); ret += fprintf(fp, "\n# Processor Socket: %d", socked_id);
return ret + fprintf(fp, "\n#\n"); return ret + fprintf(fp, "\n#\n");
} }
......
...@@ -1261,7 +1261,7 @@ static int hists__browser_title(struct hists *hists, ...@@ -1261,7 +1261,7 @@ static int hists__browser_title(struct hists *hists,
int printed; int printed;
const struct dso *dso = hists->dso_filter; const struct dso *dso = hists->dso_filter;
const struct thread *thread = hists->thread_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]; unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
u64 nr_events = hists->stats.total_period; u64 nr_events = hists->stats.total_period;
struct perf_evsel *evsel = hists_to_evsel(hists); struct perf_evsel *evsel = hists_to_evsel(hists);
...@@ -1315,9 +1315,9 @@ static int hists__browser_title(struct hists *hists, ...@@ -1315,9 +1315,9 @@ static int hists__browser_title(struct hists *hists,
if (dso) if (dso)
printed += scnprintf(bf + printed, size - printed, printed += scnprintf(bf + printed, size - printed,
", DSO: %s", dso->short_name); ", DSO: %s", dso->short_name);
if (socket > -1) if (socket_id > -1)
printed += scnprintf(bf + printed, size - printed, printed += scnprintf(bf + printed, size - printed,
", Processor Socket: %d", socket); ", Processor Socket: %d", socket_id);
if (!is_report_browser(hbt)) { if (!is_report_browser(hbt)) {
struct perf_top *top = hbt->arg; struct perf_top *top = hbt->arg;
...@@ -1429,6 +1429,7 @@ struct popup_action { ...@@ -1429,6 +1429,7 @@ struct popup_action {
struct thread *thread; struct thread *thread;
struct dso *dso; struct dso *dso;
struct map_symbol ms; struct map_symbol ms;
int socket;
int (*fn)(struct hist_browser *browser, struct popup_action *act); int (*fn)(struct hist_browser *browser, struct popup_action *act);
}; };
...@@ -1676,6 +1677,41 @@ add_exit_opt(struct hist_browser *browser __maybe_unused, ...@@ -1676,6 +1677,41 @@ add_exit_opt(struct hist_browser *browser __maybe_unused,
return 1; 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) static void hist_browser__update_nr_entries(struct hist_browser *hb)
{ {
u64 nr_entries = 0; u64 nr_entries = 0;
...@@ -1729,6 +1765,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, ...@@ -1729,6 +1765,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
"E Expand all callchains\n" \ "E Expand all callchains\n" \
"F Toggle percentage of filtered entries\n" \ "F Toggle percentage of filtered entries\n" \
"H Display column headers\n" \ "H Display column headers\n" \
"S Zoom into current Processor Socket\n" \
/* help messages are sorted by lexical order of the hotkey */ /* help messages are sorted by lexical order of the hotkey */
const char report_help[] = HIST_BROWSER_HELP_COMMON 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, ...@@ -1759,7 +1796,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
hist_browser__update_nr_entries(browser); hist_browser__update_nr_entries(browser);
} }
browser->pstack = pstack__new(2); browser->pstack = pstack__new(3);
if (browser->pstack == NULL) if (browser->pstack == NULL)
goto out; goto out;
...@@ -1778,6 +1815,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, ...@@ -1778,6 +1815,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
struct thread *thread = NULL; struct thread *thread = NULL;
struct dso *dso = NULL; struct dso *dso = NULL;
int choice = 0; int choice = 0;
int socked_id = -1;
nr_options = 0; nr_options = 0;
...@@ -1786,6 +1824,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, ...@@ -1786,6 +1824,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
if (browser->he_selection != NULL) { if (browser->he_selection != NULL) {
thread = hist_browser__selected_thread(browser); thread = hist_browser__selected_thread(browser);
dso = browser->selection->map ? browser->selection->map->dso : NULL; dso = browser->selection->map ? browser->selection->map->dso : NULL;
socked_id = browser->he_selection->socket;
} }
switch (key) { switch (key) {
case K_TAB: case K_TAB:
...@@ -1828,6 +1867,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, ...@@ -1828,6 +1867,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
actions->thread = thread; actions->thread = thread;
do_zoom_thread(browser, actions); do_zoom_thread(browser, actions);
continue; continue;
case 'S':
actions->socket = socked_id;
do_zoom_socket(browser, actions);
continue;
case '/': case '/':
if (ui_browser__input_window("Symbol to show", if (ui_browser__input_window("Symbol to show",
"Please enter the name of symbol you want to see", "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, ...@@ -1903,9 +1946,11 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
* Ditto for thread below. * Ditto for thread below.
*/ */
do_zoom_dso(browser, actions); do_zoom_dso(browser, actions);
} } else if (top == &browser->hists->thread_filter) {
if (top == &browser->hists->thread_filter)
do_zoom_thread(browser, actions); do_zoom_thread(browser, actions);
} else if (top == &browser->hists->socket_filter) {
do_zoom_socket(browser, actions);
}
continue; continue;
} }
case 'q': case 'q':
...@@ -1973,7 +2018,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, ...@@ -1973,7 +2018,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
nr_options += add_map_opt(browser, &actions[nr_options], nr_options += add_map_opt(browser, &actions[nr_options],
&options[nr_options], &options[nr_options],
browser->selection->map); browser->selection->map);
nr_options += add_socket_opt(browser, &actions[nr_options],
&options[nr_options],
socked_id);
/* perf script support */ /* perf script support */
if (browser->he_selection) { if (browser->he_selection) {
nr_options += add_script_opt(browser, nr_options += add_script_opt(browser,
......
...@@ -1310,6 +1310,25 @@ static bool hists__filter_entry_by_socket(struct hists *hists, ...@@ -1310,6 +1310,25 @@ static bool hists__filter_entry_by_socket(struct hists *hists,
return false; 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) void events_stats__inc(struct events_stats *stats, u32 type)
{ {
++stats->nr_events[0]; ++stats->nr_events[0];
......
...@@ -147,6 +147,7 @@ size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp); ...@@ -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_dso(struct hists *hists);
void hists__filter_by_thread(struct hists *hists); void hists__filter_by_thread(struct hists *hists);
void hists__filter_by_symbol(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) static inline bool hists__has_filter(struct hists *hists)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment