aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2019-02-28 02:29:50 -0500
committerIngo Molnar <mingo@kernel.org>2019-02-28 02:29:50 -0500
commitc978b9460fe1d4a1e1effa0abd6bd69b18a098a8 (patch)
treeeecc4c6179dea191c55ac8ef50467573b29a0b06 /kernel
parent0a1571243d3f150fa99c6f41f1b8e17a307a2b8b (diff)
parentde667cce7f4f96b6e22da8fd9c065b961f355080 (diff)
Merge tag 'perf-core-for-mingo-5.1-20190225' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: perf annotate: Wei Li: - Fix getting source line failure perf script: Andi Kleen: - Handle missing fields with -F +... perf data: Jiri Olsa: - Prep work to support per-cpu files in a directory. Intel PT: Adrian Hunter: - Improve thread_stack__no_call_return() - Hide x86 retpolines in thread stacks. - exported SQL viewer refactorings, new 'top calls' report.. Alexander Shishkin: - Copy parent's address filter offsets on clone - Fix address filters for vmas with non-zero offset. Applies to ARM's CoreSight as well. python scripts: Tony Jones: - Python3 support for several 'perf script' python scripts. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/events/core.c90
1 files changed, 59 insertions, 31 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 932babd9e86c..5f59d848171e 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -1255,6 +1255,7 @@ static void put_ctx(struct perf_event_context *ctx)
1255 * perf_event_context::lock 1255 * perf_event_context::lock
1256 * perf_event::mmap_mutex 1256 * perf_event::mmap_mutex
1257 * mmap_sem 1257 * mmap_sem
1258 * perf_addr_filters_head::lock
1258 * 1259 *
1259 * cpu_hotplug_lock 1260 * cpu_hotplug_lock
1260 * pmus_lock 1261 * pmus_lock
@@ -2798,7 +2799,7 @@ static int perf_event_stop(struct perf_event *event, int restart)
2798 * 2799 *
2799 * (p1) when userspace mappings change as a result of (1) or (2) or (3) below, 2800 * (p1) when userspace mappings change as a result of (1) or (2) or (3) below,
2800 * we update the addresses of corresponding vmas in 2801 * we update the addresses of corresponding vmas in
2801 * event::addr_filters_offs array and bump the event::addr_filters_gen; 2802 * event::addr_filter_ranges array and bump the event::addr_filters_gen;
2802 * (p2) when an event is scheduled in (pmu::add), it calls 2803 * (p2) when an event is scheduled in (pmu::add), it calls
2803 * perf_event_addr_filters_sync() which calls pmu::addr_filters_sync() 2804 * perf_event_addr_filters_sync() which calls pmu::addr_filters_sync()
2804 * if the generation has changed since the previous call. 2805 * if the generation has changed since the previous call.
@@ -4445,7 +4446,7 @@ static void _free_event(struct perf_event *event)
4445 4446
4446 perf_event_free_bpf_prog(event); 4447 perf_event_free_bpf_prog(event);
4447 perf_addr_filters_splice(event, NULL); 4448 perf_addr_filters_splice(event, NULL);
4448 kfree(event->addr_filters_offs); 4449 kfree(event->addr_filter_ranges);
4449 4450
4450 if (event->destroy) 4451 if (event->destroy)
4451 event->destroy(event); 4452 event->destroy(event);
@@ -6694,7 +6695,8 @@ static void perf_event_addr_filters_exec(struct perf_event *event, void *data)
6694 raw_spin_lock_irqsave(&ifh->lock, flags); 6695 raw_spin_lock_irqsave(&ifh->lock, flags);
6695 list_for_each_entry(filter, &ifh->list, entry) { 6696 list_for_each_entry(filter, &ifh->list, entry) {
6696 if (filter->path.dentry) { 6697 if (filter->path.dentry) {
6697 event->addr_filters_offs[count] = 0; 6698 event->addr_filter_ranges[count].start = 0;
6699 event->addr_filter_ranges[count].size = 0;
6698 restart++; 6700 restart++;
6699 } 6701 }
6700 6702
@@ -7374,28 +7376,47 @@ static bool perf_addr_filter_match(struct perf_addr_filter *filter,
7374 return true; 7376 return true;
7375} 7377}
7376 7378
7379static bool perf_addr_filter_vma_adjust(struct perf_addr_filter *filter,
7380 struct vm_area_struct *vma,
7381 struct perf_addr_filter_range *fr)
7382{
7383 unsigned long vma_size = vma->vm_end - vma->vm_start;
7384 unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
7385 struct file *file = vma->vm_file;
7386
7387 if (!perf_addr_filter_match(filter, file, off, vma_size))
7388 return false;
7389
7390 if (filter->offset < off) {
7391 fr->start = vma->vm_start;
7392 fr->size = min(vma_size, filter->size - (off - filter->offset));
7393 } else {
7394 fr->start = vma->vm_start + filter->offset - off;
7395 fr->size = min(vma->vm_end - fr->start, filter->size);
7396 }
7397
7398 return true;
7399}
7400
7377static void __perf_addr_filters_adjust(struct perf_event *event, void *data) 7401static void __perf_addr_filters_adjust(struct perf_event *event, void *data)
7378{ 7402{
7379 struct perf_addr_filters_head *ifh = perf_event_addr_filters(event); 7403 struct perf_addr_filters_head *ifh = perf_event_addr_filters(event);
7380 struct vm_area_struct *vma = data; 7404 struct vm_area_struct *vma = data;
7381 unsigned long off = vma->vm_pgoff << PAGE_SHIFT, flags;
7382 struct file *file = vma->vm_file;
7383 struct perf_addr_filter *filter; 7405 struct perf_addr_filter *filter;
7384 unsigned int restart = 0, count = 0; 7406 unsigned int restart = 0, count = 0;
7407 unsigned long flags;
7385 7408
7386 if (!has_addr_filter(event)) 7409 if (!has_addr_filter(event))
7387 return; 7410 return;
7388 7411
7389 if (!file) 7412 if (!vma->vm_file)
7390 return; 7413 return;
7391 7414
7392 raw_spin_lock_irqsave(&ifh->lock, flags); 7415 raw_spin_lock_irqsave(&ifh->lock, flags);
7393 list_for_each_entry(filter, &ifh->list, entry) { 7416 list_for_each_entry(filter, &ifh->list, entry) {
7394 if (perf_addr_filter_match(filter, file, off, 7417 if (perf_addr_filter_vma_adjust(filter, vma,
7395 vma->vm_end - vma->vm_start)) { 7418 &event->addr_filter_ranges[count]))
7396 event->addr_filters_offs[count] = vma->vm_start;
7397 restart++; 7419 restart++;
7398 }
7399 7420
7400 count++; 7421 count++;
7401 } 7422 }
@@ -8985,26 +9006,19 @@ static void perf_addr_filters_splice(struct perf_event *event,
8985 * @filter; if so, adjust filter's address range. 9006 * @filter; if so, adjust filter's address range.
8986 * Called with mm::mmap_sem down for reading. 9007 * Called with mm::mmap_sem down for reading.
8987 */ 9008 */
8988static unsigned long perf_addr_filter_apply(struct perf_addr_filter *filter, 9009static void perf_addr_filter_apply(struct perf_addr_filter *filter,
8989 struct mm_struct *mm) 9010 struct mm_struct *mm,
9011 struct perf_addr_filter_range *fr)
8990{ 9012{
8991 struct vm_area_struct *vma; 9013 struct vm_area_struct *vma;
8992 9014
8993 for (vma = mm->mmap; vma; vma = vma->vm_next) { 9015 for (vma = mm->mmap; vma; vma = vma->vm_next) {
8994 struct file *file = vma->vm_file; 9016 if (!vma->vm_file)
8995 unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
8996 unsigned long vma_size = vma->vm_end - vma->vm_start;
8997
8998 if (!file)
8999 continue; 9017 continue;
9000 9018
9001 if (!perf_addr_filter_match(filter, file, off, vma_size)) 9019 if (perf_addr_filter_vma_adjust(filter, vma, fr))
9002 continue; 9020 return;
9003
9004 return vma->vm_start;
9005 } 9021 }
9006
9007 return 0;
9008} 9022}
9009 9023
9010/* 9024/*
@@ -9038,15 +9052,15 @@ static void perf_event_addr_filters_apply(struct perf_event *event)
9038 9052
9039 raw_spin_lock_irqsave(&ifh->lock, flags); 9053 raw_spin_lock_irqsave(&ifh->lock, flags);
9040 list_for_each_entry(filter, &ifh->list, entry) { 9054 list_for_each_entry(filter, &ifh->list, entry) {
9041 event->addr_filters_offs[count] = 0; 9055 event->addr_filter_ranges[count].start = 0;
9056 event->addr_filter_ranges[count].size = 0;
9042 9057
9043 /* 9058 /*
9044 * Adjust base offset if the filter is associated to a binary 9059 * Adjust base offset if the filter is associated to a binary
9045 * that needs to be mapped: 9060 * that needs to be mapped:
9046 */ 9061 */
9047 if (filter->path.dentry) 9062 if (filter->path.dentry)
9048 event->addr_filters_offs[count] = 9063 perf_addr_filter_apply(filter, mm, &event->addr_filter_ranges[count]);
9049 perf_addr_filter_apply(filter, mm);
9050 9064
9051 count++; 9065 count++;
9052 } 9066 }
@@ -10320,14 +10334,28 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
10320 goto err_pmu; 10334 goto err_pmu;
10321 10335
10322 if (has_addr_filter(event)) { 10336 if (has_addr_filter(event)) {
10323 event->addr_filters_offs = kcalloc(pmu->nr_addr_filters, 10337 event->addr_filter_ranges = kcalloc(pmu->nr_addr_filters,
10324 sizeof(unsigned long), 10338 sizeof(struct perf_addr_filter_range),
10325 GFP_KERNEL); 10339 GFP_KERNEL);
10326 if (!event->addr_filters_offs) { 10340 if (!event->addr_filter_ranges) {
10327 err = -ENOMEM; 10341 err = -ENOMEM;
10328 goto err_per_task; 10342 goto err_per_task;
10329 } 10343 }
10330 10344
10345 /*
10346 * Clone the parent's vma offsets: they are valid until exec()
10347 * even if the mm is not shared with the parent.
10348 */
10349 if (event->parent) {
10350 struct perf_addr_filters_head *ifh = perf_event_addr_filters(event);
10351
10352 raw_spin_lock_irq(&ifh->lock);
10353 memcpy(event->addr_filter_ranges,
10354 event->parent->addr_filter_ranges,
10355 pmu->nr_addr_filters * sizeof(struct perf_addr_filter_range));
10356 raw_spin_unlock_irq(&ifh->lock);
10357 }
10358
10331 /* force hw sync on the address filters */ 10359 /* force hw sync on the address filters */
10332 event->addr_filters_gen = 1; 10360 event->addr_filters_gen = 1;
10333 } 10361 }
@@ -10346,7 +10374,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
10346 return event; 10374 return event;
10347 10375
10348err_addr_filters: 10376err_addr_filters:
10349 kfree(event->addr_filters_offs); 10377 kfree(event->addr_filter_ranges);
10350 10378
10351err_per_task: 10379err_per_task:
10352 exclusive_event_destroy(event); 10380 exclusive_event_destroy(event);