diff options
Diffstat (limited to 'kernel/events/core.c')
| -rw-r--r-- | kernel/events/core.c | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index 15d0f2418e54..c7ee497c39a7 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
| @@ -4776,7 +4776,7 @@ next: | |||
| 4776 | /* | 4776 | /* |
| 4777 | * task tracking -- fork/exit | 4777 | * task tracking -- fork/exit |
| 4778 | * | 4778 | * |
| 4779 | * enabled by: attr.comm | attr.mmap | attr.mmap_data | attr.task | 4779 | * enabled by: attr.comm | attr.mmap | attr.mmap2 | attr.mmap_data | attr.task |
| 4780 | */ | 4780 | */ |
| 4781 | 4781 | ||
| 4782 | struct perf_task_event { | 4782 | struct perf_task_event { |
| @@ -4796,8 +4796,9 @@ struct perf_task_event { | |||
| 4796 | 4796 | ||
| 4797 | static int perf_event_task_match(struct perf_event *event) | 4797 | static int perf_event_task_match(struct perf_event *event) |
| 4798 | { | 4798 | { |
| 4799 | return event->attr.comm || event->attr.mmap || | 4799 | return event->attr.comm || event->attr.mmap || |
| 4800 | event->attr.mmap_data || event->attr.task; | 4800 | event->attr.mmap2 || event->attr.mmap_data || |
| 4801 | event->attr.task; | ||
| 4801 | } | 4802 | } |
| 4802 | 4803 | ||
| 4803 | static void perf_event_task_output(struct perf_event *event, | 4804 | static void perf_event_task_output(struct perf_event *event, |
| @@ -4992,6 +4993,9 @@ struct perf_mmap_event { | |||
| 4992 | 4993 | ||
| 4993 | const char *file_name; | 4994 | const char *file_name; |
| 4994 | int file_size; | 4995 | int file_size; |
| 4996 | int maj, min; | ||
| 4997 | u64 ino; | ||
| 4998 | u64 ino_generation; | ||
| 4995 | 4999 | ||
| 4996 | struct { | 5000 | struct { |
| 4997 | struct perf_event_header header; | 5001 | struct perf_event_header header; |
| @@ -5012,7 +5016,7 @@ static int perf_event_mmap_match(struct perf_event *event, | |||
| 5012 | int executable = vma->vm_flags & VM_EXEC; | 5016 | int executable = vma->vm_flags & VM_EXEC; |
| 5013 | 5017 | ||
| 5014 | return (!executable && event->attr.mmap_data) || | 5018 | return (!executable && event->attr.mmap_data) || |
| 5015 | (executable && event->attr.mmap); | 5019 | (executable && (event->attr.mmap || event->attr.mmap2)); |
| 5016 | } | 5020 | } |
| 5017 | 5021 | ||
| 5018 | static void perf_event_mmap_output(struct perf_event *event, | 5022 | static void perf_event_mmap_output(struct perf_event *event, |
| @@ -5027,6 +5031,13 @@ static void perf_event_mmap_output(struct perf_event *event, | |||
| 5027 | if (!perf_event_mmap_match(event, data)) | 5031 | if (!perf_event_mmap_match(event, data)) |
| 5028 | return; | 5032 | return; |
| 5029 | 5033 | ||
| 5034 | if (event->attr.mmap2) { | ||
| 5035 | mmap_event->event_id.header.type = PERF_RECORD_MMAP2; | ||
| 5036 | mmap_event->event_id.header.size += sizeof(mmap_event->maj); | ||
| 5037 | mmap_event->event_id.header.size += sizeof(mmap_event->min); | ||
| 5038 | mmap_event->event_id.header.size += sizeof(mmap_event->ino); | ||
| 5039 | } | ||
| 5040 | |||
| 5030 | perf_event_header__init_id(&mmap_event->event_id.header, &sample, event); | 5041 | perf_event_header__init_id(&mmap_event->event_id.header, &sample, event); |
| 5031 | ret = perf_output_begin(&handle, event, | 5042 | ret = perf_output_begin(&handle, event, |
| 5032 | mmap_event->event_id.header.size); | 5043 | mmap_event->event_id.header.size); |
| @@ -5037,6 +5048,14 @@ static void perf_event_mmap_output(struct perf_event *event, | |||
| 5037 | mmap_event->event_id.tid = perf_event_tid(event, current); | 5048 | mmap_event->event_id.tid = perf_event_tid(event, current); |
| 5038 | 5049 | ||
| 5039 | perf_output_put(&handle, mmap_event->event_id); | 5050 | perf_output_put(&handle, mmap_event->event_id); |
| 5051 | |||
| 5052 | if (event->attr.mmap2) { | ||
| 5053 | perf_output_put(&handle, mmap_event->maj); | ||
| 5054 | perf_output_put(&handle, mmap_event->min); | ||
| 5055 | perf_output_put(&handle, mmap_event->ino); | ||
| 5056 | perf_output_put(&handle, mmap_event->ino_generation); | ||
| 5057 | } | ||
| 5058 | |||
| 5040 | __output_copy(&handle, mmap_event->file_name, | 5059 | __output_copy(&handle, mmap_event->file_name, |
| 5041 | mmap_event->file_size); | 5060 | mmap_event->file_size); |
| 5042 | 5061 | ||
| @@ -5051,6 +5070,8 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) | |||
| 5051 | { | 5070 | { |
| 5052 | struct vm_area_struct *vma = mmap_event->vma; | 5071 | struct vm_area_struct *vma = mmap_event->vma; |
| 5053 | struct file *file = vma->vm_file; | 5072 | struct file *file = vma->vm_file; |
| 5073 | int maj = 0, min = 0; | ||
| 5074 | u64 ino = 0, gen = 0; | ||
| 5054 | unsigned int size; | 5075 | unsigned int size; |
| 5055 | char tmp[16]; | 5076 | char tmp[16]; |
| 5056 | char *buf = NULL; | 5077 | char *buf = NULL; |
| @@ -5059,6 +5080,8 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) | |||
| 5059 | memset(tmp, 0, sizeof(tmp)); | 5080 | memset(tmp, 0, sizeof(tmp)); |
| 5060 | 5081 | ||
| 5061 | if (file) { | 5082 | if (file) { |
| 5083 | struct inode *inode; | ||
| 5084 | dev_t dev; | ||
| 5062 | /* | 5085 | /* |
| 5063 | * d_path works from the end of the rb backwards, so we | 5086 | * d_path works from the end of the rb backwards, so we |
| 5064 | * need to add enough zero bytes after the string to handle | 5087 | * need to add enough zero bytes after the string to handle |
| @@ -5074,6 +5097,13 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) | |||
| 5074 | name = strncpy(tmp, "//toolong", sizeof(tmp)); | 5097 | name = strncpy(tmp, "//toolong", sizeof(tmp)); |
| 5075 | goto got_name; | 5098 | goto got_name; |
| 5076 | } | 5099 | } |
| 5100 | inode = file_inode(vma->vm_file); | ||
| 5101 | dev = inode->i_sb->s_dev; | ||
| 5102 | ino = inode->i_ino; | ||
| 5103 | gen = inode->i_generation; | ||
| 5104 | maj = MAJOR(dev); | ||
| 5105 | min = MINOR(dev); | ||
| 5106 | |||
| 5077 | } else { | 5107 | } else { |
| 5078 | if (arch_vma_name(mmap_event->vma)) { | 5108 | if (arch_vma_name(mmap_event->vma)) { |
| 5079 | name = strncpy(tmp, arch_vma_name(mmap_event->vma), | 5109 | name = strncpy(tmp, arch_vma_name(mmap_event->vma), |
| @@ -5104,6 +5134,10 @@ got_name: | |||
| 5104 | 5134 | ||
| 5105 | mmap_event->file_name = name; | 5135 | mmap_event->file_name = name; |
| 5106 | mmap_event->file_size = size; | 5136 | mmap_event->file_size = size; |
| 5137 | mmap_event->maj = maj; | ||
| 5138 | mmap_event->min = min; | ||
| 5139 | mmap_event->ino = ino; | ||
| 5140 | mmap_event->ino_generation = gen; | ||
| 5107 | 5141 | ||
| 5108 | if (!(vma->vm_flags & VM_EXEC)) | 5142 | if (!(vma->vm_flags & VM_EXEC)) |
| 5109 | mmap_event->event_id.header.misc |= PERF_RECORD_MISC_MMAP_DATA; | 5143 | mmap_event->event_id.header.misc |= PERF_RECORD_MISC_MMAP_DATA; |
| @@ -5140,6 +5174,10 @@ void perf_event_mmap(struct vm_area_struct *vma) | |||
| 5140 | .len = vma->vm_end - vma->vm_start, | 5174 | .len = vma->vm_end - vma->vm_start, |
| 5141 | .pgoff = (u64)vma->vm_pgoff << PAGE_SHIFT, | 5175 | .pgoff = (u64)vma->vm_pgoff << PAGE_SHIFT, |
| 5142 | }, | 5176 | }, |
| 5177 | /* .maj (attr_mmap2 only) */ | ||
| 5178 | /* .min (attr_mmap2 only) */ | ||
| 5179 | /* .ino (attr_mmap2 only) */ | ||
| 5180 | /* .ino_generation (attr_mmap2 only) */ | ||
| 5143 | }; | 5181 | }; |
| 5144 | 5182 | ||
| 5145 | perf_event_mmap_event(&mmap_event); | 5183 | perf_event_mmap_event(&mmap_event); |
