aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2013-04-01 15:41:35 -0400
committerIngo Molnar <mingo@kernel.org>2013-04-01 15:41:35 -0400
commitb847d0501afec4c7b12eb276aec10a2834f953ea (patch)
tree69ff786e4280456345a03de9f70f85baf0e34d66 /tools/perf/util
parent0a11953851213fd1d3eebcb68b4a537d458c70c2 (diff)
parentd06f7911792780c6e973a137b766530c8d031aeb (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: * Revert "perf sched: Handle PERF_RECORD_EXIT events" to get 'perf sched lat' back working. * We don't use Newt anymore, just plain libslang. * Kill a bunch of die() calls, from Namhyung Kim. * Add --no-demangle to report/top, from Namhyung Kim. * Fix dependency of the python binding wrt libtraceevent, from Naohiro Aota. * Introduce per core aggregation in 'perf stat', from Stephane Eranian. * Add memory profiling via PEBS, from Stephane Eranian. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/annotate.h2
-rw-r--r--tools/perf/util/cpumap.c86
-rw-r--r--tools/perf/util/cpumap.h12
-rw-r--r--tools/perf/util/event.h9
-rw-r--r--tools/perf/util/evsel.c19
-rw-r--r--tools/perf/util/header.c11
-rw-r--r--tools/perf/util/hist.c110
-rw-r--r--tools/perf/util/hist.h23
-rw-r--r--tools/perf/util/machine.c42
-rw-r--r--tools/perf/util/machine.h3
-rw-r--r--tools/perf/util/session.c8
-rw-r--r--tools/perf/util/sort.c414
-rw-r--r--tools/perf/util/sort.h12
-rw-r--r--tools/perf/util/symbol-elf.c9
-rw-r--r--tools/perf/util/symbol.c1
-rw-r--r--tools/perf/util/symbol.h9
-rw-r--r--tools/perf/util/trace-event-info.c347
-rw-r--r--tools/perf/util/trace-event-read.c272
-rw-r--r--tools/perf/util/trace-event.h2
-rw-r--r--tools/perf/util/util.h2
20 files changed, 1144 insertions, 249 deletions
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 6f3c16f01ab4..af755156d278 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -150,7 +150,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
150 struct perf_evsel *evsel, bool print_lines, 150 struct perf_evsel *evsel, bool print_lines,
151 bool full_paths, int min_pcnt, int max_lines); 151 bool full_paths, int min_pcnt, int max_lines);
152 152
153#ifdef NEWT_SUPPORT 153#ifdef SLANG_SUPPORT
154int symbol__tui_annotate(struct symbol *sym, struct map *map, 154int symbol__tui_annotate(struct symbol *sym, struct map *map,
155 struct perf_evsel *evsel, 155 struct perf_evsel *evsel,
156 struct hist_browser_timer *hbt); 156 struct hist_browser_timer *hbt);
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index f817046e22b1..beb8cf9f9976 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -4,6 +4,7 @@
4#include "cpumap.h" 4#include "cpumap.h"
5#include <assert.h> 5#include <assert.h>
6#include <stdio.h> 6#include <stdio.h>
7#include <stdlib.h>
7 8
8static struct cpu_map *cpu_map__default_new(void) 9static struct cpu_map *cpu_map__default_new(void)
9{ 10{
@@ -219,7 +220,7 @@ int cpu_map__get_socket(struct cpu_map *map, int idx)
219 if (!mnt) 220 if (!mnt)
220 return -1; 221 return -1;
221 222
222 sprintf(path, 223 snprintf(path, PATH_MAX,
223 "%s/devices/system/cpu/cpu%d/topology/physical_package_id", 224 "%s/devices/system/cpu/cpu%d/topology/physical_package_id",
224 mnt, cpu); 225 mnt, cpu);
225 226
@@ -231,27 +232,88 @@ int cpu_map__get_socket(struct cpu_map *map, int idx)
231 return ret == 1 ? cpu : -1; 232 return ret == 1 ? cpu : -1;
232} 233}
233 234
234int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp) 235static int cmp_ids(const void *a, const void *b)
235{ 236{
236 struct cpu_map *sock; 237 return *(int *)a - *(int *)b;
238}
239
240static int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res,
241 int (*f)(struct cpu_map *map, int cpu))
242{
243 struct cpu_map *c;
237 int nr = cpus->nr; 244 int nr = cpus->nr;
238 int cpu, s1, s2; 245 int cpu, s1, s2;
239 246
240 sock = calloc(1, sizeof(*sock) + nr * sizeof(int)); 247 /* allocate as much as possible */
241 if (!sock) 248 c = calloc(1, sizeof(*c) + nr * sizeof(int));
249 if (!c)
242 return -1; 250 return -1;
243 251
244 for (cpu = 0; cpu < nr; cpu++) { 252 for (cpu = 0; cpu < nr; cpu++) {
245 s1 = cpu_map__get_socket(cpus, cpu); 253 s1 = f(cpus, cpu);
246 for (s2 = 0; s2 < sock->nr; s2++) { 254 for (s2 = 0; s2 < c->nr; s2++) {
247 if (s1 == sock->map[s2]) 255 if (s1 == c->map[s2])
248 break; 256 break;
249 } 257 }
250 if (s2 == sock->nr) { 258 if (s2 == c->nr) {
251 sock->map[sock->nr] = s1; 259 c->map[c->nr] = s1;
252 sock->nr++; 260 c->nr++;
253 } 261 }
254 } 262 }
255 *sockp = sock; 263 /* ensure we process id in increasing order */
264 qsort(c->map, c->nr, sizeof(int), cmp_ids);
265
266 *res = c;
256 return 0; 267 return 0;
257} 268}
269
270int cpu_map__get_core(struct cpu_map *map, int idx)
271{
272 FILE *fp;
273 const char *mnt;
274 char path[PATH_MAX];
275 int cpu, ret, s;
276
277 if (idx > map->nr)
278 return -1;
279
280 cpu = map->map[idx];
281
282 mnt = sysfs_find_mountpoint();
283 if (!mnt)
284 return -1;
285
286 snprintf(path, PATH_MAX,
287 "%s/devices/system/cpu/cpu%d/topology/core_id",
288 mnt, cpu);
289
290 fp = fopen(path, "r");
291 if (!fp)
292 return -1;
293 ret = fscanf(fp, "%d", &cpu);
294 fclose(fp);
295 if (ret != 1)
296 return -1;
297
298 s = cpu_map__get_socket(map, idx);
299 if (s == -1)
300 return -1;
301
302 /*
303 * encode socket in upper 16 bits
304 * core_id is relative to socket, and
305 * we need a global id. So we combine
306 * socket+ core id
307 */
308 return (s << 16) | (cpu & 0xffff);
309}
310
311int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp)
312{
313 return cpu_map__build_map(cpus, sockp, cpu_map__get_socket);
314}
315
316int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep)
317{
318 return cpu_map__build_map(cpus, corep, cpu_map__get_core);
319}
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 161b00756a12..9bed02e5fb3d 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -15,7 +15,9 @@ void cpu_map__delete(struct cpu_map *map);
15struct cpu_map *cpu_map__read(FILE *file); 15struct cpu_map *cpu_map__read(FILE *file);
16size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp); 16size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp);
17int cpu_map__get_socket(struct cpu_map *map, int idx); 17int cpu_map__get_socket(struct cpu_map *map, int idx);
18int cpu_map__get_core(struct cpu_map *map, int idx);
18int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp); 19int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp);
20int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep);
19 21
20static inline int cpu_map__socket(struct cpu_map *sock, int s) 22static inline int cpu_map__socket(struct cpu_map *sock, int s)
21{ 23{
@@ -24,6 +26,16 @@ static inline int cpu_map__socket(struct cpu_map *sock, int s)
24 return sock->map[s]; 26 return sock->map[s];
25} 27}
26 28
29static inline int cpu_map__id_to_socket(int id)
30{
31 return id >> 16;
32}
33
34static inline int cpu_map__id_to_cpu(int id)
35{
36 return id & 0xffff;
37}
38
27static inline int cpu_map__nr(const struct cpu_map *map) 39static inline int cpu_map__nr(const struct cpu_map *map)
28{ 40{
29 return map ? map->nr : 1; 41 return map ? map->nr : 1;
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 0d573ff4771a..181389535c0c 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -88,8 +88,10 @@ struct perf_sample {
88 u64 id; 88 u64 id;
89 u64 stream_id; 89 u64 stream_id;
90 u64 period; 90 u64 period;
91 u64 weight;
91 u32 cpu; 92 u32 cpu;
92 u32 raw_size; 93 u32 raw_size;
94 u64 data_src;
93 void *raw_data; 95 void *raw_data;
94 struct ip_callchain *callchain; 96 struct ip_callchain *callchain;
95 struct branch_stack *branch_stack; 97 struct branch_stack *branch_stack;
@@ -97,6 +99,13 @@ struct perf_sample {
97 struct stack_dump user_stack; 99 struct stack_dump user_stack;
98}; 100};
99 101
102#define PERF_MEM_DATA_SRC_NONE \
103 (PERF_MEM_S(OP, NA) |\
104 PERF_MEM_S(LVL, NA) |\
105 PERF_MEM_S(SNOOP, NA) |\
106 PERF_MEM_S(LOCK, NA) |\
107 PERF_MEM_S(TLB, NA))
108
100struct build_id_event { 109struct build_id_event {
101 struct perf_event_header header; 110 struct perf_event_header header;
102 pid_t pid; 111 pid_t pid;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 1adb824610f0..07b1a3ad3e24 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -554,6 +554,9 @@ void perf_evsel__config(struct perf_evsel *evsel,
554 perf_evsel__set_sample_bit(evsel, CPU); 554 perf_evsel__set_sample_bit(evsel, CPU);
555 } 555 }
556 556
557 if (opts->sample_address)
558 attr->sample_type |= PERF_SAMPLE_DATA_SRC;
559
557 if (opts->no_delay) { 560 if (opts->no_delay) {
558 attr->watermark = 0; 561 attr->watermark = 0;
559 attr->wakeup_events = 1; 562 attr->wakeup_events = 1;
@@ -563,6 +566,9 @@ void perf_evsel__config(struct perf_evsel *evsel,
563 attr->branch_sample_type = opts->branch_stack; 566 attr->branch_sample_type = opts->branch_stack;
564 } 567 }
565 568
569 if (opts->sample_weight)
570 attr->sample_type |= PERF_SAMPLE_WEIGHT;
571
566 attr->mmap = track; 572 attr->mmap = track;
567 attr->comm = track; 573 attr->comm = track;
568 574
@@ -1017,6 +1023,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
1017 data->cpu = data->pid = data->tid = -1; 1023 data->cpu = data->pid = data->tid = -1;
1018 data->stream_id = data->id = data->time = -1ULL; 1024 data->stream_id = data->id = data->time = -1ULL;
1019 data->period = 1; 1025 data->period = 1;
1026 data->weight = 0;
1020 1027
1021 if (event->header.type != PERF_RECORD_SAMPLE) { 1028 if (event->header.type != PERF_RECORD_SAMPLE) {
1022 if (!evsel->attr.sample_id_all) 1029 if (!evsel->attr.sample_id_all)
@@ -1167,6 +1174,18 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
1167 } 1174 }
1168 } 1175 }
1169 1176
1177 data->weight = 0;
1178 if (type & PERF_SAMPLE_WEIGHT) {
1179 data->weight = *array;
1180 array++;
1181 }
1182
1183 data->data_src = PERF_MEM_DATA_SRC_NONE;
1184 if (type & PERF_SAMPLE_DATA_SRC) {
1185 data->data_src = *array;
1186 array++;
1187 }
1188
1170 return 0; 1189 return 0;
1171} 1190}
1172 1191
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index a9b7349f7c5f..326068a593a5 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1,5 +1,3 @@
1#define _FILE_OFFSET_BITS 64
2
3#include "util.h" 1#include "util.h"
4#include <sys/types.h> 2#include <sys/types.h>
5#include <byteswap.h> 3#include <byteswap.h>
@@ -1672,8 +1670,8 @@ static int process_tracing_data(struct perf_file_section *section __maybe_unused
1672 struct perf_header *ph __maybe_unused, 1670 struct perf_header *ph __maybe_unused,
1673 int fd, void *data) 1671 int fd, void *data)
1674{ 1672{
1675 trace_report(fd, data, false); 1673 ssize_t ret = trace_report(fd, data, false);
1676 return 0; 1674 return ret < 0 ? -1 : 0;
1677} 1675}
1678 1676
1679static int process_build_id(struct perf_file_section *section, 1677static int process_build_id(struct perf_file_section *section,
@@ -2752,6 +2750,11 @@ static int perf_evsel__prepare_tracepoint_event(struct perf_evsel *evsel,
2752 if (evsel->tp_format) 2750 if (evsel->tp_format)
2753 return 0; 2751 return 0;
2754 2752
2753 if (pevent == NULL) {
2754 pr_debug("broken or missing trace data\n");
2755 return -1;
2756 }
2757
2755 event = pevent_find_event(pevent, evsel->attr.config); 2758 event = pevent_find_event(pevent, evsel->attr.config);
2756 if (event == NULL) 2759 if (event == NULL)
2757 return -1; 2760 return -1;
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index f855941bebea..6b32721f829a 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -67,12 +67,16 @@ static void hists__set_unres_dso_col_len(struct hists *hists, int dso)
67void hists__calc_col_len(struct hists *hists, struct hist_entry *h) 67void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
68{ 68{
69 const unsigned int unresolved_col_width = BITS_PER_LONG / 4; 69 const unsigned int unresolved_col_width = BITS_PER_LONG / 4;
70 int symlen;
70 u16 len; 71 u16 len;
71 72
72 if (h->ms.sym) 73 if (h->ms.sym)
73 hists__new_col_len(hists, HISTC_SYMBOL, h->ms.sym->namelen + 4); 74 hists__new_col_len(hists, HISTC_SYMBOL, h->ms.sym->namelen + 4);
74 else 75 else {
76 symlen = unresolved_col_width + 4 + 2;
77 hists__new_col_len(hists, HISTC_SYMBOL, symlen);
75 hists__set_unres_dso_col_len(hists, HISTC_DSO); 78 hists__set_unres_dso_col_len(hists, HISTC_DSO);
79 }
76 80
77 len = thread__comm_len(h->thread); 81 len = thread__comm_len(h->thread);
78 if (hists__new_col_len(hists, HISTC_COMM, len)) 82 if (hists__new_col_len(hists, HISTC_COMM, len))
@@ -87,7 +91,6 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
87 hists__new_col_len(hists, HISTC_PARENT, h->parent->namelen); 91 hists__new_col_len(hists, HISTC_PARENT, h->parent->namelen);
88 92
89 if (h->branch_info) { 93 if (h->branch_info) {
90 int symlen;
91 /* 94 /*
92 * +4 accounts for '[x] ' priv level info 95 * +4 accounts for '[x] ' priv level info
93 * +2 account of 0x prefix on raw addresses 96 * +2 account of 0x prefix on raw addresses
@@ -116,6 +119,42 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
116 hists__set_unres_dso_col_len(hists, HISTC_DSO_TO); 119 hists__set_unres_dso_col_len(hists, HISTC_DSO_TO);
117 } 120 }
118 } 121 }
122
123 if (h->mem_info) {
124 /*
125 * +4 accounts for '[x] ' priv level info
126 * +2 account of 0x prefix on raw addresses
127 */
128 if (h->mem_info->daddr.sym) {
129 symlen = (int)h->mem_info->daddr.sym->namelen + 4
130 + unresolved_col_width + 2;
131 hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL,
132 symlen);
133 } else {
134 symlen = unresolved_col_width + 4 + 2;
135 hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL,
136 symlen);
137 }
138 if (h->mem_info->daddr.map) {
139 symlen = dso__name_len(h->mem_info->daddr.map->dso);
140 hists__new_col_len(hists, HISTC_MEM_DADDR_DSO,
141 symlen);
142 } else {
143 symlen = unresolved_col_width + 4 + 2;
144 hists__set_unres_dso_col_len(hists, HISTC_MEM_DADDR_DSO);
145 }
146 } else {
147 symlen = unresolved_col_width + 4 + 2;
148 hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL, symlen);
149 hists__set_unres_dso_col_len(hists, HISTC_MEM_DADDR_DSO);
150 }
151
152 hists__new_col_len(hists, HISTC_MEM_LOCKED, 6);
153 hists__new_col_len(hists, HISTC_MEM_TLB, 22);
154 hists__new_col_len(hists, HISTC_MEM_SNOOP, 12);
155 hists__new_col_len(hists, HISTC_MEM_LVL, 21 + 3);
156 hists__new_col_len(hists, HISTC_LOCAL_WEIGHT, 12);
157 hists__new_col_len(hists, HISTC_GLOBAL_WEIGHT, 12);
119} 158}
120 159
121void hists__output_recalc_col_len(struct hists *hists, int max_rows) 160void hists__output_recalc_col_len(struct hists *hists, int max_rows)
@@ -155,9 +194,12 @@ static void hist_entry__add_cpumode_period(struct hist_entry *he,
155 } 194 }
156} 195}
157 196
158static void he_stat__add_period(struct he_stat *he_stat, u64 period) 197static void he_stat__add_period(struct he_stat *he_stat, u64 period,
198 u64 weight)
159{ 199{
200
160 he_stat->period += period; 201 he_stat->period += period;
202 he_stat->weight += weight;
161 he_stat->nr_events += 1; 203 he_stat->nr_events += 1;
162} 204}
163 205
@@ -169,12 +211,14 @@ static void he_stat__add_stat(struct he_stat *dest, struct he_stat *src)
169 dest->period_guest_sys += src->period_guest_sys; 211 dest->period_guest_sys += src->period_guest_sys;
170 dest->period_guest_us += src->period_guest_us; 212 dest->period_guest_us += src->period_guest_us;
171 dest->nr_events += src->nr_events; 213 dest->nr_events += src->nr_events;
214 dest->weight += src->weight;
172} 215}
173 216
174static void hist_entry__decay(struct hist_entry *he) 217static void hist_entry__decay(struct hist_entry *he)
175{ 218{
176 he->stat.period = (he->stat.period * 7) / 8; 219 he->stat.period = (he->stat.period * 7) / 8;
177 he->stat.nr_events = (he->stat.nr_events * 7) / 8; 220 he->stat.nr_events = (he->stat.nr_events * 7) / 8;
221 /* XXX need decay for weight too? */
178} 222}
179 223
180static bool hists__decay_entry(struct hists *hists, struct hist_entry *he) 224static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
@@ -239,7 +283,7 @@ void hists__decay_entries_threaded(struct hists *hists,
239static struct hist_entry *hist_entry__new(struct hist_entry *template) 283static struct hist_entry *hist_entry__new(struct hist_entry *template)
240{ 284{
241 size_t callchain_size = symbol_conf.use_callchain ? sizeof(struct callchain_root) : 0; 285 size_t callchain_size = symbol_conf.use_callchain ? sizeof(struct callchain_root) : 0;
242 struct hist_entry *he = malloc(sizeof(*he) + callchain_size); 286 struct hist_entry *he = zalloc(sizeof(*he) + callchain_size);
243 287
244 if (he != NULL) { 288 if (he != NULL) {
245 *he = *template; 289 *he = *template;
@@ -254,6 +298,13 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)
254 he->branch_info->to.map->referenced = true; 298 he->branch_info->to.map->referenced = true;
255 } 299 }
256 300
301 if (he->mem_info) {
302 if (he->mem_info->iaddr.map)
303 he->mem_info->iaddr.map->referenced = true;
304 if (he->mem_info->daddr.map)
305 he->mem_info->daddr.map->referenced = true;
306 }
307
257 if (symbol_conf.use_callchain) 308 if (symbol_conf.use_callchain)
258 callchain_init(he->callchain); 309 callchain_init(he->callchain);
259 310
@@ -282,7 +333,8 @@ static u8 symbol__parent_filter(const struct symbol *parent)
282static struct hist_entry *add_hist_entry(struct hists *hists, 333static struct hist_entry *add_hist_entry(struct hists *hists,
283 struct hist_entry *entry, 334 struct hist_entry *entry,
284 struct addr_location *al, 335 struct addr_location *al,
285 u64 period) 336 u64 period,
337 u64 weight)
286{ 338{
287 struct rb_node **p; 339 struct rb_node **p;
288 struct rb_node *parent = NULL; 340 struct rb_node *parent = NULL;
@@ -306,7 +358,7 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
306 cmp = hist_entry__cmp(he, entry); 358 cmp = hist_entry__cmp(he, entry);
307 359
308 if (!cmp) { 360 if (!cmp) {
309 he_stat__add_period(&he->stat, period); 361 he_stat__add_period(&he->stat, period, weight);
310 362
311 /* If the map of an existing hist_entry has 363 /* If the map of an existing hist_entry has
312 * become out-of-date due to an exec() or 364 * become out-of-date due to an exec() or
@@ -341,11 +393,42 @@ out_unlock:
341 return he; 393 return he;
342} 394}
343 395
396struct hist_entry *__hists__add_mem_entry(struct hists *self,
397 struct addr_location *al,
398 struct symbol *sym_parent,
399 struct mem_info *mi,
400 u64 period,
401 u64 weight)
402{
403 struct hist_entry entry = {
404 .thread = al->thread,
405 .ms = {
406 .map = al->map,
407 .sym = al->sym,
408 },
409 .stat = {
410 .period = period,
411 .weight = weight,
412 .nr_events = 1,
413 },
414 .cpu = al->cpu,
415 .ip = al->addr,
416 .level = al->level,
417 .parent = sym_parent,
418 .filtered = symbol__parent_filter(sym_parent),
419 .hists = self,
420 .mem_info = mi,
421 .branch_info = NULL,
422 };
423 return add_hist_entry(self, &entry, al, period, weight);
424}
425
344struct hist_entry *__hists__add_branch_entry(struct hists *self, 426struct hist_entry *__hists__add_branch_entry(struct hists *self,
345 struct addr_location *al, 427 struct addr_location *al,
346 struct symbol *sym_parent, 428 struct symbol *sym_parent,
347 struct branch_info *bi, 429 struct branch_info *bi,
348 u64 period) 430 u64 period,
431 u64 weight)
349{ 432{
350 struct hist_entry entry = { 433 struct hist_entry entry = {
351 .thread = al->thread, 434 .thread = al->thread,
@@ -359,19 +442,22 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
359 .stat = { 442 .stat = {
360 .period = period, 443 .period = period,
361 .nr_events = 1, 444 .nr_events = 1,
445 .weight = weight,
362 }, 446 },
363 .parent = sym_parent, 447 .parent = sym_parent,
364 .filtered = symbol__parent_filter(sym_parent), 448 .filtered = symbol__parent_filter(sym_parent),
365 .branch_info = bi, 449 .branch_info = bi,
366 .hists = self, 450 .hists = self,
451 .mem_info = NULL,
367 }; 452 };
368 453
369 return add_hist_entry(self, &entry, al, period); 454 return add_hist_entry(self, &entry, al, period, weight);
370} 455}
371 456
372struct hist_entry *__hists__add_entry(struct hists *self, 457struct hist_entry *__hists__add_entry(struct hists *self,
373 struct addr_location *al, 458 struct addr_location *al,
374 struct symbol *sym_parent, u64 period) 459 struct symbol *sym_parent, u64 period,
460 u64 weight)
375{ 461{
376 struct hist_entry entry = { 462 struct hist_entry entry = {
377 .thread = al->thread, 463 .thread = al->thread,
@@ -385,13 +471,16 @@ struct hist_entry *__hists__add_entry(struct hists *self,
385 .stat = { 471 .stat = {
386 .period = period, 472 .period = period,
387 .nr_events = 1, 473 .nr_events = 1,
474 .weight = weight,
388 }, 475 },
389 .parent = sym_parent, 476 .parent = sym_parent,
390 .filtered = symbol__parent_filter(sym_parent), 477 .filtered = symbol__parent_filter(sym_parent),
391 .hists = self, 478 .hists = self,
479 .branch_info = NULL,
480 .mem_info = NULL,
392 }; 481 };
393 482
394 return add_hist_entry(self, &entry, al, period); 483 return add_hist_entry(self, &entry, al, period, weight);
395} 484}
396 485
397int64_t 486int64_t
@@ -431,6 +520,7 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
431void hist_entry__free(struct hist_entry *he) 520void hist_entry__free(struct hist_entry *he)
432{ 521{
433 free(he->branch_info); 522 free(he->branch_info);
523 free(he->mem_info);
434 free(he); 524 free(he);
435} 525}
436 526
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 848331377bdb..14c2fe20aa62 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -49,6 +49,14 @@ enum hist_column {
49 HISTC_DSO_FROM, 49 HISTC_DSO_FROM,
50 HISTC_DSO_TO, 50 HISTC_DSO_TO,
51 HISTC_SRCLINE, 51 HISTC_SRCLINE,
52 HISTC_LOCAL_WEIGHT,
53 HISTC_GLOBAL_WEIGHT,
54 HISTC_MEM_DADDR_SYMBOL,
55 HISTC_MEM_DADDR_DSO,
56 HISTC_MEM_LOCKED,
57 HISTC_MEM_TLB,
58 HISTC_MEM_LVL,
59 HISTC_MEM_SNOOP,
52 HISTC_NR_COLS, /* Last entry */ 60 HISTC_NR_COLS, /* Last entry */
53}; 61};
54 62
@@ -73,7 +81,8 @@ struct hists {
73 81
74struct hist_entry *__hists__add_entry(struct hists *self, 82struct hist_entry *__hists__add_entry(struct hists *self,
75 struct addr_location *al, 83 struct addr_location *al,
76 struct symbol *parent, u64 period); 84 struct symbol *parent, u64 period,
85 u64 weight);
77int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right); 86int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right);
78int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right); 87int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right);
79int hist_entry__sort_snprintf(struct hist_entry *self, char *bf, size_t size, 88int hist_entry__sort_snprintf(struct hist_entry *self, char *bf, size_t size,
@@ -84,7 +93,15 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
84 struct addr_location *al, 93 struct addr_location *al,
85 struct symbol *sym_parent, 94 struct symbol *sym_parent,
86 struct branch_info *bi, 95 struct branch_info *bi,
87 u64 period); 96 u64 period,
97 u64 weight);
98
99struct hist_entry *__hists__add_mem_entry(struct hists *self,
100 struct addr_location *al,
101 struct symbol *sym_parent,
102 struct mem_info *mi,
103 u64 period,
104 u64 weight);
88 105
89void hists__output_resort(struct hists *self); 106void hists__output_resort(struct hists *self);
90void hists__output_resort_threaded(struct hists *hists); 107void hists__output_resort_threaded(struct hists *hists);
@@ -175,7 +192,7 @@ struct hist_browser_timer {
175 int refresh; 192 int refresh;
176}; 193};
177 194
178#ifdef NEWT_SUPPORT 195#ifdef SLANG_SUPPORT
179#include "../ui/keysyms.h" 196#include "../ui/keysyms.h"
180int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel, 197int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
181 struct hist_browser_timer *hbt); 198 struct hist_browser_timer *hbt);
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index c5e3b123782b..b2ecad6ec46b 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -955,6 +955,7 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event
955 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 955 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
956 struct thread *thread; 956 struct thread *thread;
957 struct map *map; 957 struct map *map;
958 enum map_type type;
958 int ret = 0; 959 int ret = 0;
959 960
960 if (dump_trace) 961 if (dump_trace)
@@ -971,10 +972,17 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event
971 thread = machine__findnew_thread(machine, event->mmap.pid); 972 thread = machine__findnew_thread(machine, event->mmap.pid);
972 if (thread == NULL) 973 if (thread == NULL)
973 goto out_problem; 974 goto out_problem;
975
976 if (event->header.misc & PERF_RECORD_MISC_MMAP_DATA)
977 type = MAP__VARIABLE;
978 else
979 type = MAP__FUNCTION;
980
974 map = map__new(&machine->user_dsos, event->mmap.start, 981 map = map__new(&machine->user_dsos, event->mmap.start,
975 event->mmap.len, event->mmap.pgoff, 982 event->mmap.len, event->mmap.pgoff,
976 event->mmap.pid, event->mmap.filename, 983 event->mmap.pid, event->mmap.filename,
977 MAP__FUNCTION); 984 type);
985
978 if (map == NULL) 986 if (map == NULL)
979 goto out_problem; 987 goto out_problem;
980 988
@@ -1097,6 +1105,38 @@ found:
1097 ams->map = al.map; 1105 ams->map = al.map;
1098} 1106}
1099 1107
1108static void ip__resolve_data(struct machine *machine, struct thread *thread,
1109 u8 m, struct addr_map_symbol *ams, u64 addr)
1110{
1111 struct addr_location al;
1112
1113 memset(&al, 0, sizeof(al));
1114
1115 thread__find_addr_location(thread, machine, m, MAP__VARIABLE, addr, &al,
1116 NULL);
1117 ams->addr = addr;
1118 ams->al_addr = al.addr;
1119 ams->sym = al.sym;
1120 ams->map = al.map;
1121}
1122
1123struct mem_info *machine__resolve_mem(struct machine *machine,
1124 struct thread *thr,
1125 struct perf_sample *sample,
1126 u8 cpumode)
1127{
1128 struct mem_info *mi = zalloc(sizeof(*mi));
1129
1130 if (!mi)
1131 return NULL;
1132
1133 ip__resolve_ams(machine, thr, &mi->iaddr, sample->ip);
1134 ip__resolve_data(machine, thr, cpumode, &mi->daddr, sample->addr);
1135 mi->data_src.val = sample->data_src;
1136
1137 return mi;
1138}
1139
1100struct branch_info *machine__resolve_bstack(struct machine *machine, 1140struct branch_info *machine__resolve_bstack(struct machine *machine,
1101 struct thread *thr, 1141 struct thread *thr,
1102 struct branch_stack *bs) 1142 struct branch_stack *bs)
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index e0b2c00b2e75..77940680f1fc 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -76,6 +76,9 @@ void machine__delete(struct machine *machine);
76struct branch_info *machine__resolve_bstack(struct machine *machine, 76struct branch_info *machine__resolve_bstack(struct machine *machine,
77 struct thread *thread, 77 struct thread *thread,
78 struct branch_stack *bs); 78 struct branch_stack *bs);
79struct mem_info *machine__resolve_mem(struct machine *machine,
80 struct thread *thread,
81 struct perf_sample *sample, u8 cpumode);
79int machine__resolve_callchain(struct machine *machine, 82int machine__resolve_callchain(struct machine *machine,
80 struct perf_evsel *evsel, 83 struct perf_evsel *evsel,
81 struct thread *thread, 84 struct thread *thread,
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index ab265c2cfab3..cf1fe01b7e89 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1,5 +1,3 @@
1#define _FILE_OFFSET_BITS 64
2
3#include <linux/kernel.h> 1#include <linux/kernel.h>
4 2
5#include <byteswap.h> 3#include <byteswap.h>
@@ -800,6 +798,12 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event,
800 798
801 if (sample_type & PERF_SAMPLE_STACK_USER) 799 if (sample_type & PERF_SAMPLE_STACK_USER)
802 stack_user__printf(&sample->user_stack); 800 stack_user__printf(&sample->user_stack);
801
802 if (sample_type & PERF_SAMPLE_WEIGHT)
803 printf("... weight: %" PRIu64 "\n", sample->weight);
804
805 if (sample_type & PERF_SAMPLE_DATA_SRC)
806 printf(" . data_src: 0x%"PRIx64"\n", sample->data_src);
803} 807}
804 808
805static struct machine * 809static struct machine *
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index d41926cb9e3f..5f52d492590c 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -198,11 +198,19 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
198 } 198 }
199 199
200 ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level); 200 ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level);
201 if (sym) 201 if (sym && map) {
202 ret += repsep_snprintf(bf + ret, size - ret, "%-*s", 202 if (map->type == MAP__VARIABLE) {
203 width - ret, 203 ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name);
204 sym->name); 204 ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx",
205 else { 205 ip - map->unmap_ip(map, sym->start));
206 ret += repsep_snprintf(bf + ret, size - ret, "%-*s",
207 width - ret, "");
208 } else {
209 ret += repsep_snprintf(bf + ret, size - ret, "%-*s",
210 width - ret,
211 sym->name);
212 }
213 } else {
206 size_t len = BITS_PER_LONG / 4; 214 size_t len = BITS_PER_LONG / 4;
207 ret += repsep_snprintf(bf + ret, size - ret, "%-#.*llx", 215 ret += repsep_snprintf(bf + ret, size - ret, "%-#.*llx",
208 len, ip); 216 len, ip);
@@ -457,6 +465,304 @@ static int hist_entry__mispredict_snprintf(struct hist_entry *self, char *bf,
457 return repsep_snprintf(bf, size, "%-*s", width, out); 465 return repsep_snprintf(bf, size, "%-*s", width, out);
458} 466}
459 467
468/* --sort daddr_sym */
469static int64_t
470sort__daddr_cmp(struct hist_entry *left, struct hist_entry *right)
471{
472 uint64_t l = 0, r = 0;
473
474 if (left->mem_info)
475 l = left->mem_info->daddr.addr;
476 if (right->mem_info)
477 r = right->mem_info->daddr.addr;
478
479 return (int64_t)(r - l);
480}
481
482static int hist_entry__daddr_snprintf(struct hist_entry *self, char *bf,
483 size_t size, unsigned int width)
484{
485 uint64_t addr = 0;
486 struct map *map = NULL;
487 struct symbol *sym = NULL;
488
489 if (self->mem_info) {
490 addr = self->mem_info->daddr.addr;
491 map = self->mem_info->daddr.map;
492 sym = self->mem_info->daddr.sym;
493 }
494 return _hist_entry__sym_snprintf(map, sym, addr, self->level, bf, size,
495 width);
496}
497
498static int64_t
499sort__dso_daddr_cmp(struct hist_entry *left, struct hist_entry *right)
500{
501 struct map *map_l = NULL;
502 struct map *map_r = NULL;
503
504 if (left->mem_info)
505 map_l = left->mem_info->daddr.map;
506 if (right->mem_info)
507 map_r = right->mem_info->daddr.map;
508
509 return _sort__dso_cmp(map_l, map_r);
510}
511
512static int hist_entry__dso_daddr_snprintf(struct hist_entry *self, char *bf,
513 size_t size, unsigned int width)
514{
515 struct map *map = NULL;
516
517 if (self->mem_info)
518 map = self->mem_info->daddr.map;
519
520 return _hist_entry__dso_snprintf(map, bf, size, width);
521}
522
523static int64_t
524sort__locked_cmp(struct hist_entry *left, struct hist_entry *right)
525{
526 union perf_mem_data_src data_src_l;
527 union perf_mem_data_src data_src_r;
528
529 if (left->mem_info)
530 data_src_l = left->mem_info->data_src;
531 else
532 data_src_l.mem_lock = PERF_MEM_LOCK_NA;
533
534 if (right->mem_info)
535 data_src_r = right->mem_info->data_src;
536 else
537 data_src_r.mem_lock = PERF_MEM_LOCK_NA;
538
539 return (int64_t)(data_src_r.mem_lock - data_src_l.mem_lock);
540}
541
542static int hist_entry__locked_snprintf(struct hist_entry *self, char *bf,
543 size_t size, unsigned int width)
544{
545 const char *out;
546 u64 mask = PERF_MEM_LOCK_NA;
547
548 if (self->mem_info)
549 mask = self->mem_info->data_src.mem_lock;
550
551 if (mask & PERF_MEM_LOCK_NA)
552 out = "N/A";
553 else if (mask & PERF_MEM_LOCK_LOCKED)
554 out = "Yes";
555 else
556 out = "No";
557
558 return repsep_snprintf(bf, size, "%-*s", width, out);
559}
560
561static int64_t
562sort__tlb_cmp(struct hist_entry *left, struct hist_entry *right)
563{
564 union perf_mem_data_src data_src_l;
565 union perf_mem_data_src data_src_r;
566
567 if (left->mem_info)
568 data_src_l = left->mem_info->data_src;
569 else
570 data_src_l.mem_dtlb = PERF_MEM_TLB_NA;
571
572 if (right->mem_info)
573 data_src_r = right->mem_info->data_src;
574 else
575 data_src_r.mem_dtlb = PERF_MEM_TLB_NA;
576
577 return (int64_t)(data_src_r.mem_dtlb - data_src_l.mem_dtlb);
578}
579
580static const char * const tlb_access[] = {
581 "N/A",
582 "HIT",
583 "MISS",
584 "L1",
585 "L2",
586 "Walker",
587 "Fault",
588};
589#define NUM_TLB_ACCESS (sizeof(tlb_access)/sizeof(const char *))
590
591static int hist_entry__tlb_snprintf(struct hist_entry *self, char *bf,
592 size_t size, unsigned int width)
593{
594 char out[64];
595 size_t sz = sizeof(out) - 1; /* -1 for null termination */
596 size_t l = 0, i;
597 u64 m = PERF_MEM_TLB_NA;
598 u64 hit, miss;
599
600 out[0] = '\0';
601
602 if (self->mem_info)
603 m = self->mem_info->data_src.mem_dtlb;
604
605 hit = m & PERF_MEM_TLB_HIT;
606 miss = m & PERF_MEM_TLB_MISS;
607
608 /* already taken care of */
609 m &= ~(PERF_MEM_TLB_HIT|PERF_MEM_TLB_MISS);
610
611 for (i = 0; m && i < NUM_TLB_ACCESS; i++, m >>= 1) {
612 if (!(m & 0x1))
613 continue;
614 if (l) {
615 strcat(out, " or ");
616 l += 4;
617 }
618 strncat(out, tlb_access[i], sz - l);
619 l += strlen(tlb_access[i]);
620 }
621 if (*out == '\0')
622 strcpy(out, "N/A");
623 if (hit)
624 strncat(out, " hit", sz - l);
625 if (miss)
626 strncat(out, " miss", sz - l);
627
628 return repsep_snprintf(bf, size, "%-*s", width, out);
629}
630
631static int64_t
632sort__lvl_cmp(struct hist_entry *left, struct hist_entry *right)
633{
634 union perf_mem_data_src data_src_l;
635 union perf_mem_data_src data_src_r;
636
637 if (left->mem_info)
638 data_src_l = left->mem_info->data_src;
639 else
640 data_src_l.mem_lvl = PERF_MEM_LVL_NA;
641
642 if (right->mem_info)
643 data_src_r = right->mem_info->data_src;
644 else
645 data_src_r.mem_lvl = PERF_MEM_LVL_NA;
646
647 return (int64_t)(data_src_r.mem_lvl - data_src_l.mem_lvl);
648}
649
650static const char * const mem_lvl[] = {
651 "N/A",
652 "HIT",
653 "MISS",
654 "L1",
655 "LFB",
656 "L2",
657 "L3",
658 "Local RAM",
659 "Remote RAM (1 hop)",
660 "Remote RAM (2 hops)",
661 "Remote Cache (1 hop)",
662 "Remote Cache (2 hops)",
663 "I/O",
664 "Uncached",
665};
666#define NUM_MEM_LVL (sizeof(mem_lvl)/sizeof(const char *))
667
668static int hist_entry__lvl_snprintf(struct hist_entry *self, char *bf,
669 size_t size, unsigned int width)
670{
671 char out[64];
672 size_t sz = sizeof(out) - 1; /* -1 for null termination */
673 size_t i, l = 0;
674 u64 m = PERF_MEM_LVL_NA;
675 u64 hit, miss;
676
677 if (self->mem_info)
678 m = self->mem_info->data_src.mem_lvl;
679
680 out[0] = '\0';
681
682 hit = m & PERF_MEM_LVL_HIT;
683 miss = m & PERF_MEM_LVL_MISS;
684
685 /* already taken care of */
686 m &= ~(PERF_MEM_LVL_HIT|PERF_MEM_LVL_MISS);
687
688 for (i = 0; m && i < NUM_MEM_LVL; i++, m >>= 1) {
689 if (!(m & 0x1))
690 continue;
691 if (l) {
692 strcat(out, " or ");
693 l += 4;
694 }
695 strncat(out, mem_lvl[i], sz - l);
696 l += strlen(mem_lvl[i]);
697 }
698 if (*out == '\0')
699 strcpy(out, "N/A");
700 if (hit)
701 strncat(out, " hit", sz - l);
702 if (miss)
703 strncat(out, " miss", sz - l);
704
705 return repsep_snprintf(bf, size, "%-*s", width, out);
706}
707
708static int64_t
709sort__snoop_cmp(struct hist_entry *left, struct hist_entry *right)
710{
711 union perf_mem_data_src data_src_l;
712 union perf_mem_data_src data_src_r;
713
714 if (left->mem_info)
715 data_src_l = left->mem_info->data_src;
716 else
717 data_src_l.mem_snoop = PERF_MEM_SNOOP_NA;
718
719 if (right->mem_info)
720 data_src_r = right->mem_info->data_src;
721 else
722 data_src_r.mem_snoop = PERF_MEM_SNOOP_NA;
723
724 return (int64_t)(data_src_r.mem_snoop - data_src_l.mem_snoop);
725}
726
727static const char * const snoop_access[] = {
728 "N/A",
729 "None",
730 "Miss",
731 "Hit",
732 "HitM",
733};
734#define NUM_SNOOP_ACCESS (sizeof(snoop_access)/sizeof(const char *))
735
736static int hist_entry__snoop_snprintf(struct hist_entry *self, char *bf,
737 size_t size, unsigned int width)
738{
739 char out[64];
740 size_t sz = sizeof(out) - 1; /* -1 for null termination */
741 size_t i, l = 0;
742 u64 m = PERF_MEM_SNOOP_NA;
743
744 out[0] = '\0';
745
746 if (self->mem_info)
747 m = self->mem_info->data_src.mem_snoop;
748
749 for (i = 0; m && i < NUM_SNOOP_ACCESS; i++, m >>= 1) {
750 if (!(m & 0x1))
751 continue;
752 if (l) {
753 strcat(out, " or ");
754 l += 4;
755 }
756 strncat(out, snoop_access[i], sz - l);
757 l += strlen(snoop_access[i]);
758 }
759
760 if (*out == '\0')
761 strcpy(out, "N/A");
762
763 return repsep_snprintf(bf, size, "%-*s", width, out);
764}
765
460struct sort_entry sort_mispredict = { 766struct sort_entry sort_mispredict = {
461 .se_header = "Branch Mispredicted", 767 .se_header = "Branch Mispredicted",
462 .se_cmp = sort__mispredict_cmp, 768 .se_cmp = sort__mispredict_cmp,
@@ -464,6 +770,91 @@ struct sort_entry sort_mispredict = {
464 .se_width_idx = HISTC_MISPREDICT, 770 .se_width_idx = HISTC_MISPREDICT,
465}; 771};
466 772
773static u64 he_weight(struct hist_entry *he)
774{
775 return he->stat.nr_events ? he->stat.weight / he->stat.nr_events : 0;
776}
777
778static int64_t
779sort__local_weight_cmp(struct hist_entry *left, struct hist_entry *right)
780{
781 return he_weight(left) - he_weight(right);
782}
783
784static int hist_entry__local_weight_snprintf(struct hist_entry *self, char *bf,
785 size_t size, unsigned int width)
786{
787 return repsep_snprintf(bf, size, "%-*llu", width, he_weight(self));
788}
789
790struct sort_entry sort_local_weight = {
791 .se_header = "Local Weight",
792 .se_cmp = sort__local_weight_cmp,
793 .se_snprintf = hist_entry__local_weight_snprintf,
794 .se_width_idx = HISTC_LOCAL_WEIGHT,
795};
796
797static int64_t
798sort__global_weight_cmp(struct hist_entry *left, struct hist_entry *right)
799{
800 return left->stat.weight - right->stat.weight;
801}
802
803static int hist_entry__global_weight_snprintf(struct hist_entry *self, char *bf,
804 size_t size, unsigned int width)
805{
806 return repsep_snprintf(bf, size, "%-*llu", width, self->stat.weight);
807}
808
809struct sort_entry sort_global_weight = {
810 .se_header = "Weight",
811 .se_cmp = sort__global_weight_cmp,
812 .se_snprintf = hist_entry__global_weight_snprintf,
813 .se_width_idx = HISTC_GLOBAL_WEIGHT,
814};
815
816struct sort_entry sort_mem_daddr_sym = {
817 .se_header = "Data Symbol",
818 .se_cmp = sort__daddr_cmp,
819 .se_snprintf = hist_entry__daddr_snprintf,
820 .se_width_idx = HISTC_MEM_DADDR_SYMBOL,
821};
822
823struct sort_entry sort_mem_daddr_dso = {
824 .se_header = "Data Object",
825 .se_cmp = sort__dso_daddr_cmp,
826 .se_snprintf = hist_entry__dso_daddr_snprintf,
827 .se_width_idx = HISTC_MEM_DADDR_SYMBOL,
828};
829
830struct sort_entry sort_mem_locked = {
831 .se_header = "Locked",
832 .se_cmp = sort__locked_cmp,
833 .se_snprintf = hist_entry__locked_snprintf,
834 .se_width_idx = HISTC_MEM_LOCKED,
835};
836
837struct sort_entry sort_mem_tlb = {
838 .se_header = "TLB access",
839 .se_cmp = sort__tlb_cmp,
840 .se_snprintf = hist_entry__tlb_snprintf,
841 .se_width_idx = HISTC_MEM_TLB,
842};
843
844struct sort_entry sort_mem_lvl = {
845 .se_header = "Memory access",
846 .se_cmp = sort__lvl_cmp,
847 .se_snprintf = hist_entry__lvl_snprintf,
848 .se_width_idx = HISTC_MEM_LVL,
849};
850
851struct sort_entry sort_mem_snoop = {
852 .se_header = "Snoop",
853 .se_cmp = sort__snoop_cmp,
854 .se_snprintf = hist_entry__snoop_snprintf,
855 .se_width_idx = HISTC_MEM_SNOOP,
856};
857
467struct sort_dimension { 858struct sort_dimension {
468 const char *name; 859 const char *name;
469 struct sort_entry *entry; 860 struct sort_entry *entry;
@@ -480,6 +871,14 @@ static struct sort_dimension common_sort_dimensions[] = {
480 DIM(SORT_PARENT, "parent", sort_parent), 871 DIM(SORT_PARENT, "parent", sort_parent),
481 DIM(SORT_CPU, "cpu", sort_cpu), 872 DIM(SORT_CPU, "cpu", sort_cpu),
482 DIM(SORT_SRCLINE, "srcline", sort_srcline), 873 DIM(SORT_SRCLINE, "srcline", sort_srcline),
874 DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
875 DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
876 DIM(SORT_MEM_DADDR_SYMBOL, "symbol_daddr", sort_mem_daddr_sym),
877 DIM(SORT_MEM_DADDR_DSO, "dso_daddr", sort_mem_daddr_dso),
878 DIM(SORT_MEM_LOCKED, "locked", sort_mem_locked),
879 DIM(SORT_MEM_TLB, "tlb", sort_mem_tlb),
880 DIM(SORT_MEM_LVL, "mem", sort_mem_lvl),
881 DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop),
483}; 882};
484 883
485#undef DIM 884#undef DIM
@@ -516,7 +915,10 @@ int sort_dimension__add(const char *tok)
516 return -EINVAL; 915 return -EINVAL;
517 } 916 }
518 sort__has_parent = 1; 917 sort__has_parent = 1;
519 } else if (sd->entry == &sort_sym) { 918 } else if (sd->entry == &sort_sym ||
919 sd->entry == &sort_sym_from ||
920 sd->entry == &sort_sym_to ||
921 sd->entry == &sort_mem_daddr_sym) {
520 sort__has_sym = 1; 922 sort__has_sym = 1;
521 } 923 }
522 924
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index b13e56f6ccbe..f24bdf64238c 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -49,6 +49,7 @@ struct he_stat {
49 u64 period_us; 49 u64 period_us;
50 u64 period_guest_sys; 50 u64 period_guest_sys;
51 u64 period_guest_us; 51 u64 period_guest_us;
52 u64 weight;
52 u32 nr_events; 53 u32 nr_events;
53}; 54};
54 55
@@ -100,7 +101,8 @@ struct hist_entry {
100 struct rb_root sorted_chain; 101 struct rb_root sorted_chain;
101 struct branch_info *branch_info; 102 struct branch_info *branch_info;
102 struct hists *hists; 103 struct hists *hists;
103 struct callchain_root callchain[0]; 104 struct mem_info *mem_info;
105 struct callchain_root callchain[0]; /* must be last member */
104}; 106};
105 107
106static inline bool hist_entry__has_pairs(struct hist_entry *he) 108static inline bool hist_entry__has_pairs(struct hist_entry *he)
@@ -130,6 +132,14 @@ enum sort_type {
130 SORT_PARENT, 132 SORT_PARENT,
131 SORT_CPU, 133 SORT_CPU,
132 SORT_SRCLINE, 134 SORT_SRCLINE,
135 SORT_LOCAL_WEIGHT,
136 SORT_GLOBAL_WEIGHT,
137 SORT_MEM_DADDR_SYMBOL,
138 SORT_MEM_DADDR_DSO,
139 SORT_MEM_LOCKED,
140 SORT_MEM_TLB,
141 SORT_MEM_LVL,
142 SORT_MEM_SNOOP,
133 143
134 /* branch stack specific sort keys */ 144 /* branch stack specific sort keys */
135 __SORT_BRANCH_STACK, 145 __SORT_BRANCH_STACK,
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 54efcb5659ac..4b12bf850325 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -806,9 +806,12 @@ int dso__load_sym(struct dso *dso, struct map *map,
806 * DWARF DW_compile_unit has this, but we don't always have access 806 * DWARF DW_compile_unit has this, but we don't always have access
807 * to it... 807 * to it...
808 */ 808 */
809 demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI); 809 if (symbol_conf.demangle) {
810 if (demangled != NULL) 810 demangled = bfd_demangle(NULL, elf_name,
811 elf_name = demangled; 811 DMGL_PARAMS | DMGL_ANSI);
812 if (demangled != NULL)
813 elf_name = demangled;
814 }
812new_symbol: 815new_symbol:
813 f = symbol__new(sym.st_value, sym.st_size, 816 f = symbol__new(sym.st_value, sym.st_size,
814 GELF_ST_BIND(sym.st_info), elf_name); 817 GELF_ST_BIND(sym.st_info), elf_name);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index e6432d85b43d..8cf3b5426a9a 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -36,6 +36,7 @@ struct symbol_conf symbol_conf = {
36 .use_modules = true, 36 .use_modules = true,
37 .try_vmlinux_path = true, 37 .try_vmlinux_path = true,
38 .annotate_src = true, 38 .annotate_src = true,
39 .demangle = true,
39 .symfs = "", 40 .symfs = "",
40}; 41};
41 42
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index b62ca37c4b77..5f720dc076da 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -97,7 +97,8 @@ struct symbol_conf {
97 kptr_restrict, 97 kptr_restrict,
98 annotate_asm_raw, 98 annotate_asm_raw,
99 annotate_src, 99 annotate_src,
100 event_group; 100 event_group,
101 demangle;
101 const char *vmlinux_name, 102 const char *vmlinux_name,
102 *kallsyms_name, 103 *kallsyms_name,
103 *source_prefix, 104 *source_prefix,
@@ -155,6 +156,12 @@ struct branch_info {
155 struct branch_flags flags; 156 struct branch_flags flags;
156}; 157};
157 158
159struct mem_info {
160 struct addr_map_symbol iaddr;
161 struct addr_map_symbol daddr;
162 union perf_mem_data_src data_src;
163};
164
158struct addr_location { 165struct addr_location {
159 struct thread *thread; 166 struct thread *thread;
160 struct map *map; 167 struct map *map;
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index 5729f434c5b1..3917eb9a8479 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -43,26 +43,15 @@
43 43
44#define VERSION "0.5" 44#define VERSION "0.5"
45 45
46static const char *output_file = "trace.info";
47static int output_fd; 46static int output_fd;
48 47
49 48
50static void *malloc_or_die(unsigned int size)
51{
52 void *data;
53
54 data = malloc(size);
55 if (!data)
56 die("malloc");
57 return data;
58}
59
60static const char *find_debugfs(void) 49static const char *find_debugfs(void)
61{ 50{
62 const char *path = perf_debugfs_mount(NULL); 51 const char *path = perf_debugfs_mount(NULL);
63 52
64 if (!path) 53 if (!path)
65 die("Your kernel not support debugfs filesystem"); 54 pr_debug("Your kernel does not support the debugfs filesystem");
66 55
67 return path; 56 return path;
68} 57}
@@ -81,8 +70,12 @@ static const char *find_tracing_dir(void)
81 return tracing; 70 return tracing;
82 71
83 debugfs = find_debugfs(); 72 debugfs = find_debugfs();
73 if (!debugfs)
74 return NULL;
84 75
85 tracing = malloc_or_die(strlen(debugfs) + 9); 76 tracing = malloc(strlen(debugfs) + 9);
77 if (!tracing)
78 return NULL;
86 79
87 sprintf(tracing, "%s/tracing", debugfs); 80 sprintf(tracing, "%s/tracing", debugfs);
88 81
@@ -99,7 +92,9 @@ static char *get_tracing_file(const char *name)
99 if (!tracing) 92 if (!tracing)
100 return NULL; 93 return NULL;
101 94
102 file = malloc_or_die(strlen(tracing) + strlen(name) + 2); 95 file = malloc(strlen(tracing) + strlen(name) + 2);
96 if (!file)
97 return NULL;
103 98
104 sprintf(file, "%s/%s", tracing, name); 99 sprintf(file, "%s/%s", tracing, name);
105 return file; 100 return file;
@@ -110,17 +105,6 @@ static void put_tracing_file(char *file)
110 free(file); 105 free(file);
111} 106}
112 107
113static ssize_t write_or_die(const void *buf, size_t len)
114{
115 int ret;
116
117 ret = write(output_fd, buf, len);
118 if (ret < 0)
119 die("writing to '%s'", output_file);
120
121 return ret;
122}
123
124int bigendian(void) 108int bigendian(void)
125{ 109{
126 unsigned char str[] = { 0x1, 0x2, 0x3, 0x4, 0x0, 0x0, 0x0, 0x0}; 110 unsigned char str[] = { 0x1, 0x2, 0x3, 0x4, 0x0, 0x0, 0x0, 0x0};
@@ -131,59 +115,106 @@ int bigendian(void)
131} 115}
132 116
133/* unfortunately, you can not stat debugfs or proc files for size */ 117/* unfortunately, you can not stat debugfs or proc files for size */
134static void record_file(const char *file, size_t hdr_sz) 118static int record_file(const char *file, ssize_t hdr_sz)
135{ 119{
136 unsigned long long size = 0; 120 unsigned long long size = 0;
137 char buf[BUFSIZ], *sizep; 121 char buf[BUFSIZ], *sizep;
138 off_t hdr_pos = lseek(output_fd, 0, SEEK_CUR); 122 off_t hdr_pos = lseek(output_fd, 0, SEEK_CUR);
139 int r, fd; 123 int r, fd;
124 int err = -EIO;
140 125
141 fd = open(file, O_RDONLY); 126 fd = open(file, O_RDONLY);
142 if (fd < 0) 127 if (fd < 0) {
143 die("Can't read '%s'", file); 128 pr_debug("Can't read '%s'", file);
129 return -errno;
130 }
144 131
145 /* put in zeros for file size, then fill true size later */ 132 /* put in zeros for file size, then fill true size later */
146 if (hdr_sz) 133 if (hdr_sz) {
147 write_or_die(&size, hdr_sz); 134 if (write(output_fd, &size, hdr_sz) != hdr_sz)
135 goto out;
136 }
148 137
149 do { 138 do {
150 r = read(fd, buf, BUFSIZ); 139 r = read(fd, buf, BUFSIZ);
151 if (r > 0) { 140 if (r > 0) {
152 size += r; 141 size += r;
153 write_or_die(buf, r); 142 if (write(output_fd, buf, r) != r)
143 goto out;
154 } 144 }
155 } while (r > 0); 145 } while (r > 0);
156 close(fd);
157 146
158 /* ugh, handle big-endian hdr_size == 4 */ 147 /* ugh, handle big-endian hdr_size == 4 */
159 sizep = (char*)&size; 148 sizep = (char*)&size;
160 if (bigendian()) 149 if (bigendian())
161 sizep += sizeof(u64) - hdr_sz; 150 sizep += sizeof(u64) - hdr_sz;
162 151
163 if (hdr_sz && pwrite(output_fd, sizep, hdr_sz, hdr_pos) < 0) 152 if (hdr_sz && pwrite(output_fd, sizep, hdr_sz, hdr_pos) < 0) {
164 die("writing to %s", output_file); 153 pr_debug("writing file size failed\n");
154 goto out;
155 }
156
157 err = 0;
158out:
159 close(fd);
160 return err;
165} 161}
166 162
167static void read_header_files(void) 163static int read_header_files(void)
168{ 164{
169 char *path; 165 char *path;
170 struct stat st; 166 struct stat st;
167 int err = -EIO;
171 168
172 path = get_tracing_file("events/header_page"); 169 path = get_tracing_file("events/header_page");
173 if (stat(path, &st) < 0) 170 if (!path) {
174 die("can't read '%s'", path); 171 pr_debug("can't get tracing/events/header_page");
172 return -ENOMEM;
173 }
174
175 if (stat(path, &st) < 0) {
176 pr_debug("can't read '%s'", path);
177 goto out;
178 }
179
180 if (write(output_fd, "header_page", 12) != 12) {
181 pr_debug("can't write header_page\n");
182 goto out;
183 }
184
185 if (record_file(path, 8) < 0) {
186 pr_debug("can't record header_page file\n");
187 goto out;
188 }
175 189
176 write_or_die("header_page", 12);
177 record_file(path, 8);
178 put_tracing_file(path); 190 put_tracing_file(path);
179 191
180 path = get_tracing_file("events/header_event"); 192 path = get_tracing_file("events/header_event");
181 if (stat(path, &st) < 0) 193 if (!path) {
182 die("can't read '%s'", path); 194 pr_debug("can't get tracing/events/header_event");
195 err = -ENOMEM;
196 goto out;
197 }
198
199 if (stat(path, &st) < 0) {
200 pr_debug("can't read '%s'", path);
201 goto out;
202 }
203
204 if (write(output_fd, "header_event", 13) != 13) {
205 pr_debug("can't write header_event\n");
206 goto out;
207 }
208
209 if (record_file(path, 8) < 0) {
210 pr_debug("can't record header_event file\n");
211 goto out;
212 }
183 213
184 write_or_die("header_event", 13); 214 err = 0;
185 record_file(path, 8); 215out:
186 put_tracing_file(path); 216 put_tracing_file(path);
217 return err;
187} 218}
188 219
189static bool name_in_tp_list(char *sys, struct tracepoint_path *tps) 220static bool name_in_tp_list(char *sys, struct tracepoint_path *tps)
@@ -197,7 +228,7 @@ static bool name_in_tp_list(char *sys, struct tracepoint_path *tps)
197 return false; 228 return false;
198} 229}
199 230
200static void copy_event_system(const char *sys, struct tracepoint_path *tps) 231static int copy_event_system(const char *sys, struct tracepoint_path *tps)
201{ 232{
202 struct dirent *dent; 233 struct dirent *dent;
203 struct stat st; 234 struct stat st;
@@ -205,10 +236,13 @@ static void copy_event_system(const char *sys, struct tracepoint_path *tps)
205 DIR *dir; 236 DIR *dir;
206 int count = 0; 237 int count = 0;
207 int ret; 238 int ret;
239 int err;
208 240
209 dir = opendir(sys); 241 dir = opendir(sys);
210 if (!dir) 242 if (!dir) {
211 die("can't read directory '%s'", sys); 243 pr_debug("can't read directory '%s'", sys);
244 return -errno;
245 }
212 246
213 while ((dent = readdir(dir))) { 247 while ((dent = readdir(dir))) {
214 if (dent->d_type != DT_DIR || 248 if (dent->d_type != DT_DIR ||
@@ -216,7 +250,11 @@ static void copy_event_system(const char *sys, struct tracepoint_path *tps)
216 strcmp(dent->d_name, "..") == 0 || 250 strcmp(dent->d_name, "..") == 0 ||
217 !name_in_tp_list(dent->d_name, tps)) 251 !name_in_tp_list(dent->d_name, tps))
218 continue; 252 continue;
219 format = malloc_or_die(strlen(sys) + strlen(dent->d_name) + 10); 253 format = malloc(strlen(sys) + strlen(dent->d_name) + 10);
254 if (!format) {
255 err = -ENOMEM;
256 goto out;
257 }
220 sprintf(format, "%s/%s/format", sys, dent->d_name); 258 sprintf(format, "%s/%s/format", sys, dent->d_name);
221 ret = stat(format, &st); 259 ret = stat(format, &st);
222 free(format); 260 free(format);
@@ -225,7 +263,11 @@ static void copy_event_system(const char *sys, struct tracepoint_path *tps)
225 count++; 263 count++;
226 } 264 }
227 265
228 write_or_die(&count, 4); 266 if (write(output_fd, &count, 4) != 4) {
267 err = -EIO;
268 pr_debug("can't write count\n");
269 goto out;
270 }
229 271
230 rewinddir(dir); 272 rewinddir(dir);
231 while ((dent = readdir(dir))) { 273 while ((dent = readdir(dir))) {
@@ -234,27 +276,45 @@ static void copy_event_system(const char *sys, struct tracepoint_path *tps)
234 strcmp(dent->d_name, "..") == 0 || 276 strcmp(dent->d_name, "..") == 0 ||
235 !name_in_tp_list(dent->d_name, tps)) 277 !name_in_tp_list(dent->d_name, tps))
236 continue; 278 continue;
237 format = malloc_or_die(strlen(sys) + strlen(dent->d_name) + 10); 279 format = malloc(strlen(sys) + strlen(dent->d_name) + 10);
280 if (!format) {
281 err = -ENOMEM;
282 goto out;
283 }
238 sprintf(format, "%s/%s/format", sys, dent->d_name); 284 sprintf(format, "%s/%s/format", sys, dent->d_name);
239 ret = stat(format, &st); 285 ret = stat(format, &st);
240 286
241 if (ret >= 0) 287 if (ret >= 0) {
242 record_file(format, 8); 288 err = record_file(format, 8);
243 289 if (err) {
290 free(format);
291 goto out;
292 }
293 }
244 free(format); 294 free(format);
245 } 295 }
296 err = 0;
297out:
246 closedir(dir); 298 closedir(dir);
299 return err;
247} 300}
248 301
249static void read_ftrace_files(struct tracepoint_path *tps) 302static int read_ftrace_files(struct tracepoint_path *tps)
250{ 303{
251 char *path; 304 char *path;
305 int ret;
252 306
253 path = get_tracing_file("events/ftrace"); 307 path = get_tracing_file("events/ftrace");
308 if (!path) {
309 pr_debug("can't get tracing/events/ftrace");
310 return -ENOMEM;
311 }
254 312
255 copy_event_system(path, tps); 313 ret = copy_event_system(path, tps);
256 314
257 put_tracing_file(path); 315 put_tracing_file(path);
316
317 return ret;
258} 318}
259 319
260static bool system_in_tp_list(char *sys, struct tracepoint_path *tps) 320static bool system_in_tp_list(char *sys, struct tracepoint_path *tps)
@@ -268,7 +328,7 @@ static bool system_in_tp_list(char *sys, struct tracepoint_path *tps)
268 return false; 328 return false;
269} 329}
270 330
271static void read_event_files(struct tracepoint_path *tps) 331static int read_event_files(struct tracepoint_path *tps)
272{ 332{
273 struct dirent *dent; 333 struct dirent *dent;
274 struct stat st; 334 struct stat st;
@@ -277,12 +337,20 @@ static void read_event_files(struct tracepoint_path *tps)
277 DIR *dir; 337 DIR *dir;
278 int count = 0; 338 int count = 0;
279 int ret; 339 int ret;
340 int err;
280 341
281 path = get_tracing_file("events"); 342 path = get_tracing_file("events");
343 if (!path) {
344 pr_debug("can't get tracing/events");
345 return -ENOMEM;
346 }
282 347
283 dir = opendir(path); 348 dir = opendir(path);
284 if (!dir) 349 if (!dir) {
285 die("can't read directory '%s'", path); 350 err = -errno;
351 pr_debug("can't read directory '%s'", path);
352 goto out;
353 }
286 354
287 while ((dent = readdir(dir))) { 355 while ((dent = readdir(dir))) {
288 if (dent->d_type != DT_DIR || 356 if (dent->d_type != DT_DIR ||
@@ -294,7 +362,11 @@ static void read_event_files(struct tracepoint_path *tps)
294 count++; 362 count++;
295 } 363 }
296 364
297 write_or_die(&count, 4); 365 if (write(output_fd, &count, 4) != 4) {
366 err = -EIO;
367 pr_debug("can't write count\n");
368 goto out;
369 }
298 370
299 rewinddir(dir); 371 rewinddir(dir);
300 while ((dent = readdir(dir))) { 372 while ((dent = readdir(dir))) {
@@ -304,56 +376,90 @@ static void read_event_files(struct tracepoint_path *tps)
304 strcmp(dent->d_name, "ftrace") == 0 || 376 strcmp(dent->d_name, "ftrace") == 0 ||
305 !system_in_tp_list(dent->d_name, tps)) 377 !system_in_tp_list(dent->d_name, tps))
306 continue; 378 continue;
307 sys = malloc_or_die(strlen(path) + strlen(dent->d_name) + 2); 379 sys = malloc(strlen(path) + strlen(dent->d_name) + 2);
380 if (!sys) {
381 err = -ENOMEM;
382 goto out;
383 }
308 sprintf(sys, "%s/%s", path, dent->d_name); 384 sprintf(sys, "%s/%s", path, dent->d_name);
309 ret = stat(sys, &st); 385 ret = stat(sys, &st);
310 if (ret >= 0) { 386 if (ret >= 0) {
311 write_or_die(dent->d_name, strlen(dent->d_name) + 1); 387 ssize_t size = strlen(dent->d_name) + 1;
312 copy_event_system(sys, tps); 388
389 if (write(output_fd, dent->d_name, size) != size ||
390 copy_event_system(sys, tps) < 0) {
391 err = -EIO;
392 free(sys);
393 goto out;
394 }
313 } 395 }
314 free(sys); 396 free(sys);
315 } 397 }
316 398 err = 0;
399out:
317 closedir(dir); 400 closedir(dir);
318 put_tracing_file(path); 401 put_tracing_file(path);
402
403 return err;
319} 404}
320 405
321static void read_proc_kallsyms(void) 406static int read_proc_kallsyms(void)
322{ 407{
323 unsigned int size; 408 unsigned int size;
324 const char *path = "/proc/kallsyms"; 409 const char *path = "/proc/kallsyms";
325 struct stat st; 410 struct stat st;
326 int ret; 411 int ret, err = 0;
327 412
328 ret = stat(path, &st); 413 ret = stat(path, &st);
329 if (ret < 0) { 414 if (ret < 0) {
330 /* not found */ 415 /* not found */
331 size = 0; 416 size = 0;
332 write_or_die(&size, 4); 417 if (write(output_fd, &size, 4) != 4)
333 return; 418 err = -EIO;
419 return err;
334 } 420 }
335 record_file(path, 4); 421 return record_file(path, 4);
336} 422}
337 423
338static void read_ftrace_printk(void) 424static int read_ftrace_printk(void)
339{ 425{
340 unsigned int size; 426 unsigned int size;
341 char *path; 427 char *path;
342 struct stat st; 428 struct stat st;
343 int ret; 429 int ret, err = 0;
344 430
345 path = get_tracing_file("printk_formats"); 431 path = get_tracing_file("printk_formats");
432 if (!path) {
433 pr_debug("can't get tracing/printk_formats");
434 return -ENOMEM;
435 }
436
346 ret = stat(path, &st); 437 ret = stat(path, &st);
347 if (ret < 0) { 438 if (ret < 0) {
348 /* not found */ 439 /* not found */
349 size = 0; 440 size = 0;
350 write_or_die(&size, 4); 441 if (write(output_fd, &size, 4) != 4)
442 err = -EIO;
351 goto out; 443 goto out;
352 } 444 }
353 record_file(path, 4); 445 err = record_file(path, 4);
354 446
355out: 447out:
356 put_tracing_file(path); 448 put_tracing_file(path);
449 return err;
450}
451
452static void
453put_tracepoints_path(struct tracepoint_path *tps)
454{
455 while (tps) {
456 struct tracepoint_path *t = tps;
457
458 tps = tps->next;
459 free(t->name);
460 free(t->system);
461 free(t);
462 }
357} 463}
358 464
359static struct tracepoint_path * 465static struct tracepoint_path *
@@ -368,27 +474,17 @@ get_tracepoints_path(struct list_head *pattrs)
368 continue; 474 continue;
369 ++nr_tracepoints; 475 ++nr_tracepoints;
370 ppath->next = tracepoint_id_to_path(pos->attr.config); 476 ppath->next = tracepoint_id_to_path(pos->attr.config);
371 if (!ppath->next) 477 if (!ppath->next) {
372 die("%s\n", "No memory to alloc tracepoints list"); 478 pr_debug("No memory to alloc tracepoints list\n");
479 put_tracepoints_path(&path);
480 return NULL;
481 }
373 ppath = ppath->next; 482 ppath = ppath->next;
374 } 483 }
375 484
376 return nr_tracepoints > 0 ? path.next : NULL; 485 return nr_tracepoints > 0 ? path.next : NULL;
377} 486}
378 487
379static void
380put_tracepoints_path(struct tracepoint_path *tps)
381{
382 while (tps) {
383 struct tracepoint_path *t = tps;
384
385 tps = tps->next;
386 free(t->name);
387 free(t->system);
388 free(t);
389 }
390}
391
392bool have_tracepoints(struct list_head *pattrs) 488bool have_tracepoints(struct list_head *pattrs)
393{ 489{
394 struct perf_evsel *pos; 490 struct perf_evsel *pos;
@@ -400,9 +496,10 @@ bool have_tracepoints(struct list_head *pattrs)
400 return false; 496 return false;
401} 497}
402 498
403static void tracing_data_header(void) 499static int tracing_data_header(void)
404{ 500{
405 char buf[20]; 501 char buf[20];
502 ssize_t size;
406 503
407 /* just guessing this is someone's birthday.. ;) */ 504 /* just guessing this is someone's birthday.. ;) */
408 buf[0] = 23; 505 buf[0] = 23;
@@ -410,9 +507,12 @@ static void tracing_data_header(void)
410 buf[2] = 68; 507 buf[2] = 68;
411 memcpy(buf + 3, "tracing", 7); 508 memcpy(buf + 3, "tracing", 7);
412 509
413 write_or_die(buf, 10); 510 if (write(output_fd, buf, 10) != 10)
511 return -1;
414 512
415 write_or_die(VERSION, strlen(VERSION) + 1); 513 size = strlen(VERSION) + 1;
514 if (write(output_fd, VERSION, size) != size)
515 return -1;
416 516
417 /* save endian */ 517 /* save endian */
418 if (bigendian()) 518 if (bigendian())
@@ -422,14 +522,19 @@ static void tracing_data_header(void)
422 522
423 read_trace_init(buf[0], buf[0]); 523 read_trace_init(buf[0], buf[0]);
424 524
425 write_or_die(buf, 1); 525 if (write(output_fd, buf, 1) != 1)
526 return -1;
426 527
427 /* save size of long */ 528 /* save size of long */
428 buf[0] = sizeof(long); 529 buf[0] = sizeof(long);
429 write_or_die(buf, 1); 530 if (write(output_fd, buf, 1) != 1)
531 return -1;
430 532
431 /* save page_size */ 533 /* save page_size */
432 write_or_die(&page_size, 4); 534 if (write(output_fd, &page_size, 4) != 4)
535 return -1;
536
537 return 0;
433} 538}
434 539
435struct tracing_data *tracing_data_get(struct list_head *pattrs, 540struct tracing_data *tracing_data_get(struct list_head *pattrs,
@@ -437,6 +542,7 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
437{ 542{
438 struct tracepoint_path *tps; 543 struct tracepoint_path *tps;
439 struct tracing_data *tdata; 544 struct tracing_data *tdata;
545 int err;
440 546
441 output_fd = fd; 547 output_fd = fd;
442 548
@@ -444,7 +550,10 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
444 if (!tps) 550 if (!tps)
445 return NULL; 551 return NULL;
446 552
447 tdata = malloc_or_die(sizeof(*tdata)); 553 tdata = malloc(sizeof(*tdata));
554 if (!tdata)
555 return NULL;
556
448 tdata->temp = temp; 557 tdata->temp = temp;
449 tdata->size = 0; 558 tdata->size = 0;
450 559
@@ -453,12 +562,16 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
453 562
454 snprintf(tdata->temp_file, sizeof(tdata->temp_file), 563 snprintf(tdata->temp_file, sizeof(tdata->temp_file),
455 "/tmp/perf-XXXXXX"); 564 "/tmp/perf-XXXXXX");
456 if (!mkstemp(tdata->temp_file)) 565 if (!mkstemp(tdata->temp_file)) {
457 die("Can't make temp file"); 566 pr_debug("Can't make temp file");
567 return NULL;
568 }
458 569
459 temp_fd = open(tdata->temp_file, O_RDWR); 570 temp_fd = open(tdata->temp_file, O_RDWR);
460 if (temp_fd < 0) 571 if (temp_fd < 0) {
461 die("Can't read '%s'", tdata->temp_file); 572 pr_debug("Can't read '%s'", tdata->temp_file);
573 return NULL;
574 }
462 575
463 /* 576 /*
464 * Set the temp file the default output, so all the 577 * Set the temp file the default output, so all the
@@ -467,13 +580,24 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
467 output_fd = temp_fd; 580 output_fd = temp_fd;
468 } 581 }
469 582
470 tracing_data_header(); 583 err = tracing_data_header();
471 read_header_files(); 584 if (err)
472 read_ftrace_files(tps); 585 goto out;
473 read_event_files(tps); 586 err = read_header_files();
474 read_proc_kallsyms(); 587 if (err)
475 read_ftrace_printk(); 588 goto out;
589 err = read_ftrace_files(tps);
590 if (err)
591 goto out;
592 err = read_event_files(tps);
593 if (err)
594 goto out;
595 err = read_proc_kallsyms();
596 if (err)
597 goto out;
598 err = read_ftrace_printk();
476 599
600out:
477 /* 601 /*
478 * All tracing data are stored by now, we can restore 602 * All tracing data are stored by now, we can restore
479 * the default output file in case we used temp file. 603 * the default output file in case we used temp file.
@@ -484,22 +608,31 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
484 output_fd = fd; 608 output_fd = fd;
485 } 609 }
486 610
611 if (err) {
612 free(tdata);
613 tdata = NULL;
614 }
615
487 put_tracepoints_path(tps); 616 put_tracepoints_path(tps);
488 return tdata; 617 return tdata;
489} 618}
490 619
491void tracing_data_put(struct tracing_data *tdata) 620int tracing_data_put(struct tracing_data *tdata)
492{ 621{
622 int err = 0;
623
493 if (tdata->temp) { 624 if (tdata->temp) {
494 record_file(tdata->temp_file, 0); 625 err = record_file(tdata->temp_file, 0);
495 unlink(tdata->temp_file); 626 unlink(tdata->temp_file);
496 } 627 }
497 628
498 free(tdata); 629 free(tdata);
630 return err;
499} 631}
500 632
501int read_tracing_data(int fd, struct list_head *pattrs) 633int read_tracing_data(int fd, struct list_head *pattrs)
502{ 634{
635 int err;
503 struct tracing_data *tdata; 636 struct tracing_data *tdata;
504 637
505 /* 638 /*
@@ -510,6 +643,6 @@ int read_tracing_data(int fd, struct list_head *pattrs)
510 if (!tdata) 643 if (!tdata)
511 return -ENOMEM; 644 return -ENOMEM;
512 645
513 tracing_data_put(tdata); 646 err = tracing_data_put(tdata);
514 return 0; 647 return err;
515} 648}
diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index 7cb24635adf2..af215c0d2379 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -18,8 +18,6 @@
18 * 18 *
19 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 19 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 */ 20 */
21#define _FILE_OFFSET_BITS 64
22
23#include <dirent.h> 21#include <dirent.h>
24#include <stdio.h> 22#include <stdio.h>
25#include <stdlib.h> 23#include <stdlib.h>
@@ -45,20 +43,10 @@ int file_bigendian;
45int host_bigendian; 43int host_bigendian;
46static int long_size; 44static int long_size;
47 45
48static ssize_t calc_data_size; 46static ssize_t trace_data_size;
49static bool repipe; 47static bool repipe;
50 48
51static void *malloc_or_die(int size) 49static int __do_read(int fd, void *buf, int size)
52{
53 void *ret;
54
55 ret = malloc(size);
56 if (!ret)
57 die("malloc");
58 return ret;
59}
60
61static int do_read(int fd, void *buf, int size)
62{ 50{
63 int rsize = size; 51 int rsize = size;
64 52
@@ -71,8 +59,10 @@ static int do_read(int fd, void *buf, int size)
71 if (repipe) { 59 if (repipe) {
72 int retw = write(STDOUT_FILENO, buf, ret); 60 int retw = write(STDOUT_FILENO, buf, ret);
73 61
74 if (retw <= 0 || retw != ret) 62 if (retw <= 0 || retw != ret) {
75 die("repiping input file"); 63 pr_debug("repiping input file");
64 return -1;
65 }
76 } 66 }
77 67
78 size -= ret; 68 size -= ret;
@@ -82,17 +72,18 @@ static int do_read(int fd, void *buf, int size)
82 return rsize; 72 return rsize;
83} 73}
84 74
85static int read_or_die(void *data, int size) 75static int do_read(void *data, int size)
86{ 76{
87 int r; 77 int r;
88 78
89 r = do_read(input_fd, data, size); 79 r = __do_read(input_fd, data, size);
90 if (r <= 0) 80 if (r <= 0) {
91 die("reading input file (size expected=%d received=%d)", 81 pr_debug("reading input file (size expected=%d received=%d)",
92 size, r); 82 size, r);
83 return -1;
84 }
93 85
94 if (calc_data_size) 86 trace_data_size += r;
95 calc_data_size += r;
96 87
97 return r; 88 return r;
98} 89}
@@ -105,7 +96,7 @@ static void skip(int size)
105 96
106 while (size) { 97 while (size) {
107 r = size > BUFSIZ ? BUFSIZ : size; 98 r = size > BUFSIZ ? BUFSIZ : size;
108 read_or_die(buf, r); 99 do_read(buf, r);
109 size -= r; 100 size -= r;
110 }; 101 };
111} 102}
@@ -114,7 +105,8 @@ static unsigned int read4(struct pevent *pevent)
114{ 105{
115 unsigned int data; 106 unsigned int data;
116 107
117 read_or_die(&data, 4); 108 if (do_read(&data, 4) < 0)
109 return 0;
118 return __data2host4(pevent, data); 110 return __data2host4(pevent, data);
119} 111}
120 112
@@ -122,7 +114,8 @@ static unsigned long long read8(struct pevent *pevent)
122{ 114{
123 unsigned long long data; 115 unsigned long long data;
124 116
125 read_or_die(&data, 8); 117 if (do_read(&data, 8) < 0)
118 return 0;
126 return __data2host8(pevent, data); 119 return __data2host8(pevent, data);
127} 120}
128 121
@@ -136,17 +129,23 @@ static char *read_string(void)
136 129
137 for (;;) { 130 for (;;) {
138 r = read(input_fd, &c, 1); 131 r = read(input_fd, &c, 1);
139 if (r < 0) 132 if (r < 0) {
140 die("reading input file"); 133 pr_debug("reading input file");
134 goto out;
135 }
141 136
142 if (!r) 137 if (!r) {
143 die("no data"); 138 pr_debug("no data");
139 goto out;
140 }
144 141
145 if (repipe) { 142 if (repipe) {
146 int retw = write(STDOUT_FILENO, &c, 1); 143 int retw = write(STDOUT_FILENO, &c, 1);
147 144
148 if (retw <= 0 || retw != r) 145 if (retw <= 0 || retw != r) {
149 die("repiping input file string"); 146 pr_debug("repiping input file string");
147 goto out;
148 }
150 } 149 }
151 150
152 buf[size++] = c; 151 buf[size++] = c;
@@ -155,60 +154,79 @@ static char *read_string(void)
155 break; 154 break;
156 } 155 }
157 156
158 if (calc_data_size) 157 trace_data_size += size;
159 calc_data_size += size;
160
161 str = malloc_or_die(size);
162 memcpy(str, buf, size);
163 158
159 str = malloc(size);
160 if (str)
161 memcpy(str, buf, size);
162out:
164 return str; 163 return str;
165} 164}
166 165
167static void read_proc_kallsyms(struct pevent *pevent) 166static int read_proc_kallsyms(struct pevent *pevent)
168{ 167{
169 unsigned int size; 168 unsigned int size;
170 char *buf; 169 char *buf;
171 170
172 size = read4(pevent); 171 size = read4(pevent);
173 if (!size) 172 if (!size)
174 return; 173 return 0;
175 174
176 buf = malloc_or_die(size + 1); 175 buf = malloc(size + 1);
177 read_or_die(buf, size); 176 if (buf == NULL)
177 return -1;
178
179 if (do_read(buf, size) < 0) {
180 free(buf);
181 return -1;
182 }
178 buf[size] = '\0'; 183 buf[size] = '\0';
179 184
180 parse_proc_kallsyms(pevent, buf, size); 185 parse_proc_kallsyms(pevent, buf, size);
181 186
182 free(buf); 187 free(buf);
188 return 0;
183} 189}
184 190
185static void read_ftrace_printk(struct pevent *pevent) 191static int read_ftrace_printk(struct pevent *pevent)
186{ 192{
187 unsigned int size; 193 unsigned int size;
188 char *buf; 194 char *buf;
189 195
196 /* it can have 0 size */
190 size = read4(pevent); 197 size = read4(pevent);
191 if (!size) 198 if (!size)
192 return; 199 return 0;
193 200
194 buf = malloc_or_die(size); 201 buf = malloc(size);
195 read_or_die(buf, size); 202 if (buf == NULL)
203 return -1;
204
205 if (do_read(buf, size) < 0) {
206 free(buf);
207 return -1;
208 }
196 209
197 parse_ftrace_printk(pevent, buf, size); 210 parse_ftrace_printk(pevent, buf, size);
198 211
199 free(buf); 212 free(buf);
213 return 0;
200} 214}
201 215
202static void read_header_files(struct pevent *pevent) 216static int read_header_files(struct pevent *pevent)
203{ 217{
204 unsigned long long size; 218 unsigned long long size;
205 char *header_event; 219 char *header_event;
206 char buf[BUFSIZ]; 220 char buf[BUFSIZ];
221 int ret = 0;
207 222
208 read_or_die(buf, 12); 223 if (do_read(buf, 12) < 0)
224 return -1;
209 225
210 if (memcmp(buf, "header_page", 12) != 0) 226 if (memcmp(buf, "header_page", 12) != 0) {
211 die("did not read header page"); 227 pr_debug("did not read header page");
228 return -1;
229 }
212 230
213 size = read8(pevent); 231 size = read8(pevent);
214 skip(size); 232 skip(size);
@@ -219,70 +237,107 @@ static void read_header_files(struct pevent *pevent)
219 */ 237 */
220 long_size = header_page_size_size; 238 long_size = header_page_size_size;
221 239
222 read_or_die(buf, 13); 240 if (do_read(buf, 13) < 0)
223 if (memcmp(buf, "header_event", 13) != 0) 241 return -1;
224 die("did not read header event"); 242
243 if (memcmp(buf, "header_event", 13) != 0) {
244 pr_debug("did not read header event");
245 return -1;
246 }
225 247
226 size = read8(pevent); 248 size = read8(pevent);
227 header_event = malloc_or_die(size); 249 header_event = malloc(size);
228 read_or_die(header_event, size); 250 if (header_event == NULL)
251 return -1;
252
253 if (do_read(header_event, size) < 0)
254 ret = -1;
255
229 free(header_event); 256 free(header_event);
257 return ret;
230} 258}
231 259
232static void read_ftrace_file(struct pevent *pevent, unsigned long long size) 260static int read_ftrace_file(struct pevent *pevent, unsigned long long size)
233{ 261{
234 char *buf; 262 char *buf;
235 263
236 buf = malloc_or_die(size); 264 buf = malloc(size);
237 read_or_die(buf, size); 265 if (buf == NULL)
266 return -1;
267
268 if (do_read(buf, size) < 0) {
269 free(buf);
270 return -1;
271 }
272
238 parse_ftrace_file(pevent, buf, size); 273 parse_ftrace_file(pevent, buf, size);
239 free(buf); 274 free(buf);
275 return 0;
240} 276}
241 277
242static void read_event_file(struct pevent *pevent, char *sys, 278static int read_event_file(struct pevent *pevent, char *sys,
243 unsigned long long size) 279 unsigned long long size)
244{ 280{
245 char *buf; 281 char *buf;
246 282
247 buf = malloc_or_die(size); 283 buf = malloc(size);
248 read_or_die(buf, size); 284 if (buf == NULL)
285 return -1;
286
287 if (do_read(buf, size) < 0) {
288 free(buf);
289 return -1;
290 }
291
249 parse_event_file(pevent, buf, size, sys); 292 parse_event_file(pevent, buf, size, sys);
250 free(buf); 293 free(buf);
294 return 0;
251} 295}
252 296
253static void read_ftrace_files(struct pevent *pevent) 297static int read_ftrace_files(struct pevent *pevent)
254{ 298{
255 unsigned long long size; 299 unsigned long long size;
256 int count; 300 int count;
257 int i; 301 int i;
302 int ret;
258 303
259 count = read4(pevent); 304 count = read4(pevent);
260 305
261 for (i = 0; i < count; i++) { 306 for (i = 0; i < count; i++) {
262 size = read8(pevent); 307 size = read8(pevent);
263 read_ftrace_file(pevent, size); 308 ret = read_ftrace_file(pevent, size);
309 if (ret)
310 return ret;
264 } 311 }
312 return 0;
265} 313}
266 314
267static void read_event_files(struct pevent *pevent) 315static int read_event_files(struct pevent *pevent)
268{ 316{
269 unsigned long long size; 317 unsigned long long size;
270 char *sys; 318 char *sys;
271 int systems; 319 int systems;
272 int count; 320 int count;
273 int i,x; 321 int i,x;
322 int ret;
274 323
275 systems = read4(pevent); 324 systems = read4(pevent);
276 325
277 for (i = 0; i < systems; i++) { 326 for (i = 0; i < systems; i++) {
278 sys = read_string(); 327 sys = read_string();
328 if (sys == NULL)
329 return -1;
279 330
280 count = read4(pevent); 331 count = read4(pevent);
332
281 for (x=0; x < count; x++) { 333 for (x=0; x < count; x++) {
282 size = read8(pevent); 334 size = read8(pevent);
283 read_event_file(pevent, sys, size); 335 ret = read_event_file(pevent, sys, size);
336 if (ret)
337 return ret;
284 } 338 }
285 } 339 }
340 return 0;
286} 341}
287 342
288ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe) 343ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)
@@ -293,58 +348,85 @@ ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)
293 int show_version = 0; 348 int show_version = 0;
294 int show_funcs = 0; 349 int show_funcs = 0;
295 int show_printk = 0; 350 int show_printk = 0;
296 ssize_t size; 351 ssize_t size = -1;
352 struct pevent *pevent;
353 int err;
297 354
298 calc_data_size = 1; 355 *ppevent = NULL;
299 repipe = __repipe;
300 356
357 repipe = __repipe;
301 input_fd = fd; 358 input_fd = fd;
302 359
303 read_or_die(buf, 3); 360 if (do_read(buf, 3) < 0)
304 if (memcmp(buf, test, 3) != 0) 361 return -1;
305 die("no trace data in the file"); 362 if (memcmp(buf, test, 3) != 0) {
363 pr_debug("no trace data in the file");
364 return -1;
365 }
306 366
307 read_or_die(buf, 7); 367 if (do_read(buf, 7) < 0)
308 if (memcmp(buf, "tracing", 7) != 0) 368 return -1;
309 die("not a trace file (missing 'tracing' tag)"); 369 if (memcmp(buf, "tracing", 7) != 0) {
370 pr_debug("not a trace file (missing 'tracing' tag)");
371 return -1;
372 }
310 373
311 version = read_string(); 374 version = read_string();
375 if (version == NULL)
376 return -1;
312 if (show_version) 377 if (show_version)
313 printf("version = %s\n", version); 378 printf("version = %s\n", version);
314 free(version); 379 free(version);
315 380
316 read_or_die(buf, 1); 381 if (do_read(buf, 1) < 0)
382 return -1;
317 file_bigendian = buf[0]; 383 file_bigendian = buf[0];
318 host_bigendian = bigendian(); 384 host_bigendian = bigendian();
319 385
320 *ppevent = read_trace_init(file_bigendian, host_bigendian); 386 pevent = read_trace_init(file_bigendian, host_bigendian);
321 if (*ppevent == NULL) 387 if (pevent == NULL) {
322 die("read_trace_init failed"); 388 pr_debug("read_trace_init failed");
389 goto out;
390 }
323 391
324 read_or_die(buf, 1); 392 if (do_read(buf, 1) < 0)
393 goto out;
325 long_size = buf[0]; 394 long_size = buf[0];
326 395
327 page_size = read4(*ppevent); 396 page_size = read4(pevent);
328 397 if (!page_size)
329 read_header_files(*ppevent); 398 goto out;
330 399
331 read_ftrace_files(*ppevent); 400 err = read_header_files(pevent);
332 read_event_files(*ppevent); 401 if (err)
333 read_proc_kallsyms(*ppevent); 402 goto out;
334 read_ftrace_printk(*ppevent); 403 err = read_ftrace_files(pevent);
335 404 if (err)
336 size = calc_data_size - 1; 405 goto out;
337 calc_data_size = 0; 406 err = read_event_files(pevent);
407 if (err)
408 goto out;
409 err = read_proc_kallsyms(pevent);
410 if (err)
411 goto out;
412 err = read_ftrace_printk(pevent);
413 if (err)
414 goto out;
415
416 size = trace_data_size;
338 repipe = false; 417 repipe = false;
339 418
340 if (show_funcs) { 419 if (show_funcs) {
341 pevent_print_funcs(*ppevent); 420 pevent_print_funcs(pevent);
342 return size; 421 } else if (show_printk) {
343 } 422 pevent_print_printk(pevent);
344 if (show_printk) {
345 pevent_print_printk(*ppevent);
346 return size;
347 } 423 }
348 424
425 *ppevent = pevent;
426 pevent = NULL;
427
428out:
429 if (pevent)
430 pevent_free(pevent);
349 return size; 431 return size;
350} 432}
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index 28ccde8ba20f..1978c398ad87 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -68,7 +68,7 @@ struct tracing_data {
68 68
69struct tracing_data *tracing_data_get(struct list_head *pattrs, 69struct tracing_data *tracing_data_get(struct list_head *pattrs,
70 int fd, bool temp); 70 int fd, bool temp);
71void tracing_data_put(struct tracing_data *tdata); 71int tracing_data_put(struct tracing_data *tdata);
72 72
73 73
74struct addr_location; 74struct addr_location;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 6a0781c3a573..a45710b70a55 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -1,8 +1,6 @@
1#ifndef GIT_COMPAT_UTIL_H 1#ifndef GIT_COMPAT_UTIL_H
2#define GIT_COMPAT_UTIL_H 2#define GIT_COMPAT_UTIL_H
3 3
4#define _FILE_OFFSET_BITS 64
5
6#ifndef FLEX_ARRAY 4#ifndef FLEX_ARRAY
7/* 5/*
8 * See if our compiler is known to support flexible array members. 6 * See if our compiler is known to support flexible array members.