diff options
| -rw-r--r-- | arch/x86/oprofile/nmi_int.c | 5 | ||||
| -rw-r--r-- | arch/x86/oprofile/op_counter.h | 1 | ||||
| -rw-r--r-- | include/linux/perf_event.h | 2 | ||||
| -rw-r--r-- | kernel/perf_event.c | 9 | ||||
| -rw-r--r-- | tools/perf/Makefile | 8 | ||||
| -rw-r--r-- | tools/perf/builtin-record.c | 25 | ||||
| -rw-r--r-- | tools/perf/builtin-top.c | 44 | ||||
| -rw-r--r-- | tools/perf/util/debug.c | 10 | ||||
| -rw-r--r-- | tools/perf/util/debug.h | 1 | ||||
| -rw-r--r-- | tools/perf/util/event.c | 2 | ||||
| -rw-r--r-- | tools/perf/util/setup.py | 7 | ||||
| -rw-r--r-- | tools/perf/util/symbol.c | 5 |
12 files changed, 91 insertions, 28 deletions
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 8dace181c88e..cf9750004a08 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c | |||
| @@ -49,6 +49,10 @@ u64 op_x86_get_ctrl(struct op_x86_model_spec const *model, | |||
| 49 | val |= counter_config->user ? ARCH_PERFMON_EVENTSEL_USR : 0; | 49 | val |= counter_config->user ? ARCH_PERFMON_EVENTSEL_USR : 0; |
| 50 | val |= counter_config->kernel ? ARCH_PERFMON_EVENTSEL_OS : 0; | 50 | val |= counter_config->kernel ? ARCH_PERFMON_EVENTSEL_OS : 0; |
| 51 | val |= (counter_config->unit_mask & 0xFF) << 8; | 51 | val |= (counter_config->unit_mask & 0xFF) << 8; |
| 52 | counter_config->extra &= (ARCH_PERFMON_EVENTSEL_INV | | ||
| 53 | ARCH_PERFMON_EVENTSEL_EDGE | | ||
| 54 | ARCH_PERFMON_EVENTSEL_CMASK); | ||
| 55 | val |= counter_config->extra; | ||
| 52 | event &= model->event_mask ? model->event_mask : 0xFF; | 56 | event &= model->event_mask ? model->event_mask : 0xFF; |
| 53 | val |= event & 0xFF; | 57 | val |= event & 0xFF; |
| 54 | val |= (event & 0x0F00) << 24; | 58 | val |= (event & 0x0F00) << 24; |
| @@ -440,6 +444,7 @@ static int nmi_create_files(struct super_block *sb, struct dentry *root) | |||
| 440 | oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask); | 444 | oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask); |
| 441 | oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel); | 445 | oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel); |
| 442 | oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user); | 446 | oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user); |
| 447 | oprofilefs_create_ulong(sb, dir, "extra", &counter_config[i].extra); | ||
| 443 | } | 448 | } |
| 444 | 449 | ||
| 445 | return 0; | 450 | return 0; |
diff --git a/arch/x86/oprofile/op_counter.h b/arch/x86/oprofile/op_counter.h index e28398df0df2..0b7b7b179cbe 100644 --- a/arch/x86/oprofile/op_counter.h +++ b/arch/x86/oprofile/op_counter.h | |||
| @@ -22,6 +22,7 @@ struct op_counter_config { | |||
| 22 | unsigned long kernel; | 22 | unsigned long kernel; |
| 23 | unsigned long user; | 23 | unsigned long user; |
| 24 | unsigned long unit_mask; | 24 | unsigned long unit_mask; |
| 25 | unsigned long extra; | ||
| 25 | }; | 26 | }; |
| 26 | 27 | ||
| 27 | extern struct op_counter_config counter_config[]; | 28 | extern struct op_counter_config counter_config[]; |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 311b4dc785a1..04d75a8a20ee 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
| @@ -1086,7 +1086,7 @@ void perf_event_task_sched_out(struct task_struct *task, struct task_struct *nex | |||
| 1086 | { | 1086 | { |
| 1087 | perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0); | 1087 | perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0); |
| 1088 | 1088 | ||
| 1089 | COND_STMT(&perf_sched_events, __perf_event_task_sched_out(task, next)); | 1089 | __perf_event_task_sched_out(task, next); |
| 1090 | } | 1090 | } |
| 1091 | 1091 | ||
| 1092 | extern void perf_event_mmap(struct vm_area_struct *vma); | 1092 | extern void perf_event_mmap(struct vm_area_struct *vma); |
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index c75925c4d1e2..27960f114efd 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
| @@ -145,8 +145,8 @@ static struct srcu_struct pmus_srcu; | |||
| 145 | */ | 145 | */ |
| 146 | int sysctl_perf_event_paranoid __read_mostly = 1; | 146 | int sysctl_perf_event_paranoid __read_mostly = 1; |
| 147 | 147 | ||
| 148 | /* Minimum for 128 pages + 1 for the user control page */ | 148 | /* Minimum for 512 kiB + 1 user control page */ |
| 149 | int sysctl_perf_event_mlock __read_mostly = 516; /* 'free' kb per user */ | 149 | int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */ |
| 150 | 150 | ||
| 151 | /* | 151 | /* |
| 152 | * max perf event sample rate | 152 | * max perf event sample rate |
| @@ -6531,6 +6531,11 @@ SYSCALL_DEFINE5(perf_event_open, | |||
| 6531 | goto err_alloc; | 6531 | goto err_alloc; |
| 6532 | } | 6532 | } |
| 6533 | 6533 | ||
| 6534 | if (task) { | ||
| 6535 | put_task_struct(task); | ||
| 6536 | task = NULL; | ||
| 6537 | } | ||
| 6538 | |||
| 6534 | /* | 6539 | /* |
| 6535 | * Look up the group leader (we will attach this event to it): | 6540 | * Look up the group leader (we will attach this event to it): |
| 6536 | */ | 6541 | */ |
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 158c30e8210c..207dee5c5b16 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
| @@ -165,8 +165,12 @@ grep-libs = $(filter -l%,$(1)) | |||
| 165 | strip-libs = $(filter-out -l%,$(1)) | 165 | strip-libs = $(filter-out -l%,$(1)) |
| 166 | 166 | ||
| 167 | $(OUTPUT)python/perf.so: $(PYRF_OBJS) | 167 | $(OUTPUT)python/perf.so: $(PYRF_OBJS) |
| 168 | $(QUIET_GEN)python util/setup.py --quiet build_ext --build-lib='$(OUTPUT)python' \ | 168 | $(QUIET_GEN)( \ |
| 169 | --build-temp='$(OUTPUT)python/temp' | 169 | export CFLAGS="$(BASIC_CFLAGS)"; \ |
| 170 | python util/setup.py --quiet build_ext --build-lib='$(OUTPUT)python' \ | ||
| 171 | --build-temp='$(OUTPUT)python/temp' \ | ||
| 172 | ) | ||
| 173 | |||
| 170 | # | 174 | # |
| 171 | # No Perl scripts right now: | 175 | # No Perl scripts right now: |
| 172 | # | 176 | # |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 6febcc168a8c..17d1dcb3c667 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
| @@ -41,7 +41,7 @@ static u64 user_interval = ULLONG_MAX; | |||
| 41 | static u64 default_interval = 0; | 41 | static u64 default_interval = 0; |
| 42 | 42 | ||
| 43 | static unsigned int page_size; | 43 | static unsigned int page_size; |
| 44 | static unsigned int mmap_pages = 128; | 44 | static unsigned int mmap_pages = UINT_MAX; |
| 45 | static unsigned int user_freq = UINT_MAX; | 45 | static unsigned int user_freq = UINT_MAX; |
| 46 | static int freq = 1000; | 46 | static int freq = 1000; |
| 47 | static int output; | 47 | static int output; |
| @@ -275,11 +275,10 @@ try_again: | |||
| 275 | !no_inherit) < 0) { | 275 | !no_inherit) < 0) { |
| 276 | int err = errno; | 276 | int err = errno; |
| 277 | 277 | ||
| 278 | if (err == EPERM || err == EACCES) | 278 | if (err == EPERM || err == EACCES) { |
| 279 | die("Permission error - are you root?\n" | 279 | ui__warning_paranoid(); |
| 280 | "\t Consider tweaking" | 280 | exit(EXIT_FAILURE); |
| 281 | " /proc/sys/kernel/perf_event_paranoid.\n"); | 281 | } else if (err == ENODEV && cpu_list) { |
| 282 | else if (err == ENODEV && cpu_list) { | ||
| 283 | die("No such device - did you specify" | 282 | die("No such device - did you specify" |
| 284 | " an out-of-range profile CPU?\n"); | 283 | " an out-of-range profile CPU?\n"); |
| 285 | } else if (err == EINVAL && sample_id_all_avail) { | 284 | } else if (err == EINVAL && sample_id_all_avail) { |
| @@ -302,11 +301,19 @@ try_again: | |||
| 302 | && attr->config == PERF_COUNT_HW_CPU_CYCLES) { | 301 | && attr->config == PERF_COUNT_HW_CPU_CYCLES) { |
| 303 | 302 | ||
| 304 | if (verbose) | 303 | if (verbose) |
| 305 | warning(" ... trying to fall back to cpu-clock-ticks\n"); | 304 | ui__warning("The cycles event is not supported, " |
| 305 | "trying to fall back to cpu-clock-ticks\n"); | ||
| 306 | attr->type = PERF_TYPE_SOFTWARE; | 306 | attr->type = PERF_TYPE_SOFTWARE; |
| 307 | attr->config = PERF_COUNT_SW_CPU_CLOCK; | 307 | attr->config = PERF_COUNT_SW_CPU_CLOCK; |
| 308 | goto try_again; | 308 | goto try_again; |
| 309 | } | 309 | } |
| 310 | |||
| 311 | if (err == ENOENT) { | ||
| 312 | ui__warning("The %s event is not supported.\n", | ||
| 313 | event_name(pos)); | ||
| 314 | exit(EXIT_FAILURE); | ||
| 315 | } | ||
| 316 | |||
| 310 | printf("\n"); | 317 | printf("\n"); |
| 311 | error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n", | 318 | error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n", |
| 312 | err, strerror(err)); | 319 | err, strerror(err)); |
| @@ -506,6 +513,10 @@ static int __cmd_record(int argc, const char **argv) | |||
| 506 | if (have_tracepoints(&evsel_list->entries)) | 513 | if (have_tracepoints(&evsel_list->entries)) |
| 507 | perf_header__set_feat(&session->header, HEADER_TRACE_INFO); | 514 | perf_header__set_feat(&session->header, HEADER_TRACE_INFO); |
| 508 | 515 | ||
| 516 | /* 512 kiB: default amount of unprivileged mlocked memory */ | ||
| 517 | if (mmap_pages == UINT_MAX) | ||
| 518 | mmap_pages = (512 * 1024) / page_size; | ||
| 519 | |||
| 509 | if (forks) { | 520 | if (forks) { |
| 510 | child_pid = fork(); | 521 | child_pid = fork(); |
| 511 | if (child_pid < 0) { | 522 | if (child_pid < 0) { |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 676b4fb0070f..fc1273e976c5 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
| @@ -850,10 +850,10 @@ try_again: | |||
| 850 | top.evlist->threads, group, inherit) < 0) { | 850 | top.evlist->threads, group, inherit) < 0) { |
| 851 | int err = errno; | 851 | int err = errno; |
| 852 | 852 | ||
| 853 | if (err == EPERM || err == EACCES) | 853 | if (err == EPERM || err == EACCES) { |
| 854 | die("Permission error - are you root?\n" | 854 | ui__warning_paranoid(); |
| 855 | "\t Consider tweaking" | 855 | goto out_err; |
| 856 | " /proc/sys/kernel/perf_event_paranoid.\n"); | 856 | } |
| 857 | /* | 857 | /* |
| 858 | * If it's cycles then fall back to hrtimer | 858 | * If it's cycles then fall back to hrtimer |
| 859 | * based cpu-clock-tick sw counter, which | 859 | * based cpu-clock-tick sw counter, which |
| @@ -861,25 +861,41 @@ try_again: | |||
| 861 | */ | 861 | */ |
| 862 | if (attr->type == PERF_TYPE_HARDWARE && | 862 | if (attr->type == PERF_TYPE_HARDWARE && |
| 863 | attr->config == PERF_COUNT_HW_CPU_CYCLES) { | 863 | attr->config == PERF_COUNT_HW_CPU_CYCLES) { |
| 864 | |||
| 865 | if (verbose) | 864 | if (verbose) |
| 866 | warning(" ... trying to fall back to cpu-clock-ticks\n"); | 865 | ui__warning("Cycles event not supported,\n" |
| 866 | "trying to fall back to cpu-clock-ticks\n"); | ||
| 867 | 867 | ||
| 868 | attr->type = PERF_TYPE_SOFTWARE; | 868 | attr->type = PERF_TYPE_SOFTWARE; |
| 869 | attr->config = PERF_COUNT_SW_CPU_CLOCK; | 869 | attr->config = PERF_COUNT_SW_CPU_CLOCK; |
| 870 | goto try_again; | 870 | goto try_again; |
| 871 | } | 871 | } |
| 872 | printf("\n"); | 872 | |
| 873 | error("sys_perf_event_open() syscall returned with %d " | 873 | if (err == ENOENT) { |
| 874 | "(%s). /bin/dmesg may provide additional information.\n", | 874 | ui__warning("The %s event is not supported.\n", |
| 875 | err, strerror(err)); | 875 | event_name(counter)); |
| 876 | die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); | 876 | goto out_err; |
| 877 | exit(-1); | 877 | } |
| 878 | |||
| 879 | ui__warning("The sys_perf_event_open() syscall " | ||
| 880 | "returned with %d (%s). /bin/dmesg " | ||
| 881 | "may provide additional information.\n" | ||
| 882 | "No CONFIG_PERF_EVENTS=y kernel support " | ||
| 883 | "configured?\n", err, strerror(err)); | ||
| 884 | goto out_err; | ||
| 878 | } | 885 | } |
| 879 | } | 886 | } |
| 880 | 887 | ||
| 881 | if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) | 888 | if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) { |
| 882 | die("failed to mmap with %d (%s)\n", errno, strerror(errno)); | 889 | ui__warning("Failed to mmap with %d (%s)\n", |
| 890 | errno, strerror(errno)); | ||
| 891 | goto out_err; | ||
| 892 | } | ||
| 893 | |||
| 894 | return; | ||
| 895 | |||
| 896 | out_err: | ||
| 897 | exit_browser(0); | ||
| 898 | exit(0); | ||
| 883 | } | 899 | } |
| 884 | 900 | ||
| 885 | static int __cmd_top(void) | 901 | static int __cmd_top(void) |
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index d4536a9e0d8c..155749d74350 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c | |||
| @@ -57,6 +57,16 @@ void ui__warning(const char *format, ...) | |||
| 57 | } | 57 | } |
| 58 | #endif | 58 | #endif |
| 59 | 59 | ||
| 60 | void ui__warning_paranoid(void) | ||
| 61 | { | ||
| 62 | ui__warning("Permission error - are you root?\n" | ||
| 63 | "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n" | ||
| 64 | " -1 - Not paranoid at all\n" | ||
| 65 | " 0 - Disallow raw tracepoint access for unpriv\n" | ||
| 66 | " 1 - Disallow cpu events for unpriv\n" | ||
| 67 | " 2 - Disallow kernel profiling for unpriv\n"); | ||
| 68 | } | ||
| 69 | |||
| 60 | void trace_event(union perf_event *event) | 70 | void trace_event(union perf_event *event) |
| 61 | { | 71 | { |
| 62 | unsigned char *raw_event = (void *)event; | 72 | unsigned char *raw_event = (void *)event; |
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index 93516cf4682c..fd53db47e3de 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h | |||
| @@ -36,5 +36,6 @@ int ui_helpline__show_help(const char *format, va_list ap); | |||
| 36 | #endif | 36 | #endif |
| 37 | 37 | ||
| 38 | void ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); | 38 | void ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); |
| 39 | void ui__warning_paranoid(void); | ||
| 39 | 40 | ||
| 40 | #endif /* __PERF_DEBUG_H */ | 41 | #endif /* __PERF_DEBUG_H */ |
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 2b15c362ef56..1023f67633a4 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
| @@ -710,7 +710,7 @@ try_again: | |||
| 710 | * in the whole kernel symbol list. | 710 | * in the whole kernel symbol list. |
| 711 | */ | 711 | */ |
| 712 | if ((long long)al->addr < 0 && | 712 | if ((long long)al->addr < 0 && |
| 713 | cpumode == PERF_RECORD_MISC_KERNEL && | 713 | cpumode == PERF_RECORD_MISC_USER && |
| 714 | machine && mg != &machine->kmaps) { | 714 | machine && mg != &machine->kmaps) { |
| 715 | mg = &machine->kmaps; | 715 | mg = &machine->kmaps; |
| 716 | goto try_again; | 716 | goto try_again; |
diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py index e24ffadb20b2..bbc982f5dd8b 100644 --- a/tools/perf/util/setup.py +++ b/tools/perf/util/setup.py | |||
| @@ -1,13 +1,18 @@ | |||
| 1 | #!/usr/bin/python2 | 1 | #!/usr/bin/python2 |
| 2 | 2 | ||
| 3 | from distutils.core import setup, Extension | 3 | from distutils.core import setup, Extension |
| 4 | from os import getenv | ||
| 5 | |||
| 6 | cflags = ['-fno-strict-aliasing', '-Wno-write-strings'] | ||
| 7 | cflags += getenv('CFLAGS', '').split() | ||
| 4 | 8 | ||
| 5 | perf = Extension('perf', | 9 | perf = Extension('perf', |
| 6 | sources = ['util/python.c', 'util/ctype.c', 'util/evlist.c', | 10 | sources = ['util/python.c', 'util/ctype.c', 'util/evlist.c', |
| 7 | 'util/evsel.c', 'util/cpumap.c', 'util/thread_map.c', | 11 | 'util/evsel.c', 'util/cpumap.c', 'util/thread_map.c', |
| 8 | 'util/util.c', 'util/xyarray.c', 'util/cgroup.c'], | 12 | 'util/util.c', 'util/xyarray.c', 'util/cgroup.c'], |
| 9 | include_dirs = ['util/include'], | 13 | include_dirs = ['util/include'], |
| 10 | extra_compile_args = ['-fno-strict-aliasing', '-Wno-write-strings']) | 14 | extra_compile_args = cflags, |
| 15 | ) | ||
| 11 | 16 | ||
| 12 | setup(name='perf', | 17 | setup(name='perf', |
| 13 | version='0.1', | 18 | version='0.1', |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 17df793c8924..f06c10f092ba 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
| @@ -1196,6 +1196,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, | |||
| 1196 | if (curr_dso == NULL) | 1196 | if (curr_dso == NULL) |
| 1197 | goto out_elf_end; | 1197 | goto out_elf_end; |
| 1198 | curr_dso->kernel = self->kernel; | 1198 | curr_dso->kernel = self->kernel; |
| 1199 | curr_dso->long_name = self->long_name; | ||
| 1200 | curr_dso->long_name_len = self->long_name_len; | ||
| 1199 | curr_map = map__new2(start, curr_dso, | 1201 | curr_map = map__new2(start, curr_dso, |
| 1200 | map->type); | 1202 | map->type); |
| 1201 | if (curr_map == NULL) { | 1203 | if (curr_map == NULL) { |
| @@ -1842,6 +1844,7 @@ int dso__load_vmlinux(struct dso *self, struct map *map, | |||
| 1842 | if (fd < 0) | 1844 | if (fd < 0) |
| 1843 | return -1; | 1845 | return -1; |
| 1844 | 1846 | ||
| 1847 | dso__set_long_name(self, (char *)vmlinux); | ||
| 1845 | dso__set_loaded(self, map->type); | 1848 | dso__set_loaded(self, map->type); |
| 1846 | err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0); | 1849 | err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0); |
| 1847 | close(fd); | 1850 | close(fd); |
| @@ -2403,6 +2406,8 @@ int symbol__init(void) | |||
| 2403 | if (symbol_conf.initialized) | 2406 | if (symbol_conf.initialized) |
| 2404 | return 0; | 2407 | return 0; |
| 2405 | 2408 | ||
| 2409 | symbol_conf.priv_size = ALIGN(symbol_conf.priv_size, sizeof(u64)); | ||
| 2410 | |||
| 2406 | elf_version(EV_CURRENT); | 2411 | elf_version(EV_CURRENT); |
| 2407 | if (symbol_conf.sort_by_name) | 2412 | if (symbol_conf.sort_by_name) |
| 2408 | symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) - | 2413 | symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) - |
