diff options
31 files changed, 651 insertions, 353 deletions
diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h index e268388146e..41235c93e4e 100644 --- a/include/linux/hw_breakpoint.h +++ b/include/linux/hw_breakpoint.h @@ -93,7 +93,7 @@ register_user_hw_breakpoint(struct perf_event_attr *attr, struct task_struct *tsk) { return NULL; } static inline int modify_user_hw_breakpoint(struct perf_event *bp, - struct perf_event_attr *attr) { return 0; } + struct perf_event_attr *attr) { return -ENOSYS; } static inline struct perf_event * register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, perf_overflow_handler_t triggered, diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h index 850d057500d..ca6b2b31799 100644 --- a/include/linux/slab_def.h +++ b/include/linux/slab_def.h @@ -110,7 +110,7 @@ extern struct cache_sizes malloc_sizes[]; void *kmem_cache_alloc(struct kmem_cache *, gfp_t); void *__kmalloc(size_t size, gfp_t flags); -#ifdef CONFIG_KMEMTRACE +#ifdef CONFIG_TRACING extern void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags); extern size_t slab_buffer_size(struct kmem_cache *cachep); #else @@ -166,7 +166,7 @@ found: extern void *__kmalloc_node(size_t size, gfp_t flags, int node); extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); -#ifdef CONFIG_KMEMTRACE +#ifdef CONFIG_TRACING extern void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep, gfp_t flags, int nodeid); diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index 5ad70a60fd7..1e14beb23f9 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h @@ -217,7 +217,7 @@ static __always_inline struct kmem_cache *kmalloc_slab(size_t size) void *kmem_cache_alloc(struct kmem_cache *, gfp_t); void *__kmalloc(size_t size, gfp_t flags); -#ifdef CONFIG_KMEMTRACE +#ifdef CONFIG_TRACING extern void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags); #else static __always_inline void * @@ -266,7 +266,7 @@ static __always_inline void *kmalloc(size_t size, gfp_t flags) void *__kmalloc_node(size_t size, gfp_t flags, int node); void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); -#ifdef CONFIG_KMEMTRACE +#ifdef CONFIG_TRACING extern void *kmem_cache_alloc_node_notrace(struct kmem_cache *s, gfp_t gfpflags, int node); diff --git a/mm/slab.c b/mm/slab.c index 29b09599af7..3f4822938f4 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -490,7 +490,7 @@ static void **dbg_userword(struct kmem_cache *cachep, void *objp) #endif -#ifdef CONFIG_KMEMTRACE +#ifdef CONFIG_TRACING size_t slab_buffer_size(struct kmem_cache *cachep) { return cachep->buffer_size; @@ -3578,7 +3578,7 @@ void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags) } EXPORT_SYMBOL(kmem_cache_alloc); -#ifdef CONFIG_KMEMTRACE +#ifdef CONFIG_TRACING void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags) { return __cache_alloc(cachep, flags, __builtin_return_address(0)); @@ -3641,7 +3641,7 @@ void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid) } EXPORT_SYMBOL(kmem_cache_alloc_node); -#ifdef CONFIG_KMEMTRACE +#ifdef CONFIG_TRACING void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep, gfp_t flags, int nodeid) @@ -3669,7 +3669,7 @@ __do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller) return ret; } -#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_KMEMTRACE) +#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_TRACING) void *__kmalloc_node(size_t size, gfp_t flags, int node) { return __do_kmalloc_node(size, flags, node, @@ -3689,7 +3689,7 @@ void *__kmalloc_node(size_t size, gfp_t flags, int node) return __do_kmalloc_node(size, flags, node, NULL); } EXPORT_SYMBOL(__kmalloc_node); -#endif /* CONFIG_DEBUG_SLAB */ +#endif /* CONFIG_DEBUG_SLAB || CONFIG_TRACING */ #endif /* CONFIG_NUMA */ /** @@ -3721,7 +3721,7 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags, } -#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_KMEMTRACE) +#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_TRACING) void *__kmalloc(size_t size, gfp_t flags) { return __do_kmalloc(size, flags, __builtin_return_address(0)); diff --git a/mm/slub.c b/mm/slub.c index da0ce55965d..8d71aaf888d 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1754,7 +1754,7 @@ void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags) } EXPORT_SYMBOL(kmem_cache_alloc); -#ifdef CONFIG_KMEMTRACE +#ifdef CONFIG_TRACING void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags) { return slab_alloc(s, gfpflags, -1, _RET_IP_); @@ -1775,7 +1775,7 @@ void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node) EXPORT_SYMBOL(kmem_cache_alloc_node); #endif -#ifdef CONFIG_KMEMTRACE +#ifdef CONFIG_TRACING void *kmem_cache_alloc_node_notrace(struct kmem_cache *s, gfp_t gfpflags, int node) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 23ec66098bd..406999668ca 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -237,8 +237,8 @@ lib = lib export prefix bindir sharedir sysconfdir -CC = gcc -AR = ar +CC = $(CROSS_COMPILE)gcc +AR = $(CROSS_COMPILE)ar RM = rm -f TAR = tar FIND = find @@ -356,7 +356,9 @@ LIB_H += util/parse-options.h LIB_H += util/parse-events.h LIB_H += util/quote.h LIB_H += util/util.h +LIB_H += util/header.h LIB_H += util/help.h +LIB_H += util/session.h LIB_H += util/strbuf.h LIB_H += util/string.h LIB_H += util/strlist.h @@ -405,6 +407,7 @@ LIB_OBJS += util/callchain.o LIB_OBJS += util/values.o LIB_OBJS += util/debug.o LIB_OBJS += util/map.o +LIB_OBJS += util/session.o LIB_OBJS += util/thread.o LIB_OBJS += util/trace-event-parse.o LIB_OBJS += util/trace-event-read.o @@ -492,8 +495,10 @@ else LIB_OBJS += util/probe-finder.o endif +ifndef NO_LIBPERL PERL_EMBED_LDOPTS = `perl -MExtUtils::Embed -e ldopts 2>/dev/null` PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` +endif ifneq ($(shell sh -c "(echo '\#include <EXTERN.h>'; echo '\#include <perl.h>'; echo 'int main(void) { perl_alloc(); return 0; }') | $(CC) -x c - $(PERL_EMBED_CCOPTS) -o /dev/null $(PERL_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y) BASIC_CFLAGS += -DNO_LIBPERL diff --git a/tools/perf/bench/sched-messaging.c b/tools/perf/bench/sched-messaging.c index 605a2a959aa..81cee78181f 100644 --- a/tools/perf/bench/sched-messaging.c +++ b/tools/perf/bench/sched-messaging.c @@ -1,6 +1,6 @@ /* * - * builtin-bench-messaging.c + * sched-messaging.c * * messaging: Benchmark for scheduler and IPC mechanisms * @@ -320,10 +320,12 @@ int bench_sched_messaging(int argc, const char **argv, num_groups, num_groups * 2 * num_fds, thread_mode ? "threads" : "processes"); printf(" %14s: %lu.%03lu [sec]\n", "Total time", - diff.tv_sec, diff.tv_usec/1000); + diff.tv_sec, + (unsigned long) (diff.tv_usec/1000)); break; case BENCH_FORMAT_SIMPLE: - printf("%lu.%03lu\n", diff.tv_sec, diff.tv_usec/1000); + printf("%lu.%03lu\n", diff.tv_sec, + (unsigned long) (diff.tv_usec/1000)); break; default: /* reaching here is something disaster */ diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c index 238185f9797..4f77c7c2764 100644 --- a/tools/perf/bench/sched-pipe.c +++ b/tools/perf/bench/sched-pipe.c @@ -1,6 +1,6 @@ /* * - * builtin-bench-pipe.c + * sched-pipe.c * * pipe: Benchmark for pipe() * @@ -87,7 +87,8 @@ int bench_sched_pipe(int argc, const char **argv, if (pid) { retpid = waitpid(pid, &wait_stat, 0); assert((retpid == pid) && WIFEXITED(wait_stat)); - return 0; + } else { + exit(0); } switch (bench_format) { @@ -99,7 +100,8 @@ int bench_sched_pipe(int argc, const char **argv, result_usec += diff.tv_usec; printf(" %14s: %lu.%03lu [sec]\n\n", "Total time", - diff.tv_sec, diff.tv_usec/1000); + diff.tv_sec, + (unsigned long) (diff.tv_usec/1000)); printf(" %14lf usecs/op\n", (double)result_usec / (double)loops); @@ -110,7 +112,8 @@ int bench_sched_pipe(int argc, const char **argv, case BENCH_FORMAT_SIMPLE: printf("%lu.%03lu\n", - diff.tv_sec, diff.tv_usec / 1000); + diff.tv_sec, + (unsigned long) (diff.tv_usec / 1000)); break; default: diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 0bf2e8f9af5..21a78d30d53 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -25,6 +25,7 @@ #include "util/thread.h" #include "util/sort.h" #include "util/hist.h" +#include "util/session.h" #include "util/data_map.h" static char const *input_name = "perf.data"; @@ -462,21 +463,23 @@ static struct perf_file_handler file_handler = { static int __cmd_annotate(void) { - struct perf_header *header; + struct perf_session *session = perf_session__new(input_name, O_RDONLY, force); struct thread *idle; int ret; + if (session == NULL) + return -ENOMEM; + idle = register_idle_thread(); register_perf_file_handler(&file_handler); - ret = mmap_dispatch_perf_file(&header, input_name, 0, 0, - &event__cwdlen, &event__cwd); + ret = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); if (ret) - return ret; + goto out_delete; if (dump_trace) { event__print_totals(); - return 0; + goto out_delete; } if (verbose > 3) @@ -489,6 +492,8 @@ static int __cmd_annotate(void) output__resort(event__total[0]); find_annotations(); +out_delete: + perf_session__delete(session); return ret; } diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c index e043eb83092..46996774e55 100644 --- a/tools/perf/builtin-bench.c +++ b/tools/perf/builtin-bench.c @@ -31,6 +31,9 @@ struct bench_suite { const char *summary; int (*fn)(int, const char **, const char *); }; + \ +/* sentinel: easy for help */ +#define suite_all { "all", "test all suite (pseudo suite)", NULL } static struct bench_suite sched_suites[] = { { "messaging", @@ -39,6 +42,7 @@ static struct bench_suite sched_suites[] = { { "pipe", "Flood of communication over pipe() between two processes", bench_sched_pipe }, + suite_all, { NULL, NULL, NULL } @@ -48,6 +52,7 @@ static struct bench_suite mem_suites[] = { { "memcpy", "Simple memory copy in various ways", bench_mem_memcpy }, + suite_all, { NULL, NULL, NULL } @@ -66,6 +71,9 @@ static struct bench_subsys subsystems[] = { { "mem", "memory access performance", mem_suites }, + { "all", /* sentinel: easy for help */ + "test all subsystem (pseudo subsystem)", + NULL }, { NULL, NULL, NULL } @@ -75,11 +83,11 @@ static void dump_suites(int subsys_index) { int i; - printf("List of available suites for %s...\n\n", + printf("# List of available suites for %s...\n\n", subsystems[subsys_index].name); for (i = 0; subsystems[subsys_index].suites[i].name; i++) - printf("\t%s: %s\n", + printf("%14s: %s\n", subsystems[subsys_index].suites[i].name, subsystems[subsys_index].suites[i].summary); @@ -110,10 +118,10 @@ static void print_usage(void) printf("\t%s\n", bench_usage[i]); printf("\n"); - printf("List of available subsystems...\n\n"); + printf("# List of available subsystems...\n\n"); for (i = 0; subsystems[i].name; i++) - printf("\t%s: %s\n", + printf("%14s: %s\n", subsystems[i].name, subsystems[i].summary); printf("\n"); } @@ -131,6 +139,37 @@ static int bench_str2int(char *str) return BENCH_FORMAT_UNKNOWN; } +static void all_suite(struct bench_subsys *subsys) /* FROM HERE */ +{ + int i; + const char *argv[2]; + struct bench_suite *suites = subsys->suites; + + argv[1] = NULL; + /* + * TODO: + * preparing preset parameters for + * embedded, ordinary PC, HPC, etc... + * will be helpful + */ + for (i = 0; suites[i].fn; i++) { + printf("# Running %s/%s benchmark...\n", + subsys->name, + suites[i].name); + + argv[1] = suites[i].name; + suites[i].fn(1, argv, NULL); + printf("\n"); + } +} + +static void all_subsystem(void) +{ + int i; + for (i = 0; subsystems[i].suites; i++) + all_suite(&subsystems[i]); +} + int cmd_bench(int argc, const char **argv, const char *prefix __used) { int i, j, status = 0; @@ -155,6 +194,11 @@ int cmd_bench(int argc, const char **argv, const char *prefix __used) goto end; } + if (!strcmp(argv[0], "all")) { + all_subsystem(); + goto end; + } + for (i = 0; subsystems[i].name; i++) { if (strcmp(subsystems[i].name, argv[0])) continue; @@ -165,6 +209,11 @@ int cmd_bench(int argc, const char **argv, const char *prefix __used) goto end; } + if (!strcmp(argv[1], "all")) { + all_suite(&subsystems[i]); + goto end; + } + for (j = 0; subsystems[i].suites[j].name; j++) { if (strcmp(subsystems[i].suites[j].name, argv[1])) continue; diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index dcb6143a000..bfd16a1594e 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -11,8 +11,8 @@ #include "util/cache.h" #include "util/data_map.h" #include "util/debug.h" -#include "util/header.h" #include "util/parse-options.h" +#include "util/session.h" #include "util/symbol.h" static char const *input_name = "perf.data"; @@ -55,56 +55,17 @@ static int perf_file_section__process_buildids(struct perf_file_section *self, static int __cmd_buildid_list(void) { int err = -1; - struct perf_header *header; - struct perf_file_header f_header; - struct stat input_stat; - int input = open(input_name, O_RDONLY); + struct perf_session *session = perf_session__new(input_name, O_RDONLY, force); - if (input < 0) { - pr_err("failed to open file: %s", input_name); - if (!strcmp(input_name, "perf.data")) - pr_err(" (try 'perf record' first)"); - pr_err("\n"); - goto out; - } - - err = fstat(input, &input_stat); - if (err < 0) { - perror("failed to stat file"); - goto out_close; - } - - if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) { - pr_err("file %s not owned by current user or root\n", - input_name); - goto out_close; - } - - if (!input_stat.st_size) { - pr_info("zero-sized file, nothing to do!\n"); - goto out_close; - } - - err = -1; - header = perf_header__new(); - if (header == NULL) - goto out_close; - - if (perf_file_header__read(&f_header, header, input) < 0) { - pr_warning("incompatible file format"); - goto out_close; - } + if (session == NULL) + return -1; - err = perf_header__process_sections(header, input, + err = perf_header__process_sections(&session->header, session->fd, perf_file_section__process_buildids); + if (err >= 0) + dsos__fprintf_buildid(stdout); - if (err < 0) - goto out_close; - - dsos__fprintf_buildid(stdout); -out_close: - close(input); -out: + perf_session__delete(session); return err; } diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 5f209514f65..2071d248591 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -6,6 +6,7 @@ #include "util/symbol.h" #include "util/thread.h" #include "util/header.h" +#include "util/session.h" #include "util/parse-options.h" #include "util/trace-event.h" @@ -20,7 +21,6 @@ typedef int (*sort_fn_t)(struct alloc_stat *, struct alloc_stat *); static char const *input_name = "perf.data"; -static struct perf_header *header; static u64 sample_type; static int alloc_flag; @@ -367,11 +367,18 @@ static struct perf_file_handler file_handler = { static int read_events(void) { + int err; + struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0); + + if (session == NULL) + return -ENOMEM; + register_idle_thread(); register_perf_file_handler(&file_handler); - return mmap_dispatch_perf_file(&header, input_name, 0, 0, - &event__cwdlen, &event__cwd); + err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); + perf_session__delete(session); + return err; } static double fragmentation(unsigned long n_req, unsigned long n_alloc) @@ -403,7 +410,7 @@ static void __print_result(struct rb_root *root, int n_lines, int is_caller) if (is_caller) { addr = data->call_site; if (!raw_ip) - sym = thread__find_function(kthread, addr, NULL); + sym = map_groups__find_function(kmaps, addr, NULL); } else addr = data->ptr; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 0e519c667e3..4decbd14eae 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -17,6 +17,7 @@ #include "util/header.h" #include "util/event.h" #include "util/debug.h" +#include "util/session.h" #include "util/symbol.h" #include <unistd.h> @@ -62,7 +63,7 @@ static int nr_cpu = 0; static int file_new = 1; -struct perf_header *header = NULL; +static struct perf_session *session; struct mmap_data { int counter; @@ -216,12 +217,12 @@ static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int n { struct perf_header_attr *h_attr; - if (nr < header->attrs) { - h_attr = header->attr[nr]; + if (nr < session->header.attrs) { + h_attr = session->header.attr[nr]; } else { h_attr = perf_header_attr__new(a); if (h_attr != NULL) - if (perf_header__add_attr(header, h_attr) < 0) { + if (perf_header__add_attr(&session->header, h_attr) < 0) { perf_header_attr__delete(h_attr); h_attr = NULL; } @@ -395,9 +396,9 @@ static void open_counters(int cpu, pid_t pid) static void atexit_header(void) { - header->data_size += bytes_written; + session->header.data_size += bytes_written; - perf_header__write(header, output, true); + perf_header__write(&session->header, output, true); } static int __cmd_record(int argc, const char **argv) @@ -440,24 +441,24 @@ static int __cmd_record(int argc, const char **argv) exit(-1); } - header = perf_header__new(); - if (header == NULL) { + session = perf_session__new(output_name, O_WRONLY, force); + if (session == NULL) { pr_err("Not enough memory for reading perf file header\n"); return -1; } if (!file_new) { - err = perf_header__read(header, output); + err = perf_header__read(&session->header, output); if (err < 0) return err; } if (raw_samples) { - perf_header__set_feat(header, HEADER_TRACE_INFO); + perf_header__set_feat(&session->header, HEADER_TRACE_INFO); } else { for (i = 0; i < nr_counters; i++) { if (attrs[i].sample_type & PERF_SAMPLE_RAW) { - perf_header__set_feat(header, HEADER_TRACE_INFO); + perf_header__set_feat(&session->header, HEADER_TRACE_INFO); break; } } @@ -481,7 +482,7 @@ static int __cmd_record(int argc, const char **argv) } if (file_new) { - err = perf_header__write(header, output, false); + err = perf_header__write(&session->header, output, false); if (err < 0) return err; } diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 2b9eb3a553e..e2ec49a9b73 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -22,6 +22,7 @@ #include "perf.h" #include "util/debug.h" #include "util/header.h" +#include "util/session.h" #include "util/parse-options.h" #include "util/parse-events.h" @@ -52,7 +53,7 @@ static int exclude_other = 1; static char callchain_default_opt[] = "fractal,0.5"; -static struct perf_header *header; +static struct perf_session *session; static u64 sample_type; @@ -701,7 +702,7 @@ static int process_read_event(event_t *event) { struct perf_event_attr *attr; - attr = perf_header__find_attr(event->read.id, header); + attr = perf_header__find_attr(event->read.id, &session->header); if (show_threads) { const char *name = attr ? __event_name(attr->type, attr->config) @@ -766,6 +767,10 @@ static int __cmd_report(void) struct thread *idle; int ret; + session = perf_session__new(input_name, O_RDONLY, force); + if (session == NULL) + return -ENOMEM; + idle = register_idle_thread(); thread__comm_adjust(idle); @@ -774,14 +779,14 @@ static int __cmd_report(void) register_perf_file_handler(&file_handler); - ret = mmap_dispatch_perf_file(&header, input_name, force, - full_paths, &event__cwdlen, &event__cwd); + ret = perf_session__process_events(session, full_paths, + &event__cwdlen, &event__cwd); if (ret) - return ret; + goto out_delete; if (dump_trace) { event__print_totals(); - return 0; + goto out_delete; } if (verbose > 3) @@ -796,7 +801,8 @@ static int __cmd_report(void) if (show_threads) perf_read_values_destroy(&show_threads_values); - +out_delete: + perf_session__delete(session); return ret; } diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 7cca7c15b40..65021fe1361 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -6,6 +6,7 @@ #include "util/symbol.h" #include "util/thread.h" #include "util/header.h" +#include "util/session.h" #include "util/parse-options.h" #include "util/trace-event.h" @@ -21,7 +22,6 @@ static char const *input_name = "perf.data"; -static struct perf_header *header; static u64 sample_type; static char default_sort_order[] = "avg, max, switch, runtime"; @@ -1663,11 +1663,18 @@ static struct perf_file_handler file_handler = { static int read_events(void) { + int err; + struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0); + + if (session == NULL) + return -ENOMEM; + register_idle_thread(); register_perf_file_handler(&file_handler); - return mmap_dispatch_perf_file(&header, input_name, 0, 0, - &event__cwdlen, &event__cwd); + err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); + perf_session__delete(session); + return err; } static void print_bad_events(void) diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index f472df9561e..759dd2b35fd 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -1059,15 +1059,17 @@ static struct perf_file_handler file_handler = { static int __cmd_timechart(void) { - struct perf_header *header; + struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0); int ret; + if (session == NULL) + return -ENOMEM; + register_perf_file_handler(&file_handler); - ret = mmap_dispatch_perf_file(&header, input_name, 0, 0, - &event__cwdlen, &event__cwd); + ret = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); if (ret) - return EXIT_FAILURE; + goto out_delete; process_samples(); @@ -1079,8 +1081,9 @@ static int __cmd_timechart(void) pr_info("Written %2.1f seconds of trace to %s.\n", (last_time - first_time) / 1000000000.0, output_name); - - return EXIT_SUCCESS; +out_delete: + perf_session__delete(session); + return ret; } static const char * const timechart_usage[] = { diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index c2fcc34486f..0756664666f 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -7,6 +7,7 @@ #include "util/header.h" #include "util/exec_cmd.h" #include "util/trace-event.h" +#include "util/session.h" static char const *script_name; static char const *generate_script_lang; @@ -61,7 +62,7 @@ static int cleanup_scripting(void) static char const *input_name = "perf.data"; -static struct perf_header *header; +static struct perf_session *session; static u64 sample_type; static int process_sample_event(event_t *event) @@ -126,11 +127,18 @@ static struct perf_file_handler file_handler = { static int __cmd_trace(void) { + int err; + + session = perf_session__new(input_name, O_RDONLY, 0); + if (session == NULL) + return -ENOMEM; + register_idle_thread(); register_perf_file_handler(&file_handler); - return mmap_dispatch_perf_file(&header, input_name, - 0, 0, &event__cwdlen, &event__cwd); + err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd); + perf_session__delete(session); + return err; } struct script_spec { @@ -348,11 +356,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) return -1; } - header = perf_header__new(); - if (header == NULL) - return -1; - - perf_header__read(header, input); + perf_header__read(&session->header, input); err = scripting_ops->generate_script("perf-trace"); goto out; } diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 454d5d55f32..75f941bfba9 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -59,6 +59,18 @@ #define cpu_relax() asm volatile ("hint @pause" ::: "memory") #endif +#ifdef __arm__ +#include "../../arch/arm/include/asm/unistd.h" +/* + * Use the __kuser_memory_barrier helper in the CPU helper page. See + * arch/arm/kernel/entry-armv.S in the kernel source for details. + */ +#define rmb() asm volatile("mov r0, #0xffff0fff; mov lr, pc;" \ + "sub pc, r0, #95" ::: "r0", "lr", "cc", \ + "memory") +#define cpu_relax() asm volatile("":::"memory") +#endif + #include <time.h> #include <unistd.h> #include <sys/types.h> |