* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: perf: Fix task_struct reference leak perf: Fix task context scheduling perf: mmap 512 kiB by default perf: Rebase max unprivileged mlock threshold on top of page size perf tools: Fix NO_NEWT=1 python build error perf symbols: Properly align symbol_conf.priv_size perf tools: Emit clearer message for sys_perf_event_open ENOENT return perf tools: Fixup exit path when not able to open events perf symbols: Fix vsyscall symbol lookup oprofile, x86: Allow setting EDGE/INV/CMASK for counter events
Unified · Split
| @@ -49,6 +49,10 @@ u64 op_x86_get_ctrl(struct op_x86_model_spec const *model, · 48 unmodified lines | ||
| 49 | 49 | val |= counter_config->user ? ARCH_PERFMON_EVENTSEL_USR : 0; |
| 50 | 50 | val |= counter_config->kernel ? ARCH_PERFMON_EVENTSEL_OS : 0; |
| 51 | 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 | 56 | event &= model->event_mask ? model->event_mask : 0xFF; |
| 53 | 57 | val |= event & 0xFF; |
| 54 | 58 | val |= (event & 0x0F00) << 24; |
| @@ -440,6 +444,7 @@ static int nmi_create_files(struct super_block *sb, struct dentry *root) · 385 unmodified lines | ||
| 440 | 444 | oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask); |
| 441 | 445 | oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel); |
| 442 | 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 | 450 | return 0; |
| @@ -22,6 +22,7 @@ struct op_counter_config { · 21 unmodified lines | ||
| 22 | 22 | unsigned long kernel; |
| 23 | 23 | unsigned long user; |
| 24 | 24 | unsigned long unit_mask; |
| 25 | + unsigned long extra; | |
| 25 | 26 | }; |
| 26 | 27 | |
| 27 | 28 | extern struct op_counter_config counter_config[]; |
| @@ -1086,7 +1086,7 @@ void perf_event_task_sched_out(struct task_struct *task, struct task_struct *nex · 1085 unmodified lines | ||
| 1086 | 1086 | { |
| 1087 | 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 | 1092 | extern void perf_event_mmap(struct vm_area_struct *vma); |
| @@ -145,8 +145,8 @@ static struct srcu_struct pmus_srcu; · 144 unmodified lines | ||
| 145 | 145 | */ |
| 146 | 146 | int sysctl_perf_event_paranoid __read_mostly = 1; |
| 147 | 147 | |
| 148 | −/* Minimum for 128 pages + 1 for the user control page */ | |
| 149 | −int sysctl_perf_event_mlock __read_mostly = 516; /* 'free' kb per user */ | |
| 148 | +/* Minimum for 512 kiB + 1 user control page */ | |
| 149 | +int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */ | |
| 150 | 150 | |
| 151 | 151 | /* |
| 152 | 152 | * max perf event sample rate |
| @@ -6531,6 +6531,11 @@ SYSCALL_DEFINE5(perf_event_open, · 6378 unmodified lines | ||
| 6531 | 6531 | goto err_alloc; |
| 6532 | 6532 | } |
| 6533 | 6533 | |
| 6534 | + if (task) { | |
| 6535 | + put_task_struct(task); | |
| 6536 | + task = NULL; | |
| 6537 | + } | |
| 6538 | + | |
| 6534 | 6539 | /* |
| 6535 | 6540 | * Look up the group leader (we will attach this event to it): |
| 6536 | 6541 | */ |
| @@ -165,8 +165,12 @@ grep-libs = $(filter -l%,$(1)) · 164 unmodified lines | ||
| 165 | 165 | strip-libs = $(filter-out -l%,$(1)) |
| 166 | 166 | |
| 167 | 167 | $(OUTPUT)python/perf.so: $(PYRF_OBJS) |
| 168 | − $(QUIET_GEN)python util/setup.py --quiet build_ext --build-lib='$(OUTPUT)python' \ | |
| 169 | − --build-temp='$(OUTPUT)python/temp' | |
| 168 | + $(QUIET_GEN)( \ | |
| 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 | 175 | # No Perl scripts right now: |
| 172 | 176 | # |
| @@ -41,7 +41,7 @@ static u64 user_interval = ULLONG_MAX; · 40 unmodified lines | ||
| 41 | 41 | static u64 default_interval = 0; |
| 42 | 42 | |
| 43 | 43 | static unsigned int page_size; |
| 44 | −static unsigned int mmap_pages = 128; | |
| 44 | +static unsigned int mmap_pages = UINT_MAX; | |
| 45 | 45 | static unsigned int user_freq = UINT_MAX; |
| 46 | 46 | static int freq = 1000; |
| 47 | 47 | static int output; |
| @@ -275,11 +275,10 @@ try_again: · 227 unmodified lines | ||
| 275 | 275 | !no_inherit) < 0) { |
| 276 | 276 | int err = errno; |
| 277 | 277 | |
| 278 | − if (err == EPERM || err == EACCES) | |
| 279 | − die("Permission error - are you root?\n" | |
| 280 | − "\t Consider tweaking" | |
| 281 | − " /proc/sys/kernel/perf_event_paranoid.\n"); | |
| 282 | − else if (err == ENODEV && cpu_list) { | |
| 278 | + if (err == EPERM || err == EACCES) { | |
| 279 | + ui__warning_paranoid(); | |
| 280 | + exit(EXIT_FAILURE); | |
| 281 | + } else if (err == ENODEV && cpu_list) { | |
| 283 | 282 | die("No such device - did you specify" |
| 284 | 283 | " an out-of-range profile CPU?\n"); |
| 285 | 284 | } else if (err == EINVAL && sample_id_all_avail) { |
| @@ -302,11 +301,19 @@ try_again: · 16 unmodified lines | ||
| 302 | 301 | && attr->config == PERF_COUNT_HW_CPU_CYCLES) { |
| 303 | 302 | |
| 304 | 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 | 306 | attr->type = PERF_TYPE_SOFTWARE; |
| 307 | 307 | attr->config = PERF_COUNT_SW_CPU_CLOCK; |
| 308 | 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 | 317 | printf("\n"); |
| 311 | 318 | error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n", |
| 312 | 319 | err, strerror(err)); |
| @@ -506,6 +513,10 @@ static int __cmd_record(int argc, const char **argv) · 193 unmodified lines | ||
| 506 | 513 | if (have_tracepoints(&evsel_list->entries)) |
| 507 | 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 | 520 | if (forks) { |
| 510 | 521 | child_pid = fork(); |
| 511 | 522 | if (child_pid < 0) { |
| @@ -850,10 +850,10 @@ try_again: · 849 unmodified lines | ||
| 850 | 850 | top.evlist->threads, group, inherit) < 0) { |
| 851 | 851 | int err = errno; |
| 852 | 852 | |
| 853 | − if (err == EPERM || err == EACCES) | |
| 854 | − die("Permission error - are you root?\n" | |
| 855 | − "\t Consider tweaking" | |
| 856 | − " /proc/sys/kernel/perf_event_paranoid.\n"); | |
| 853 | + if (err == EPERM || err == EACCES) { | |
| 854 | + ui__warning_paranoid(); | |
| 855 | + goto out_err; | |
| 856 | + } | |
| 857 | 857 | /* |
| 858 | 858 | * If it's cycles then fall back to hrtimer |
| 859 | 859 | * based cpu-clock-tick sw counter, which |
| @@ -861,25 +861,41 @@ try_again: · 1 unmodified line | ||
| 861 | 861 | */ |
| 862 | 862 | if (attr->type == PERF_TYPE_HARDWARE && |
| 863 | 863 | attr->config == PERF_COUNT_HW_CPU_CYCLES) { |
| 864 | − | |
| 865 | 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 | 868 | attr->type = PERF_TYPE_SOFTWARE; |
| 869 | 869 | attr->config = PERF_COUNT_SW_CPU_CLOCK; |
| 870 | 870 | goto try_again; |
| 871 | 871 | } |
| 872 | − printf("\n"); | |
| 873 | − error("sys_perf_event_open() syscall returned with %d " | |
| 874 | − "(%s). /bin/dmesg may provide additional information.\n", | |
| 875 | − err, strerror(err)); | |
| 876 | − die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); | |
| 877 | − exit(-1); | |
| 872 | + | |
| 873 | + if (err == ENOENT) { | |
| 874 | + ui__warning("The %s event is not supported.\n", | |
| 875 | + event_name(counter)); | |
| 876 | + goto out_err; | |
| 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) | |
| 882 | − die("failed to mmap with %d (%s)\n", errno, strerror(errno)); | |
| 888 | + if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) { | |
| 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 | 901 | static int __cmd_top(void) |
| @@ -57,6 +57,16 @@ void ui__warning(const char *format, ...) · 56 unmodified lines | ||
| 57 | 57 | } |
| 58 | 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 | 70 | void trace_event(union perf_event *event) |
| 61 | 71 | { |
| 62 | 72 | unsigned char *raw_event = (void *)event; |
| @@ -36,5 +36,6 @@ int ui_helpline__show_help(const char *format, va_list ap); · 35 unmodified lines | ||
| 36 | 36 | #endif |
| 37 | 37 | |
| 38 | 38 | void ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); |
| 39 | +void ui__warning_paranoid(void); | |
| 39 | 40 | |
| 40 | 41 | #endif /* __PERF_DEBUG_H */ |
| @@ -710,7 +710,7 @@ try_again: · 709 unmodified lines | ||
| 710 | 710 | * in the whole kernel symbol list. |
| 711 | 711 | */ |
| 712 | 712 | if ((long long)al->addr < 0 && |
| 713 | − cpumode == PERF_RECORD_MISC_KERNEL && | |
| 713 | + cpumode == PERF_RECORD_MISC_USER && | |
| 714 | 714 | machine && mg != &machine->kmaps) { |
| 715 | 715 | mg = &machine->kmaps; |
| 716 | 716 | goto try_again; |
| @@ -1,13 +1,18 @@ | ||
| 1 | 1 | #!/usr/bin/python2 |
| 2 | 2 | |
| 3 | 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 | 9 | perf = Extension('perf', |
| 6 | 10 | sources = ['util/python.c', 'util/ctype.c', 'util/evlist.c', |
| 7 | 11 | 'util/evsel.c', 'util/cpumap.c', 'util/thread_map.c', |
| 8 | 12 | 'util/util.c', 'util/xyarray.c', 'util/cgroup.c'], |
| 9 | 13 | include_dirs = ['util/include'], |
| 10 | − extra_compile_args = ['-fno-strict-aliasing', '-Wno-write-strings']) | |
| 14 | + extra_compile_args = cflags, | |
| 15 | + ) | |
| 11 | 16 | |
| 12 | 17 | setup(name='perf', |
| 13 | 18 | version='0.1', |
| @@ -1196,6 +1196,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, · 1195 unmodified lines | ||
| 1196 | 1196 | if (curr_dso == NULL) |
| 1197 | 1197 | goto out_elf_end; |
| 1198 | 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 | 1201 | curr_map = map__new2(start, curr_dso, |
| 1200 | 1202 | map->type); |
| 1201 | 1203 | if (curr_map == NULL) { |
| @@ -1842,6 +1844,7 @@ int dso__load_vmlinux(struct dso *self, struct map *map, · 640 unmodified lines | ||
| 1842 | 1844 | if (fd < 0) |
| 1843 | 1845 | return -1; |
| 1844 | 1846 | |
| 1847 | + dso__set_long_name(self, (char *)vmlinux); | |
| 1845 | 1848 | dso__set_loaded(self, map->type); |
| 1846 | 1849 | err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0); |
| 1847 | 1850 | close(fd); |
| @@ -2403,6 +2406,8 @@ int symbol__init(void) · 555 unmodified lines | ||
| 2403 | 2406 | if (symbol_conf.initialized) |
| 2404 | 2407 | return 0; |
| 2405 | 2408 | |
| 2409 | + symbol_conf.priv_size = ALIGN(symbol_conf.priv_size, sizeof(u64)); | |
| 2410 | + | |
| 2406 | 2411 | elf_version(EV_CURRENT); |
| 2407 | 2412 | if (symbol_conf.sort_by_name) |
| 2408 | 2413 | symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) - |