Skip to content

Commit c978b94

Browse files
author
Ingo Molnar
committed
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>
2 parents 0a15712 + de667cc commit c978b94

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1019
-429
lines changed

arch/x86/events/intel/pt.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,8 @@ static int pt_event_addr_filters_validate(struct list_head *filters)
12231223
static void pt_event_addr_filters_sync(struct perf_event *event)
12241224
{
12251225
struct perf_addr_filters_head *head = perf_event_addr_filters(event);
1226-
unsigned long msr_a, msr_b, *offs = event->addr_filters_offs;
1226+
unsigned long msr_a, msr_b;
1227+
struct perf_addr_filter_range *fr = event->addr_filter_ranges;
12271228
struct pt_filters *filters = event->hw.addr_filters;
12281229
struct perf_addr_filter *filter;
12291230
int range = 0;
@@ -1232,12 +1233,12 @@ static void pt_event_addr_filters_sync(struct perf_event *event)
12321233
return;
12331234

12341235
list_for_each_entry(filter, &head->list, entry) {
1235-
if (filter->path.dentry && !offs[range]) {
1236+
if (filter->path.dentry && !fr[range].start) {
12361237
msr_a = msr_b = 0;
12371238
} else {
12381239
/* apply the offset */
1239-
msr_a = filter->offset + offs[range];
1240-
msr_b = filter->size + msr_a - 1;
1240+
msr_a = fr[range].start;
1241+
msr_b = msr_a + fr[range].size - 1;
12411242
}
12421243

12431244
filters->filter[range].msr_a = msr_a;

drivers/hwtracing/coresight/coresight-etm-perf.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -433,15 +433,16 @@ static int etm_addr_filters_validate(struct list_head *filters)
433433
static void etm_addr_filters_sync(struct perf_event *event)
434434
{
435435
struct perf_addr_filters_head *head = perf_event_addr_filters(event);
436-
unsigned long start, stop, *offs = event->addr_filters_offs;
436+
unsigned long start, stop;
437+
struct perf_addr_filter_range *fr = event->addr_filter_ranges;
437438
struct etm_filters *filters = event->hw.addr_filters;
438439
struct etm_filter *etm_filter;
439440
struct perf_addr_filter *filter;
440441
int i = 0;
441442

442443
list_for_each_entry(filter, &head->list, entry) {
443-
start = filter->offset + offs[i];
444-
stop = start + filter->size;
444+
start = fr[i].start;
445+
stop = start + fr[i].size;
445446
etm_filter = &filters->etm_filter[i];
446447

447448
switch (filter->action) {

include/linux/perf_event.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,11 @@ struct perf_addr_filters_head {
495495
unsigned int nr_file_filters;
496496
};
497497

498+
struct perf_addr_filter_range {
499+
unsigned long start;
500+
unsigned long size;
501+
};
502+
498503
/**
499504
* enum perf_event_state - the states of an event:
500505
*/
@@ -671,7 +676,7 @@ struct perf_event {
671676
/* address range filters */
672677
struct perf_addr_filters_head addr_filters;
673678
/* vma address array for file-based filders */
674-
unsigned long *addr_filters_offs;
679+
struct perf_addr_filter_range *addr_filter_ranges;
675680
unsigned long addr_filters_gen;
676681

677682
void (*destroy)(struct perf_event *);

kernel/events/core.c

Lines changed: 59 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,7 @@ static void put_ctx(struct perf_event_context *ctx)
12551255
* perf_event_context::lock
12561256
* perf_event::mmap_mutex
12571257
* mmap_sem
1258+
* perf_addr_filters_head::lock
12581259
*
12591260
* cpu_hotplug_lock
12601261
* pmus_lock
@@ -2798,7 +2799,7 @@ static int perf_event_stop(struct perf_event *event, int restart)
27982799
*
27992800
* (p1) when userspace mappings change as a result of (1) or (2) or (3) below,
28002801
* 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;
28022803
* (p2) when an event is scheduled in (pmu::add), it calls
28032804
* perf_event_addr_filters_sync() which calls pmu::addr_filters_sync()
28042805
* if the generation has changed since the previous call.
@@ -4445,7 +4446,7 @@ static void _free_event(struct perf_event *event)
44454446

44464447
perf_event_free_bpf_prog(event);
44474448
perf_addr_filters_splice(event, NULL);
4448-
kfree(event->addr_filters_offs);
4449+
kfree(event->addr_filter_ranges);
44494450

44504451
if (event->destroy)
44514452
event->destroy(event);
@@ -6694,7 +6695,8 @@ static void perf_event_addr_filters_exec(struct perf_event *event, void *data)
66946695
raw_spin_lock_irqsave(&ifh->lock, flags);
66956696
list_for_each_entry(filter, &ifh->list, entry) {
66966697
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;
66986700
restart++;
66996701
}
67006702

@@ -7374,28 +7376,47 @@ static bool perf_addr_filter_match(struct perf_addr_filter *filter,
73747376
return true;
73757377
}
73767378

7379+
static 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+
73777401
static void __perf_addr_filters_adjust(struct perf_event *event, void *data)
73787402
{
73797403
struct perf_addr_filters_head *ifh = perf_event_addr_filters(event);
73807404
struct vm_area_struct *vma = data;
7381-
unsigned long off = vma->vm_pgoff << PAGE_SHIFT, flags;
7382-
struct file *file = vma->vm_file;
73837405
struct perf_addr_filter *filter;
73847406
unsigned int restart = 0, count = 0;
7407+
unsigned long flags;
73857408

73867409
if (!has_addr_filter(event))
73877410
return;
73887411

7389-
if (!file)
7412+
if (!vma->vm_file)
73907413
return;
73917414

73927415
raw_spin_lock_irqsave(&ifh->lock, flags);
73937416
list_for_each_entry(filter, &ifh->list, entry) {
7394-
if (perf_addr_filter_match(filter, file, off,
7395-
vma->vm_end - vma->vm_start)) {
7396-
event->addr_filters_offs[count] = vma->vm_start;
7417+
if (perf_addr_filter_vma_adjust(filter, vma,
7418+
&event->addr_filter_ranges[count]))
73977419
restart++;
7398-
}
73997420

74007421
count++;
74017422
}
@@ -8985,26 +9006,19 @@ static void perf_addr_filters_splice(struct perf_event *event,
89859006
* @filter; if so, adjust filter's address range.
89869007
* Called with mm::mmap_sem down for reading.
89879008
*/
8988-
static unsigned long perf_addr_filter_apply(struct perf_addr_filter *filter,
8989-
struct mm_struct *mm)
9009+
static void perf_addr_filter_apply(struct perf_addr_filter *filter,
9010+
struct mm_struct *mm,
9011+
struct perf_addr_filter_range *fr)
89909012
{
89919013
struct vm_area_struct *vma;
89929014

89939015
for (vma = mm->mmap; vma; vma = vma->vm_next) {
8994-
struct file *file = 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)
9016+
if (!vma->vm_file)
89999017
continue;
90009018

9001-
if (!perf_addr_filter_match(filter, file, off, vma_size))
9002-
continue;
9003-
9004-
return vma->vm_start;
9019+
if (perf_addr_filter_vma_adjust(filter, vma, fr))
9020+
return;
90059021
}
9006-
9007-
return 0;
90089022
}
90099023

90109024
/*
@@ -9038,15 +9052,15 @@ static void perf_event_addr_filters_apply(struct perf_event *event)
90389052

90399053
raw_spin_lock_irqsave(&ifh->lock, flags);
90409054
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;
90429057

90439058
/*
90449059
* Adjust base offset if the filter is associated to a binary
90459060
* that needs to be mapped:
90469061
*/
90479062
if (filter->path.dentry)
9048-
event->addr_filters_offs[count] =
9049-
perf_addr_filter_apply(filter, mm);
9063+
perf_addr_filter_apply(filter, mm, &event->addr_filter_ranges[count]);
90509064

90519065
count++;
90529066
}
@@ -10320,14 +10334,28 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
1032010334
goto err_pmu;
1032110335

1032210336
if (has_addr_filter(event)) {
10323-
event->addr_filters_offs = kcalloc(pmu->nr_addr_filters,
10324-
sizeof(unsigned long),
10325-
GFP_KERNEL);
10326-
if (!event->addr_filters_offs) {
10337+
event->addr_filter_ranges = kcalloc(pmu->nr_addr_filters,
10338+
sizeof(struct perf_addr_filter_range),
10339+
GFP_KERNEL);
10340+
if (!event->addr_filter_ranges) {
1032710341
err = -ENOMEM;
1032810342
goto err_per_task;
1032910343
}
1033010344

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+
1033110359
/* force hw sync on the address filters */
1033210360
event->addr_filters_gen = 1;
1033310361
}
@@ -10346,7 +10374,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
1034610374
return event;
1034710375

1034810376
err_addr_filters:
10349-
kfree(event->addr_filters_offs);
10377+
kfree(event->addr_filter_ranges);
1035010378

1035110379
err_per_task:
1035210380
exclusive_event_destroy(event);

tools/perf/builtin-annotate.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
441441
}
442442

443443
if (total_nr_samples == 0) {
444-
ui__error("The %s file has no samples!\n", session->data->file.path);
444+
ui__error("The %s data has no samples!\n", session->data->path);
445445
goto out;
446446
}
447447

@@ -578,7 +578,7 @@ int cmd_annotate(int argc, const char **argv)
578578
if (quiet)
579579
perf_quiet_option();
580580

581-
data.file.path = input_name;
581+
data.path = input_name;
582582

583583
annotate.session = perf_session__new(&data, false, &annotate.tool);
584584
if (annotate.session == NULL)

tools/perf/builtin-buildid-cache.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,8 +416,8 @@ int cmd_buildid_cache(int argc, const char **argv)
416416
nsi = nsinfo__new(ns_id);
417417

418418
if (missing_filename) {
419-
data.file.path = missing_filename;
420-
data.force = force;
419+
data.path = missing_filename;
420+
data.force = force;
421421

422422
session = perf_session__new(&data, false, NULL);
423423
if (session == NULL)

tools/perf/builtin-buildid-list.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,9 @@ static int perf_session__list_build_ids(bool force, bool with_hits)
5252
{
5353
struct perf_session *session;
5454
struct perf_data data = {
55-
.file = {
56-
.path = input_name,
57-
},
58-
.mode = PERF_DATA_MODE_READ,
59-
.force = force,
55+
.path = input_name,
56+
.mode = PERF_DATA_MODE_READ,
57+
.force = force,
6058
};
6159

6260
symbol__elf_init();

tools/perf/builtin-c2c.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2750,8 +2750,8 @@ static int perf_c2c__report(int argc, const char **argv)
27502750
if (!input_name || !strlen(input_name))
27512751
input_name = "perf.data";
27522752

2753-
data.file.path = input_name;
2754-
data.force = symbol_conf.force;
2753+
data.path = input_name;
2754+
data.force = symbol_conf.force;
27552755

27562756
err = setup_display(display);
27572757
if (err)

tools/perf/builtin-diff.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ static void data__fprintf(void)
708708

709709
data__for_each_file(i, d)
710710
fprintf(stdout, "# [%d] %s %s\n",
711-
d->idx, d->data.file.path,
711+
d->idx, d->data.path,
712712
!d->idx ? "(Baseline)" : "");
713713

714714
fprintf(stdout, "#\n");
@@ -779,14 +779,14 @@ static int __cmd_diff(void)
779779
data__for_each_file(i, d) {
780780
d->session = perf_session__new(&d->data, false, &tool);
781781
if (!d->session) {
782-
pr_err("Failed to open %s\n", d->data.file.path);
782+
pr_err("Failed to open %s\n", d->data.path);
783783
ret = -1;
784784
goto out_delete;
785785
}
786786

787787
ret = perf_session__process_events(d->session);
788788
if (ret) {
789-
pr_err("Failed to process %s\n", d->data.file.path);
789+
pr_err("Failed to process %s\n", d->data.path);
790790
goto out_delete;
791791
}
792792

@@ -1289,9 +1289,9 @@ static int data_init(int argc, const char **argv)
12891289
data__for_each_file(i, d) {
12901290
struct perf_data *data = &d->data;
12911291

1292-
data->file.path = use_default ? defaults[i] : argv[i];
1293-
data->mode = PERF_DATA_MODE_READ,
1294-
data->force = force,
1292+
data->path = use_default ? defaults[i] : argv[i];
1293+
data->mode = PERF_DATA_MODE_READ,
1294+
data->force = force,
12951295

12961296
d->idx = i;
12971297
}

tools/perf/builtin-evlist.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details
2323
struct perf_session *session;
2424
struct perf_evsel *pos;
2525
struct perf_data data = {
26-
.file = {
27-
.path = file_name,
28-
},
26+
.path = file_name,
2927
.mode = PERF_DATA_MODE_READ,
3028
.force = details->force,
3129
};

tools/perf/builtin-inject.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -770,10 +770,8 @@ int cmd_inject(int argc, const char **argv)
770770
.input_name = "-",
771771
.samples = LIST_HEAD_INIT(inject.samples),
772772
.output = {
773-
.file = {
774-
.path = "-",
775-
},
776-
.mode = PERF_DATA_MODE_WRITE,
773+
.path = "-",
774+
.mode = PERF_DATA_MODE_WRITE,
777775
},
778776
};
779777
struct perf_data data = {
@@ -786,7 +784,7 @@ int cmd_inject(int argc, const char **argv)
786784
"Inject build-ids into the output stream"),
787785
OPT_STRING('i', "input", &inject.input_name, "file",
788786
"input file name"),
789-
OPT_STRING('o', "output", &inject.output.file.path, "file",
787+
OPT_STRING('o', "output", &inject.output.path, "file",
790788
"output file name"),
791789
OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat,
792790
"Merge sched-stat and sched-switch for getting events "
@@ -834,7 +832,7 @@ int cmd_inject(int argc, const char **argv)
834832

835833
inject.tool.ordered_events = inject.sched_stat;
836834

837-
data.file.path = inject.input_name;
835+
data.path = inject.input_name;
838836
inject.session = perf_session__new(&data, true, &inject.tool);
839837
if (inject.session == NULL)
840838
return -1;

tools/perf/builtin-kmem.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1949,7 +1949,7 @@ int cmd_kmem(int argc, const char **argv)
19491949
return __cmd_record(argc, argv);
19501950
}
19511951

1952-
data.file.path = input_name;
1952+
data.path = input_name;
19531953

19541954
kmem_session = session = perf_session__new(&data, false, &perf_kmem);
19551955
if (session == NULL)

0 commit comments

Comments
 (0)