aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2012-09-10 03:53:50 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2012-09-17 12:12:02 -0400
commit7ae92e744e3fb389afb1e24920ecda331d360c61 (patch)
tree46c5d4616a003011a1237ed8d31592a662cf9720 /tools/perf/util
parent314d9f63f385096580e9e2a06eaa0745d92fe4ac (diff)
perf stat: Check PMU cpumask file
If user doesn't explicitly specify CPU list, perf-stat only collects events on CPUs listed in the PMU cpumask file. Signed-off-by: "Yah, Zheng" <zheng.z.yan@intel.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1347263631-23175-3-git-send-email-zheng.z.yan@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/cpumap.c22
-rw-r--r--tools/perf/util/cpumap.h2
-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
6 files changed, 62 insertions, 12 deletions
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index adc72f09914..2b32ffa9ebd 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 c41518573c6..17b5264f643 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/evsel.h b/tools/perf/util/evsel.h
index dc40fe32210..93876bad2e5 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 44afcf40f79..bf5d033ee1b 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 6631d828db3..8a2229da594 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 47f68d3cc5d..53c7794fc4b 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;