aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2013-12-16 08:52:03 -0500
committerIngo Molnar <mingo@kernel.org>2013-12-16 08:52:03 -0500
commitb283d2f3b74bc98174e8453c0be41dfcda3cae1b (patch)
treee9af6975920c4bf2eb4b8cdb35f88726f3db1e77 /tools/perf
parentfe361cfcf40ad4612226347573a8669cd0d44799 (diff)
parent41e12e580a7b0c151199f927193548b84d3e874c (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: Fixes: * Fix inverted error verification bug in thread__fork, from David Ahern. New features: * Shell completion for 'perf kvm', from Ramkumar Ramachandra. Refactorings: * Get rid of panic() like calls in libtraceevent, from Namyung Kim. * Start carving out symbol parsing routines from perf, just moving routines to topic files in tools/lib/symbol/, tools that want to use it need to integrate it directly, i.e. no tools/lib/symbol/Makefile is provided. * Assorted refactoring patches, moving code around and adding utility evlist methods that will be used in the IPT patchset, from Adrian Hunter. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/MANIFEST2
-rw-r--r--tools/perf/Makefile.perf5
-rw-r--r--tools/perf/perf-completion.sh4
-rw-r--r--tools/perf/util/event.c1
-rw-r--r--tools/perf/util/evlist.c20
-rw-r--r--tools/perf/util/evlist.h5
-rw-r--r--tools/perf/util/header.c3
-rw-r--r--tools/perf/util/machine.c1
-rw-r--r--tools/perf/util/record.c37
-rw-r--r--tools/perf/util/session.c21
-rw-r--r--tools/perf/util/session.h2
-rw-r--r--tools/perf/util/symbol-elf.c1
-rw-r--r--tools/perf/util/symbol.c69
-rw-r--r--tools/perf/util/symbol.h3
-rw-r--r--tools/perf/util/thread.c2
-rw-r--r--tools/perf/util/util.c41
-rw-r--r--tools/perf/util/util.h4
17 files changed, 123 insertions, 98 deletions
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index 025de796067c..3170a7ff5782 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -2,6 +2,8 @@ tools/perf
2tools/scripts 2tools/scripts
3tools/lib/traceevent 3tools/lib/traceevent
4tools/lib/lk 4tools/lib/lk
5tools/lib/symbol/kallsyms.c
6tools/lib/symbol/kallsyms.h
5include/linux/const.h 7include/linux/const.h
6include/linux/perf_event.h 8include/linux/perf_event.h
7include/linux/rbtree.h 9include/linux/rbtree.h
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 9a8cf376f874..fad61079e795 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -202,6 +202,7 @@ $(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c
202 202
203LIB_FILE=$(OUTPUT)libperf.a 203LIB_FILE=$(OUTPUT)libperf.a
204 204
205LIB_H += ../lib/symbol/kallsyms.h
205LIB_H += ../../include/uapi/linux/perf_event.h 206LIB_H += ../../include/uapi/linux/perf_event.h
206LIB_H += ../../include/linux/rbtree.h 207LIB_H += ../../include/linux/rbtree.h
207LIB_H += ../../include/linux/list.h 208LIB_H += ../../include/linux/list.h
@@ -312,6 +313,7 @@ LIB_OBJS += $(OUTPUT)util/evlist.o
312LIB_OBJS += $(OUTPUT)util/evsel.o 313LIB_OBJS += $(OUTPUT)util/evsel.o
313LIB_OBJS += $(OUTPUT)util/exec_cmd.o 314LIB_OBJS += $(OUTPUT)util/exec_cmd.o
314LIB_OBJS += $(OUTPUT)util/help.o 315LIB_OBJS += $(OUTPUT)util/help.o
316LIB_OBJS += $(OUTPUT)util/kallsyms.o
315LIB_OBJS += $(OUTPUT)util/levenshtein.o 317LIB_OBJS += $(OUTPUT)util/levenshtein.o
316LIB_OBJS += $(OUTPUT)util/parse-options.o 318LIB_OBJS += $(OUTPUT)util/parse-options.o
317LIB_OBJS += $(OUTPUT)util/parse-events.o 319LIB_OBJS += $(OUTPUT)util/parse-events.o
@@ -672,6 +674,9 @@ $(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS
672$(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS 674$(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS
673 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $< 675 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
674 676
677$(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c $(OUTPUT)PERF-CFLAGS
678 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
679
675$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS 680$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
676 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 681 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
677 682
diff --git a/tools/perf/perf-completion.sh b/tools/perf/perf-completion.sh
index 49494882d9bb..496e2abb5482 100644
--- a/tools/perf/perf-completion.sh
+++ b/tools/perf/perf-completion.sh
@@ -121,6 +121,10 @@ __perf_main ()
121 elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then 121 elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then
122 evts=$($cmd list --raw-dump) 122 evts=$($cmd list --raw-dump)
123 __perfcomp_colon "$evts" "$cur" 123 __perfcomp_colon "$evts" "$cur"
124 # List subcommands for 'perf kvm'
125 elif [[ $prev == "kvm" ]]; then
126 subcmds="top record report diff buildid-list stat"
127 __perfcomp_colon "$subcmds" "$cur"
124 # List long option names 128 # List long option names
125 elif [[ $cur == --* ]]; then 129 elif [[ $cur == --* ]]; then
126 subcmd=${words[1]} 130 subcmd=${words[1]}
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index c77814bf01e1..694876877ae2 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -7,6 +7,7 @@
7#include "strlist.h" 7#include "strlist.h"
8#include "thread.h" 8#include "thread.h"
9#include "thread_map.h" 9#include "thread_map.h"
10#include "symbol/kallsyms.h"
10 11
11static const char *perf_event__names[] = { 12static const char *perf_event__names[] = {
12 [0] = "TOTAL", 13 [0] = "TOTAL",
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index af250556b33f..0b31cee34874 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1191,8 +1191,7 @@ int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused,
1191 "Error:\t%s.\n" 1191 "Error:\t%s.\n"
1192 "Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting.", emsg); 1192 "Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting.", emsg);
1193 1193
1194 if (filename__read_int("/proc/sys/kernel/perf_event_paranoid", &value)) 1194 value = perf_event_paranoid();
1195 break;
1196 1195
1197 printed += scnprintf(buf + printed, size - printed, "\nHint:\t"); 1196 printed += scnprintf(buf + printed, size - printed, "\nHint:\t");
1198 1197
@@ -1213,3 +1212,20 @@ int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused,
1213 1212
1214 return 0; 1213 return 0;
1215} 1214}
1215
1216void perf_evlist__to_front(struct perf_evlist *evlist,
1217 struct perf_evsel *move_evsel)
1218{
1219 struct perf_evsel *evsel, *n;
1220 LIST_HEAD(move);
1221
1222 if (move_evsel == perf_evlist__first(evlist))
1223 return;
1224
1225 list_for_each_entry_safe(evsel, n, &evlist->entries, node) {
1226 if (evsel->leader == move_evsel->leader)
1227 list_move_tail(&evsel->node, &move);
1228 }
1229
1230 list_splice(&move, &evlist->entries);
1231}
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 649d6ea98a84..9f64ede3ecbd 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -193,4 +193,9 @@ static inline void perf_mmap__write_tail(struct perf_mmap *md,
193 pc->data_tail = tail; 193 pc->data_tail = tail;
194} 194}
195 195
196bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str);
197void perf_evlist__to_front(struct perf_evlist *evlist,
198 struct perf_evsel *move_evsel);
199
200
196#endif /* __PERF_EVLIST_H */ 201#endif /* __PERF_EVLIST_H */
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 0bb830f6b49c..61c54213704b 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2327,7 +2327,8 @@ int perf_session__write_header(struct perf_session *session,
2327 } 2327 }
2328 } 2328 }
2329 2329
2330 header->data_offset = lseek(fd, 0, SEEK_CUR); 2330 if (!header->data_offset)
2331 header->data_offset = lseek(fd, 0, SEEK_CUR);
2331 header->feat_offset = header->data_offset + header->data_size; 2332 header->feat_offset = header->data_offset + header->data_size;
2332 2333
2333 if (at_exit) { 2334 if (at_exit) {
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 751454bcde69..c78cc84f433e 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -9,6 +9,7 @@
9#include "strlist.h" 9#include "strlist.h"
10#include "thread.h" 10#include "thread.h"
11#include <stdbool.h> 11#include <stdbool.h>
12#include <symbol/kallsyms.h>
12#include "unwind.h" 13#include "unwind.h"
13 14
14int machine__init(struct machine *machine, const char *root_dir, pid_t pid) 15int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index c8845b107f60..e5104538c354 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -177,3 +177,40 @@ int perf_record_opts__config(struct perf_record_opts *opts)
177{ 177{
178 return perf_record_opts__config_freq(opts); 178 return perf_record_opts__config_freq(opts);
179} 179}
180
181bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str)
182{
183 struct perf_evlist *temp_evlist;
184 struct perf_evsel *evsel;
185 int err, fd, cpu;
186 bool ret = false;
187
188 temp_evlist = perf_evlist__new();
189 if (!temp_evlist)
190 return false;
191
192 err = parse_events(temp_evlist, str);
193 if (err)
194 goto out_delete;
195
196 evsel = perf_evlist__last(temp_evlist);
197
198 if (!evlist || cpu_map__empty(evlist->cpus)) {
199 struct cpu_map *cpus = cpu_map__new(NULL);
200
201 cpu = cpus ? cpus->map[0] : 0;
202 cpu_map__delete(cpus);
203 } else {
204 cpu = evlist->cpus->map[0];
205 }
206
207 fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, 0);
208 if (fd >= 0) {
209 close(fd);
210 ret = true;
211 }
212
213out_delete:
214 perf_evlist__delete(temp_evlist);
215 return ret;
216}
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index e748f29c53cf..989b2e377626 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -247,27 +247,6 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
247 } 247 }
248} 248}
249 249
250void mem_bswap_32(void *src, int byte_size)
251{
252 u32 *m = src;
253 while (byte_size > 0) {
254 *m = bswap_32(*m);
255 byte_size -= sizeof(u32);
256 ++m;
257 }
258}
259
260void mem_bswap_64(void *src, int byte_size)
261{
262 u64 *m = src;
263
264 while (byte_size > 0) {
265 *m = bswap_64(*m);
266 byte_size -= sizeof(u64);
267 ++m;
268 }
269}
270
271static void swap_sample_id_all(union perf_event *event, void *data) 250static void swap_sample_id_all(union perf_event *event, void *data)
272{ 251{
273 void *end = (void *) event + event->header.size; 252 void *end = (void *) event + event->header.size;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 2a3955ea4fd8..9c25d49900af 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -74,8 +74,6 @@ int perf_session__resolve_callchain(struct perf_session *session,
74 74
75bool perf_session__has_traces(struct perf_session *session, const char *msg); 75bool perf_session__has_traces(struct perf_session *session, const char *msg);
76 76
77void mem_bswap_64(void *src, int byte_size);
78void mem_bswap_32(void *src, int byte_size);
79void perf_event__attr_swap(struct perf_event_attr *attr); 77void perf_event__attr_swap(struct perf_event_attr *attr);
80 78
81int perf_session__create_kernel_maps(struct perf_session *session); 79int perf_session__create_kernel_maps(struct perf_session *session);
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index eed0b96302af..bf0ce29567b6 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -6,6 +6,7 @@
6#include <inttypes.h> 6#include <inttypes.h>
7 7
8#include "symbol.h" 8#include "symbol.h"
9#include <symbol/kallsyms.h>
9#include "debug.h" 10#include "debug.h"
10 11
11#ifndef HAVE_ELF_GETPHDRNUM_SUPPORT 12#ifndef HAVE_ELF_GETPHDRNUM_SUPPORT
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index e377c2e96191..61eb1cddf01a 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -18,12 +18,9 @@
18 18
19#include <elf.h> 19#include <elf.h>
20#include <limits.h> 20#include <limits.h>
21#include <symbol/kallsyms.h>
21#include <sys/utsname.h> 22#include <sys/utsname.h>
22 23
23#ifndef KSYM_NAME_LEN
24#define KSYM_NAME_LEN 256
25#endif
26
27static int dso__load_kernel_sym(struct dso *dso, struct map *map, 24static int dso__load_kernel_sym(struct dso *dso, struct map *map,
28 symbol_filter_t filter); 25 symbol_filter_t filter);
29static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map, 26static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
@@ -446,62 +443,6 @@ size_t dso__fprintf_symbols_by_name(struct dso *dso,
446 return ret; 443 return ret;
447} 444}
448 445
449int kallsyms__parse(const char *filename, void *arg,
450 int (*process_symbol)(void *arg, const char *name,
451 char type, u64 start))
452{
453 char *line = NULL;
454 size_t n;
455 int err = -1;
456 FILE *file = fopen(filename, "r");
457
458 if (file == NULL)
459 goto out_failure;
460
461 err = 0;
462
463 while (!feof(file)) {
464 u64 start;
465 int line_len, len;
466 char symbol_type;
467 char *symbol_name;
468
469 line_len = getline(&line, &n, file);
470 if (line_len < 0 || !line)
471 break;
472
473 line[--line_len] = '\0'; /* \n */
474
475 len = hex2u64(line, &start);
476
477 len++;
478 if (len + 2 >= line_len)
479 continue;
480
481 symbol_type = line[len];
482 len += 2;
483 symbol_name = line + len;
484 len = line_len - len;
485
486 if (len >= KSYM_NAME_LEN) {
487 err = -1;
488 break;
489 }
490
491 err = process_symbol(arg, symbol_name,
492 symbol_type, start);
493 if (err)
494 break;
495 }
496
497 free(line);
498 fclose(file);
499 return err;
500
501out_failure:
502 return -1;
503}
504
505int modules__parse(const char *filename, void *arg, 446int modules__parse(const char *filename, void *arg,
506 int (*process_module)(void *arg, const char *name, 447 int (*process_module)(void *arg, const char *name,
507 u64 start)) 448 u64 start))
@@ -565,14 +506,6 @@ struct process_kallsyms_args {
565 struct dso *dso; 506 struct dso *dso;
566}; 507};
567 508
568static u8 kallsyms2elf_type(char type)
569{
570 if (type == 'W')
571 return STB_WEAK;
572
573 return isupper(type) ? STB_GLOBAL : STB_LOCAL;
574}
575
576bool symbol__is_idle(struct symbol *sym) 509bool symbol__is_idle(struct symbol *sym)
577{ 510{
578 const char * const idle_symbols[] = { 511 const char * const idle_symbols[] = {
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 6de9c2b8a601..8a9d910c5345 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -221,9 +221,6 @@ struct symbol *dso__first_symbol(struct dso *dso, enum map_type type);
221 221
222int filename__read_build_id(const char *filename, void *bf, size_t size); 222int filename__read_build_id(const char *filename, void *bf, size_t size);
223int sysfs__read_build_id(const char *filename, void *bf, size_t size); 223int sysfs__read_build_id(const char *filename, void *bf, size_t size);
224int kallsyms__parse(const char *filename, void *arg,
225 int (*process_symbol)(void *arg, const char *name,
226 char type, u64 start));
227int modules__parse(const char *filename, void *arg, 224int modules__parse(const char *filename, void *arg,
228 int (*process_module)(void *arg, const char *name, 225 int (*process_module)(void *arg, const char *name,
229 u64 start)); 226 u64 start));
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 49eaf1d7d89d..e3948612543e 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -126,7 +126,7 @@ int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp)
126 if (!comm) 126 if (!comm)
127 return -ENOMEM; 127 return -ENOMEM;
128 err = thread__set_comm(thread, comm, timestamp); 128 err = thread__set_comm(thread, comm, timestamp);
129 if (!err) 129 if (err)
130 return err; 130 return err;
131 thread->comm_set = true; 131 thread->comm_set = true;
132 } 132 }
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 4a57609c0b43..42ad667bb317 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -1,5 +1,6 @@
1#include "../perf.h" 1#include "../perf.h"
2#include "util.h" 2#include "util.h"
3#include "fs.h"
3#include <sys/mman.h> 4#include <sys/mman.h>
4#ifdef HAVE_BACKTRACE_SUPPORT 5#ifdef HAVE_BACKTRACE_SUPPORT
5#include <execinfo.h> 6#include <execinfo.h>
@@ -8,6 +9,8 @@
8#include <stdlib.h> 9#include <stdlib.h>
9#include <string.h> 10#include <string.h>
10#include <errno.h> 11#include <errno.h>
12#include <limits.h>
13#include <byteswap.h>
11#include <linux/kernel.h> 14#include <linux/kernel.h>
12 15
13/* 16/*
@@ -496,3 +499,41 @@ const char *get_filename_for_perf_kvm(void)
496 499
497 return filename; 500 return filename;
498} 501}
502
503int perf_event_paranoid(void)
504{
505 char path[PATH_MAX];
506 const char *procfs = procfs__mountpoint();
507 int value;
508
509 if (!procfs)
510 return INT_MAX;
511
512 scnprintf(path, PATH_MAX, "%s/sys/kernel/perf_event_paranoid", procfs);
513
514 if (filename__read_int(path, &value))
515 return INT_MAX;
516
517 return value;
518}
519
520void mem_bswap_32(void *src, int byte_size)
521{
522 u32 *m = src;
523 while (byte_size > 0) {
524 *m = bswap_32(*m);
525 byte_size -= sizeof(u32);
526 ++m;
527 }
528}
529
530void mem_bswap_64(void *src, int byte_size)
531{
532 u64 *m = src;
533
534 while (byte_size > 0) {
535 *m = bswap_64(*m);
536 byte_size -= sizeof(u64);
537 ++m;
538 }
539}
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 0171213d1d4d..a1eea3e809a3 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -321,6 +321,10 @@ void free_srcline(char *srcline);
321 321
322int filename__read_int(const char *filename, int *value); 322int filename__read_int(const char *filename, int *value);
323int filename__read_str(const char *filename, char **buf, size_t *sizep); 323int filename__read_str(const char *filename, char **buf, size_t *sizep);
324int perf_event_paranoid(void);
325
326void mem_bswap_64(void *src, int byte_size);
327void mem_bswap_32(void *src, int byte_size);
324 328
325const char *get_filename_for_perf_kvm(void); 329const char *get_filename_for_perf_kvm(void);
326#endif /* GIT_COMPAT_UTIL_H */ 330#endif /* GIT_COMPAT_UTIL_H */