perf report: Introduce --socket-filter option

Introduce --socket-filter option for 'perf report' to only show entries
for a processor socket that match this filter.

  $ perf report --socket-filter 1 --stdio
  # To display the perf.data header info, please use --header/--header-only options.
  #
  # Total Lost Samples: 0
  #
  # Samples: 752  of event 'cycles'
  # Event count (approx.): 350995599
  # Processor Socket: 1
  #
  # Overhead  Command    Shared Object     Symbol
  # ........  .........  ................  .................................
  #
      97.02%  test       test              [.] plusB_c
       0.97%  test       test              [.] plusA_c
       0.23%  swapper    [kernel.vmlinux]  [k] acpi_idle_do_entry
       0.09%  rcu_sched  [kernel.vmlinux]  [k] dyntick_save_progress_counter
       0.01%  swapper    [kernel.vmlinux]  [k] task_waking_fair
       0.00%  swapper    [kernel.vmlinux]  [k] run_timer_softirq

Signed-off-by: Kan Liang <kan.liang@intel.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-3-git-send-email-kan.liang@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Kan Liang 2015-09-04 10:45:44 -04:00 коммит произвёл Arnaldo Carvalho de Melo
Родитель 2e7ea3ab82
Коммит 21394d948a
5 изменённых файлов: 37 добавлений и 1 удалений

Просмотреть файл

@ -350,6 +350,9 @@ include::itrace.txt[]
This option extends the perf report to show reference callgraphs, This option extends the perf report to show reference callgraphs,
which collected by reference event, in no callgraph event. which collected by reference event, in no callgraph event.
--socket-filter::
Only report the samples on the processor socket that match with this filter
include::callchain-overhead-calculation.txt[] include::callchain-overhead-calculation.txt[]
SEE ALSO SEE ALSO

Просмотреть файл

@ -62,6 +62,7 @@ struct report {
float min_percent; float min_percent;
u64 nr_entries; u64 nr_entries;
u64 queue_size; u64 queue_size;
int socket_filter;
DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
}; };
@ -286,6 +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;
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;
@ -326,6 +328,10 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report
ret += fprintf(fp, "\n# Sort order : %s", sort_order ? : default_mem_sort_order); ret += fprintf(fp, "\n# Sort order : %s", sort_order ? : default_mem_sort_order);
} 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)
ret += fprintf(fp, "\n# Processor Socket: %d", socket);
return ret + fprintf(fp, "\n#\n"); return ret + fprintf(fp, "\n#\n");
} }
@ -450,6 +456,8 @@ static void report__collapse_hists(struct report *rep)
if (pos->idx == 0) if (pos->idx == 0)
hists->symbol_filter_str = rep->symbol_filter_str; hists->symbol_filter_str = rep->symbol_filter_str;
hists->socket_filter = rep->socket_filter;
hists__collapse_resort(hists, &prog); hists__collapse_resort(hists, &prog);
/* Non-group events are considered as leader */ /* Non-group events are considered as leader */
@ -635,6 +643,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
}, },
.max_stack = PERF_MAX_STACK_DEPTH, .max_stack = PERF_MAX_STACK_DEPTH,
.pretty_printing_style = "normal", .pretty_printing_style = "normal",
.socket_filter = -1,
}; };
const struct option options[] = { const struct option options[] = {
OPT_STRING('i', "input", &input_name, "file", OPT_STRING('i', "input", &input_name, "file",
@ -747,6 +756,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
"Show full source file name path for source lines"), "Show full source file name path for source lines"),
OPT_BOOLEAN(0, "show-ref-call-graph", &symbol_conf.show_ref_callgraph, OPT_BOOLEAN(0, "show-ref-call-graph", &symbol_conf.show_ref_callgraph,
"Show callgraph from reference event"), "Show callgraph from reference event"),
OPT_INTEGER(0, "socket-filter", &report.socket_filter,
"only show processor socket that match with this filter"),
OPT_END() OPT_END()
}; };
struct perf_data_file file = { struct perf_data_file file = {

Просмотреть файл

@ -1261,6 +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;
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);
@ -1314,6 +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)
printed += scnprintf(bf + printed, size - printed,
", Processor Socket: %d", socket);
if (!is_report_browser(hbt)) { if (!is_report_browser(hbt)) {
struct perf_top *top = hbt->arg; struct perf_top *top = hbt->arg;

Просмотреть файл

@ -15,6 +15,8 @@ static bool hists__filter_entry_by_thread(struct hists *hists,
struct hist_entry *he); struct hist_entry *he);
static bool hists__filter_entry_by_symbol(struct hists *hists, static bool hists__filter_entry_by_symbol(struct hists *hists,
struct hist_entry *he); struct hist_entry *he);
static bool hists__filter_entry_by_socket(struct hists *hists,
struct hist_entry *he);
u16 hists__col_len(struct hists *hists, enum hist_column col) u16 hists__col_len(struct hists *hists, enum hist_column col)
{ {
@ -1027,6 +1029,7 @@ static void hists__apply_filters(struct hists *hists, struct hist_entry *he)
hists__filter_entry_by_dso(hists, he); hists__filter_entry_by_dso(hists, he);
hists__filter_entry_by_thread(hists, he); hists__filter_entry_by_thread(hists, he);
hists__filter_entry_by_symbol(hists, he); hists__filter_entry_by_symbol(hists, he);
hists__filter_entry_by_socket(hists, he);
} }
void hists__collapse_resort(struct hists *hists, struct ui_progress *prog) void hists__collapse_resort(struct hists *hists, struct ui_progress *prog)
@ -1295,6 +1298,18 @@ void hists__filter_by_symbol(struct hists *hists)
} }
} }
static bool hists__filter_entry_by_socket(struct hists *hists,
struct hist_entry *he)
{
if ((hists->socket_filter > -1) &&
(he->socket != hists->socket_filter)) {
he->filtered |= (1 << HIST_FILTER__SOCKET);
return true;
}
return false;
}
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];
@ -1520,6 +1535,7 @@ static int hists_evsel__init(struct perf_evsel *evsel)
hists->entries_collapsed = RB_ROOT; hists->entries_collapsed = RB_ROOT;
hists->entries = RB_ROOT; hists->entries = RB_ROOT;
pthread_mutex_init(&hists->lock, NULL); pthread_mutex_init(&hists->lock, NULL);
hists->socket_filter = -1;
return 0; return 0;
} }

Просмотреть файл

@ -20,6 +20,7 @@ enum hist_filter {
HIST_FILTER__SYMBOL, HIST_FILTER__SYMBOL,
HIST_FILTER__GUEST, HIST_FILTER__GUEST,
HIST_FILTER__HOST, HIST_FILTER__HOST,
HIST_FILTER__SOCKET,
}; };
enum hist_column { enum hist_column {
@ -71,6 +72,7 @@ struct hists {
struct events_stats stats; struct events_stats stats;
u64 event_stream; u64 event_stream;
u16 col_len[HISTC_NR_COLS]; u16 col_len[HISTC_NR_COLS];
int socket_filter;
}; };
struct hist_entry_iter; struct hist_entry_iter;
@ -149,7 +151,7 @@ void hists__filter_by_symbol(struct hists *hists);
static inline bool hists__has_filter(struct hists *hists) static inline bool hists__has_filter(struct hists *hists)
{ {
return hists->thread_filter || hists->dso_filter || return hists->thread_filter || hists->dso_filter ||
hists->symbol_filter_str; hists->symbol_filter_str || (hists->socket_filter > -1);
} }
u16 hists__col_len(struct hists *hists, enum hist_column col); u16 hists__col_len(struct hists *hists, enum hist_column col);