diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2009-06-05 08:04:55 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-06-05 08:46:41 -0400 |
commit | 089dd79db9264dc0da602bad45d42f1b3e7d1e07 (patch) | |
tree | 017b1efd0bc4f3d15b92ed6fae5dfc3d1b164872 | |
parent | f7b6eb3fa07269da20dbbde8ba37a0273fdbd9c9 (diff) |
perf_counter: Generate mmap events for install_special_mapping()
In order to track the vdso also generate mmap events for
install_special_mapping().
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | include/linux/perf_counter.h | 14 | ||||
-rw-r--r-- | kernel/perf_counter.c | 34 | ||||
-rw-r--r-- | mm/mmap.c | 5 |
3 files changed, 33 insertions, 20 deletions
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 6ca403acd419..40dc0e273d9c 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h | |||
@@ -617,8 +617,13 @@ static inline int is_software_counter(struct perf_counter *counter) | |||
617 | 617 | ||
618 | extern void perf_swcounter_event(u32, u64, int, struct pt_regs *, u64); | 618 | extern void perf_swcounter_event(u32, u64, int, struct pt_regs *, u64); |
619 | 619 | ||
620 | extern void perf_counter_mmap(unsigned long addr, unsigned long len, | 620 | extern void __perf_counter_mmap(struct vm_area_struct *vma); |
621 | unsigned long pgoff, struct file *file); | 621 | |
622 | static inline void perf_counter_mmap(struct vm_area_struct *vma) | ||
623 | { | ||
624 | if (vma->vm_flags & VM_EXEC) | ||
625 | __perf_counter_mmap(vma); | ||
626 | } | ||
622 | 627 | ||
623 | extern void perf_counter_comm(struct task_struct *tsk); | 628 | extern void perf_counter_comm(struct task_struct *tsk); |
624 | extern void perf_counter_fork(struct task_struct *tsk); | 629 | extern void perf_counter_fork(struct task_struct *tsk); |
@@ -668,10 +673,7 @@ static inline void | |||
668 | perf_swcounter_event(u32 event, u64 nr, int nmi, | 673 | perf_swcounter_event(u32 event, u64 nr, int nmi, |
669 | struct pt_regs *regs, u64 addr) { } | 674 | struct pt_regs *regs, u64 addr) { } |
670 | 675 | ||
671 | static inline void | 676 | static inline void perf_counter_mmap(struct vm_area_struct *vma) { } |
672 | perf_counter_mmap(unsigned long addr, unsigned long len, | ||
673 | unsigned long pgoff, struct file *file) { } | ||
674 | |||
675 | static inline void perf_counter_comm(struct task_struct *tsk) { } | 677 | static inline void perf_counter_comm(struct task_struct *tsk) { } |
676 | static inline void perf_counter_fork(struct task_struct *tsk) { } | 678 | static inline void perf_counter_fork(struct task_struct *tsk) { } |
677 | static inline void perf_counter_init(void) { } | 679 | static inline void perf_counter_init(void) { } |
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index a5d3e2aedd2f..37a5a241ca7e 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c | |||
@@ -2255,7 +2255,7 @@ out: | |||
2255 | } | 2255 | } |
2256 | 2256 | ||
2257 | static void perf_output_copy(struct perf_output_handle *handle, | 2257 | static void perf_output_copy(struct perf_output_handle *handle, |
2258 | void *buf, unsigned int len) | 2258 | const void *buf, unsigned int len) |
2259 | { | 2259 | { |
2260 | unsigned int pages_mask; | 2260 | unsigned int pages_mask; |
2261 | unsigned int offset; | 2261 | unsigned int offset; |
@@ -2681,9 +2681,10 @@ void perf_counter_comm(struct task_struct *task) | |||
2681 | */ | 2681 | */ |
2682 | 2682 | ||
2683 | struct perf_mmap_event { | 2683 | struct perf_mmap_event { |
2684 | struct file *file; | 2684 | struct vm_area_struct *vma; |
2685 | char *file_name; | 2685 | |
2686 | int file_size; | 2686 | const char *file_name; |
2687 | int file_size; | ||
2687 | 2688 | ||
2688 | struct { | 2689 | struct { |
2689 | struct perf_event_header header; | 2690 | struct perf_event_header header; |
@@ -2744,11 +2745,12 @@ static void perf_counter_mmap_event(struct perf_mmap_event *mmap_event) | |||
2744 | { | 2745 | { |
2745 | struct perf_cpu_context *cpuctx; | 2746 | struct perf_cpu_context *cpuctx; |
2746 | struct perf_counter_context *ctx; | 2747 | struct perf_counter_context *ctx; |
2747 | struct file *file = mmap_event->file; | 2748 | struct vm_area_struct *vma = mmap_event->vma; |
2749 | struct file *file = vma->vm_file; | ||
2748 | unsigned int size; | 2750 | unsigned int size; |
2749 | char tmp[16]; | 2751 | char tmp[16]; |
2750 | char *buf = NULL; | 2752 | char *buf = NULL; |
2751 | char *name; | 2753 | const char *name; |
2752 | 2754 | ||
2753 | if (file) { | 2755 | if (file) { |
2754 | buf = kzalloc(PATH_MAX, GFP_KERNEL); | 2756 | buf = kzalloc(PATH_MAX, GFP_KERNEL); |
@@ -2762,6 +2764,15 @@ static void perf_counter_mmap_event(struct perf_mmap_event *mmap_event) | |||
2762 | goto got_name; | 2764 | goto got_name; |
2763 | } | 2765 | } |
2764 | } else { | 2766 | } else { |
2767 | name = arch_vma_name(mmap_event->vma); | ||
2768 | if (name) | ||
2769 | goto got_name; | ||
2770 | |||
2771 | if (!vma->vm_mm) { | ||
2772 | name = strncpy(tmp, "[vdso]", sizeof(tmp)); | ||
2773 | goto got_name; | ||
2774 | } | ||
2775 | |||
2765 | name = strncpy(tmp, "//anon", sizeof(tmp)); | 2776 | name = strncpy(tmp, "//anon", sizeof(tmp)); |
2766 | goto got_name; | 2777 | goto got_name; |
2767 | } | 2778 | } |
@@ -2791,8 +2802,7 @@ got_name: | |||
2791 | kfree(buf); | 2802 | kfree(buf); |
2792 | } | 2803 | } |
2793 | 2804 | ||
2794 | void perf_counter_mmap(unsigned long addr, unsigned long len, | 2805 | void __perf_counter_mmap(struct vm_area_struct *vma) |
2795 | unsigned long pgoff, struct file *file) | ||
2796 | { | 2806 | { |
2797 | struct perf_mmap_event mmap_event; | 2807 | struct perf_mmap_event mmap_event; |
2798 | 2808 | ||
@@ -2800,12 +2810,12 @@ void perf_counter_mmap(unsigned long addr, unsigned long len, | |||
2800 | return; | 2810 | return; |
2801 | 2811 | ||
2802 | mmap_event = (struct perf_mmap_event){ | 2812 | mmap_event = (struct perf_mmap_event){ |
2803 | .file = file, | 2813 | .vma = vma, |
2804 | .event = { | 2814 | .event = { |
2805 | .header = { .type = PERF_EVENT_MMAP, }, | 2815 | .header = { .type = PERF_EVENT_MMAP, }, |
2806 | .start = addr, | 2816 | .start = vma->vm_start, |
2807 | .len = len, | 2817 | .len = vma->vm_end - vma->vm_start, |
2808 | .pgoff = pgoff, | 2818 | .pgoff = vma->vm_pgoff, |
2809 | }, | 2819 | }, |
2810 | }; | 2820 | }; |
2811 | 2821 | ||
@@ -1220,8 +1220,7 @@ munmap_back: | |||
1220 | if (correct_wcount) | 1220 | if (correct_wcount) |
1221 | atomic_inc(&inode->i_writecount); | 1221 | atomic_inc(&inode->i_writecount); |
1222 | out: | 1222 | out: |
1223 | if (vm_flags & VM_EXEC) | 1223 | perf_counter_mmap(vma); |
1224 | perf_counter_mmap(addr, len, pgoff, file); | ||
1225 | 1224 | ||
1226 | mm->total_vm += len >> PAGE_SHIFT; | 1225 | mm->total_vm += len >> PAGE_SHIFT; |
1227 | vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT); | 1226 | vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT); |
@@ -2309,6 +2308,8 @@ int install_special_mapping(struct mm_struct *mm, | |||
2309 | 2308 | ||
2310 | mm->total_vm += len >> PAGE_SHIFT; | 2309 | mm->total_vm += len >> PAGE_SHIFT; |
2311 | 2310 | ||
2311 | perf_counter_mmap(vma); | ||
2312 | |||
2312 | return 0; | 2313 | return 0; |
2313 | } | 2314 | } |
2314 | 2315 | ||