From 914a76ca5eedc9f286a36f61c4eaa95b451ba3e6 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 16 Mar 2011 15:44:33 -0400 Subject: [PATCH 01/10] oprofile, x86: Allow setting EDGE/INV/CMASK for counter events For some performance events it's useful to set the EDGE and INV bits and the CMASK mask in the counter control register. The list of predefined events Intel releases for each CPU has some events which require these settings to get more "natural" to use higher level events. oprofile currently doesn't allow this. This patch adds new extra configuration fields for them, so that they can be specified in oprofilefs. An updated oprofile daemon can then make use of this to set them. v2: Write back masked extra value to variable. Signed-off-by: Andi Kleen Signed-off-by: Robert Richter --- arch/x86/oprofile/nmi_int.c | 5 +++++ arch/x86/oprofile/op_counter.h | 1 + 2 files changed, 6 insertions(+) diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index e2b7b0c06cdf..ee165f1a1f37 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, val |= counter_config->user ? ARCH_PERFMON_EVENTSEL_USR : 0; val |= counter_config->kernel ? ARCH_PERFMON_EVENTSEL_OS : 0; val |= (counter_config->unit_mask & 0xFF) << 8; + counter_config->extra &= (ARCH_PERFMON_EVENTSEL_INV | + ARCH_PERFMON_EVENTSEL_EDGE | + ARCH_PERFMON_EVENTSEL_CMASK); + val |= counter_config->extra; event &= model->event_mask ? model->event_mask : 0xFF; val |= event & 0xFF; val |= (event & 0x0F00) << 24; @@ -440,6 +444,7 @@ static int nmi_create_files(struct super_block *sb, struct dentry *root) oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask); oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel); oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user); + oprofilefs_create_ulong(sb, dir, "extra", &counter_config[i].extra); } 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 { unsigned long kernel; unsigned long user; unsigned long unit_mask; + unsigned long extra; }; extern struct op_counter_config counter_config[]; From 6c6804fb2cef2d6aceb38b0eb0803210d77ff390 Mon Sep 17 00:00:00 2001 From: Andrew Lutomirski Date: Thu, 24 Mar 2011 00:36:56 -0400 Subject: [PATCH 02/10] perf symbols: Fix vsyscall symbol lookup Perf can't currently trace into the vsyscall page. It looks like it was meant to work. Tested on 2.6.38 and today's -git. The bug is easy to reproduce. Compile this: int main() { int i; struct timespec t; for(i = 0; i < 10000000; i++) clock_gettime(CLOCK_MONOTONIC, &t); return 0; } and run it through perf record; perf report. The top entry shows "[unknown]" and you can't zoom in. It looks like there are two issues. The first is a that a test for user mode executing in kernel space is backwards. (That's the first hunk below). The second (I think) is that something's wrong with the code that generates lots of little struct dso objects for different sections -- when it runs on vmlinux it results in bogus long_name values which cause objdump to fail. Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra LPU-Reference: Signed-off-by: Andy Lutomirski Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/event.c | 2 +- tools/perf/util/symbol.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) 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: * in the whole kernel symbol list. */ if ((long long)al->addr < 0 && - cpumode == PERF_RECORD_MISC_KERNEL && + cpumode == PERF_RECORD_MISC_USER && machine && mg != &machine->kmaps) { mg = &machine->kmaps; goto try_again; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 17df793c8924..8f73907a959e 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, if (curr_dso == NULL) goto out_elf_end; curr_dso->kernel = self->kernel; + curr_dso->long_name = self->long_name; + curr_dso->long_name_len = self->long_name_len; curr_map = map__new2(start, curr_dso, map->type); if (curr_map == NULL) { @@ -1842,6 +1844,7 @@ int dso__load_vmlinux(struct dso *self, struct map *map, if (fd < 0) return -1; + dso__set_long_name(self, (char *)vmlinux); dso__set_loaded(self, map->type); err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0); close(fd); From c286c419c784c238cd699be37fec7a9acc30d89f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 28 Mar 2011 09:50:11 -0300 Subject: [PATCH 03/10] perf tools: Fixup exit path when not able to open events We have to deal with the TUI mode in perf top, so that we don't end up with a garbled screen when, say, a non root user on a machine with a paranoid setting (the default) tries to use 'perf top'. Introduce a ui__warning_paranoid() routine shared by top and record that tells the user the valid values for /proc/sys/kernel/perf_event_paranoid. Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 9 ++++----- tools/perf/builtin-top.c | 38 +++++++++++++++++++++++-------------- tools/perf/util/debug.c | 10 ++++++++++ tools/perf/util/debug.h | 1 + 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 6febcc168a8c..623695e18254 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -275,11 +275,10 @@ try_again: !no_inherit) < 0) { int err = errno; - if (err == EPERM || err == EACCES) - die("Permission error - are you root?\n" - "\t Consider tweaking" - " /proc/sys/kernel/perf_event_paranoid.\n"); - else if (err == ENODEV && cpu_list) { + if (err == EPERM || err == EACCES) { + ui__warning_paranoid(); + exit(EXIT_FAILURE); + } else if (err == ENODEV && cpu_list) { die("No such device - did you specify" " an out-of-range profile CPU?\n"); } else if (err == EINVAL && sample_id_all_avail) { diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 676b4fb0070f..935fc4fd878e 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -850,10 +850,10 @@ try_again: top.evlist->threads, group, inherit) < 0) { int err = errno; - if (err == EPERM || err == EACCES) - die("Permission error - are you root?\n" - "\t Consider tweaking" - " /proc/sys/kernel/perf_event_paranoid.\n"); + if (err == EPERM || err == EACCES) { + ui__warning_paranoid(); + goto out_err; + } /* * If it's cycles then fall back to hrtimer * based cpu-clock-tick sw counter, which @@ -861,25 +861,35 @@ try_again: */ if (attr->type == PERF_TYPE_HARDWARE && attr->config == PERF_COUNT_HW_CPU_CYCLES) { - if (verbose) - warning(" ... trying to fall back to cpu-clock-ticks\n"); + ui__warning("Cycles event not supported,\n" + "trying to fall back to cpu-clock-ticks\n"); attr->type = PERF_TYPE_SOFTWARE; attr->config = PERF_COUNT_SW_CPU_CLOCK; goto try_again; } - printf("\n"); - error("sys_perf_event_open() syscall returned with %d " - "(%s). /bin/dmesg may provide additional information.\n", - err, strerror(err)); - die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); - exit(-1); + + ui__warning("The sys_perf_event_open() syscall " + "returned with %d (%s). /bin/dmesg " + "may provide additional information.\n" + "No CONFIG_PERF_EVENTS=y kernel support " + "configured?\n", err, strerror(err)); + goto out_err; } } - if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) - die("failed to mmap with %d (%s)\n", errno, strerror(errno)); + if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) { + ui__warning("Failed to mmap with %d (%s)\n", + errno, strerror(errno)); + goto out_err; + } + + return; + +out_err: + exit_browser(0); + exit(0); } 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, ...) } #endif +void ui__warning_paranoid(void) +{ + ui__warning("Permission error - are you root?\n" + "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n" + " -1 - Not paranoid at all\n" + " 0 - Disallow raw tracepoint access for unpriv\n" + " 1 - Disallow cpu events for unpriv\n" + " 2 - Disallow kernel profiling for unpriv\n"); +} + void trace_event(union perf_event *event) { 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); #endif void ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); +void ui__warning_paranoid(void); #endif /* __PERF_DEBUG_H */ From ca6a42586fae639ff9e5285d9bdc550fcb1b8d41 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Fri, 25 Mar 2011 13:11:11 -0600 Subject: [PATCH 04/10] perf tools: Emit clearer message for sys_perf_event_open ENOENT return Resend of patch sent back in January 2011 in light of recent confusion around unsupported events for a given platform. Improve sys_perf_event_open ENOENT return handling in top and record, just like 5a3446b does for stat. Retry of Arnaldo's patch using ui_warning instead of die which allows the fallback from hardware cycles to software clock. Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-kernel@vger.kernel.org LKML-Reference: <1301080271-20945-1-git-send-email-daahern@cisco.com> Signed-off-by: David Ahern [ committer note: Some adjustments to make it apply to newer codebase ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 10 +++++++++- tools/perf/builtin-top.c | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 623695e18254..db6adecf46f1 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -301,11 +301,19 @@ try_again: && attr->config == PERF_COUNT_HW_CPU_CYCLES) { if (verbose) - warning(" ... trying to fall back to cpu-clock-ticks\n"); + ui__warning("The cycles event is not supported, " + "trying to fall back to cpu-clock-ticks\n"); attr->type = PERF_TYPE_SOFTWARE; attr->config = PERF_COUNT_SW_CPU_CLOCK; goto try_again; } + + if (err == ENOENT) { + ui__warning("The %s event is not supported.\n", + event_name(pos)); + exit(EXIT_FAILURE); + } + printf("\n"); error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n", err, strerror(err)); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 935fc4fd878e..fc1273e976c5 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -870,6 +870,12 @@ try_again: goto try_again; } + if (err == ENOENT) { + ui__warning("The %s event is not supported.\n", + event_name(counter)); + goto out_err; + } + ui__warning("The sys_perf_event_open() syscall " "returned with %d (%s). /bin/dmesg " "may provide additional information.\n" From 4d439517561d009e170e2fe20be1ba25e19abe75 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 29 Mar 2011 14:18:39 -0300 Subject: [PATCH 05/10] perf symbols: Properly align symbol_conf.priv_size If symbol_conf.priv_size is not a multiple of "sizeof(u64)" we'll bus error on sparc64 in symbol__new because the "struct symbol *" pointer is computed by adding symbol_conf.priv_size to the memory allocated. We cannot isolate the fix to symbol__new and symbol__delete since the private area is computed by subtracting the priv_size value from a "struct symbol" pointer, so then the private area can still be potentially unaligned. So, simply align the symbol_conf.priv_size value in symbol__init() Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra LKML-Reference: <20110328.175849.112593455.davem@davemloft.net> Signed-off-by: David S. Miller Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 8f73907a959e..f06c10f092ba 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -2406,6 +2406,8 @@ int symbol__init(void) if (symbol_conf.initialized) return 0; + symbol_conf.priv_size = ALIGN(symbol_conf.priv_size, sizeof(u64)); + elf_version(EV_CURRENT); if (symbol_conf.sort_by_name) symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) - From 1b7155f7de119870f0d3fad89f125de2ff6c16be Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Tue, 29 Mar 2011 20:02:57 +0200 Subject: [PATCH 06/10] perf tools: Fix NO_NEWT=1 python build error Fix the following build error: GEN python/perf.so In file included from util/evsel.h:10, from util/python.c:6: util/hist.h:106:18: error: newt.h: No such file or directory error: command 'x86_64-pc-linux-gnu-gcc' failed with exit status 1 make: *** [python/perf.so] Error 1 by passing BASIC_CFLAGS to setup.py. BASIC_CFLAGS variable contains the -DNO_NEWT_SUPPORT switch which prevents building python c extension with newt. Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Stephane Eranian LKML-Reference: <20110329180236.GA19366@erda.amd.com> Signed-off-by: Robert Richter Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 8 ++++++-- tools/perf/util/setup.py | 7 ++++++- 2 files changed, 12 insertions(+), 3 deletions(-) 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)) strip-libs = $(filter-out -l%,$(1)) $(OUTPUT)python/perf.so: $(PYRF_OBJS) - $(QUIET_GEN)python util/setup.py --quiet build_ext --build-lib='$(OUTPUT)python' \ - --build-temp='$(OUTPUT)python/temp' + $(QUIET_GEN)( \ + export CFLAGS="$(BASIC_CFLAGS)"; \ + python util/setup.py --quiet build_ext --build-lib='$(OUTPUT)python' \ + --build-temp='$(OUTPUT)python/temp' \ + ) + # # No Perl scripts right now: # 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 @@ #!/usr/bin/python2 from distutils.core import setup, Extension +from os import getenv + +cflags = ['-fno-strict-aliasing', '-Wno-write-strings'] +cflags += getenv('CFLAGS', '').split() perf = Extension('perf', sources = ['util/python.c', 'util/ctype.c', 'util/evlist.c', 'util/evsel.c', 'util/cpumap.c', 'util/thread_map.c', 'util/util.c', 'util/xyarray.c', 'util/cgroup.c'], include_dirs = ['util/include'], - extra_compile_args = ['-fno-strict-aliasing', '-Wno-write-strings']) + extra_compile_args = cflags, + ) setup(name='perf', version='0.1', From 20443384fe090c5f8aeb016e7e85659c5bbdd69f Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 31 Mar 2011 03:33:29 +0200 Subject: [PATCH 07/10] perf: Rebase max unprivileged mlock threshold on top of page size Ensure we allow 512 kiB + 1 page for user control without assuming a 4096 bytes page size. Reported-by: Peter Zijlstra Signed-off-by: Frederic Weisbecker Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras Cc: Stephane Eranian Cc: LKML-Reference: <1301535209-9679-1-git-send-email-fweisbec@gmail.com> Signed-off-by: Ingo Molnar --- kernel/perf_event.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/perf_event.c b/kernel/perf_event.c index c75925c4d1e2..261690923ffb 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -145,8 +145,8 @@ static struct srcu_struct pmus_srcu; */ int sysctl_perf_event_paranoid __read_mostly = 1; -/* Minimum for 128 pages + 1 for the user control page */ -int sysctl_perf_event_mlock __read_mostly = 516; /* 'free' kb per user */ +/* Minimum for 512 kiB + 1 user control page */ +int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */ /* * max perf event sample rate From 800cd25c12981c99e5401c3551ffffd99f1c6c85 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 31 Mar 2011 03:35:24 +0200 Subject: [PATCH 08/10] perf: mmap 512 kiB by default The default setting of perf record is to mmap 128 pages if the user did not override with -m. However the page size may vary accross different architecture settings, giving different default size between each. Moreover the kernel side still has a default max number of mlocked pages of 512 kiB + 1 page for unprivileged users. 128 + 1 pages with page size > 4096 overlaps this threshold. Thus, better adapt to this limitation and set the default number of pages to fit those 512 kiB + 1 page. Signed-off-by: Frederic Weisbecker Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras Cc: Stephane Eranian LKML-Reference: <1301535324-9735-1-git-send-email-fweisbec@gmail.com> Signed-off-by: Ingo Molnar --- tools/perf/builtin-record.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index db6adecf46f1..17d1dcb3c667 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -41,7 +41,7 @@ static u64 user_interval = ULLONG_MAX; static u64 default_interval = 0; static unsigned int page_size; -static unsigned int mmap_pages = 128; +static unsigned int mmap_pages = UINT_MAX; static unsigned int user_freq = UINT_MAX; static int freq = 1000; static int output; @@ -513,6 +513,10 @@ static int __cmd_record(int argc, const char **argv) if (have_tracepoints(&evsel_list->entries)) perf_header__set_feat(&session->header, HEADER_TRACE_INFO); + /* 512 kiB: default amount of unprivileged mlocked memory */ + if (mmap_pages == UINT_MAX) + mmap_pages = (512 * 1024) / page_size; + if (forks) { child_pid = fork(); if (child_pid < 0) { From ab711fe08297de1485fff0a366e6db8828cafd6a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 31 Mar 2011 10:29:26 +0200 Subject: [PATCH 09/10] perf: Fix task context scheduling Jiri reported: | | - once an event is created by sys_perf_event_open, task context | is created and it stays even if the event is closed, until the | task is finished ... thats what I see in code and I assume it's | correct | | - when the task opens event, perf_sched_events jump label is | incremented and following callbacks are started from scheduler | | __perf_event_task_sched_in | __perf_event_task_sched_out | | These callback *in/out set/unset cpuctx->task_ctx value to the | task context. | | - close is called on event on CPU 0: | - the task is scheduled on CPU 0 | - __perf_event_task_sched_in is called | - cpuctx->task_ctx is set | - perf_sched_events jump label is decremented and == 0 | - __perf_event_task_sched_out is not called | - cpuctx->task_ctx on CPU 0 stays set | | - exit is called on CPU 1: | - the task is scheduled on CPU 1 | - perf_event_exit_task is called | - task_ctx_sched_out unsets cpuctx->task_ctx on CPU 1 | - put_ctx destroys the context | | - another call of perf_rotate_context on CPU 0 will use invalid | task_ctx pointer, and eventualy panic. | Cure this the simplest possibly way by partially reverting the jump_label optimization for the sched_out case. Reported-and-tested-by: Jiri Olsa Signed-off-by: Peter Zijlstra Cc: Oleg Nesterov Cc: # .37+ LKML-Reference: <1301520405.4859.213.camel@twins> Signed-off-by: Ingo Molnar --- include/linux/perf_event.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 { perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0); - COND_STMT(&perf_sched_events, __perf_event_task_sched_out(task, next)); + __perf_event_task_sched_out(task, next); } extern void perf_event_mmap(struct vm_area_struct *vma); From fd1edb3aa2c1d92618d8f0c6d15d44ea41fcac6a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 28 Mar 2011 13:13:56 +0200 Subject: [PATCH 10/10] perf: Fix task_struct reference leak sys_perf_event_open() had an imbalance in the number of task refs it took causing memory leakage Cc: Jiri Olsa Cc: Oleg Nesterov Cc: stable@kernel.org # .37+ Signed-off-by: Peter Zijlstra LKML-Reference: Signed-off-by: Ingo Molnar --- kernel/perf_event.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 261690923ffb..27960f114efd 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -6531,6 +6531,11 @@ SYSCALL_DEFINE5(perf_event_open, goto err_alloc; } + if (task) { + put_task_struct(task); + task = NULL; + } + /* * Look up the group leader (we will attach this event to it): */