aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2012-09-19 10:59:01 -0400
committerIngo Molnar <mingo@kernel.org>2012-09-19 10:59:01 -0400
commitbea8f35421628266658c14ea990d18b0969c4c0b (patch)
tree46c5d4616a003011a1237ed8d31592a662cf9720
parent26f45274afd938d82463816a12ec67448513294a (diff)
parent7ae92e744e3fb389afb1e24920ecda331d360c61 (diff)
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: * Fix handling of unresolved samples when --symbols is used in 'report', from Feng Tang. * Add --symbols to 'script', similar to the one in 'report', from Feng Tang. * Add union member access support to 'probe', from Hyeoncheol Lee. * Make 'archive' work on Android, tweaking some of the utility parameters used (tar, rm), from Irina Tirdea. * Fixups to die() removal, from Namhyung Kim. * Render fixes for the TUI, from Namhyung Kim. * Don't enable annotation in non symbolic view, from Namhyung Kim. * Fix pipe mode in 'report', from Namhyung Kim. * Move related stats code from stat to util/, will be used by the 'stat' kvm tool, from Xiao Guangrong. * Add cpumask for uncore pmu, use it in 'stat', from Yan, Zheng. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore.c28
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore.h6
-rw-r--r--tools/lib/traceevent/Makefile2
-rw-r--r--tools/lib/traceevent/event-parse.c1
-rw-r--r--tools/perf/Makefile1
-rw-r--r--tools/perf/builtin-report.c16
-rw-r--r--tools/perf/builtin-sched.c14
-rw-r--r--tools/perf/builtin-script.c58
-rw-r--r--tools/perf/builtin-stat.c74
-rw-r--r--tools/perf/builtin-test.c8
-rw-r--r--tools/perf/builtin.h1
-rw-r--r--tools/perf/perf-archive.sh6
-rw-r--r--tools/perf/scripts/python/bin/event_analyzing_sample-record8
-rw-r--r--tools/perf/scripts/python/bin/event_analyzing_sample-report3
-rw-r--r--tools/perf/ui/browsers/hists.c6
-rw-r--r--tools/perf/ui/gtk/browser.c2
-rw-r--r--tools/perf/ui/hist.c28
-rw-r--r--tools/perf/util/cpumap.c22
-rw-r--r--tools/perf/util/cpumap.h2
-rw-r--r--tools/perf/util/event.c5
-rw-r--r--tools/perf/util/evsel.h1
-rw-r--r--tools/perf/util/parse-events.c18
-rw-r--r--tools/perf/util/pmu.c30
-rw-r--r--tools/perf/util/pmu.h1
-rw-r--r--tools/perf/util/probe-finder.c24
-rw-r--r--tools/perf/util/sort.c5
-rw-r--r--tools/perf/util/sort.h1
-rw-r--r--tools/perf/util/stat.c57
-rw-r--r--tools/perf/util/stat.h16
29 files changed, 318 insertions, 126 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
index 0a5571080e74..62ec3e6af7ea 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
@@ -2341,6 +2341,27 @@ int uncore_pmu_event_init(struct perf_event *event)
2341 return ret; 2341 return ret;
2342} 2342}
2343 2343
2344static ssize_t uncore_get_attr_cpumask(struct device *dev,
2345 struct device_attribute *attr, char *buf)
2346{
2347 int n = cpulist_scnprintf(buf, PAGE_SIZE - 2, &uncore_cpu_mask);
2348
2349 buf[n++] = '\n';
2350 buf[n] = '\0';
2351 return n;
2352}
2353
2354static DEVICE_ATTR(cpumask, S_IRUGO, uncore_get_attr_cpumask, NULL);
2355
2356static struct attribute *uncore_pmu_attrs[] = {
2357 &dev_attr_cpumask.attr,
2358 NULL,
2359};
2360
2361static struct attribute_group uncore_pmu_attr_group = {
2362 .attrs = uncore_pmu_attrs,
2363};
2364
2344static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu) 2365static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu)
2345{ 2366{
2346 int ret; 2367 int ret;
@@ -2378,8 +2399,8 @@ static void __init uncore_type_exit(struct intel_uncore_type *type)
2378 free_percpu(type->pmus[i].box); 2399 free_percpu(type->pmus[i].box);
2379 kfree(type->pmus); 2400 kfree(type->pmus);
2380 type->pmus = NULL; 2401 type->pmus = NULL;
2381 kfree(type->attr_groups[1]); 2402 kfree(type->events_group);
2382 type->attr_groups[1] = NULL; 2403 type->events_group = NULL;
2383} 2404}
2384 2405
2385static void __init uncore_types_exit(struct intel_uncore_type **types) 2406static void __init uncore_types_exit(struct intel_uncore_type **types)
@@ -2431,9 +2452,10 @@ static int __init uncore_type_init(struct intel_uncore_type *type)
2431 for (j = 0; j < i; j++) 2452 for (j = 0; j < i; j++)
2432 attrs[j] = &type->event_descs[j].attr.attr; 2453 attrs[j] = &type->event_descs[j].attr.attr;
2433 2454
2434 type->attr_groups[1] = events_group; 2455 type->events_group = events_group;
2435 } 2456 }
2436 2457
2458 type->pmu_group = &uncore_pmu_attr_group;
2437 type->pmus = pmus; 2459 type->pmus = pmus;
2438 return 0; 2460 return 0;
2439fail: 2461fail:
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h
index 5b81c1856aac..e68a4550e952 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h
@@ -369,10 +369,12 @@ struct intel_uncore_type {
369 struct intel_uncore_pmu *pmus; 369 struct intel_uncore_pmu *pmus;
370 struct intel_uncore_ops *ops; 370 struct intel_uncore_ops *ops;
371 struct uncore_event_desc *event_descs; 371 struct uncore_event_desc *event_descs;
372 const struct attribute_group *attr_groups[3]; 372 const struct attribute_group *attr_groups[4];
373}; 373};
374 374
375#define format_group attr_groups[0] 375#define pmu_group attr_groups[0]
376#define format_group attr_groups[1]
377#define events_group attr_groups[2]
376 378
377struct intel_uncore_ops { 379struct intel_uncore_ops {
378 void (*init_box)(struct intel_uncore_box *); 380 void (*init_box)(struct intel_uncore_box *);
diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 14131cb0522d..04d959fa0226 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -129,7 +129,7 @@ CFLAGS ?= -g -Wall
129 129
130# Append required CFLAGS 130# Append required CFLAGS
131override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ) 131override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ)
132override CFLAGS += $(udis86-flags) 132override CFLAGS += $(udis86-flags) -D_GNU_SOURCE
133 133
134ifeq ($(VERBOSE),1) 134ifeq ($(VERBOSE),1)
135 Q = 135 Q =
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 2c54cdd8ae1b..77ebeb8266f4 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -24,7 +24,6 @@
24 * Frederic Weisbecker gave his permission to relicense the code to 24 * Frederic Weisbecker gave his permission to relicense the code to
25 * the Lesser General Public License. 25 * the Lesser General Public License.
26 */ 26 */
27#define _GNU_SOURCE
28#include <stdio.h> 27#include <stdio.h>
29#include <stdlib.h> 28#include <stdlib.h>
30#include <string.h> 29#include <string.h>
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 209774bcee2e..5077f8e2ef72 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -406,6 +406,7 @@ LIB_OBJS += $(OUTPUT)util/target.o
406LIB_OBJS += $(OUTPUT)util/rblist.o 406LIB_OBJS += $(OUTPUT)util/rblist.o
407LIB_OBJS += $(OUTPUT)util/intlist.o 407LIB_OBJS += $(OUTPUT)util/intlist.o
408LIB_OBJS += $(OUTPUT)util/vdso.o 408LIB_OBJS += $(OUTPUT)util/vdso.o
409LIB_OBJS += $(OUTPUT)util/stat.o
409 410
410LIB_OBJS += $(OUTPUT)ui/helpline.o 411LIB_OBJS += $(OUTPUT)ui/helpline.o
411LIB_OBJS += $(OUTPUT)ui/hist.o 412LIB_OBJS += $(OUTPUT)ui/hist.o
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 97b2e6300f4c..1da243dfbc3e 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -93,7 +93,7 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
93 struct annotation *notes; 93 struct annotation *notes;
94 err = -ENOMEM; 94 err = -ENOMEM;
95 bx = he->branch_info; 95 bx = he->branch_info;
96 if (bx->from.sym && use_browser > 0) { 96 if (bx->from.sym && use_browser == 1 && sort__has_sym) {
97 notes = symbol__annotation(bx->from.sym); 97 notes = symbol__annotation(bx->from.sym);
98 if (!notes->src 98 if (!notes->src
99 && symbol__alloc_hist(bx->from.sym) < 0) 99 && symbol__alloc_hist(bx->from.sym) < 0)
@@ -107,7 +107,7 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
107 goto out; 107 goto out;
108 } 108 }
109 109
110 if (bx->to.sym && use_browser > 0) { 110 if (bx->to.sym && use_browser == 1 && sort__has_sym) {
111 notes = symbol__annotation(bx->to.sym); 111 notes = symbol__annotation(bx->to.sym);
112 if (!notes->src 112 if (!notes->src
113 && symbol__alloc_hist(bx->to.sym) < 0) 113 && symbol__alloc_hist(bx->to.sym) < 0)
@@ -162,7 +162,7 @@ static int perf_evsel__add_hist_entry(struct perf_evsel *evsel,
162 * so we don't allocated the extra space needed because the stdio 162 * so we don't allocated the extra space needed because the stdio
163 * code will not use it. 163 * code will not use it.
164 */ 164 */
165 if (he->ms.sym != NULL && use_browser > 0) { 165 if (he->ms.sym != NULL && use_browser == 1 && sort__has_sym) {
166 struct annotation *notes = symbol__annotation(he->ms.sym); 166 struct annotation *notes = symbol__annotation(he->ms.sym);
167 167
168 assert(evsel != NULL); 168 assert(evsel != NULL);
@@ -689,15 +689,19 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
689 689
690 if (strcmp(report.input_name, "-") != 0) 690 if (strcmp(report.input_name, "-") != 0)
691 setup_browser(true); 691 setup_browser(true);
692 else 692 else {
693 use_browser = 0; 693 use_browser = 0;
694 perf_hpp__init(false, false);
695 }
696
697 setup_sorting(report_usage, options);
694 698
695 /* 699 /*
696 * Only in the newt browser we are doing integrated annotation, 700 * Only in the newt browser we are doing integrated annotation,
697 * so don't allocate extra space that won't be used in the stdio 701 * so don't allocate extra space that won't be used in the stdio
698 * implementation. 702 * implementation.
699 */ 703 */
700 if (use_browser > 0) { 704 if (use_browser == 1 && sort__has_sym) {
701 symbol_conf.priv_size = sizeof(struct annotation); 705 symbol_conf.priv_size = sizeof(struct annotation);
702 report.annotate_init = symbol__annotate_init; 706 report.annotate_init = symbol__annotate_init;
703 /* 707 /*
@@ -720,8 +724,6 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
720 if (symbol__init() < 0) 724 if (symbol__init() < 0)
721 goto error; 725 goto error;
722 726
723 setup_sorting(report_usage, options);
724
725 if (parent_pattern != default_parent_pattern) { 727 if (parent_pattern != default_parent_pattern) {
726 if (sort_dimension__add("parent") < 0) 728 if (sort_dimension__add("parent") < 0)
727 goto error; 729 goto error;
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index af305f57bd22..9b9e32eaa805 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -438,8 +438,8 @@ static int self_open_counters(void)
438 fd = sys_perf_event_open(&attr, 0, -1, -1, 0); 438 fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
439 439
440 if (fd < 0) 440 if (fd < 0)
441 pr_debug("Error: sys_perf_event_open() syscall returned" 441 pr_err("Error: sys_perf_event_open() syscall returned "
442 "with %d (%s)\n", fd, strerror(errno)); 442 "with %d (%s)\n", fd, strerror(errno));
443 return fd; 443 return fd;
444} 444}
445 445
@@ -700,7 +700,7 @@ static int replay_switch_event(struct perf_sched *sched,
700 delta = 0; 700 delta = 0;
701 701
702 if (delta < 0) { 702 if (delta < 0) {
703 pr_debug("hm, delta: %" PRIu64 " < 0 ?\n", delta); 703 pr_err("hm, delta: %" PRIu64 " < 0 ?\n", delta);
704 return -1; 704 return -1;
705 } 705 }
706 706
@@ -990,7 +990,7 @@ static int latency_runtime_event(struct perf_sched *sched,
990 return -1; 990 return -1;
991 atoms = thread_atoms_search(&sched->atom_root, thread, &sched->cmp_pid); 991 atoms = thread_atoms_search(&sched->atom_root, thread, &sched->cmp_pid);
992 if (!atoms) { 992 if (!atoms) {
993 pr_debug("in-event: Internal tree error"); 993 pr_err("in-event: Internal tree error");
994 return -1; 994 return -1;
995 } 995 }
996 if (add_sched_out_event(atoms, 'R', timestamp)) 996 if (add_sched_out_event(atoms, 'R', timestamp))
@@ -1024,7 +1024,7 @@ static int latency_wakeup_event(struct perf_sched *sched,
1024 return -1; 1024 return -1;
1025 atoms = thread_atoms_search(&sched->atom_root, wakee, &sched->cmp_pid); 1025 atoms = thread_atoms_search(&sched->atom_root, wakee, &sched->cmp_pid);
1026 if (!atoms) { 1026 if (!atoms) {
1027 pr_debug("wakeup-event: Internal tree error"); 1027 pr_err("wakeup-event: Internal tree error");
1028 return -1; 1028 return -1;
1029 } 1029 }
1030 if (add_sched_out_event(atoms, 'S', timestamp)) 1030 if (add_sched_out_event(atoms, 'S', timestamp))
@@ -1079,7 +1079,7 @@ static int latency_migrate_task_event(struct perf_sched *sched,
1079 register_pid(sched, migrant->pid, migrant->comm); 1079 register_pid(sched, migrant->pid, migrant->comm);
1080 atoms = thread_atoms_search(&sched->atom_root, migrant, &sched->cmp_pid); 1080 atoms = thread_atoms_search(&sched->atom_root, migrant, &sched->cmp_pid);
1081 if (!atoms) { 1081 if (!atoms) {
1082 pr_debug("migration-event: Internal tree error"); 1082 pr_err("migration-event: Internal tree error");
1083 return -1; 1083 return -1;
1084 } 1084 }
1085 if (add_sched_out_event(atoms, 'R', timestamp)) 1085 if (add_sched_out_event(atoms, 'R', timestamp))
@@ -1286,7 +1286,7 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
1286 delta = 0; 1286 delta = 0;
1287 1287
1288 if (delta < 0) { 1288 if (delta < 0) {
1289 pr_debug("hm, delta: %" PRIu64 " < 0 ?\n", delta); 1289 pr_err("hm, delta: %" PRIu64 " < 0 ?\n", delta);
1290 return -1; 1290 return -1;
1291 } 1291 }
1292 1292
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 6d98a83d5a60..1be843aa1546 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -14,6 +14,7 @@
14#include "util/util.h" 14#include "util/util.h"
15#include "util/evlist.h" 15#include "util/evlist.h"
16#include "util/evsel.h" 16#include "util/evsel.h"
17#include "util/sort.h"
17#include <linux/bitmap.h> 18#include <linux/bitmap.h>
18 19
19static char const *script_name; 20static char const *script_name;
@@ -1031,6 +1032,61 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
1031 exit(0); 1032 exit(0);
1032} 1033}
1033 1034
1035/*
1036 * Return -1 if none is found, otherwise the actual scripts number.
1037 *
1038 * Currently the only user of this function is the script browser, which
1039 * will list all statically runnable scripts, select one, execute it and
1040 * show the output in a perf browser.
1041 */
1042int find_scripts(char **scripts_array, char **scripts_path_array)
1043{
1044 struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
1045 char scripts_path[MAXPATHLEN];
1046 DIR *scripts_dir, *lang_dir;
1047 char lang_path[MAXPATHLEN];
1048 char *temp;
1049 int i = 0;
1050
1051 snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path());
1052
1053 scripts_dir = opendir(scripts_path);
1054 if (!scripts_dir)
1055 return -1;
1056
1057 for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
1058 snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
1059 lang_dirent.d_name);
1060#ifdef NO_LIBPERL
1061 if (strstr(lang_path, "perl"))
1062 continue;
1063#endif
1064#ifdef NO_LIBPYTHON
1065 if (strstr(lang_path, "python"))
1066 continue;
1067#endif
1068
1069 lang_dir = opendir(lang_path);
1070 if (!lang_dir)
1071 continue;
1072
1073 for_each_script(lang_path, lang_dir, script_dirent, script_next) {
1074 /* Skip those real time scripts: xxxtop.p[yl] */
1075 if (strstr(script_dirent.d_name, "top."))
1076 continue;
1077 sprintf(scripts_path_array[i], "%s/%s", lang_path,
1078 script_dirent.d_name);
1079 temp = strchr(script_dirent.d_name, '.');
1080 snprintf(scripts_array[i],
1081 (temp - script_dirent.d_name) + 1,
1082 "%s", script_dirent.d_name);
1083 i++;
1084 }
1085 }
1086
1087 return i;
1088}
1089
1034static char *get_script_path(const char *script_root, const char *suffix) 1090static char *get_script_path(const char *script_root, const char *suffix)
1035{ 1091{
1036 struct dirent *script_next, *lang_next, script_dirent, lang_dirent; 1092 struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
@@ -1143,6 +1199,8 @@ static const struct option options[] = {
1143 parse_output_fields), 1199 parse_output_fields),
1144 OPT_BOOLEAN('a', "all-cpus", &system_wide, 1200 OPT_BOOLEAN('a', "all-cpus", &system_wide,
1145 "system-wide collection from all CPUs"), 1201 "system-wide collection from all CPUs"),
1202 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
1203 "only consider these symbols"),
1146 OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"), 1204 OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
1147 OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]", 1205 OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
1148 "only display events for these comms"), 1206 "only display events for these comms"),
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index dab347d7b010..e0f65fe65944 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -51,13 +51,13 @@
51#include "util/evsel.h" 51#include "util/evsel.h"
52#include "util/debug.h" 52#include "util/debug.h"
53#include "util/color.h" 53#include "util/color.h"
54#include "util/stat.h"
54#include "util/header.h" 55#include "util/header.h"
55#include "util/cpumap.h" 56#include "util/cpumap.h"
56#include "util/thread.h" 57#include "util/thread.h"
57#include "util/thread_map.h" 58#include "util/thread_map.h"
58 59
59#include <sys/prctl.h> 60#include <sys/prctl.h>
60#include <math.h>
61#include <locale.h> 61#include <locale.h>
62 62
63#define DEFAULT_SEPARATOR " " 63#define DEFAULT_SEPARATOR " "
@@ -199,11 +199,6 @@ static int output_fd;
199 199
200static volatile int done = 0; 200static volatile int done = 0;
201 201
202struct stats
203{
204 double n, mean, M2;
205};
206
207struct perf_stat { 202struct perf_stat {
208 struct stats res_stats[3]; 203 struct stats res_stats[3];
209}; 204};
@@ -220,48 +215,14 @@ static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
220 evsel->priv = NULL; 215 evsel->priv = NULL;
221} 216}
222 217
223static void update_stats(struct stats *stats, u64 val) 218static inline struct cpu_map *perf_evsel__cpus(struct perf_evsel *evsel)
224{ 219{
225 double delta; 220 return (evsel->cpus && !target.cpu_list) ? evsel->cpus : evsel_list->cpus;
226
227 stats->n++;
228 delta = val - stats->mean;
229 stats->mean += delta / stats->n;
230 stats->M2 += delta*(val - stats->mean);
231} 221}
232 222
233static double avg_stats(struct stats *stats) 223static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel)
234{
235 return stats->mean;
236}
237
238/*
239 * http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
240 *
241 * (\Sum n_i^2) - ((\Sum n_i)^2)/n
242 * s^2 = -------------------------------
243 * n - 1
244 *
245 * http://en.wikipedia.org/wiki/Stddev
246 *
247 * The std dev of the mean is related to the std dev by:
248 *
249 * s
250 * s_mean = -------
251 * sqrt(n)
252 *
253 */
254static double stddev_stats(struct stats *stats)
255{ 224{
256 double variance, variance_mean; 225 return perf_evsel__cpus(evsel)->nr;
257
258 if (!stats->n)
259 return 0.0;
260
261 variance = stats->M2 / (stats->n - 1);
262 variance_mean = variance / stats->n;
263
264 return sqrt(variance_mean);
265} 226}
266 227
267static struct stats runtime_nsecs_stats[MAX_NR_CPUS]; 228static struct stats runtime_nsecs_stats[MAX_NR_CPUS];
@@ -295,7 +256,7 @@ retry:
295 evsel->attr.exclude_guest = evsel->attr.exclude_host = 0; 256 evsel->attr.exclude_guest = evsel->attr.exclude_host = 0;
296 257
297 if (perf_target__has_cpu(&target)) { 258 if (perf_target__has_cpu(&target)) {
298 ret = perf_evsel__open_per_cpu(evsel, evsel_list->cpus); 259 ret = perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));
299 if (ret) 260 if (ret)
300 goto check_ret; 261 goto check_ret;
301 return 0; 262 return 0;
@@ -376,7 +337,7 @@ static int read_counter_aggr(struct perf_evsel *counter)
376 u64 *count = counter->counts->aggr.values; 337 u64 *count = counter->counts->aggr.values;
377 int i; 338 int i;
378 339
379 if (__perf_evsel__read(counter, evsel_list->cpus->nr, 340 if (__perf_evsel__read(counter, perf_evsel__nr_cpus(counter),
380 evsel_list->threads->nr, scale) < 0) 341 evsel_list->threads->nr, scale) < 0)
381 return -1; 342 return -1;
382 343
@@ -405,7 +366,7 @@ static int read_counter(struct perf_evsel *counter)
405 u64 *count; 366 u64 *count;
406 int cpu; 367 int cpu;
407 368
408 for (cpu = 0; cpu < evsel_list->cpus->nr; cpu++) { 369 for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
409 if (__perf_evsel__read_on_cpu(counter, cpu, 0, scale) < 0) 370 if (__perf_evsel__read_on_cpu(counter, cpu, 0, scale) < 0)
410 return -1; 371 return -1;
411 372
@@ -544,12 +505,12 @@ static int run_perf_stat(int argc __maybe_unused, const char **argv)
544 if (no_aggr) { 505 if (no_aggr) {
545 list_for_each_entry(counter, &evsel_list->entries, node) { 506 list_for_each_entry(counter, &evsel_list->entries, node) {
546 read_counter(counter); 507 read_counter(counter);
547 perf_evsel__close_fd(counter, evsel_list->cpus->nr, 1); 508 perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1);
548 } 509 }
549 } else { 510 } else {
550 list_for_each_entry(counter, &evsel_list->entries, node) { 511 list_for_each_entry(counter, &evsel_list->entries, node) {
551 read_counter_aggr(counter); 512 read_counter_aggr(counter);
552 perf_evsel__close_fd(counter, evsel_list->cpus->nr, 513 perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
553 evsel_list->threads->nr); 514 evsel_list->threads->nr);
554 } 515 }
555 } 516 }
@@ -559,10 +520,7 @@ static int run_perf_stat(int argc __maybe_unused, const char **argv)
559 520
560static void print_noise_pct(double total, double avg) 521static void print_noise_pct(double total, double avg)
561{ 522{
562 double pct = 0.0; 523 double pct = rel_stddev_stats(total, avg);
563
564 if (avg)
565 pct = 100.0*total/avg;
566 524
567 if (csv_output) 525 if (csv_output)
568 fprintf(output, "%s%.2f%%", csv_sep, pct); 526 fprintf(output, "%s%.2f%%", csv_sep, pct);
@@ -590,7 +548,7 @@ static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg)
590 if (no_aggr) 548 if (no_aggr)
591 sprintf(cpustr, "CPU%*d%s", 549 sprintf(cpustr, "CPU%*d%s",
592 csv_output ? 0 : -4, 550 csv_output ? 0 : -4,
593 evsel_list->cpus->map[cpu], csv_sep); 551 perf_evsel__cpus(evsel)->map[cpu], csv_sep);
594 552
595 fprintf(output, fmt, cpustr, msecs, csv_sep, perf_evsel__name(evsel)); 553 fprintf(output, fmt, cpustr, msecs, csv_sep, perf_evsel__name(evsel));
596 554
@@ -802,7 +760,7 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
802 if (no_aggr) 760 if (no_aggr)
803 sprintf(cpustr, "CPU%*d%s", 761 sprintf(cpustr, "CPU%*d%s",
804 csv_output ? 0 : -4, 762 csv_output ? 0 : -4,
805 evsel_list->cpus->map[cpu], csv_sep); 763 perf_evsel__cpus(evsel)->map[cpu], csv_sep);
806 else 764 else
807 cpu = 0; 765 cpu = 0;
808 766
@@ -963,14 +921,14 @@ static void print_counter(struct perf_evsel *counter)
963 u64 ena, run, val; 921 u64 ena, run, val;
964 int cpu; 922 int cpu;
965 923
966 for (cpu = 0; cpu < evsel_list->cpus->nr; cpu++) { 924 for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
967 val = counter->counts->cpu[cpu].val; 925 val = counter->counts->cpu[cpu].val;
968 ena = counter->counts->cpu[cpu].ena; 926 ena = counter->counts->cpu[cpu].ena;
969 run = counter->counts->cpu[cpu].run; 927 run = counter->counts->cpu[cpu].run;
970 if (run == 0 || ena == 0) { 928 if (run == 0 || ena == 0) {
971 fprintf(output, "CPU%*d%s%*s%s%*s", 929 fprintf(output, "CPU%*d%s%*s%s%*s",
972 csv_output ? 0 : -4, 930 csv_output ? 0 : -4,
973 evsel_list->cpus->map[cpu], csv_sep, 931 perf_evsel__cpus(counter)->map[cpu], csv_sep,
974 csv_output ? 0 : 18, 932 csv_output ? 0 : 18,
975 counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 933 counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
976 csv_sep, 934 csv_sep,
@@ -1269,7 +1227,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
1269 1227
1270 list_for_each_entry(pos, &evsel_list->entries, node) { 1228 list_for_each_entry(pos, &evsel_list->entries, node) {
1271 if (perf_evsel__alloc_stat_priv(pos) < 0 || 1229 if (perf_evsel__alloc_stat_priv(pos) < 0 ||
1272 perf_evsel__alloc_counts(pos, evsel_list->cpus->nr) < 0) 1230 perf_evsel__alloc_counts(pos, perf_evsel__nr_cpus(pos)) < 0)
1273 goto out_free_fd; 1231 goto out_free_fd;
1274 } 1232 }
1275 1233
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index d33143efefce..4aed1553db56 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -1026,15 +1026,15 @@ static int __test__rdpmc(void)
1026 1026
1027 fd = sys_perf_event_open(&attr, 0, -1, -1, 0); 1027 fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
1028 if (fd < 0) { 1028 if (fd < 0) {
1029 pr_debug("Error: sys_perf_event_open() syscall returned " 1029 pr_err("Error: sys_perf_event_open() syscall returned "
1030 "with %d (%s)\n", fd, strerror(errno)); 1030 "with %d (%s)\n", fd, strerror(errno));
1031 return -1; 1031 return -1;
1032 } 1032 }
1033 1033
1034 addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0); 1034 addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0);
1035 if (addr == (void *)(-1)) { 1035 if (addr == (void *)(-1)) {
1036 pr_debug("Error: mmap() syscall returned with (%s)\n", 1036 pr_err("Error: mmap() syscall returned with (%s)\n",
1037 strerror(errno)); 1037 strerror(errno));
1038 goto out_close; 1038 goto out_close;
1039 } 1039 }
1040 1040
diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index b382bd551aac..3ea74ed1b26b 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -36,4 +36,5 @@ extern int cmd_kvm(int argc, const char **argv, const char *prefix);
36extern int cmd_test(int argc, const char **argv, const char *prefix); 36extern int cmd_test(int argc, const char **argv, const char *prefix);
37extern int cmd_inject(int argc, const char **argv, const char *prefix); 37extern int cmd_inject(int argc, const char **argv, const char *prefix);
38 38
39extern int find_scripts(char **scripts_array, char **scripts_path_array);
39#endif 40#endif
diff --git a/tools/perf/perf-archive.sh b/tools/perf/perf-archive.sh
index 95b6f8b6177a..e91930620269 100644
--- a/tools/perf/perf-archive.sh
+++ b/tools/perf/perf-archive.sh
@@ -24,7 +24,7 @@ NOBUILDID=0000000000000000000000000000000000000000
24perf buildid-list -i $PERF_DATA --with-hits | grep -v "^$NOBUILDID " > $BUILDIDS 24perf buildid-list -i $PERF_DATA --with-hits | grep -v "^$NOBUILDID " > $BUILDIDS
25if [ ! -s $BUILDIDS ] ; then 25if [ ! -s $BUILDIDS ] ; then
26 echo "perf archive: no build-ids found" 26 echo "perf archive: no build-ids found"
27 rm -f $BUILDIDS 27 rm $BUILDIDS || true
28 exit 1 28 exit 1
29fi 29fi
30 30
@@ -39,8 +39,8 @@ while read build_id ; do
39 echo ${filename#$PERF_BUILDID_LINKDIR} >> $MANIFEST 39 echo ${filename#$PERF_BUILDID_LINKDIR} >> $MANIFEST
40done 40done
41 41
42tar cfj $PERF_DATA.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST 42tar cjf $PERF_DATA.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST
43rm -f $MANIFEST $BUILDIDS 43rm $MANIFEST $BUILDIDS || true
44echo -e "Now please run:\n" 44echo -e "Now please run:\n"
45echo -e "$ tar xvf $PERF_DATA.tar.bz2 -C ~/.debug\n" 45echo -e "$ tar xvf $PERF_DATA.tar.bz2 -C ~/.debug\n"
46echo "wherever you need to run 'perf report' on." 46echo "wherever you need to run 'perf report' on."
diff --git a/tools/perf/scripts/python/bin/event_analyzing_sample-record b/tools/perf/scripts/python/bin/event_analyzing_sample-record
new file mode 100644
index 000000000000..5ce652dabd02
--- /dev/null
+++ b/tools/perf/scripts/python/bin/event_analyzing_sample-record
@@ -0,0 +1,8 @@
1#!/bin/bash
2
3#
4# event_analyzing_sample.py can cover all type of perf samples including
5# the tracepoints, so no special record requirements, just record what
6# you want to analyze.
7#
8perf record $@
diff --git a/tools/perf/scripts/python/bin/event_analyzing_sample-report b/tools/perf/scripts/python/bin/event_analyzing_sample-report
new file mode 100644
index 000000000000..0941fc94e158
--- /dev/null
+++ b/tools/perf/scripts/python/bin/event_analyzing_sample-report
@@ -0,0 +1,3 @@
1#!/bin/bash
2# description: analyze all perf samples
3perf script $@ -s "$PERF_EXEC_PATH"/scripts/python/event_analyzing_sample.py
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 5a5739bbe6ac..a21f40bebbac 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -571,7 +571,7 @@ static int hist_browser__hpp_color_ ## _name(struct perf_hpp *hpp, \
571{ \ 571{ \
572 double percent = 100.0 * he->_field / hpp->total_period; \ 572 double percent = 100.0 * he->_field / hpp->total_period; \
573 *(double *)hpp->ptr = percent; \ 573 *(double *)hpp->ptr = percent; \
574 return scnprintf(hpp->buf, hpp->size, "%5.2f%%", percent); \ 574 return scnprintf(hpp->buf, hpp->size, "%6.2f%%", percent); \
575} 575}
576 576
577HPP__COLOR_FN(overhead, period) 577HPP__COLOR_FN(overhead, period)
@@ -605,7 +605,7 @@ static int hist_browser__show_entry(struct hist_browser *browser,
605 char s[256]; 605 char s[256];
606 double percent; 606 double percent;
607 int i, printed = 0; 607 int i, printed = 0;
608 int width = browser->b.width - 1; 608 int width = browser->b.width;
609 char folded_sign = ' '; 609 char folded_sign = ' ';
610 bool current_entry = ui_browser__is_current_entry(&browser->b, row); 610 bool current_entry = ui_browser__is_current_entry(&browser->b, row);
611 off_t row_offset = entry->row_offset; 611 off_t row_offset = entry->row_offset;
@@ -627,7 +627,7 @@ static int hist_browser__show_entry(struct hist_browser *browser,
627 .total_period = browser->hists->stats.total_period, 627 .total_period = browser->hists->stats.total_period,
628 }; 628 };
629 629
630 ui_browser__gotorc(&browser->b, row, 1); 630 ui_browser__gotorc(&browser->b, row, 0);
631 631
632 for (i = 0; i < PERF_HPP__MAX_INDEX; i++) { 632 for (i = 0; i < PERF_HPP__MAX_INDEX; i++) {
633 if (!perf_hpp__format[i].cond) 633 if (!perf_hpp__format[i].cond)
diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c
index 55acba6e0df4..7ff99ec1d95e 100644
--- a/tools/perf/ui/gtk/browser.c
+++ b/tools/perf/ui/gtk/browser.c
@@ -56,7 +56,7 @@ static int perf_gtk__hpp_color_ ## _name(struct perf_hpp *hpp, \
56 markup = perf_gtk__get_percent_color(percent); \ 56 markup = perf_gtk__get_percent_color(percent); \
57 if (markup) \ 57 if (markup) \
58 ret += scnprintf(hpp->buf, hpp->size, "%s", markup); \ 58 ret += scnprintf(hpp->buf, hpp->size, "%s", markup); \
59 ret += scnprintf(hpp->buf + ret, hpp->size - ret, "%5.2f%%", percent); \ 59 ret += scnprintf(hpp->buf + ret, hpp->size - ret, "%6.2f%%", percent); \
60 if (markup) \ 60 if (markup) \
61 ret += scnprintf(hpp->buf + ret, hpp->size - ret, "</span>"); \ 61 ret += scnprintf(hpp->buf + ret, hpp->size - ret, "</span>"); \
62 \ 62 \
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 407e855cccb8..e3f8cd46e7d7 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -33,13 +33,13 @@ static int hpp__color_overhead(struct perf_hpp *hpp, struct hist_entry *he)
33 percent = 0.0; 33 percent = 0.0;
34 } 34 }
35 35
36 return percent_color_snprintf(hpp->buf, hpp->size, " %5.2f%%", percent); 36 return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%%", percent);
37} 37}
38 38
39static int hpp__entry_overhead(struct perf_hpp *hpp, struct hist_entry *he) 39static int hpp__entry_overhead(struct perf_hpp *hpp, struct hist_entry *he)
40{ 40{
41 double percent = 100.0 * he->period / hpp->total_period; 41 double percent = 100.0 * he->period / hpp->total_period;
42 const char *fmt = symbol_conf.field_sep ? "%.2f" : " %5.2f%%"; 42 const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%%";
43 43
44 if (hpp->ptr) { 44 if (hpp->ptr) {
45 struct hists *old_hists = hpp->ptr; 45 struct hists *old_hists = hpp->ptr;
@@ -57,52 +57,52 @@ static int hpp__entry_overhead(struct perf_hpp *hpp, struct hist_entry *he)
57 57
58static int hpp__header_overhead_sys(struct perf_hpp *hpp) 58static int hpp__header_overhead_sys(struct perf_hpp *hpp)
59{ 59{
60 const char *fmt = symbol_conf.field_sep ? "%s" : "%6s"; 60 const char *fmt = symbol_conf.field_sep ? "%s" : "%7s";
61 61
62 return scnprintf(hpp->buf, hpp->size, fmt, "sys"); 62 return scnprintf(hpp->buf, hpp->size, fmt, "sys");
63} 63}
64 64
65static int hpp__width_overhead_sys(struct perf_hpp *hpp __maybe_unused) 65static int hpp__width_overhead_sys(struct perf_hpp *hpp __maybe_unused)
66{ 66{
67 return 6; 67 return 7;
68} 68}
69 69
70static int hpp__color_overhead_sys(struct perf_hpp *hpp, struct hist_entry *he) 70static int hpp__color_overhead_sys(struct perf_hpp *hpp, struct hist_entry *he)
71{ 71{
72 double percent = 100.0 * he->period_sys / hpp->total_period; 72 double percent = 100.0 * he->period_sys / hpp->total_period;
73 return percent_color_snprintf(hpp->buf, hpp->size, "%5.2f%%", percent); 73 return percent_color_snprintf(hpp->buf, hpp->size, "%6.2f%%", percent);
74} 74}
75 75
76static int hpp__entry_overhead_sys(struct perf_hpp *hpp, struct hist_entry *he) 76static int hpp__entry_overhead_sys(struct perf_hpp *hpp, struct hist_entry *he)
77{ 77{
78 double percent = 100.0 * he->period_sys / hpp->total_period; 78 double percent = 100.0 * he->period_sys / hpp->total_period;
79 const char *fmt = symbol_conf.field_sep ? "%.2f" : "%5.2f%%"; 79 const char *fmt = symbol_conf.field_sep ? "%.2f" : "%6.2f%%";
80 80
81 return scnprintf(hpp->buf, hpp->size, fmt, percent); 81 return scnprintf(hpp->buf, hpp->size, fmt, percent);
82} 82}
83 83
84static int hpp__header_overhead_us(struct perf_hpp *hpp) 84static int hpp__header_overhead_us(struct perf_hpp *hpp)
85{ 85{
86 const char *fmt = symbol_conf.field_sep ? "%s" : "%6s"; 86 const char *fmt = symbol_conf.field_sep ? "%s" : "%7s";
87 87
88 return scnprintf(hpp->buf, hpp->size, fmt, "user"); 88 return scnprintf(hpp->buf, hpp->size, fmt, "user");
89} 89}
90 90
91static int hpp__width_overhead_us(struct perf_hpp *hpp __maybe_unused) 91static int hpp__width_overhead_us(struct perf_hpp *hpp __maybe_unused)
92{ 92{
93 return 6; 93 return 7;
94} 94}
95 95
96static int hpp__color_overhead_us(struct perf_hpp *hpp, struct hist_entry *he) 96static int hpp__color_overhead_us(struct perf_hpp *hpp, struct hist_entry *he)
97{ 97{
98 double percent = 100.0 * he->period_us / hpp->total_period; 98 double percent = 100.0 * he->period_us / hpp->total_period;
99 return percent_color_snprintf(hpp->buf, hpp->size, "%5.2f%%", percent); 99 return percent_color_snprintf(hpp->buf, hpp->size, "%6.2f%%", percent);
100} 100}
101 101
102static int hpp__entry_overhead_us(struct perf_hpp *hpp, struct hist_entry *he) 102static int hpp__entry_overhead_us(struct perf_hpp *hpp, struct hist_entry *he)
103{ 103{
104 double percent = 100.0 * he->period_us / hpp->total_period; 104 double percent = 100.0 * he->period_us / hpp->total_period;
105 const char *fmt = symbol_conf.field_sep ? "%.2f" : "%5.2f%%"; 105 const char *fmt = symbol_conf.field_sep ? "%.2f" : "%6.2f%%";
106 106
107 return scnprintf(hpp->buf, hpp->size, fmt, percent); 107 return scnprintf(hpp->buf, hpp->size, fmt, percent);
108} 108}
@@ -121,14 +121,14 @@ static int hpp__color_overhead_guest_sys(struct perf_hpp *hpp,
121 struct hist_entry *he) 121 struct hist_entry *he)
122{ 122{
123 double percent = 100.0 * he->period_guest_sys / hpp->total_period; 123 double percent = 100.0 * he->period_guest_sys / hpp->total_period;
124 return percent_color_snprintf(hpp->buf, hpp->size, " %5.2f%% ", percent); 124 return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%% ", percent);
125} 125}
126 126
127static int hpp__entry_overhead_guest_sys(struct perf_hpp *hpp, 127static int hpp__entry_overhead_guest_sys(struct perf_hpp *hpp,
128 struct hist_entry *he) 128 struct hist_entry *he)
129{ 129{
130 double percent = 100.0 * he->period_guest_sys / hpp->total_period; 130 double percent = 100.0 * he->period_guest_sys / hpp->total_period;
131 const char *fmt = symbol_conf.field_sep ? "%.2f" : " %5.2f%% "; 131 const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%% ";
132 132
133 return scnprintf(hpp->buf, hpp->size, fmt, percent); 133 return scnprintf(hpp->buf, hpp->size, fmt, percent);
134} 134}
@@ -147,14 +147,14 @@ static int hpp__color_overhead_guest_us(struct perf_hpp *hpp,
147 struct hist_entry *he) 147 struct hist_entry *he)
148{ 148{
149 double percent = 100.0 * he->period_guest_us / hpp->total_period; 149 double percent = 100.0 * he->period_guest_us / hpp->total_period;
150 return percent_color_snprintf(hpp->buf, hpp->size, " %5.2f%% ", percent); 150 return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%% ", percent);
151} 151}
152 152
153static int hpp__entry_overhead_guest_us(struct perf_hpp *hpp, 153static int hpp__entry_overhead_guest_us(struct perf_hpp *hpp,
154 struct hist_entry *he) 154 struct hist_entry *he)
155{ 155{
156 double percent = 100.0 * he->period_guest_us / hpp->total_period; 156 double percent = 100.0 * he->period_guest_us / hpp->total_period;
157 const char *fmt = symbol_conf.field_sep ? "%.2f" : " %5.2f%% "; 157 const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%% ";
158 158
159 return scnprintf(hpp->buf, hpp->size, fmt, percent); 159 return scnprintf(hpp->buf, hpp->size, fmt, percent);
160} 160}
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index adc72f09914d..2b32ffa9ebdb 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -38,24 +38,19 @@ static struct cpu_map *cpu_map__trim_new(int nr_cpus, int *tmp_cpus)
38 return cpus; 38 return cpus;
39} 39}
40 40
41static struct cpu_map *cpu_map__read_all_cpu_map(void) 41struct cpu_map *cpu_map__read(FILE *file)
42{ 42{
43 struct cpu_map *cpus = NULL; 43 struct cpu_map *cpus = NULL;
44 FILE *onlnf;
45 int nr_cpus = 0; 44 int nr_cpus = 0;
46 int *tmp_cpus = NULL, *tmp; 45 int *tmp_cpus = NULL, *tmp;
47 int max_entries = 0; 46 int max_entries = 0;
48 int n, cpu, prev; 47 int n, cpu, prev;
49 char sep; 48 char sep;
50 49
51 onlnf = fopen("/sys/devices/system/cpu/online", "r");
52 if (!onlnf)
53 return cpu_map__default_new();
54
55 sep = 0; 50 sep = 0;
56 prev = -1; 51 prev = -1;
57 for (;;) { 52 for (;;) {
58 n = fscanf(onlnf, "%u%c", &cpu, &sep); 53 n = fscanf(file, "%u%c", &cpu, &sep);
59 if (n <= 0) 54 if (n <= 0)
60 break; 55 break;
61 if (prev >= 0) { 56 if (prev >= 0) {
@@ -95,6 +90,19 @@ static struct cpu_map *cpu_map__read_all_cpu_map(void)
95 cpus = cpu_map__default_new(); 90 cpus = cpu_map__default_new();
96out_free_tmp: 91out_free_tmp:
97 free(tmp_cpus); 92 free(tmp_cpus);
93 return cpus;
94}
95
96static struct cpu_map *cpu_map__read_all_cpu_map(void)
97{
98 struct cpu_map *cpus = NULL;
99 FILE *onlnf;
100
101 onlnf = fopen("/sys/devices/system/cpu/online", "r");
102 if (!onlnf)
103 return cpu_map__default_new();
104
105 cpus = cpu_map__read(onlnf);
98 fclose(onlnf); 106 fclose(onlnf);
99 return cpus; 107 return cpus;
100} 108}
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index c41518573c6a..17b5264f6436 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -11,7 +11,7 @@ struct cpu_map {
11struct cpu_map *cpu_map__new(const char *cpu_list); 11struct cpu_map *cpu_map__new(const char *cpu_list);
12struct cpu_map *cpu_map__dummy_new(void); 12struct cpu_map *cpu_map__dummy_new(void);
13void cpu_map__delete(struct cpu_map *map); 13void cpu_map__delete(struct cpu_map *map);
14 14struct cpu_map *cpu_map__read(FILE *file);
15size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp); 15size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp);
16 16
17#endif /* __PERF_CPUMAP_H */ 17#endif /* __PERF_CPUMAP_H */
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 8202f5ca0483..6715b1938725 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -904,8 +904,9 @@ int perf_event__preprocess_sample(const union perf_event *event,
904 al->sym = map__find_symbol(al->map, al->addr, filter); 904 al->sym = map__find_symbol(al->map, al->addr, filter);
905 } 905 }
906 906
907 if (symbol_conf.sym_list && al->sym && 907 if (symbol_conf.sym_list &&
908 !strlist__has_entry(symbol_conf.sym_list, al->sym->name)) 908 (!al->sym || !strlist__has_entry(symbol_conf.sym_list,
909 al->sym->name)))
909 goto out_filtered; 910 goto out_filtered;
910 911
911 return 0; 912 return 0;
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index dc40fe32210b..93876bad2e52 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -66,6 +66,7 @@ struct perf_evsel {
66 void *func; 66 void *func;
67 void *data; 67 void *data;
68 } handler; 68 } handler;
69 struct cpu_map *cpus;
69 unsigned int sample_size; 70 unsigned int sample_size;
70 bool supported; 71 bool supported;
71 /* parse modifier helper */ 72 /* parse modifier helper */
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 44afcf40f796..bf5d033ee1b4 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -239,8 +239,11 @@ const char *event_type(int type)
239 return "unknown"; 239 return "unknown";
240} 240}
241 241
242static int add_event(struct list_head **_list, int *idx, 242
243 struct perf_event_attr *attr, char *name) 243
244static int __add_event(struct list_head **_list, int *idx,
245 struct perf_event_attr *attr,
246 char *name, struct cpu_map *cpus)
244{ 247{
245 struct perf_evsel *evsel; 248 struct perf_evsel *evsel;
246 struct list_head *list = *_list; 249 struct list_head *list = *_list;
@@ -260,6 +263,7 @@ static int add_event(struct list_head **_list, int *idx,
260 return -ENOMEM; 263 return -ENOMEM;
261 } 264 }
262 265
266 evsel->cpus = cpus;
263 if (name) 267 if (name)
264 evsel->name = strdup(name); 268 evsel->name = strdup(name);
265 list_add_tail(&evsel->node, list); 269 list_add_tail(&evsel->node, list);
@@ -267,6 +271,12 @@ static int add_event(struct list_head **_list, int *idx,
267 return 0; 271 return 0;
268} 272}
269 273
274static int add_event(struct list_head **_list, int *idx,
275 struct perf_event_attr *attr, char *name)
276{
277 return __add_event(_list, idx, attr, name, NULL);
278}
279
270static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size) 280static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size)
271{ 281{
272 int i, j; 282 int i, j;
@@ -607,8 +617,8 @@ int parse_events_add_pmu(struct list_head **list, int *idx,
607 if (perf_pmu__config(pmu, &attr, head_config)) 617 if (perf_pmu__config(pmu, &attr, head_config))
608 return -EINVAL; 618 return -EINVAL;
609 619
610 return add_event(list, idx, &attr, 620 return __add_event(list, idx, &attr, pmu_event_name(head_config),
611 pmu_event_name(head_config)); 621 pmu->cpus);
612} 622}
613 623
614int parse_events__modifier_group(struct list_head *list, 624int parse_events__modifier_group(struct list_head *list,
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 6631d828db3d..8a2229da594f 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -9,6 +9,7 @@
9#include "util.h" 9#include "util.h"
10#include "pmu.h" 10#include "pmu.h"
11#include "parse-events.h" 11#include "parse-events.h"
12#include "cpumap.h"
12 13
13#define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/" 14#define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/"
14 15
@@ -253,6 +254,33 @@ static void pmu_read_sysfs(void)
253 closedir(dir); 254 closedir(dir);
254} 255}
255 256
257static struct cpu_map *pmu_cpumask(char *name)
258{
259 struct stat st;
260 char path[PATH_MAX];
261 const char *sysfs;
262 FILE *file;
263 struct cpu_map *cpus;
264
265 sysfs = sysfs_find_mountpoint();
266 if (!sysfs)
267 return NULL;
268
269 snprintf(path, PATH_MAX,
270 "%s/bus/event_source/devices/%s/cpumask", sysfs, name);
271
272 if (stat(path, &st) < 0)
273 return NULL;
274
275 file = fopen(path, "r");
276 if (!file)
277 return NULL;
278
279 cpus = cpu_map__read(file);
280 fclose(file);
281 return cpus;
282}
283
256static struct perf_pmu *pmu_lookup(char *name) 284static struct perf_pmu *pmu_lookup(char *name)
257{ 285{
258 struct perf_pmu *pmu; 286 struct perf_pmu *pmu;
@@ -275,6 +303,8 @@ static struct perf_pmu *pmu_lookup(char *name)
275 if (!pmu) 303 if (!pmu)
276 return NULL; 304 return NULL;
277 305
306 pmu->cpus = pmu_cpumask(name);
307
278 pmu_aliases(name, &aliases); 308 pmu_aliases(name, &aliases);
279 309
280 INIT_LIST_HEAD(&pmu->format); 310 INIT_LIST_HEAD(&pmu->format);
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 47f68d3cc5d1..53c7794fc4be 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -28,6 +28,7 @@ struct perf_pmu__alias {
28struct perf_pmu { 28struct perf_pmu {
29 char *name; 29 char *name;
30 __u32 type; 30 __u32 type;
31 struct cpu_map *cpus;
31 struct list_head format; 32 struct list_head format;
32 struct list_head aliases; 33 struct list_head aliases;
33 struct list_head list; 34 struct list_head list;
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 526ba56e720b..1daf5c14e751 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -525,8 +525,10 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
525 return -ENOENT; 525 return -ENOENT;
526 } 526 }
527 /* Verify it is a data structure */ 527 /* Verify it is a data structure */
528 if (dwarf_tag(&type) != DW_TAG_structure_type) { 528 tag = dwarf_tag(&type);
529 pr_warning("%s is not a data structure.\n", varname); 529 if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) {
530 pr_warning("%s is not a data structure nor an union.\n",
531 varname);
530 return -EINVAL; 532 return -EINVAL;
531 } 533 }
532 534
@@ -539,8 +541,9 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
539 *ref_ptr = ref; 541 *ref_ptr = ref;
540 } else { 542 } else {
541 /* Verify it is a data structure */ 543 /* Verify it is a data structure */
542 if (tag != DW_TAG_structure_type) { 544 if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) {
543 pr_warning("%s is not a data structure.\n", varname); 545 pr_warning("%s is not a data structure nor an union.\n",
546 varname);
544 return -EINVAL; 547 return -EINVAL;
545 } 548 }
546 if (field->name[0] == '[') { 549 if (field->name[0] == '[') {
@@ -567,10 +570,15 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
567 } 570 }
568 571
569 /* Get the offset of the field */ 572 /* Get the offset of the field */
570 ret = die_get_data_member_location(die_mem, &offs); 573 if (tag == DW_TAG_union_type) {
571 if (ret < 0) { 574 offs = 0;
572 pr_warning("Failed to get the offset of %s.\n", field->name); 575 } else {
573 return ret; 576 ret = die_get_data_member_location(die_mem, &offs);
577 if (ret < 0) {
578 pr_warning("Failed to get the offset of %s.\n",
579 field->name);
580 return ret;
581 }
574 } 582 }
575 ref->offset += (long)offs; 583 ref->offset += (long)offs;
576 584
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 0981bc7a2917..b5b1b9211960 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -8,6 +8,7 @@ const char default_sort_order[] = "comm,dso,symbol";
8const char *sort_order = default_sort_order; 8const char *sort_order = default_sort_order;
9int sort__need_collapse = 0; 9int sort__need_collapse = 0;
10int sort__has_parent = 0; 10int sort__has_parent = 0;
11int sort__has_sym = 0;
11int sort__branch_mode = -1; /* -1 = means not set */ 12int sort__branch_mode = -1; /* -1 = means not set */
12 13
13enum sort_type sort__first_dimension; 14enum sort_type sort__first_dimension;
@@ -511,6 +512,10 @@ int sort_dimension__add(const char *tok)
511 return -EINVAL; 512 return -EINVAL;
512 } 513 }
513 sort__has_parent = 1; 514 sort__has_parent = 1;
515 } else if (sd->entry == &sort_sym ||
516 sd->entry == &sort_sym_from ||
517 sd->entry == &sort_sym_to) {
518 sort__has_sym = 1;
514 } 519 }
515 520
516 if (sd->taken) 521 if (sd->taken)
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index e459c981b039..12d634792de5 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -31,6 +31,7 @@ extern const char *parent_pattern;
31extern const char default_sort_order[]; 31extern const char default_sort_order[];
32extern int sort__need_collapse; 32extern int sort__need_collapse;
33extern int sort__has_parent; 33extern int sort__has_parent;
34extern int sort__has_sym;
34extern int sort__branch_mode; 35extern int sort__branch_mode;
35extern struct sort_entry sort_comm; 36extern struct sort_entry sort_comm;
36extern struct sort_entry sort_dso; 37extern struct sort_entry sort_dso;
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
new file mode 100644
index 000000000000..23742126f47c
--- /dev/null
+++ b/tools/perf/util/stat.c
@@ -0,0 +1,57 @@
1#include <math.h>
2
3#include "stat.h"
4
5void update_stats(struct stats *stats, u64 val)
6{
7 double delta;
8
9 stats->n++;
10 delta = val - stats->mean;
11 stats->mean += delta / stats->n;
12 stats->M2 += delta*(val - stats->mean);
13}
14
15double avg_stats(struct stats *stats)
16{
17 return stats->mean;
18}
19
20/*
21 * http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
22 *
23 * (\Sum n_i^2) - ((\Sum n_i)^2)/n
24 * s^2 = -------------------------------
25 * n - 1
26 *
27 * http://en.wikipedia.org/wiki/Stddev
28 *
29 * The std dev of the mean is related to the std dev by:
30 *
31 * s
32 * s_mean = -------
33 * sqrt(n)
34 *
35 */
36double stddev_stats(struct stats *stats)
37{
38 double variance, variance_mean;
39
40 if (!stats->n)
41 return 0.0;
42
43 variance = stats->M2 / (stats->n - 1);
44 variance_mean = variance / stats->n;
45
46 return sqrt(variance_mean);
47}
48
49double rel_stddev_stats(double stddev, double avg)
50{
51 double pct = 0.0;
52
53 if (avg)
54 pct = 100.0 * stddev/avg;
55
56 return pct;
57}
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
new file mode 100644
index 000000000000..588367c3c767
--- /dev/null
+++ b/tools/perf/util/stat.h
@@ -0,0 +1,16 @@
1#ifndef __PERF_STATS_H
2#define __PERF_STATS_H
3
4#include "types.h"
5
6struct stats
7{
8 double n, mean, M2;
9};
10
11void update_stats(struct stats *stats, u64 val);
12double avg_stats(struct stats *stats);
13double stddev_stats(struct stats *stats);
14double rel_stddev_stats(double stddev, double avg);
15
16#endif