From ea7659fb2b876337aee719d9d5ddb05531dfb334 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 26 May 2011 10:21:05 +0200 Subject: perf: Remove duplicate headers Signed-off-by: Jesper Juhl Cc: Tom Zanussi Cc: Arnaldo Carvalho de Melo Cc: trivial@kernel.org Cc: Peter Zijlstra Cc: Paul Mackerras Link: http://lkml.kernel.org/r/alpine.LNX.2.00.1105261011290.17400@swampdragon.chaosbits.net Signed-off-by: Ingo Molnar --- tools/perf/builtin-annotate.c | 2 -- tools/perf/builtin-script.c | 1 - 2 files changed, 3 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index e18eb7ed30a..7b139e1e7e8 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -7,8 +7,6 @@ */ #include "builtin.h" -#include "util/util.h" - #include "util/util.h" #include "util/color.h" #include diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 974f6d3f4e5..22747de7234 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -10,7 +10,6 @@ #include "util/symbol.h" #include "util/thread.h" #include "util/trace-event.h" -#include "util/parse-options.h" #include "util/util.h" #include "util/evlist.h" #include "util/evsel.h" -- cgit v1.2.3-70-g09d2 From ec80fde746e3ccf93895d25ae1a7071c9af52585 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 26 May 2011 09:53:51 -0300 Subject: perf symbols: Handle /proc/sys/kernel/kptr_restrict Perf uses /proc/modules to figure out where kernel modules are loaded. With the advent of kptr_restrict, non root users get zeroes for all module start addresses. So check if kptr_restrict is non zero and don't generate the syntethic PERF_RECORD_MMAP events for them. Warn the user about it in perf record and in perf report. In perf report the reference relocation symbol being zero means that kptr_restrict was set, thus /proc/kallsyms has only zeroed addresses, so don't use it to fixup symbol addresses when using a valid kallsyms (in the buildid cache) or vmlinux (in the vmlinux path) build-id located automatically or specified by the user. Provide an explanation about it in 'perf report' if kernel samples were taken, checking if a suitable vmlinux or kallsyms was found/specified. Restricted /proc/kallsyms don't go to the buildid cache anymore. Example: [acme@emilia ~]$ perf record -F 100000 sleep 1 WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted, check /proc/sys/kernel/kptr_restrict. Samples in kernel functions may not be resolved if a suitable vmlinux file is not found in the buildid cache or in the vmlinux path. Samples in kernel modules won't be resolved at all. If some relocation was applied (e.g. kexec) symbols may be misresolved even with a suitable vmlinux or kallsyms file. [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.005 MB perf.data (~231 samples) ] [acme@emilia ~]$ [acme@emilia ~]$ perf report --stdio Kernel address maps (/proc/{kallsyms,modules}) were restricted, check /proc/sys/kernel/kptr_restrict before running 'perf record'. If some relocation was applied (e.g. kexec) symbols may be misresolved. Samples in kernel modules can't be resolved as well. # Events: 13 cycles # # Overhead Command Shared Object Symbol # ........ ....... ................. ..................... # 20.24% sleep [kernel.kallsyms] [k] page_fault 20.04% sleep [kernel.kallsyms] [k] filemap_fault 19.78% sleep [kernel.kallsyms] [k] __lru_cache_add 19.69% sleep ld-2.12.so [.] memcpy 14.71% sleep [kernel.kallsyms] [k] dput 4.70% sleep [kernel.kallsyms] [k] flush_signal_handlers 0.73% sleep [kernel.kallsyms] [k] perf_event_comm 0.11% sleep [kernel.kallsyms] [k] native_write_msr_safe # # (For a higher level overview, try: perf report --sort comm,dso) # [acme@emilia ~]$ This is because it found a suitable vmlinux (build-id checked) in /lib/modules/2.6.39-rc7+/build/vmlinux (use -v in perf report to see the long file name). If we remove that file from the vmlinux path: [root@emilia ~]# mv /lib/modules/2.6.39-rc7+/build/vmlinux \ /lib/modules/2.6.39-rc7+/build/vmlinux.OFF [acme@emilia ~]$ perf report --stdio [kernel.kallsyms] with build id 57298cdbe0131f6871667ec0eaab4804dcf6f562 not found, continuing without symbols Kernel address maps (/proc/{kallsyms,modules}) were restricted, check /proc/sys/kernel/kptr_restrict before running 'perf record'. As no suitable kallsyms nor vmlinux was found, kernel samples can't be resolved. Samples in kernel modules can't be resolved as well. # Events: 13 cycles # # Overhead Command Shared Object Symbol # ........ ....... ................. ...... # 80.31% sleep [kernel.kallsyms] [k] 0xffffffff8103425a 19.69% sleep ld-2.12.so [.] memcpy # # (For a higher level overview, try: perf report --sort comm,dso) # [acme@emilia ~]$ Reported-by: Stephane Eranian Suggested-by: David Miller Cc: Dave Jones Cc: David Miller Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Kees Cook Cc: Linus Torvalds Cc: Mike Galbraith Cc: Paul Mackerras Cc: Pekka Enberg Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi Link: http://lkml.kernel.org/n/tip-mt512joaxxbhhp1odop04yit@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 13 ++++++++++++ tools/perf/builtin-report.c | 26 ++++++++++++++++++++++++ tools/perf/util/event.c | 15 +++++++++++--- tools/perf/util/header.c | 8 ++++++-- tools/perf/util/symbol.c | 48 +++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/symbol.h | 3 ++- 6 files changed, 107 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 0974f957b8f..2ca107f3efd 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -823,6 +823,19 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) symbol__init(); + if (symbol_conf.kptr_restrict) + pr_warning("WARNING: Kernel address maps " + "(/proc/{kallsyms,modules}) are restricted, " + "check /proc/sys/kernel/kptr_restrict.\n\n" + "Samples in kernel functions may not be resolved " + "if a suitable vmlinux file is not found in the " + "buildid cache or in the vmlinux path.\n\n" + "Samples in kernel modules won't be resolved " + "at all.\n\n" + "If some relocation was applied (e.g. kexec) " + "symbols may be misresolved even with a suitable " + "vmlinux or kallsyms file.\n\n"); + if (no_buildid_cache || no_buildid) disable_buildid_cache(); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 498c6f70a74..99156c35bc6 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -116,6 +116,9 @@ static int process_sample_event(union perf_event *event, if (al.filtered || (hide_unresolved && al.sym == NULL)) return 0; + if (al.map != NULL) + al.map->dso->hit = 1; + if (perf_session__add_hist_entry(session, &al, sample, evsel)) { pr_debug("problem incrementing symbol period, skipping event\n"); return -1; @@ -249,6 +252,8 @@ static int __cmd_report(void) u64 nr_samples; struct perf_session *session; struct perf_evsel *pos; + struct map *kernel_map; + struct kmap *kernel_kmap; const char *help = "For a higher level overview, try: perf report --sort comm,dso"; signal(SIGINT, sig_handler); @@ -268,6 +273,27 @@ static int __cmd_report(void) if (ret) goto out_delete; + kernel_map = session->host_machine.vmlinux_maps[MAP__FUNCTION]; + kernel_kmap = map__kmap(kernel_map); + if (kernel_map == NULL || + (kernel_map->dso->hit && + (kernel_kmap->ref_reloc_sym == NULL || + kernel_kmap->ref_reloc_sym->addr == 0))) { + const struct dso *kdso = kernel_map->dso; + + ui__warning("Kernel address maps " + "(/proc/{kallsyms,modules}) were restricted, " + "check /proc/sys/kernel/kptr_restrict before " + "running 'perf record'.\n\n%s\n\n" + "Samples in kernel modules can't be resolved " + "as well.\n\n", + RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION]) ? + "As no suitable kallsyms nor vmlinux was found, " + "kernel samples can't be resolved." : + "If some relocation was applied (e.g. kexec) " + "symbols may be misresolved."); + } + if (dump_trace) { perf_session__fprintf_nr_events(session, stdout); goto out_delete; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 6635fcd11ca..0fe9adf7637 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -553,9 +553,18 @@ static int perf_event__process_kernel_mmap(union perf_event *event, goto out_problem; perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps); - perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, - symbol_name, - event->mmap.pgoff); + + /* + * Avoid using a zero address (kptr_restrict) for the ref reloc + * symbol. Effectively having zero here means that at record + * time /proc/sys/kernel/kptr_restrict was non zero. + */ + if (event->mmap.pgoff != 0) { + perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, + symbol_name, + event->mmap.pgoff); + } + if (machine__is_default_guest(machine)) { /* * preload dso of guest kernel and modules diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 0717bebc764..afb0849fe53 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -193,9 +193,13 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, *linkname = malloc(size), *targetname; int len, err = -1; - if (is_kallsyms) + if (is_kallsyms) { + if (symbol_conf.kptr_restrict) { + pr_debug("Not caching a kptr_restrict'ed /proc/kallsyms\n"); + return 0; + } realname = (char *)name; - else + } else realname = realpath(name, NULL); if (realname == NULL || filename == NULL || linkname == NULL) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 516876dfbe5..eec196329fd 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -676,9 +676,30 @@ discard_symbol: rb_erase(&pos->rb_node, root); return count + moved; } +static bool symbol__restricted_filename(const char *filename, + const char *restricted_filename) +{ + bool restricted = false; + + if (symbol_conf.kptr_restrict) { + char *r = realpath(filename, NULL); + + if (r != NULL) { + restricted = strcmp(r, restricted_filename) == 0; + free(r); + return restricted; + } + } + + return restricted; +} + int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map, symbol_filter_t filter) { + if (symbol__restricted_filename(filename, "/proc/kallsyms")) + return -1; + if (dso__load_all_kallsyms(dso, filename, map) < 0) return -1; @@ -1790,6 +1811,9 @@ static int machine__create_modules(struct machine *machine) modules = path; } + if (symbol__restricted_filename(path, "/proc/modules")) + return -1; + file = fopen(modules, "r"); if (file == NULL) return -1; @@ -2239,6 +2263,9 @@ static u64 machine__get_kernel_start_addr(struct machine *machine) } } + if (symbol__restricted_filename(filename, "/proc/kallsyms")) + return 0; + if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0) return 0; @@ -2410,6 +2437,25 @@ static int setup_list(struct strlist **list, const char *list_str, return 0; } +static bool symbol__read_kptr_restrict(void) +{ + bool value = false; + + if (geteuid() != 0) { + FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r"); + if (fp != NULL) { + char line[8]; + + if (fgets(line, sizeof(line), fp) != NULL) + value = atoi(line) != 0; + + fclose(fp); + } + } + + return value; +} + int symbol__init(void) { const char *symfs; @@ -2456,6 +2502,8 @@ int symbol__init(void) if (symfs != symbol_conf.symfs) free((void *)symfs); + symbol_conf.kptr_restrict = symbol__read_kptr_restrict(); + symbol_conf.initialized = true; return 0; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 242de0101a8..325ee36a9d2 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -75,7 +75,8 @@ struct symbol_conf { use_callchain, exclude_other, show_cpu_utilization, - initialized; + initialized, + kptr_restrict; const char *vmlinux_name, *kallsyms_name, *source_prefix, -- cgit v1.2.3-70-g09d2 From 75911c9bd1134f8c0b682aa1e8a8dbefec3ca07a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 26 May 2011 10:13:38 -0300 Subject: perf tools: Fix build on older systems Where /usr/include/linux/const.h is not present, e.g. RHEL5. Reported-by: Srikar Dronamraju Cc: Srikar Dronamraju Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi Link: http://lkml.kernel.org/n/tip-ypcw2mu0w7dl1rrc6ncz3pee@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 2 ++ tools/perf/util/include/linux/const.h | 1 + 2 files changed, 3 insertions(+) create mode 100644 tools/perf/util/include/linux/const.h (limited to 'tools') diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 1455413ec7a..032ba6398a5 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -215,11 +215,13 @@ LIB_FILE=$(OUTPUT)libperf.a LIB_H += ../../include/linux/perf_event.h LIB_H += ../../include/linux/rbtree.h LIB_H += ../../include/linux/list.h +LIB_H += ../../include/linux/const.h LIB_H += ../../include/linux/hash.h LIB_H += ../../include/linux/stringify.h LIB_H += util/include/linux/bitmap.h LIB_H += util/include/linux/bitops.h LIB_H += util/include/linux/compiler.h +LIB_H += util/include/linux/const.h LIB_H += util/include/linux/ctype.h LIB_H += util/include/linux/kernel.h LIB_H += util/include/linux/list.h diff --git a/tools/perf/util/include/linux/const.h b/tools/perf/util/include/linux/const.h new file mode 100644 index 00000000000..1b476c9ae64 --- /dev/null +++ b/tools/perf/util/include/linux/const.h @@ -0,0 +1 @@ +#include "../../../../include/linux/const.h" -- cgit v1.2.3-70-g09d2 From 646aaea615704010b5fd2c8c8891ff1a3a4b4f1a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 27 May 2011 11:00:41 -0300 Subject: perf tools: Make sure kptr_restrict warnings fit 80 col terms Suggested-by: Ingo Molnar Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi Link: http://lkml.kernel.org/n/tip-i1p8vrhq7xveyui6t1sc914e@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 19 ++++++++----------- tools/perf/builtin-report.c | 17 +++++++---------- 2 files changed, 15 insertions(+), 21 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 2ca107f3efd..8e2c8579818 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -824,17 +824,14 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) symbol__init(); if (symbol_conf.kptr_restrict) - pr_warning("WARNING: Kernel address maps " - "(/proc/{kallsyms,modules}) are restricted, " - "check /proc/sys/kernel/kptr_restrict.\n\n" - "Samples in kernel functions may not be resolved " - "if a suitable vmlinux file is not found in the " - "buildid cache or in the vmlinux path.\n\n" - "Samples in kernel modules won't be resolved " - "at all.\n\n" - "If some relocation was applied (e.g. kexec) " - "symbols may be misresolved even with a suitable " - "vmlinux or kallsyms file.\n\n"); + pr_warning( +"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n" +"check /proc/sys/kernel/kptr_restrict.\n\n" +"Samples in kernel functions may not be resolved if a suitable vmlinux\n" +"file is not found in the buildid cache or in the vmlinux path.\n\n" +"Samples in kernel modules won't be resolved at all.\n\n" +"If some relocation was applied (e.g. kexec) symbols may be misresolved\n" +"even with a suitable vmlinux or kallsyms file.\n\n"); if (no_buildid_cache || no_buildid) disable_buildid_cache(); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 99156c35bc6..287a173523a 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -281,17 +281,14 @@ static int __cmd_report(void) kernel_kmap->ref_reloc_sym->addr == 0))) { const struct dso *kdso = kernel_map->dso; - ui__warning("Kernel address maps " - "(/proc/{kallsyms,modules}) were restricted, " - "check /proc/sys/kernel/kptr_restrict before " - "running 'perf record'.\n\n%s\n\n" - "Samples in kernel modules can't be resolved " - "as well.\n\n", + ui__warning( +"Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n" +"Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n" +"Samples in kernel modules can't be resolved as well.\n\n", RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION]) ? - "As no suitable kallsyms nor vmlinux was found, " - "kernel samples can't be resolved." : - "If some relocation was applied (e.g. kexec) " - "symbols may be misresolved."); +"As no suitable kallsyms nor vmlinux was found, kernel samples\n" +"can't be resolved." : +"If some relocation was applied (e.g. kexec) symbols may be misresolved."); } if (dump_trace) { -- cgit v1.2.3-70-g09d2 From 4af4c9550ccaaf0b53013ff730bc15068ffe6abc Mon Sep 17 00:00:00 2001 From: David Ahern Date: Fri, 27 May 2011 09:58:34 -0600 Subject: perf events: initialize fd array to -1 instead of 0 perf_evsel__alloc_fd allocates an array of file descriptors with the memory initialized to 0. The array has dimensions for cpus and threads. Later, __perf_evsel__open calls sys_perf_event_open for each cpu and thread dimensions. If the open fails for any of the cpus or threads then the fd's for this event are closed and the fd entry in the array is set to -1. Now, if the first attempt fails for the event (e.g., the event is not supported) the remaining dimensions (cpu > 0 and thread > 0) are not touched and left at the initialized value of 0. builtin-stat catches ENOENT and ENOSYS failures and allows the command to continue. The end result is that stat attempts to read from an fd of 0 which of course is stdin and so the command hangs until you type ctrl-D. Resolve by initializing the array to -1 since an fd < 0 is already handled. Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1306511914-8016-1-git-send-email-dsahern@gmail.com Signed-off-by: David Ahern Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evsel.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tools') diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index ee0fe0dffa7..cca29ededb5 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -35,7 +35,17 @@ struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx) int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) { + int cpu, thread; evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int)); + + if (evsel->fd) { + for (cpu = 0; cpu < ncpus; cpu++) { + for (thread = 0; thread < nthreads; thread++) { + FD(evsel, cpu, thread) = -1; + } + } + } + return evsel->fd != NULL ? 0 : -ENOMEM; } -- cgit v1.2.3-70-g09d2 From 59fb1ee95e74e8e0777289c44300cbe812aca836 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 27 May 2011 11:14:00 -0300 Subject: perf top: Remove unused macro Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi Link: http://lkml.kernel.org/n/tip-weqbs0tkk2u0qp1xxdxxosfg@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 2d7934e9de3..375ed160d93 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -62,8 +62,6 @@ #include #include -#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) - static struct perf_top top = { .count_filter = 5, .delay_secs = 2, -- cgit v1.2.3-70-g09d2 From 5f6f55809758e106eca72c6e01402c8080a88ee8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 27 May 2011 11:53:28 -0300 Subject: perf top: Handle kptr_restrict Reported-by: Ingo Molnar Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi Link: http://lkml.kernel.org/n/tip-cyl5zmi1nu35vyu7l5im2pyv@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'tools') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 375ed160d93..472f6279002 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -80,6 +80,7 @@ static bool use_tui, use_stdio; static int default_interval = 0; +static bool kptr_restrict_warned; static bool inherit = false; static int realtime_prio = 0; static bool group = false; @@ -738,6 +739,20 @@ static void perf_event__process_sample(const union perf_event *event, al.filtered) return; + if (!kptr_restrict_warned && + symbol_conf.kptr_restrict && + al.cpumode == PERF_RECORD_MISC_KERNEL) { + ui__warning( +"Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n" +"Check /proc/sys/kernel/kptr_restrict.\n\n" +"Kernel%s samples will not be resolved.\n", + !RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION]) ? + " modules" : ""); + if (use_browser <= 0) + sleep(5); + kptr_restrict_warned = true; + } + if (al.sym == NULL) { /* * As we do lazy loading of symtabs we only will know if the -- cgit v1.2.3-70-g09d2 From e4a338d05df93ab1ebf291aca1e753064319d301 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 27 May 2011 13:42:16 -0300 Subject: perf top: Don't stop if no kernel symtab is found We now just warn the user about the fact and go on providing just userspace samples. This fixes a problem when no vmlinux is explicetely passed by the user, thus symbol_conf.vmlinux_name is NULL, no suitable vmlinux is found, and then we get: aldebaran:~> perf top -p 7557 [kernel.kallsyms] with build id 44d9a989eabbd79e486bc079d6b743d397c204e0 not found, continuing without symbols The (null) file can't be used Reported-by: Ingo Molnar Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi Link: http://lkml.kernel.org/n/tip-cj2g81hn64wv2bipmqk4fy2m@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 472f6279002..f2f3f4937aa 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -81,6 +81,7 @@ static bool use_tui, use_stdio; static int default_interval = 0; static bool kptr_restrict_warned; +static bool vmlinux_warned; static bool inherit = false; static int realtime_prio = 0; static bool group = false; @@ -754,6 +755,7 @@ static void perf_event__process_sample(const union perf_event *event, } if (al.sym == NULL) { + const char *msg = "Kernel samples will not be resolved.\n"; /* * As we do lazy loading of symtabs we only will know if the * specified vmlinux file is invalid when we actually have a @@ -765,12 +767,20 @@ static void perf_event__process_sample(const union perf_event *event, * --hide-kernel-symbols, even if the user specifies an * invalid --vmlinux ;-) */ - if (al.map == machine->vmlinux_maps[MAP__FUNCTION] && + if (!kptr_restrict_warned && !vmlinux_warned && + al.map == machine->vmlinux_maps[MAP__FUNCTION] && RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) { - ui__warning("The %s file can't be used\n", - symbol_conf.vmlinux_name); - exit_browser(0); - exit(1); + if (symbol_conf.vmlinux_name) { + ui__warning("The %s file can't be used.\n%s", + symbol_conf.vmlinux_name, msg); + } else { + ui__warning("A vmlinux file was not found.\n%s", + msg); + } + + if (use_browser <= 0) + sleep(5); + vmlinux_warned = true; } return; -- cgit v1.2.3-70-g09d2 From 4423fe40b03f32b11e72ecfa03077e702e55d5a9 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Fri, 20 May 2011 02:11:05 +0300 Subject: virtio_test: support event index Add ability to test the new event idx feature, enable by default. Signed-off-by: Rusty Russell --- tools/virtio/virtio_test.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c index df0c6d2c386..74d3331bdaf 100644 --- a/tools/virtio/virtio_test.c +++ b/tools/virtio/virtio_test.c @@ -197,6 +197,14 @@ const struct option longopts[] = { .name = "help", .val = 'h', }, + { + .name = "event-idx", + .val = 'E', + }, + { + .name = "no-event-idx", + .val = 'e', + }, { .name = "indirect", .val = 'I', @@ -211,13 +219,17 @@ const struct option longopts[] = { static void help() { - fprintf(stderr, "Usage: virtio_test [--help] [--no-indirect]\n"); + fprintf(stderr, "Usage: virtio_test [--help]" + " [--no-indirect]" + " [--no-event-idx]" + "\n"); } int main(int argc, char **argv) { struct vdev_info dev; - unsigned long long features = 1ULL << VIRTIO_RING_F_INDIRECT_DESC; + unsigned long long features = (1ULL << VIRTIO_RING_F_INDIRECT_DESC) | + (1ULL << VIRTIO_RING_F_EVENT_IDX); int o; for (;;) { @@ -228,6 +240,9 @@ int main(int argc, char **argv) case '?': help(); exit(2); + case 'e': + features &= ~(1ULL << VIRTIO_RING_F_EVENT_IDX); + break; case 'h': help(); goto done; -- cgit v1.2.3-70-g09d2 From 4c8cc55b3c0ebe989e727017933945b68b4327cd Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 1 Jun 2011 23:22:30 -0400 Subject: ktest: Fix off-by-one in config bisect result Because in perl the array size returned by $#arr, is the last index and not the actually size of the array, we end the config bisect early, thinking there is only one config left when there are in fact two. Thus the result has a 50% chance of picking the correct config that caused the problem. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 1fd29b2daa9..8dc8c3cf3ac 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -1638,7 +1638,7 @@ sub run_config_bisect { if (!$found) { # try the other half doprint "Top half produced no set configs, trying bottom half\n"; - @tophalf = @start_list[$half .. $#start_list]; + @tophalf = @start_list[$half + 1 .. $#start_list]; create_config @tophalf; read_current_config \%current_config; foreach my $config (@tophalf) { @@ -1690,7 +1690,7 @@ sub run_config_bisect { # remove half the configs we are looking at and see if # they are good. $half = int($#start_list / 2); - } while ($half > 0); + } while ($#start_list > 0); # we found a single config, try it again unless we are running manually -- cgit v1.2.3-70-g09d2 From 4da46da2d295c0d9f4aaf28dd2b70a1ecb42d972 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 1 Jun 2011 23:25:13 -0400 Subject: ktest: Fix result of rebooting the kernel The command that is called that reboots the kernel may fail but the return code is not passed back to the ktest.pl script. This is because a ';' is used between the two commands and if the second command fails, only the first command's return code is returned. Using a '&&' between the two commands fixes this. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 8dc8c3cf3ac..6c68259e730 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -788,7 +788,7 @@ sub wait_for_input sub reboot_to { if ($reboot_type eq "grub") { - run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; + run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'"; return; } -- cgit v1.2.3-70-g09d2 From 9bf7174949aef2f43253956e1f3ab01698abbd79 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 1 Jun 2011 23:27:19 -0400 Subject: ktest: Ignore unset values of the minconfig in config_bisect By ignoring the unset values of the minconfig in deciding what to test in the config_bisect can cause the problem config from being tested too. Just do not test the configs that are set in the minconfig. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 6c68259e730..cef28e6632b 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -1480,7 +1480,7 @@ sub process_config_ignore { or dodie "Failed to read $config"; while () { - if (/^(.*?(CONFIG\S*)(=.*| is not set))/) { + if (/^((CONFIG\S*)=.*)/) { $config_ignore{$2} = $1; } } -- cgit v1.2.3-70-g09d2 From d21cc9f67d689effbfd24bac878bc2c057de8c46 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 2 Jun 2011 10:39:43 -0300 Subject: perf evlist: Remove dependency on debug routines So far we avoided having to link debug.o in the python binding, keep it that way by not using ui__warning() in evlist.c. Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-4wtew8hd3g7ejnlehtspys2t@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 50aa34879c3..04c8a60075b 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -12,7 +12,6 @@ #include "evlist.h" #include "evsel.h" #include "util.h" -#include "debug.h" #include @@ -257,19 +256,15 @@ int perf_evlist__alloc_mmap(struct perf_evlist *evlist) return evlist->mmap != NULL ? 0 : -ENOMEM; } -static int __perf_evlist__mmap(struct perf_evlist *evlist, struct perf_evsel *evsel, +static int __perf_evlist__mmap(struct perf_evlist *evlist, int idx, int prot, int mask, int fd) { evlist->mmap[idx].prev = 0; evlist->mmap[idx].mask = mask; evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot, MAP_SHARED, fd, 0); - if (evlist->mmap[idx].base == MAP_FAILED) { - if (evlist->cpus->map[idx] == -1 && evsel->attr.inherit) - ui__warning("Inherit is not allowed on per-task " - "events using mmap.\n"); + if (evlist->mmap[idx].base == MAP_FAILED) return -1; - } perf_evlist__add_pollfd(evlist, fd); return 0; @@ -289,7 +284,7 @@ static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int m if (output == -1) { output = fd; - if (__perf_evlist__mmap(evlist, evsel, cpu, + if (__perf_evlist__mmap(evlist, cpu, prot, mask, output) < 0) goto out_unmap; } else { @@ -329,7 +324,7 @@ static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, in if (output == -1) { output = fd; - if (__perf_evlist__mmap(evlist, evsel, thread, + if (__perf_evlist__mmap(evlist, thread, prot, mask, output) < 0) goto out_unmap; } else { -- cgit v1.2.3-70-g09d2 From 9c850d6c4b95bb07fb066eb7f43dd4e3b4842b85 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 2 Jun 2011 10:55:10 -0300 Subject: perf python: Use exception to propagate errors We were using pr_debug to tell the user about not being able to parse a sample where we should really use the python way of reporting errors: exceptions. Fixes this problem: [root@emilia ~]# python >>> import perf Traceback (most recent call last): File "", line 1, in ImportError: /home/acme/git/build/perf/python/perf.so: undefined symbol: eprintf >>> [root@emilia ~] As we want to keep the objects linked in the python binding (and in the future in a shared library) minimal. Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-m9dba9kaluas0kq8r58z191c@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/python.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 69436b3200a..2dd1698e093 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -694,14 +694,12 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, err = perf_event__parse_sample(event, first->attr.sample_type, perf_sample_size(first->attr.sample_type), sample_id_all, &pevent->sample); - if (err) { - pr_err("Can't parse sample, err = %d\n", err); - goto end; - } - + if (err) + return PyErr_Format(PyExc_OSError, + "perf: can't parse sample, err=%d", err); return pyevent; } -end: + Py_INCREF(Py_None); return Py_None; } -- cgit v1.2.3-70-g09d2 From 56722381b8506733852c44dacf6d7bc5f90aedaf Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 2 Jun 2011 11:04:54 -0300 Subject: perf evlist: Don't die if sample_{id_all|type} is invalid Fixes two more cases where the python binding would not load: . Not finding die(), which it shouldn't anyway, not good to just stop the world because some particular perf.data file is invalid, just propagate the error to the caller. . Not finding perf_sample_size: fix it by moving it from event.c to evsel, where it belongs, as most cases are moving to operate on an evsel object.o One of the fixed problems: [root@emilia ~]# python >>> import perf Traceback (most recent call last): File "", line 1, in ImportError: /home/acme/git/build/perf/python/perf.so: undefined symbol: perf_sample_size >>> [root@emilia ~]# Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-1hkj7b2cvgbfnoizsekjb6c9@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-test.c | 2 +- tools/perf/util/event.c | 16 -------------- tools/perf/util/event.h | 2 -- tools/perf/util/evlist.c | 55 +++++++++++++++++++++++++++++------------------ tools/perf/util/evlist.h | 6 ++++-- tools/perf/util/evsel.c | 16 ++++++++++++++ tools/perf/util/evsel.h | 7 ++++++ tools/perf/util/python.c | 2 +- tools/perf/util/session.c | 12 ++++++++++- 9 files changed, 74 insertions(+), 44 deletions(-) (limited to 'tools') diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index b67186228c8..2da9162262b 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c @@ -474,7 +474,7 @@ static int test__basic_mmap(void) unsigned int nr_events[nsyscalls], expected_nr_events[nsyscalls], i, j; struct perf_evsel *evsels[nsyscalls], *evsel; - int sample_size = perf_sample_size(attr.sample_type); + int sample_size = __perf_evsel__sample_size(attr.sample_type); for (i = 0; i < nsyscalls; ++i) { char name[64]; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 0fe9adf7637..3c1b8a63210 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -35,22 +35,6 @@ const char *perf_event__name(unsigned int id) return perf_event__names[id]; } -int perf_sample_size(u64 sample_type) -{ - u64 mask = sample_type & PERF_SAMPLE_MASK; - int size = 0; - int i; - - for (i = 0; i < 64; i++) { - if (mask & (1ULL << i)) - size++; - } - - size *= sizeof(u64); - - return size; -} - static struct perf_sample synth_sample = { .pid = -1, .tid = -1, diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index c0833287140..1d7f66488a8 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -82,8 +82,6 @@ struct perf_sample { struct ip_callchain *callchain; }; -int perf_sample_size(u64 sample_type); - #define BUILD_ID_SIZE 20 struct build_id_event { diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 04c8a60075b..b021ea9265c 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -455,33 +455,46 @@ int perf_evlist__set_filters(struct perf_evlist *evlist) return 0; } -u64 perf_evlist__sample_type(struct perf_evlist *evlist) +bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist) { - struct perf_evsel *pos; - u64 type = 0; - - list_for_each_entry(pos, &evlist->entries, node) { - if (!type) - type = pos->attr.sample_type; - else if (type != pos->attr.sample_type) - die("non matching sample_type"); + struct perf_evsel *pos, *first; + + pos = first = list_entry(evlist->entries.next, struct perf_evsel, node); + + list_for_each_entry_continue(pos, &evlist->entries, node) { + if (first->attr.sample_type != pos->attr.sample_type) + return false; } - return type; + return true; } -bool perf_evlist__sample_id_all(const struct perf_evlist *evlist) +u64 perf_evlist__sample_type(const struct perf_evlist *evlist) +{ + struct perf_evsel *first; + + first = list_entry(evlist->entries.next, struct perf_evsel, node); + return first->attr.sample_type; +} + +bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist) { - bool value = false, first = true; - struct perf_evsel *pos; - - list_for_each_entry(pos, &evlist->entries, node) { - if (first) { - value = pos->attr.sample_id_all; - first = false; - } else if (value != pos->attr.sample_id_all) - die("non matching sample_id_all"); + struct perf_evsel *pos, *first; + + pos = first = list_entry(evlist->entries.next, struct perf_evsel, node); + + list_for_each_entry_continue(pos, &evlist->entries, node) { + if (first->attr.sample_id_all != pos->attr.sample_id_all) + return false; } - return value; + return true; +} + +bool perf_evlist__sample_id_all(const struct perf_evlist *evlist) +{ + struct perf_evsel *first; + + first = list_entry(evlist->entries.next, struct perf_evsel, node); + return first->attr.sample_id_all; } diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 0a1ef1f051f..b2b862374f3 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -66,7 +66,9 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, void perf_evlist__delete_maps(struct perf_evlist *evlist); int perf_evlist__set_filters(struct perf_evlist *evlist); -u64 perf_evlist__sample_type(struct perf_evlist *evlist); -bool perf_evlist__sample_id_all(const struct perf_evlist *evlist); +u64 perf_evlist__sample_type(const struct perf_evlist *evlist); +bool perf_evlist__sample_id_all(const const struct perf_evlist *evlist); +bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist); +bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist); #endif /* __PERF_EVLIST_H */ diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index cca29ededb5..0239eb87b23 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -15,6 +15,22 @@ #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) +int __perf_evsel__sample_size(u64 sample_type) +{ + u64 mask = sample_type & PERF_SAMPLE_MASK; + int size = 0; + int i; + + for (i = 0; i < 64; i++) { + if (mask & (1ULL << i)) + size++; + } + + size *= sizeof(u64); + + return size; +} + void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr, int idx) { diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index f79bb2c09a6..7e9366e4490 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -149,4 +149,11 @@ static inline int perf_evsel__read_scaled(struct perf_evsel *evsel, return __perf_evsel__read(evsel, ncpus, nthreads, true); } +int __perf_evsel__sample_size(u64 sample_type); + +static inline int perf_evsel__sample_size(struct perf_evsel *evsel) +{ + return __perf_evsel__sample_size(evsel->attr.sample_type); +} + #endif /* __PERF_EVSEL_H */ diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 2dd1698e093..24063b4d41e 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -692,7 +692,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, first = list_entry(evlist->entries.next, struct perf_evsel, node); err = perf_event__parse_sample(event, first->attr.sample_type, - perf_sample_size(first->attr.sample_type), + perf_evsel__sample_size(first), sample_id_all, &pevent->sample); if (err) return PyErr_Format(PyExc_OSError, diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 64500fc7879..f5a8fbdd3f7 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -58,6 +58,16 @@ static int perf_session__open(struct perf_session *self, bool force) goto out_close; } + if (!perf_evlist__valid_sample_type(self->evlist)) { + pr_err("non matching sample_type"); + goto out_close; + } + + if (!perf_evlist__valid_sample_id_all(self->evlist)) { + pr_err("non matching sample_id_all"); + goto out_close; + } + self->size = input_stat.st_size; return 0; @@ -97,7 +107,7 @@ out: void perf_session__update_sample_type(struct perf_session *self) { self->sample_type = perf_evlist__sample_type(self->evlist); - self->sample_size = perf_sample_size(self->sample_type); + self->sample_size = __perf_evsel__sample_size(self->sample_type); self->sample_id_all = perf_evlist__sample_id_all(self->evlist); perf_session__id_header_size(self); } -- cgit v1.2.3-70-g09d2 From b273fa9716aa1564bee88ceee62f9042981cdc81 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 31 Mar 2011 18:27:42 +0200 Subject: perf python: Fix argument name list of read_on_cpu() Mandatory arguments need to be present in the argument name list, as well as optional arguments, otherwise python barfs: # ./python/twatch.py Traceback (most recent call last): File "./python/twatch.py", line 41, in main() File "./python/twatch.py", line 32, in main event = evlist.read_on_cpu(cpu) RuntimeError: more argument specifiers than keyword list entries Hence, add cpu to the name list. Cc: David Ahern Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi Link: http://lkml.kernel.org/r/1301588863-20210-1-git-send-email-fweisbec@gmail.com Signed-off-by: Frederic Weisbecker Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/python.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 24063b4d41e..a9ac0504aab 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -674,7 +674,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, struct perf_evlist *evlist = &pevlist->evlist; union perf_event *event; int sample_id_all = 1, cpu; - static char *kwlist[] = {"sample_id_all", NULL, NULL}; + static char *kwlist[] = {"cpu", "sample_id_all", NULL, NULL}; int err; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist, -- cgit v1.2.3-70-g09d2 From 5d61b9fd19d9f3cf653dbba615876e7792eea5ea Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Mon, 30 May 2011 14:12:09 +0200 Subject: perf: Use make kernelversion instead of parsing the Makefile Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Ingo Molnar Cc: Arnaldo Carvalho de Melo Signed-off-by: Michal Marek --- tools/perf/util/PERF-VERSION-GEN | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN index 26d4d3fd6de..9c5fb4d9382 100755 --- a/tools/perf/util/PERF-VERSION-GEN +++ b/tools/perf/util/PERF-VERSION-GEN @@ -23,12 +23,7 @@ if test -d ../../.git -o -f ../../.git && then VN=$(echo "$VN" | sed -e 's/-/./g'); else - eval $(grep '^VERSION[[:space:]]*=' ../../Makefile|tr -d ' ') - eval $(grep '^PATCHLEVEL[[:space:]]*=' ../../Makefile|tr -d ' ') - eval $(grep '^SUBLEVEL[[:space:]]*=' ../../Makefile|tr -d ' ') - eval $(grep '^EXTRAVERSION[[:space:]]*=' ../../Makefile|tr -d ' ') - - VN="${VERSION}.${PATCHLEVEL}.${SUBLEVEL}${EXTRAVERSION}" + VN=$(make -sC ../.. kernelversion) fi VN=$(expr "$VN" : v*'\(.*\)') -- cgit v1.2.3-70-g09d2 From 09223371deac67d08ca0b70bd18787920284c967 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Tue, 14 Jun 2011 13:26:25 +0800 Subject: rcu: Use softirq to address performance regression Commit a26ac2455ffcf3(rcu: move TREE_RCU from softirq to kthread) introduced performance regression. In an AIM7 test, this commit degraded performance by about 40%. The commit runs rcu callbacks in a kthread instead of softirq. We observed high rate of context switch which is caused by this. Out test system has 64 CPUs and HZ is 1000, so we saw more than 64k context switch per second which is caused by RCU's per-CPU kthread. A trace showed that most of the time the RCU per-CPU kthread doesn't actually handle any callbacks, but instead just does a very small amount of work handling grace periods. This means that RCU's per-CPU kthreads are making the scheduler do quite a bit of work in order to allow a very small amount of RCU-related processing to be done. Alex Shi's analysis determined that this slowdown is due to lock contention within the scheduler. Unfortunately, as Peter Zijlstra points out, the scheduler's real-time semantics require global action, which means that this contention is inherent in real-time scheduling. (Yes, perhaps someone will come up with a workaround -- otherwise, -rt is not going to do well on large SMP systems -- but this patch will work around this issue in the meantime. And "the meantime" might well be forever.) This patch therefore re-introduces softirq processing to RCU, but only for core RCU work. RCU callbacks are still executed in kthread context, so that only a small amount of RCU work runs in softirq context in the common case. This should minimize ksoftirqd execution, allowing us to skip boosting of ksoftirqd for CONFIG_RCU_BOOST=y kernels. Signed-off-by: Shaohua Li Tested-by: "Alex,Shi" Signed-off-by: Paul E. McKenney --- Documentation/filesystems/proc.txt | 1 + include/linux/interrupt.h | 1 + include/trace/events/irq.h | 3 ++- kernel/rcutree.c | 23 +++++++++++++++++++---- kernel/rcutree.h | 1 + kernel/rcutree_plugin.h | 9 +++++++++ kernel/softirq.c | 2 +- tools/perf/util/trace-event-parse.c | 1 + 8 files changed, 35 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index f4817802406..db3b1aba32a 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -843,6 +843,7 @@ Provides counts of softirq handlers serviced since boot time, for each cpu. TASKLET: 0 0 0 290 SCHED: 27035 26983 26971 26746 HRTIMER: 0 0 0 0 + RCU: 1678 1769 2178 2250 1.3 IDE devices in /proc/ide diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 6c12989839d..f6efed0039e 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -414,6 +414,7 @@ enum TASKLET_SOFTIRQ, SCHED_SOFTIRQ, HRTIMER_SOFTIRQ, + RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */ NR_SOFTIRQS }; diff --git a/include/trace/events/irq.h b/include/trace/events/irq.h index ae045ca7d35..1c09820df58 100644 --- a/include/trace/events/irq.h +++ b/include/trace/events/irq.h @@ -20,7 +20,8 @@ struct softirq_action; softirq_name(BLOCK_IOPOLL), \ softirq_name(TASKLET), \ softirq_name(SCHED), \ - softirq_name(HRTIMER)) + softirq_name(HRTIMER), \ + softirq_name(RCU)) /** * irq_handler_entry - called immediately before the irq action handler diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 0a8ec5b2e20..ae5c9ea6866 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -100,6 +100,7 @@ static char rcu_kthreads_spawnable; static void rcu_node_kthread_setaffinity(struct rcu_node *rnp, int outgoingcpu); static void invoke_rcu_cpu_kthread(void); +static void __invoke_rcu_cpu_kthread(void); #define RCU_KTHREAD_PRIO 1 /* RT priority for per-CPU kthreads. */ @@ -1442,13 +1443,21 @@ __rcu_process_callbacks(struct rcu_state *rsp, struct rcu_data *rdp) } /* If there are callbacks ready, invoke them. */ - rcu_do_batch(rsp, rdp); + if (cpu_has_callbacks_ready_to_invoke(rdp)) + __invoke_rcu_cpu_kthread(); +} + +static void rcu_kthread_do_work(void) +{ + rcu_do_batch(&rcu_sched_state, &__get_cpu_var(rcu_sched_data)); + rcu_do_batch(&rcu_bh_state, &__get_cpu_var(rcu_bh_data)); + rcu_preempt_do_callbacks(); } /* * Do softirq processing for the current CPU. */ -static void rcu_process_callbacks(void) +static void rcu_process_callbacks(struct softirq_action *unused) { __rcu_process_callbacks(&rcu_sched_state, &__get_cpu_var(rcu_sched_data)); @@ -1465,7 +1474,7 @@ static void rcu_process_callbacks(void) * the current CPU with interrupts disabled, the rcu_cpu_kthread_task * cannot disappear out from under us. */ -static void invoke_rcu_cpu_kthread(void) +static void __invoke_rcu_cpu_kthread(void) { unsigned long flags; @@ -1479,6 +1488,11 @@ static void invoke_rcu_cpu_kthread(void) local_irq_restore(flags); } +static void invoke_rcu_cpu_kthread(void) +{ + raise_softirq(RCU_SOFTIRQ); +} + /* * Wake up the specified per-rcu_node-structure kthread. * Because the per-rcu_node kthreads are immortal, we don't need @@ -1613,7 +1627,7 @@ static int rcu_cpu_kthread(void *arg) *workp = 0; local_irq_restore(flags); if (work) - rcu_process_callbacks(); + rcu_kthread_do_work(); local_bh_enable(); if (*workp != 0) spincnt++; @@ -2387,6 +2401,7 @@ void __init rcu_init(void) rcu_init_one(&rcu_sched_state, &rcu_sched_data); rcu_init_one(&rcu_bh_state, &rcu_bh_data); __rcu_init_preempt(); + open_softirq(RCU_SOFTIRQ, rcu_process_callbacks); /* * We don't need protection against CPU-hotplug here because diff --git a/kernel/rcutree.h b/kernel/rcutree.h index 7b9a08b4aae..0fed6b934d2 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h @@ -439,6 +439,7 @@ static void rcu_preempt_offline_cpu(int cpu); #endif /* #ifdef CONFIG_HOTPLUG_CPU */ static void rcu_preempt_check_callbacks(int cpu); static void rcu_preempt_process_callbacks(void); +static void rcu_preempt_do_callbacks(void); void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu)); #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU) static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp); diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index ea2e2fb79e8..38d09c5f2b4 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h @@ -602,6 +602,11 @@ static void rcu_preempt_process_callbacks(void) &__get_cpu_var(rcu_preempt_data)); } +static void rcu_preempt_do_callbacks(void) +{ + rcu_do_batch(&rcu_preempt_state, &__get_cpu_var(rcu_preempt_data)); +} + /* * Queue a preemptible-RCU callback for invocation after a grace period. */ @@ -997,6 +1002,10 @@ static void rcu_preempt_process_callbacks(void) { } +static void rcu_preempt_do_callbacks(void) +{ +} + /* * Wait for an rcu-preempt grace period, but make it happen quickly. * But because preemptible RCU does not exist, map to rcu-sched. diff --git a/kernel/softirq.c b/kernel/softirq.c index 13960170cad..40cf63ddd4b 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -58,7 +58,7 @@ DEFINE_PER_CPU(struct task_struct *, ksoftirqd); char *softirq_to_name[NR_SOFTIRQS] = { "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "BLOCK_IOPOLL", - "TASKLET", "SCHED", "HRTIMER" + "TASKLET", "SCHED", "HRTIMER", "RCU" }; /* diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index 1e88485c16a..0a7ed5b5e28 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c @@ -2187,6 +2187,7 @@ static const struct flag flags[] = { { "TASKLET_SOFTIRQ", 6 }, { "SCHED_SOFTIRQ", 7 }, { "HRTIMER_SOFTIRQ", 8 }, + { "RCU_SOFTIRQ", 9 }, { "HRTIMER_NORESTART", 0 }, { "HRTIMER_RESTART", 1 }, -- cgit v1.2.3-70-g09d2 From 37aa9a2eb4d9b1a4aec1fd18bb2bb6bca029de27 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Wed, 15 Jun 2011 14:35:00 +0100 Subject: perf: clear out make flags when calling kernel make kernelver When generating the perf version from the kernel version using 'make kernelver' it is necessary to clear out any MAKEFLAGS otherwise they may trigger additional output which pollute the contents. Signed-off-by: Andy Whitcroft Signed-off-by: Michal Marek --- tools/perf/util/PERF-VERSION-GEN | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN index 9c5fb4d9382..ad73300f7ba 100755 --- a/tools/perf/util/PERF-VERSION-GEN +++ b/tools/perf/util/PERF-VERSION-GEN @@ -23,7 +23,7 @@ if test -d ../../.git -o -f ../../.git && then VN=$(echo "$VN" | sed -e 's/-/./g'); else - VN=$(make -sC ../.. kernelversion) + VN=$(MAKEFLAGS= make -sC ../.. kernelversion) fi VN=$(expr "$VN" : v*'\(.*\)') -- cgit v1.2.3-70-g09d2 From 203db2952bc87f5d610c9ad53a7d02b85897721f Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Wed, 15 Jun 2011 23:03:38 +0200 Subject: tools/perf: Fix static build of perf tool To build a statically linked version of the perf tool all needed libraries must be added in the correct order to get the symbols resolved. Currently this is broken when, e.g. python or newt support is enabled -- libpython needs libpthread which is an unconditional link dependency of the perf tool; libslang needs libm, another unconditional dependency. To solve the problem in the long run without the need to keep track of transitive library dependencies, simply make the linker look at the EXTLIBS multiple times until it has all symbols resolved. Signed-off-by: Mathias Krause Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo Link: http://lkml.kernel.org/r/1308171818-20370-1-git-send-email-minipli@googlemail.com Signed-off-by: Ingo Molnar --- tools/perf/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 032ba6398a5..940257b5774 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -633,7 +633,7 @@ prefix_SQ = $(subst ','\'',$(prefix)) SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) -LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive $(EXTLIBS) +LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group ALL_CFLAGS += $(BASIC_CFLAGS) ALL_CFLAGS += $(ARCH_CFLAGS) -- cgit v1.2.3-70-g09d2