aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/perf_counter.h14
-rw-r--r--kernel/perf_counter.c34
-rw-r--r--mm/mmap.c5
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
618extern void perf_swcounter_event(u32, u64, int, struct pt_regs *, u64); 618extern void perf_swcounter_event(u32, u64, int, struct pt_regs *, u64);
619 619
620extern void perf_counter_mmap(unsigned long addr, unsigned long len, 620extern void __perf_counter_mmap(struct vm_area_struct *vma);
621 unsigned long pgoff, struct file *file); 621
622static 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
623extern void perf_counter_comm(struct task_struct *tsk); 628extern void perf_counter_comm(struct task_struct *tsk);
624extern void perf_counter_fork(struct task_struct *tsk); 629extern void perf_counter_fork(struct task_struct *tsk);
@@ -668,10 +673,7 @@ static inline void
668perf_swcounter_event(u32 event, u64 nr, int nmi, 673perf_swcounter_event(u32 event, u64 nr, int nmi,
669 struct pt_regs *regs, u64 addr) { } 674 struct pt_regs *regs, u64 addr) { }
670 675
671static inline void 676static inline void perf_counter_mmap(struct vm_area_struct *vma) { }
672perf_counter_mmap(unsigned long addr, unsigned long len,
673 unsigned long pgoff, struct file *file) { }
674
675static inline void perf_counter_comm(struct task_struct *tsk) { } 677static inline void perf_counter_comm(struct task_struct *tsk) { }
676static inline void perf_counter_fork(struct task_struct *tsk) { } 678static inline void perf_counter_fork(struct task_struct *tsk) { }
677static inline void perf_counter_init(void) { } 679static 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
2257static void perf_output_copy(struct perf_output_handle *handle, 2257static 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
2683struct perf_mmap_event { 2683struct 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
2794void perf_counter_mmap(unsigned long addr, unsigned long len, 2805void __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
diff --git a/mm/mmap.c b/mm/mmap.c
index 6451ce2854b9..8101de490c73 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -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);
1222out: 1222out:
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