summaryrefslogtreecommitdiffstats
path: root/kernel/events/internal.h
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2013-05-28 10:55:48 +0200
committerIngo Molnar <mingo@kernel.org>2013-05-28 11:05:08 +0200
commit26cb63ad11e04047a64309362674bcbbd6a6f246 (patch)
tree559c0a9778e7aa6639a24d9a7951879dc65d0551 /kernel/events/internal.h
parentkprobes: Fix to free gone and unused optprobes (diff)
downloadlinux-26cb63ad11e04047a64309362674bcbbd6a6f246.tar.xz
linux-26cb63ad11e04047a64309362674bcbbd6a6f246.zip
perf: Fix perf mmap bugs
Vince reported a problem found by his perf specific trinity fuzzer. Al noticed 2 problems with perf's mmap(): - it has issues against fork() since we use vma->vm_mm for accounting. - it has an rb refcount leak on double mmap(). We fix the issues against fork() by using VM_DONTCOPY; I don't think there's code out there that uses this; we didn't hear about weird accounting problems/crashes. If we do need this to work, the previously proposed VM_PINNED could make this work. Aside from the rb reference leak spotted by Al, Vince's example prog was indeed doing a double mmap() through the use of perf_event_set_output(). This exposes another problem, since we now have 2 events with one buffer, the accounting gets screwy because we account per event. Fix this by making the buffer responsible for its own accounting. Reported-by: Vince Weaver <vincent.weaver@maine.edu> Signed-off-by: Peter Zijlstra <peterz@infradead.org> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Paul Mackerras <paulus@samba.org> Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> Link: http://lkml.kernel.org/r/20130528085548.GA12193@twins.programming.kicks-ass.net Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/events/internal.h')
-rw-r--r--kernel/events/internal.h3
1 files changed, 3 insertions, 0 deletions
diff --git a/kernel/events/internal.h b/kernel/events/internal.h
index eb675c4d59df..5bc6c8e9b851 100644
--- a/kernel/events/internal.h
+++ b/kernel/events/internal.h
@@ -31,6 +31,9 @@ struct ring_buffer {
spinlock_t event_lock;
struct list_head event_list;
+ int mmap_locked;
+ struct user_struct *mmap_user;
+
struct perf_event_mmap_page *user_page;
void *data_pages[0];
};