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 option extends the perf report to show reference callgraphs,
        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[]
 
 SEE ALSO
 
        float                   min_percent;
        u64                     nr_entries;
        u64                     queue_size;
+       int                     socket_filter;
        DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
 };
 
        struct perf_evsel *evsel = hists_to_evsel(hists);
        char buf[512];
        size_t size = sizeof(buf);
+       int socket = hists->socket_filter;
 
        if (symbol_conf.filter_relative) {
                nr_samples = hists->stats.nr_non_filtered_samples;
                ret += fprintf(fp, "\n# Sort order   : %s", sort_order ? : default_mem_sort_order);
        } else
                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");
 }
 
                if (pos->idx == 0)
                        hists->symbol_filter_str = rep->symbol_filter_str;
 
+               hists->socket_filter = rep->socket_filter;
+
                hists__collapse_resort(hists, &prog);
 
                /* Non-group events are considered as leader */
                },
                .max_stack               = PERF_MAX_STACK_DEPTH,
                .pretty_printing_style   = "normal",
+               .socket_filter           = -1,
        };
        const struct option options[] = {
        OPT_STRING('i', "input", &input_name, "file",
                        "Show full source file name path for source lines"),
        OPT_BOOLEAN(0, "show-ref-call-graph", &symbol_conf.show_ref_callgraph,
                    "Show callgraph from reference event"),
+       OPT_INTEGER(0, "socket-filter", &report.socket_filter,
+                   "only show processor socket that match with this filter"),
        OPT_END()
        };
        struct perf_data_file file = {
 
        int printed;
        const struct dso *dso = hists->dso_filter;
        const struct thread *thread = hists->thread_filter;
+       int socket = 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);
        if (dso)
                printed += scnprintf(bf + printed, size - printed,
                                    ", DSO: %s", dso->short_name);
+       if (socket > -1)
+               printed += scnprintf(bf + printed, size - printed,
+                                   ", Processor Socket: %d", socket);
        if (!is_report_browser(hbt)) {
                struct perf_top *top = hbt->arg;
 
 
                                          struct hist_entry *he);
 static bool hists__filter_entry_by_symbol(struct hists *hists,
                                          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)
 {
        hists__filter_entry_by_dso(hists, he);
        hists__filter_entry_by_thread(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)
        }
 }
 
+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)
 {
        ++stats->nr_events[0];
        hists->entries_collapsed = RB_ROOT;
        hists->entries = RB_ROOT;
        pthread_mutex_init(&hists->lock, NULL);
+       hists->socket_filter = -1;
        return 0;
 }
 
 
        HIST_FILTER__SYMBOL,
        HIST_FILTER__GUEST,
        HIST_FILTER__HOST,
+       HIST_FILTER__SOCKET,
 };
 
 enum hist_column {
        struct events_stats     stats;
        u64                     event_stream;
        u16                     col_len[HISTC_NR_COLS];
+       int                     socket_filter;
 };
 
 struct hist_entry_iter;
 static inline bool hists__has_filter(struct hists *hists)
 {
        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);