diff options
Diffstat (limited to 'tools')
53 files changed, 272 insertions, 173 deletions
diff --git a/tools/build/feature/test-sched_getcpu.c b/tools/build/feature/test-sched_getcpu.c index c4a148d..9c6b4cb 100644 --- a/tools/build/feature/test-sched_getcpu.c +++ b/tools/build/feature/test-sched_getcpu.c @@ -1,4 +1,6 @@ +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include <sched.h> int main(void) diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h index f436d24..d62b56c 100644 --- a/tools/include/linux/string.h +++ b/tools/include/linux/string.h @@ -18,4 +18,6 @@ extern size_t strlcpy(char *dest, const char *src, size_t size); char *str_error_r(int errnum, char *buf, size_t buflen); +int prefixcmp(const char *str, const char *prefix); + #endif /* _LINUX_STRING_H_ */ diff --git a/tools/lib/string.c b/tools/lib/string.c index bd239bc..8e678af 100644 --- a/tools/lib/string.c +++ b/tools/lib/string.c @@ -87,3 +87,12 @@ size_t __weak strlcpy(char *dest, const char *src, size_t size) } return ret; } + +int prefixcmp(const char *str, const char *prefix) +{ + for (; ; str++, prefix++) + if (!*prefix) + return 0; + else if (*str != *prefix) + return (unsigned char)*prefix - (unsigned char)*str; +} diff --git a/tools/lib/subcmd/help.c b/tools/lib/subcmd/help.c index e228c3c..ba970a7 100644 --- a/tools/lib/subcmd/help.c +++ b/tools/lib/subcmd/help.c @@ -1,6 +1,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <linux/string.h> #include <termios.h> #include <sys/ioctl.h> #include <sys/types.h> diff --git a/tools/lib/subcmd/parse-options.c b/tools/lib/subcmd/parse-options.c index 6bc2402..359bfa7 100644 --- a/tools/lib/subcmd/parse-options.c +++ b/tools/lib/subcmd/parse-options.c @@ -1,4 +1,5 @@ #include <linux/compiler.h> +#include <linux/string.h> #include <linux/types.h> #include <stdio.h> #include <stdlib.h> diff --git a/tools/lib/subcmd/subcmd-util.h b/tools/lib/subcmd/subcmd-util.h index fc2e45d..8fa5f03 100644 --- a/tools/lib/subcmd/subcmd-util.h +++ b/tools/lib/subcmd/subcmd-util.h @@ -79,13 +79,4 @@ static inline void astrcat(char **out, const char *add) free(tmp); } -static inline int prefixcmp(const char *str, const char *prefix) -{ - for (; ; str++, prefix++) - if (!*prefix) - return 0; - else if (*str != *prefix) - return (unsigned char)*prefix - (unsigned char)*str; -} - #endif /* __SUBCMD_UTIL_H */ diff --git a/tools/perf/Documentation/perf-c2c.txt b/tools/perf/Documentation/perf-c2c.txt index 2da07e5..8224142 100644 --- a/tools/perf/Documentation/perf-c2c.txt +++ b/tools/perf/Documentation/perf-c2c.txt @@ -76,7 +76,7 @@ REPORT OPTIONS -c:: --coalesce:: - Specify sorintg fields for single cacheline display. + Specify sorting fields for single cacheline display. Following fields are available: tid,pid,iaddr,dso (see COALESCE) @@ -106,7 +106,7 @@ REPORT OPTIONS -d:: --display:: - Siwtch to HITM type (rmt, lcl) to display and sort on. Total HITMs as default. + Switch to HITM type (rmt, lcl) to display and sort on. Total HITMs as default. C2C RECORD ---------- diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index ea3789d..b0e9e92 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -225,7 +225,7 @@ OPTIONS the libunwind or libdw library) should be used instead. Using the "lbr" method doesn't require any compiler options. It will produce call graphs from the hardware LBR registers. The - main limition is that it is only available on new Intel + main limitation is that it is only available on new Intel platforms, such as Haswell. It can only get user call chain. It doesn't work with branch stack sampling at the same time. diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 37a1759..9fa8461 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -182,7 +182,7 @@ OPTIONS --parent=<regex>:: A regex filter to identify parent. The parent is a caller of this function and searched through the callchain, thus it requires callchain - information recorded. The pattern is in the exteneded regex format and + information recorded. The pattern is in the extended regex format and defaults to "\^sys_|^do_page_fault", see '--sort parent'. -x:: @@ -207,8 +207,8 @@ OPTIONS -g:: --call-graph=<print_type,threshold[,print_limit],order,sort_key[,branch],value>:: Display call chains using type, min percent threshold, print limit, - call order, sort key, optional branch and value. Note that ordering of - parameters is not fixed so any parement can be given in an arbitraty order. + call order, sort key, optional branch and value. Note that ordering + is not fixed so any parameter can be given in an arbitrary order. One exception is the print_limit which should be preceded by threshold. print_type can be either: diff --git a/tools/perf/Documentation/perf.data-file-format.txt b/tools/perf/Documentation/perf.data-file-format.txt index fa2a913..de8b39d 100644 --- a/tools/perf/Documentation/perf.data-file-format.txt +++ b/tools/perf/Documentation/perf.data-file-format.txt @@ -270,7 +270,7 @@ When the event stream contains multiple events each event is identified by an ID. This can be either through the PERF_SAMPLE_ID or the PERF_SAMPLE_IDENTIFIER header. The PERF_SAMPLE_IDENTIFIER header is at a fixed offset from the event header, which allows reliable -parsing of the header. Relying on ID may be ambigious. +parsing of the header. Relying on ID may be ambiguous. IDENTIFIER is only supported by newer Linux kernels. Perf record specific events: @@ -288,7 +288,7 @@ struct attr_event { uint64_t id[]; }; - PERF_RECORD_HEADER_EVENT_TYPE = 65, /* depreceated */ + PERF_RECORD_HEADER_EVENT_TYPE = 65, /* deprecated */ #define MAX_EVENT_NAME 64 diff --git a/tools/perf/Documentation/tips.txt b/tools/perf/Documentation/tips.txt index 170b028..db0ca30 100644 --- a/tools/perf/Documentation/tips.txt +++ b/tools/perf/Documentation/tips.txt @@ -23,7 +23,7 @@ For memory address profiling, try: perf mem record / perf mem report For tracepoint events, try: perf report -s trace_fields To record callchains for each sample: perf record -g To record every process run by a user: perf record -u <user> -Skip collecing build-id when recording: perf record -B +Skip collecting build-id when recording: perf record -B To change sampling frequency to 100 Hz: perf record -F 100 See assembly instructions with percentage: perf annotate <symbol> If you prefer Intel style assembly, try: perf annotate -M intel diff --git a/tools/perf/arch/arm64/annotate/instructions.c b/tools/perf/arch/arm64/annotate/instructions.c index 44eafd6..8f19087 100644 --- a/tools/perf/arch/arm64/annotate/instructions.c +++ b/tools/perf/arch/arm64/annotate/instructions.c @@ -50,7 +50,7 @@ static int arm64__annotate_init(struct arch *arch) arch->initialized = true; arch->priv = arm; arch->associate_instruction_ops = arm64__associate_instruction_ops; - arch->objdump.comment_char = ';'; + arch->objdump.comment_char = '/'; arch->objdump.skip_functions_char = '+'; return 0; diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c index 39dbe51..bf9a259 100644 --- a/tools/perf/arch/powerpc/util/sym-handling.c +++ b/tools/perf/arch/powerpc/util/sym-handling.c @@ -52,6 +52,18 @@ int arch__compare_symbol_names(const char *namea, const char *nameb) return strcmp(namea, nameb); } + +int arch__compare_symbol_names_n(const char *namea, const char *nameb, + unsigned int n) +{ + /* Skip over initial dot */ + if (*namea == '.') + namea++; + if (*nameb == '.') + nameb++; + + return strncmp(namea, nameb, n); +} #endif #if defined(_CALL_ELF) && _CALL_ELF == 2 diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index 64b44e8..9eba7f1 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -49,19 +49,22 @@ static bool same_kallsyms_reloc(const char *from_dir, char *to_dir) char to[PATH_MAX]; const char *name; u64 addr1 = 0, addr2 = 0; - int i; + int i, err = -1; scnprintf(from, sizeof(from), "%s/kallsyms", from_dir); scnprintf(to, sizeof(to), "%s/kallsyms", to_dir); for (i = 0; (name = ref_reloc_sym_names[i]) != NULL; i++) { - addr1 = kallsyms__get_function_start(from, name); - if (addr1) + err = kallsyms__get_function_start(from, name, &addr1); + if (!err) break; } - if (name) - addr2 = kallsyms__get_function_start(to, name); + if (err) + return false; + + if (kallsyms__get_function_start(to, name, &addr2)) + return false; return addr1 == addr2; } diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index e33b4ac..620a467 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -27,6 +27,7 @@ #include "tool.h" #include "data.h" #include "sort.h" +#include "event.h" #include "evlist.h" #include "evsel.h" #include <asm/bug.h> diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index 55f04f8..80668fa 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -159,6 +159,7 @@ int cmd_config(int argc, const char **argv) int i, ret = 0; struct perf_config_set *set; char *user_config = mkpath("%s/.perfconfig", getenv("HOME")); + const char *config_filename; argc = parse_options(argc, argv, config_options, config_usage, PARSE_OPT_STOP_AT_NON_OPTION); @@ -175,6 +176,11 @@ int cmd_config(int argc, const char **argv) else if (use_user_config) config_exclusive_filename = user_config; + if (!config_exclusive_filename) + config_filename = user_config; + else + config_filename = config_exclusive_filename; + /* * At only 'config' sub-command, individually use the config set * because of reinitializing with options config file location. @@ -192,13 +198,9 @@ int cmd_config(int argc, const char **argv) parse_options_usage(config_usage, config_options, "l", 1); } else { ret = show_config(set); - if (ret < 0) { - const char * config_filename = config_exclusive_filename; - if (!config_exclusive_filename) - config_filename = user_config; + if (ret < 0) pr_err("Nothing configured, " "please check your %s \n", config_filename); - } } break; default: @@ -221,13 +223,8 @@ int cmd_config(int argc, const char **argv) if (value == NULL) ret = show_spec_config(set, var); - else { - const char *config_filename = config_exclusive_filename; - - if (!config_exclusive_filename) - config_filename = user_config; + else ret = set_config(set, config_filename, var, value); - } free(arg); } } else diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 7ab42b8..10b6362 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -27,13 +27,13 @@ #include "util/drv_configs.h" #include "util/evlist.h" #include "util/evsel.h" +#include "util/event.h" #include "util/machine.h" #include "util/session.h" #include "util/symbol.h" #include "util/thread.h" #include "util/thread_map.h" #include "util/top.h" -#include "util/util.h" #include <linux/rbtree.h> #include <subcmd/parse-options.h> #include "util/parse-events.h" diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index eaa66fb..d014350 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -21,6 +21,7 @@ #include "builtin.h" #include "util/color.h" #include "util/debug.h" +#include "util/event.h" #include "util/evlist.h" #include <subcmd/exec-cmd.h> #include "util/machine.h" diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 4cc6960..628a5e4 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -17,6 +17,7 @@ #include <subcmd/parse-options.h> #include "util/bpf-loader.h" #include "util/debug.h" +#include "util/event.h" #include <api/fs/fs.h> #include <api/fs/tracing_path.h> #include <errno.h> diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index 70918b9..d549a9f 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -1,5 +1,6 @@ #include "perf.h" #include "util/debug.h" +#include "util/event.h" #include "util/symbol.h" #include "util/sort.h" #include "util/evsel.h" diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index f171b2d..df9c91f 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -3,6 +3,7 @@ #include "util/symbol.h" #include "util/sort.h" #include "util/evsel.h" +#include "util/event.h" #include "util/evlist.h" #include "util/machine.h" #include "util/thread.h" diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index cdf0dde..06e5080 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -1,5 +1,6 @@ #include "perf.h" #include "util/debug.h" +#include "util/event.h" #include "util/symbol.h" #include "util/sort.h" #include "util/evsel.h" diff --git a/tools/perf/tests/kmod-path.c b/tools/perf/tests/kmod-path.c index 76f41f2..6cd9e51 100644 --- a/tools/perf/tests/kmod-path.c +++ b/tools/perf/tests/kmod-path.c @@ -61,6 +61,7 @@ int test__kmod_path__parse(int subtest __maybe_unused) M("/xxxx/xxxx/x-x.ko", PERF_RECORD_MISC_KERNEL, true); M("/xxxx/xxxx/x-x.ko", PERF_RECORD_MISC_USER, false); +#ifdef HAVE_ZLIB_SUPPORT /* path alloc_name alloc_ext kmod comp name ext */ T("/xxxx/xxxx/x.ko.gz", true , true , true, true, "[x]", "gz"); T("/xxxx/xxxx/x.ko.gz", false , true , true, true, NULL , "gz"); @@ -96,6 +97,7 @@ int test__kmod_path__parse(int subtest __maybe_unused) M("x.ko.gz", PERF_RECORD_MISC_CPUMODE_UNKNOWN, true); M("x.ko.gz", PERF_RECORD_MISC_KERNEL, true); M("x.ko.gz", PERF_RECORD_MISC_USER, false); +#endif /* path alloc_name alloc_ext kmod comp name ext */ T("[test_module]", true , true , true, false, "[test_module]", NULL); diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c index f73b3c5..06eda67 100644 --- a/tools/perf/tests/sdt.c +++ b/tools/perf/tests/sdt.c @@ -1,7 +1,6 @@ #include <errno.h> #include <stdio.h> #include <sys/epoll.h> -#include <util/util.h> #include <util/evlist.h> #include <linux/filter.h> #include "tests.h" diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c index 5ea0b40..caf1ce6f 100644 --- a/tools/perf/ui/setup.c +++ b/tools/perf/ui/setup.c @@ -10,7 +10,10 @@ pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; void *perf_gtk_handle; int use_browser = -1; +#define PERF_GTK_DSO "libperf-gtk.so" + #ifdef HAVE_GTK2_SUPPORT + static int setup_gtk_browser(void) { int (*perf_ui_init)(void); diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 069583b..79dea95 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -13,6 +13,7 @@ libperf-y += find_bit.o libperf-y += kallsyms.o libperf-y += levenshtein.o libperf-y += llvm-utils.o +libperf-y += memswap.o libperf-y += parse-events.o libperf-y += perf_regs.o libperf-y += path.o diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h index a960811..8a89b19 100644 --- a/tools/perf/util/build-id.h +++ b/tools/perf/util/build-id.h @@ -44,6 +44,10 @@ bool build_id_cache__cached(const char *sbuild_id); int build_id_cache__add_s(const char *sbuild_id, const char *name, bool is_kallsyms, bool is_vdso); int build_id_cache__remove_s(const char *sbuild_id); + +extern char buildid_dir[]; + +void set_buildid_dir(const char *dir); void disable_buildid_cache(void); #endif diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 142835c..dc5c3bb 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -8,6 +8,7 @@ #include <unistd.h> #include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */ #include <api/fs/fs.h> +#include <linux/perf_event.h> #include "event.h" #include "debug.h" #include "hist.h" @@ -767,15 +768,16 @@ static int find_symbol_cb(void *arg, const char *name, char type, return 1; } -u64 kallsyms__get_function_start(const char *kallsyms_filename, - const char *symbol_name) +int kallsyms__get_function_start(const char *kallsyms_filename, + const char *symbol_name, u64 *addr) { struct process_symbol_args args = { .name = symbol_name, }; if (kallsyms__parse(kallsyms_filename, &args, find_symbol_cb) <= 0) - return 0; + return -1; - return args.start; + *addr = args.start; + return 0; } int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index db2de64..7c3fa1c 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -229,7 +229,7 @@ struct build_id_event { enum perf_user_event_type { /* above any possible kernel type */ PERF_RECORD_USER_TYPE_START = 64, PERF_RECORD_HEADER_ATTR = 64, - PERF_RECORD_HEADER_EVENT_TYPE = 65, /* depreceated */ + PERF_RECORD_HEADER_EVENT_TYPE = 65, /* deprecated */ PERF_RECORD_HEADER_TRACING_DATA = 66, PERF_RECORD_HEADER_BUILD_ID = 67, PERF_RECORD_FINISHED_ROUND = 68, @@ -675,10 +675,18 @@ size_t perf_event__fprintf_cpu_map(union perf_event *event, FILE *fp); size_t perf_event__fprintf_namespaces(union perf_event *event, FILE *fp); size_t perf_event__fprintf(union perf_event *event, FILE *fp); -u64 kallsyms__get_function_start(const char *kallsyms_filename, - const char *symbol_name); +int kallsyms__get_function_start(const char *kallsyms_filename, + const char *symbol_name, u64 *addr); void *cpu_map_data__alloc(struct cpu_map *map, size_t *size, u16 *type, int *max); void cpu_map_data__synthesize(struct cpu_map_data *data, struct cpu_map *map, u16 type, int max); + +void event_attr_init(struct perf_event_attr *attr); + +int perf_event_paranoid(void); + +extern int sysctl_perf_event_max_stack; +extern int sysctl_perf_event_max_contexts_per_stack; + #endif /* __PERF_RECORD_H */ diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 0e87909..e4f7902 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -21,6 +21,7 @@ #include "asm/bug.h" #include "callchain.h" #include "cgroup.h" +#include "event.h" #include "evsel.h" #include "evlist.h" #include "util.h" diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 948b2c5..314a071 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -19,6 +19,7 @@ #include "evlist.h" #include "evsel.h" #include "header.h" +#include "memswap.h" #include "../perf.h" #include "trace-event.h" #include "session.h" diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index bdd4a28..4c7718f 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -23,6 +23,7 @@ #include "../perf.h" #include "session.h" #include "machine.h" +#include "memswap.h" #include "sort.h" #include "tool.h" #include "event.h" diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 7a47f52..d97e014 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -796,11 +796,11 @@ const char *ref_reloc_sym_names[] = {"_text", "_stext", NULL}; * Returns the name of the start symbol in *symbol_name. Pass in NULL as * symbol_name if it's not that important. */ -static u64 machine__get_running_kernel_start(struct machine *machine, - const char **symbol_name) +static int machine__get_running_kernel_start(struct machine *machine, + const char **symbol_name, u64 *start) { char filename[PATH_MAX]; - int i; + int i, err = -1; const char *name; u64 addr = 0; @@ -810,21 +810,28 @@ static u64 machine__get_running_kernel_start(struct machine *machine, return 0; for (i = 0; (name = ref_reloc_sym_names[i]) != NULL; i++) { - addr = kallsyms__get_function_start(filename, name); - if (addr) + err = kallsyms__get_function_start(filename, name, &addr); + if (!err) break; } + if (err) + return -1; + if (symbol_name) *symbol_name = name; - return addr; + *start = addr; + return 0; } int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel) { int type; - u64 start = machine__get_running_kernel_start(machine, NULL); + u64 start = 0; + + if (machine__get_running_kernel_start(machine, NULL, &start)) + return -1; /* In case of renewal the kernel map, destroy previous one */ machine__destroy_kernel_maps(machine); @@ -1185,8 +1192,8 @@ static int machine__create_modules(struct machine *machine) int machine__create_kernel_maps(struct machine *machine) { struct dso *kernel = machine__get_kernel(machine); - const char *name; - u64 addr; + const char *name = NULL; + u64 addr = 0; int ret; if (kernel == NULL) @@ -1211,8 +1218,7 @@ int machine__create_kernel_maps(struct machine *machine) */ map_groups__fixup_end(&machine->kmaps); - addr = machine__get_running_kernel_start(machine, &name); - if (!addr) { + if (machine__get_running_kernel_start(machine, &name, &addr)) { } else if (maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, name, addr)) { machine__destroy_kernel_maps(machine); return -1; diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index ebfa5d9..2179b2d 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -325,11 +325,6 @@ int map__load(struct map *map) return 0; } -int __weak arch__compare_symbol_names(const char *namea, const char *nameb) -{ - return strcmp(namea, nameb); -} - struct symbol *map__find_symbol(struct map *map, u64 addr) { if (map__load(map) < 0) diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index c8a5a64..f9e8ac8 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -130,13 +130,14 @@ struct thread; */ #define __map__for_each_symbol_by_name(map, sym_name, pos) \ for (pos = map__find_symbol_by_name(map, sym_name); \ - pos && arch__compare_symbol_names(pos->name, sym_name) == 0; \ + pos && \ + !symbol__match_symbol_name(pos->name, sym_name, \ + SYMBOL_TAG_INCLUDE__DEFAULT_ONLY); \ pos = symbol__next_by_name(pos)) #define map__for_each_symbol_by_name(map, sym_name, pos) \ __map__for_each_symbol_by_name(map, sym_name, (pos)) -int arch__compare_symbol_names(const char *namea, const char *nameb); void map__init(struct map *map, enum map_type type, u64 start, u64 end, u64 pgoff, struct dso *dso); struct map *map__new(struct machine *machine, u64 start, u64 len, diff --git a/tools/perf/util/memswap.c b/tools/perf/util/memswap.c new file mode 100644 index 0000000..55f7faa --- /dev/null +++ b/tools/perf/util/memswap.c @@ -0,0 +1,24 @@ +#include <byteswap.h> +#include "memswap.h" +#include <linux/types.h> + +void mem_bswap_32(void *src, int byte_size) +{ + u32 *m = src; + while (byte_size > 0) { + *m = bswap_32(*m); + byte_size -= sizeof(u32); + ++m; + } +} + +void mem_bswap_64(void *src, int byte_size) +{ + u64 *m = src; + + while (byte_size > 0) { + *m = bswap_64(*m); + byte_size -= sizeof(u64); + ++m; + } +} diff --git a/tools/perf/util/memswap.h b/tools/perf/util/memswap.h new file mode 100644 index 0000000..7d1b1c3 --- /dev/null +++ b/tools/perf/util/memswap.h @@ -0,0 +1,7 @@ +#ifndef PERF_MEMSWAP_H_ +#define PERF_MEMSWAP_H_ + +void mem_bswap_64(void *src, int byte_size); +void mem_bswap_32(void *src, int byte_size); + +#endif /* PERF_MEMSWAP_H_ */ diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index 2b12bdb..7b79c41 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c @@ -28,7 +28,9 @@ #include <linux/bitmap.h> #include <linux/time64.h> -#include "../util.h" +#include <stdbool.h> +/* perl needs the following define, right after including stdbool.h */ +#define HAS_BOOL #include <EXTERN.h> #include <perl.h> diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 3041c6b..7dc1096 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -11,6 +11,7 @@ #include "evlist.h" #include "evsel.h" +#include "memswap.h" #include "session.h" #include "tool.h" #include "sort.h" diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c index e91b5e8..aafe908 100644 --- a/tools/perf/util/strbuf.c +++ b/tools/perf/util/strbuf.c @@ -3,15 +3,6 @@ #include <linux/kernel.h> #include <errno.h> -int prefixcmp(const char *str, const char *prefix) -{ - for (; ; str++, prefix++) - if (!*prefix) - return 0; - else if (*str != *prefix) - return (unsigned char)*prefix - (unsigned char)*str; -} - /* * Used as the default ->buf value, so that people can always assume * buf is non NULL and ->buf is NUL terminated even for a freshly diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 2cb7665..8f2b068 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -90,6 +90,17 @@ static int prefix_underscores_count(const char *str) return tail - str; } +int __weak arch__compare_symbol_names(const char *namea, const char *nameb) +{ + return strcmp(namea, nameb); +} + +int __weak arch__compare_symbol_names_n(const char *namea, const char *nameb, + unsigned int n) +{ + return strncmp(namea, nameb, n); +} + int __weak arch__choose_best_symbol(struct symbol *syma, struct symbol *symb __maybe_unused) { @@ -399,8 +410,26 @@ static void symbols__sort_by_name(struct rb_root *symbols, } } +int symbol__match_symbol_name(const char *name, const char *str, + enum symbol_tag_include includes) +{ + const char *versioning; + + if (includes == SYMBOL_TAG_INCLUDE__DEFAULT_ONLY && + (versioning = strstr(name, "@@"))) { + int len = strlen(str); + + if (len < versioning - name) + len = versioning - name; + + return arch__compare_symbol_names_n(name, str, len); + } else + return arch__compare_symbol_names(name, str); +} + static struct symbol *symbols__find_by_name(struct rb_root *symbols, - const char *name) + const char *name, + enum symbol_tag_include includes) { struct rb_node *n; struct symbol_name_rb_node *s = NULL; @@ -414,11 +443,11 @@ static struct symbol *symbols__find_by_name(struct rb_root *symbols, int cmp; s = rb_entry(n, struct symbol_name_rb_node, rb_node); - cmp = arch__compare_symbol_names(name, s->sym.name); + cmp = symbol__match_symbol_name(s->sym.name, name, includes); - if (cmp < 0) + if (cmp > 0) n = n->rb_left; - else if (cmp > 0) + else if (cmp < 0) n = n->rb_right; else break; @@ -427,16 +456,17 @@ static struct symbol *symbols__find_by_name(struct rb_root *symbols, if (n == NULL) return NULL; - /* return first symbol that has same name (if any) */ - for (n = rb_prev(n); n; n = rb_prev(n)) { - struct symbol_name_rb_node *tmp; + if (includes != SYMBOL_TAG_INCLUDE__DEFAULT_ONLY) + /* return first symbol that has same name (if any) */ + for (n = rb_prev(n); n; n = rb_prev(n)) { + struct symbol_name_rb_node *tmp; - tmp = rb_entry(n, struct symbol_name_rb_node, rb_node); - if (arch__compare_symbol_names(tmp->sym.name, s->sym.name)) - break; + tmp = rb_entry(n, struct symbol_name_rb_node, rb_node); + if (arch__compare_symbol_names(tmp->sym.name, s->sym.name)) + break; - s = tmp; - } + s = tmp; + } return &s->sym; } @@ -466,7 +496,7 @@ void dso__insert_symbol(struct dso *dso, enum map_type type, struct symbol *sym) struct symbol *dso__find_symbol(struct dso *dso, enum map_type type, u64 addr) { - if (dso->last_find_result[type].addr != addr) { + if (dso->last_find_result[type].addr != addr || dso->last_find_result[type].symbol == NULL) { dso->last_find_result[type].addr = addr; dso->last_find_result[type].symbol = symbols__find(&dso->symbols[type], addr); } @@ -503,7 +533,12 @@ struct symbol *symbol__next_by_name(struct symbol *sym) struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, const char *name) { - return symbols__find_by_name(&dso->symbol_names[type], name); + struct symbol *s = symbols__find_by_name(&dso->symbol_names[type], name, + SYMBOL_TAG_INCLUDE__NONE); + if (!s) + s = symbols__find_by_name(&dso->symbol_names[type], name, + SYMBOL_TAG_INCLUDE__DEFAULT_ONLY); + return s; } void dso__sort_by_name(struct dso *dso, enum map_type type) @@ -1075,8 +1110,9 @@ static int validate_kcore_addresses(const char *kallsyms_filename, if (kmap->ref_reloc_sym && kmap->ref_reloc_sym->name) { u64 start; - start = kallsyms__get_function_start(kallsyms_filename, - kmap->ref_reloc_sym->name); + if (kallsyms__get_function_start(kallsyms_filename, + kmap->ref_reloc_sym->name, &start)) + return -ENOENT; if (start != kmap->ref_reloc_sym->addr) return -EINVAL; } @@ -1248,9 +1284,7 @@ static int kallsyms__delta(struct map *map, const char *filename, u64 *delta) if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->name) return 0; - addr = kallsyms__get_function_start(filename, - kmap->ref_reloc_sym->name); - if (!addr) + if (kallsyms__get_function_start(filename, kmap->ref_reloc_sym->name, &addr)) return -1; *delta = addr - kmap->ref_reloc_sym->addr; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 7acd70f..41ebba9 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -348,8 +348,19 @@ void arch__sym_update(struct symbol *s, GElf_Sym *sym); #define SYMBOL_A 0 #define SYMBOL_B 1 +int arch__compare_symbol_names(const char *namea, const char *nameb); +int arch__compare_symbol_names_n(const char *namea, const char *nameb, + unsigned int n); int arch__choose_best_symbol(struct symbol *syma, struct symbol *symb); +enum symbol_tag_include { + SYMBOL_TAG_INCLUDE__NONE = 0, + SYMBOL_TAG_INCLUDE__DEFAULT_ONLY +}; + +int symbol__match_symbol_name(const char *namea, const char *nameb, + enum symbol_tag_include includes); + /* structure containing an SDT note's info */ struct sdt_note { char *name; /* name of the note*/ diff --git a/tools/perf/util/units.c b/tools/perf/util/units.c index f6a2a3d..4767ec2 100644 --- a/tools/perf/util/units.c +++ b/tools/perf/util/units.c @@ -1,8 +1,37 @@ #include "units.h" #include <inttypes.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> #include <linux/kernel.h> #include <linux/time64.h> +unsigned long parse_tag_value(const char *str, struct parse_tag *tags) +{ + struct parse_tag *i = tags; + + while (i->tag) { + char *s = strchr(str, i->tag); + + if (s) { + unsigned long int value; + char *endptr; + + value = strtoul(str, &endptr, 10); + if (s != endptr) + break; + + if (value > ULONG_MAX / i->mult) + break; + value *= i->mult; + return value; + } + i++; + } + + return (unsigned long) -1; +} + unsigned long convert_unit(unsigned long value, char *unit) { *unit = ' '; diff --git a/tools/perf/util/units.h b/tools/perf/util/units.h index 3ed7774..f02c873 100644 --- a/tools/perf/util/units.h +++ b/tools/perf/util/units.h @@ -4,6 +4,13 @@ #include <stddef.h> #include <linux/types.h> +struct parse_tag { + char tag; + int mult; +}; + +unsigned long parse_tag_value(const char *str, struct parse_tag *tags); + unsigned long convert_unit(unsigned long value, char *unit); int unit_number__scnprintf(char *buf, size_t size, u64 n); diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 6450c75..28c9f33 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -13,7 +13,6 @@ #include <string.h> #include <errno.h> #include <limits.h> -#include <byteswap.h> #include <linux/kernel.h> #include <linux/log2.h> #include <linux/time64.h> @@ -335,33 +334,6 @@ int hex2u64(const char *ptr, u64 *long_val) return p - ptr; } -unsigned long parse_tag_value(const char *str, struct parse_tag *tags) -{ - struct parse_tag *i = tags; - - while (i->tag) { - char *s; - - s = strchr(str, i->tag); - if (s) { - unsigned long int value; - char *endptr; - - value = strtoul(str, &endptr, 10); - if (s != endptr) - break; - - if (value > ULONG_MAX / i->mult) - break; - value *= i->mult; - return value; - } - i++; - } - - return (unsigned long) -1; -} - int perf_event_paranoid(void) { int value; @@ -372,27 +344,6 @@ int perf_event_paranoid(void) return value; } -void mem_bswap_32(void *src, int byte_size) -{ - u32 *m = src; - while (byte_size > 0) { - *m = bswap_32(*m); - byte_size -= sizeof(u32); - ++m; - } -} - -void mem_bswap_64(void *src, int byte_size) -{ - u64 *m = src; - - while (byte_size > 0) { - *m = bswap_64(*m); - byte_size -= sizeof(u64); - ++m; - } -} - bool find_process(const char *name) { size_t len = strlen(name); diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 3852b6d..5dfb9bb 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -5,7 +5,6 @@ #define _BSD_SOURCE 1 /* glibc 2.20 deprecates _BSD_SOURCE in favour of _DEFAULT_SOURCE */ #define _DEFAULT_SOURCE 1 -#define HAS_BOOL #include <fcntl.h> #include <stdbool.h> @@ -14,8 +13,6 @@ #include <stdarg.h> #include <linux/types.h> -extern char buildid_dir[]; - #ifdef __GNUC__ #define NORETURN __attribute__((__noreturn__)) #else @@ -25,8 +22,6 @@ extern char buildid_dir[]; #endif #endif -#define PERF_GTK_DSO "libperf-gtk.so" - /* General helper functions */ void usage(const char *err) NORETURN; void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); @@ -35,9 +30,6 @@ void warning(const char *err, ...) __attribute__((format (printf, 1, 2))); void set_warning_routine(void (*routine)(const char *err, va_list params)); -int prefixcmp(const char *str, const char *prefix); -void set_buildid_dir(const char *dir); - static inline void *zalloc(size_t size) { return calloc(1, size); @@ -59,29 +51,11 @@ int copyfile_offset(int fromfd, loff_t from_ofs, int tofd, loff_t to_ofs, u64 si ssize_t readn(int fd, void *buf, size_t n); ssize_t writen(int fd, void *buf, size_t n); -struct perf_event_attr; - -void event_attr_init(struct perf_event_attr *attr); - size_t hex_width(u64 v); int hex2u64(const char *ptr, u64 *val); extern unsigned int page_size; extern int cacheline_size; -extern int sysctl_perf_event_max_stack; -extern int sysctl_perf_event_max_contexts_per_stack; - -struct parse_tag { - char tag; - int mult; -}; - -unsigned long parse_tag_value(const char *str, struct parse_tag *tags); - -int perf_event_paranoid(void); - -void mem_bswap_64(void *src, int byte_size); -void mem_bswap_32(void *src, int byte_size); bool find_process(const char *name); diff --git a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh index ea6e373..93eede4 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh @@ -170,7 +170,7 @@ qemu_append="`identify_qemu_append "$QEMU"`" # Pull in Kconfig-fragment boot parameters boot_args="`configfrag_boot_params "$boot_args" "$config_template"`" # Generate kernel-version-specific boot parameters -boot_args="`per_version_boot_params "$boot_args" $builddir/.config $seconds`" +boot_args="`per_version_boot_params "$boot_args" $resdir/.config $seconds`" if test -n "$TORTURE_BUILDONLY" then diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h index 9377c8b..d8f5340 100644 --- a/tools/virtio/linux/virtio.h +++ b/tools/virtio/linux/virtio.h @@ -57,6 +57,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int index, unsigned int vring_align, struct virtio_device *vdev, bool weak_barriers, + bool ctx, void *pages, bool (*notify)(struct virtqueue *vq), void (*callback)(struct virtqueue *vq), diff --git a/tools/virtio/ringtest/main.c b/tools/virtio/ringtest/main.c index f31353f..453ca3c 100644 --- a/tools/virtio/ringtest/main.c +++ b/tools/virtio/ringtest/main.c @@ -20,6 +20,7 @@ int runcycles = 10000000; int max_outstanding = INT_MAX; int batch = 1; +int param = 0; bool do_sleep = false; bool do_relax = false; @@ -86,7 +87,7 @@ void set_affinity(const char *arg) cpu = strtol(arg, &endptr, 0); assert(!*endptr); - assert(cpu >= 0 || cpu < CPU_SETSIZE); + assert(cpu >= 0 && cpu < CPU_SETSIZE); self = pthread_self(); CPU_ZERO(&cpuset); @@ -247,6 +248,11 @@ static const struct option longopts[] = { .val = 'b', }, { + .name = "param", + .has_arg = required_argument, + .val = 'p', + }, + { .name = "sleep", .has_arg = no_argument, .val = 's', @@ -274,6 +280,7 @@ static void help(void) " [--run-cycles C (default: %d)]" " [--batch b]" " [--outstanding o]" + " [--param p]" " [--sleep]" " [--relax]" " [--exit]" @@ -328,6 +335,12 @@ int main(int argc, char **argv) assert(c > 0 && c < INT_MAX); max_outstanding = c; break; + case 'p': + c = strtol(optarg, &endptr, 0); + assert(!*endptr); + assert(c > 0 && c < INT_MAX); + param = c; + break; case 'b': c = strtol(optarg, &endptr, 0); assert(!*endptr); diff --git a/tools/virtio/ringtest/main.h b/tools/virtio/ringtest/main.h index 14142fa..90b0133 100644 --- a/tools/virtio/ringtest/main.h +++ b/tools/virtio/ringtest/main.h @@ -10,6 +10,8 @@ #include <stdbool.h> +extern int param; + extern bool do_exit; #if defined(__x86_64__) || defined(__i386__) diff --git a/tools/virtio/ringtest/ptr_ring.c b/tools/virtio/ringtest/ptr_ring.c index 635b07b..7b22f1b 100644 --- a/tools/virtio/ringtest/ptr_ring.c +++ b/tools/virtio/ringtest/ptr_ring.c @@ -97,6 +97,9 @@ void alloc_ring(void) { int ret = ptr_ring_init(&array, ring_size, 0); assert(!ret); + /* Hacky way to poke at ring internals. Useful for testing though. */ + if (param) + array.batch = param; } /* guest side */ diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c index e044589..0fecaec 100644 --- a/tools/virtio/virtio_test.c +++ b/tools/virtio/virtio_test.c @@ -100,7 +100,7 @@ static void vq_info_add(struct vdev_info *dev, int num) vring_init(&info->vring, num, info->ring, 4096); info->vq = vring_new_virtqueue(info->idx, info->vring.num, 4096, &dev->vdev, - true, info->ring, + true, false, info->ring, vq_notify, vq_callback, "test"); assert(info->vq); info->vq->priv = info; @@ -202,7 +202,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, test = 0; r = ioctl(dev->control, VHOST_TEST_RUN, &test); assert(r >= 0); - fprintf(stderr, "spurious wakeus: 0x%llx\n", spurious); + fprintf(stderr, "spurious wakeups: 0x%llx\n", spurious); } const char optstring[] = "h"; diff --git a/tools/virtio/vringh_test.c b/tools/virtio/vringh_test.c index 5f94f51..9476c61 100644 --- a/tools/virtio/vringh_test.c +++ b/tools/virtio/vringh_test.c @@ -314,7 +314,8 @@ static int parallel_test(u64 features, err(1, "Could not set affinity to cpu %u", first_cpu); vq = vring_new_virtqueue(0, RINGSIZE, ALIGN, &gvdev.vdev, true, - guest_map, fast_vringh ? no_notify_host + false, guest_map, + fast_vringh ? no_notify_host : parallel_notify_host, never_callback_guest, "guest vq"); @@ -479,7 +480,7 @@ int main(int argc, char *argv[]) memset(__user_addr_min, 0, vring_size(RINGSIZE, ALIGN)); /* Set up guest side. */ - vq = vring_new_virtqueue(0, RINGSIZE, ALIGN, &vdev, true, + vq = vring_new_virtqueue(0, RINGSIZE, ALIGN, &vdev, true, false, __user_addr_min, never_notify_host, never_callback_guest, "guest vq"); @@ -663,7 +664,7 @@ int main(int argc, char *argv[]) /* Force creation of direct, which we modify. */ __virtio_clear_bit(&vdev, VIRTIO_RING_F_INDIRECT_DESC); vq = vring_new_virtqueue(0, RINGSIZE, ALIGN, &vdev, true, - __user_addr_min, + false, __user_addr_min, never_notify_host, never_callback_guest, "guest vq"); |