diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-25 20:53:09 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-25 20:53:09 -0400 |
| commit | 2a20b02c055a14eb60ac8da737d79dc940bb9ee0 (patch) | |
| tree | 1cf09a5e13f8ed24bc66386c153969ad49f8f098 /tools | |
| parent | 839767e79e7bdf06f241a47701f0f64b8e2d3f61 (diff) | |
| parent | 45daae575e08bbf7405c5a3633e956fa364d1b4f (diff) | |
Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
perf, x86: Complain louder about BIOSen corrupting CPU/PMU state and continue
perf, x86: P4 PMU - Read proper MSR register to catch unflagged overflows
perf symbols: Look at .dynsym again if .symtab not found
perf build-id: Add quirk to deal with perf.data file format breakage
perf session: Pass evsel in event_ops->sample()
perf: Better fit max unprivileged mlock pages for tools needs
perf_events: Fix stale ->cgrp pointer in update_cgrp_time_from_cpuctx()
perf top: Fix uninitialized 'counter' variable
tracing: Fix set_ftrace_filter probe function display
perf, x86: Fix Intel fixed counters base initialization
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/perf/builtin-annotate.c | 18 | ||||
| -rw-r--r-- | tools/perf/builtin-diff.c | 1 | ||||
| -rw-r--r-- | tools/perf/builtin-inject.c | 11 | ||||
| -rw-r--r-- | tools/perf/builtin-kmem.c | 1 | ||||
| -rw-r--r-- | tools/perf/builtin-lock.c | 4 | ||||
| -rw-r--r-- | tools/perf/builtin-report.c | 19 | ||||
| -rw-r--r-- | tools/perf/builtin-sched.c | 1 | ||||
| -rw-r--r-- | tools/perf/builtin-script.c | 15 | ||||
| -rw-r--r-- | tools/perf/builtin-timechart.c | 11 | ||||
| -rw-r--r-- | tools/perf/builtin-top.c | 4 | ||||
| -rw-r--r-- | tools/perf/util/build-id.c | 1 | ||||
| -rw-r--r-- | tools/perf/util/header.c | 57 | ||||
| -rw-r--r-- | tools/perf/util/hist.h | 1 | ||||
| -rw-r--r-- | tools/perf/util/scripting-engines/trace-event-perl.c | 1 | ||||
| -rw-r--r-- | tools/perf/util/scripting-engines/trace-event-python.c | 1 | ||||
| -rw-r--r-- | tools/perf/util/session.c | 25 | ||||
| -rw-r--r-- | tools/perf/util/session.h | 7 | ||||
| -rw-r--r-- | tools/perf/util/symbol.c | 25 | ||||
| -rw-r--r-- | tools/perf/util/trace-event-scripting.c | 1 | ||||
| -rw-r--r-- | tools/perf/util/trace-event.h | 1 |
20 files changed, 145 insertions, 60 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 695de4b5ae63..e18eb7ed30ae 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -42,9 +42,9 @@ static const char *sym_hist_filter; | |||
| 42 | 42 | ||
| 43 | static int perf_evlist__add_sample(struct perf_evlist *evlist, | 43 | static int perf_evlist__add_sample(struct perf_evlist *evlist, |
| 44 | struct perf_sample *sample, | 44 | struct perf_sample *sample, |
| 45 | struct perf_evsel *evsel, | ||
| 45 | struct addr_location *al) | 46 | struct addr_location *al) |
| 46 | { | 47 | { |
| 47 | struct perf_evsel *evsel; | ||
| 48 | struct hist_entry *he; | 48 | struct hist_entry *he; |
| 49 | int ret; | 49 | int ret; |
| 50 | 50 | ||
| @@ -59,18 +59,6 @@ static int perf_evlist__add_sample(struct perf_evlist *evlist, | |||
| 59 | return 0; | 59 | return 0; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | evsel = perf_evlist__id2evsel(evlist, sample->id); | ||
| 63 | if (evsel == NULL) { | ||
| 64 | /* | ||
| 65 | * FIXME: Propagate this back, but at least we're in a builtin, | ||
| 66 | * where exit() is allowed. ;-) | ||
| 67 | */ | ||
| 68 | ui__warning("Invalid %s file, contains samples with id not in " | ||
| 69 | "its header!\n", input_name); | ||
| 70 | exit_browser(0); | ||
| 71 | exit(1); | ||
| 72 | } | ||
| 73 | |||
| 74 | he = __hists__add_entry(&evsel->hists, al, NULL, 1); | 62 | he = __hists__add_entry(&evsel->hists, al, NULL, 1); |
| 75 | if (he == NULL) | 63 | if (he == NULL) |
| 76 | return -ENOMEM; | 64 | return -ENOMEM; |
| @@ -92,6 +80,7 @@ static int perf_evlist__add_sample(struct perf_evlist *evlist, | |||
| 92 | 80 | ||
| 93 | static int process_sample_event(union perf_event *event, | 81 | static int process_sample_event(union perf_event *event, |
| 94 | struct perf_sample *sample, | 82 | struct perf_sample *sample, |
| 83 | struct perf_evsel *evsel, | ||
| 95 | struct perf_session *session) | 84 | struct perf_session *session) |
| 96 | { | 85 | { |
| 97 | struct addr_location al; | 86 | struct addr_location al; |
| @@ -103,7 +92,8 @@ static int process_sample_event(union perf_event *event, | |||
| 103 | return -1; | 92 | return -1; |
| 104 | } | 93 | } |
| 105 | 94 | ||
| 106 | if (!al.filtered && perf_evlist__add_sample(session->evlist, sample, &al)) { | 95 | if (!al.filtered && |
| 96 | perf_evlist__add_sample(session->evlist, sample, evsel, &al)) { | ||
| 107 | pr_warning("problem incrementing symbol count, " | 97 | pr_warning("problem incrementing symbol count, " |
| 108 | "skipping event\n"); | 98 | "skipping event\n"); |
| 109 | return -1; | 99 | return -1; |
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 6b7d91160ecb..e8219990f8b8 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
| @@ -32,6 +32,7 @@ static int hists__add_entry(struct hists *self, | |||
| 32 | 32 | ||
| 33 | static int diff__process_sample_event(union perf_event *event, | 33 | static int diff__process_sample_event(union perf_event *event, |
| 34 | struct perf_sample *sample, | 34 | struct perf_sample *sample, |
| 35 | struct perf_evsel *evsel __used, | ||
| 35 | struct perf_session *session) | 36 | struct perf_session *session) |
| 36 | { | 37 | { |
| 37 | struct addr_location al; | 38 | struct addr_location al; |
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index e29f04ed3396..8dfc12bb119b 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c | |||
| @@ -43,6 +43,14 @@ static int perf_event__repipe(union perf_event *event, | |||
| 43 | return perf_event__repipe_synth(event, session); | 43 | return perf_event__repipe_synth(event, session); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | static int perf_event__repipe_sample(union perf_event *event, | ||
| 47 | struct perf_sample *sample __used, | ||
| 48 | struct perf_evsel *evsel __used, | ||
| 49 | struct perf_session *session) | ||
| 50 | { | ||
| 51 | return perf_event__repipe_synth(event, session); | ||
| 52 | } | ||
| 53 | |||
| 46 | static int perf_event__repipe_mmap(union perf_event *event, | 54 | static int perf_event__repipe_mmap(union perf_event *event, |
| 47 | struct perf_sample *sample, | 55 | struct perf_sample *sample, |
| 48 | struct perf_session *session) | 56 | struct perf_session *session) |
| @@ -124,6 +132,7 @@ static int dso__inject_build_id(struct dso *self, struct perf_session *session) | |||
| 124 | 132 | ||
| 125 | static int perf_event__inject_buildid(union perf_event *event, | 133 | static int perf_event__inject_buildid(union perf_event *event, |
| 126 | struct perf_sample *sample, | 134 | struct perf_sample *sample, |
| 135 | struct perf_evsel *evsel __used, | ||
| 127 | struct perf_session *session) | 136 | struct perf_session *session) |
| 128 | { | 137 | { |
| 129 | struct addr_location al; | 138 | struct addr_location al; |
| @@ -164,7 +173,7 @@ repipe: | |||
| 164 | } | 173 | } |
| 165 | 174 | ||
| 166 | struct perf_event_ops inject_ops = { | 175 | struct perf_event_ops inject_ops = { |
| 167 | .sample = perf_event__repipe, | 176 | .sample = perf_event__repipe_sample, |
| 168 | .mmap = perf_event__repipe, | 177 | .mmap = perf_event__repipe, |
| 169 | .comm = perf_event__repipe, | 178 | .comm = perf_event__repipe, |
| 170 | .fork = perf_event__repipe, | 179 | .fork = perf_event__repipe, |
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 7f618f4e7b79..225e963df105 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c | |||
| @@ -305,6 +305,7 @@ static void process_raw_event(union perf_event *raw_event __used, void *data, | |||
| 305 | 305 | ||
| 306 | static int process_sample_event(union perf_event *event, | 306 | static int process_sample_event(union perf_event *event, |
| 307 | struct perf_sample *sample, | 307 | struct perf_sample *sample, |
| 308 | struct perf_evsel *evsel __used, | ||
| 308 | struct perf_session *session) | 309 | struct perf_session *session) |
| 309 | { | 310 | { |
| 310 | struct thread *thread = perf_session__findnew(session, event->ip.pid); | 311 | struct thread *thread = perf_session__findnew(session, event->ip.pid); |
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 7a2a79d2cf2c..9ac05aafd9b2 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c | |||
| @@ -845,7 +845,9 @@ static void dump_info(void) | |||
| 845 | die("Unknown type of information\n"); | 845 | die("Unknown type of information\n"); |
| 846 | } | 846 | } |
| 847 | 847 | ||
| 848 | static int process_sample_event(union perf_event *event, struct perf_sample *sample, | 848 | static int process_sample_event(union perf_event *event, |
| 849 | struct perf_sample *sample, | ||
| 850 | struct perf_evsel *evsel __used, | ||
| 849 | struct perf_session *s) | 851 | struct perf_session *s) |
| 850 | { | 852 | { |
| 851 | struct thread *thread = perf_session__findnew(s, sample->tid); | 853 | struct thread *thread = perf_session__findnew(s, sample->tid); |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index b1b82009ab9b..498c6f70a747 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -50,12 +50,12 @@ static symbol_filter_t annotate_init; | |||
| 50 | 50 | ||
| 51 | static int perf_session__add_hist_entry(struct perf_session *session, | 51 | static int perf_session__add_hist_entry(struct perf_session *session, |
| 52 | struct addr_location *al, | 52 | struct addr_location *al, |
| 53 | struct perf_sample *sample) | 53 | struct perf_sample *sample, |
| 54 | struct perf_evsel *evsel) | ||
| 54 | { | 55 | { |
| 55 | struct symbol *parent = NULL; | 56 | struct symbol *parent = NULL; |
| 56 | int err = 0; | 57 | int err = 0; |
| 57 | struct hist_entry *he; | 58 | struct hist_entry *he; |
| 58 | struct perf_evsel *evsel; | ||
| 59 | 59 | ||
| 60 | if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { | 60 | if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { |
| 61 | err = perf_session__resolve_callchain(session, al->thread, | 61 | err = perf_session__resolve_callchain(session, al->thread, |
| @@ -64,18 +64,6 @@ static int perf_session__add_hist_entry(struct perf_session *session, | |||
| 64 | return err; | 64 | return err; |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | evsel = perf_evlist__id2evsel(session->evlist, sample->id); | ||
| 68 | if (evsel == NULL) { | ||
| 69 | /* | ||
| 70 | * FIXME: Propagate this back, but at least we're in a builtin, | ||
| 71 | * where exit() is allowed. ;-) | ||
| 72 | */ | ||
| 73 | ui__warning("Invalid %s file, contains samples with id %" PRIu64 " not in " | ||
| 74 | "its header!\n", input_name, sample->id); | ||
| 75 | exit_browser(0); | ||
| 76 | exit(1); | ||
| 77 | } | ||
| 78 | |||
| 79 | he = __hists__add_entry(&evsel->hists, al, parent, sample->period); | 67 | he = __hists__add_entry(&evsel->hists, al, parent, sample->period); |
| 80 | if (he == NULL) | 68 | if (he == NULL) |
| 81 | return -ENOMEM; | 69 | return -ENOMEM; |
| @@ -113,6 +101,7 @@ out: | |||
| 113 | 101 | ||
| 114 | static int process_sample_event(union perf_event *event, | 102 | static int process_sample_event(union perf_event *event, |
| 115 | struct perf_sample *sample, | 103 | struct perf_sample *sample, |
| 104 | struct perf_evsel *evsel, | ||
| 116 | struct perf_session *session) | 105 | struct perf_session *session) |
| 117 | { | 106 | { |
| 118 | struct addr_location al; | 107 | struct addr_location al; |
| @@ -127,7 +116,7 @@ static int process_sample_event(union perf_event *event, | |||
| 127 | if (al.filtered || (hide_unresolved && al.sym == NULL)) | 116 | if (al.filtered || (hide_unresolved && al.sym == NULL)) |
| 128 | return 0; | 117 | return 0; |
| 129 | 118 | ||
| 130 | if (perf_session__add_hist_entry(session, &al, sample)) { | 119 | if (perf_session__add_hist_entry(session, &al, sample, evsel)) { |
| 131 | pr_debug("problem incrementing symbol period, skipping event\n"); | 120 | pr_debug("problem incrementing symbol period, skipping event\n"); |
| 132 | return -1; | 121 | return -1; |
| 133 | } | 122 | } |
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index a32f411faeac..dcfe8873c9a1 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
| @@ -1603,6 +1603,7 @@ static void process_raw_event(union perf_event *raw_event __used, | |||
| 1603 | 1603 | ||
| 1604 | static int process_sample_event(union perf_event *event, | 1604 | static int process_sample_event(union perf_event *event, |
| 1605 | struct perf_sample *sample, | 1605 | struct perf_sample *sample, |
| 1606 | struct perf_evsel *evsel __used, | ||
| 1606 | struct perf_session *session) | 1607 | struct perf_session *session) |
| 1607 | { | 1608 | { |
| 1608 | struct thread *thread; | 1609 | struct thread *thread; |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 9f5fc5492141..ac574ea23917 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
| @@ -162,19 +162,11 @@ static void print_sample_start(struct perf_sample *sample, | |||
| 162 | 162 | ||
| 163 | static void process_event(union perf_event *event __unused, | 163 | static void process_event(union perf_event *event __unused, |
| 164 | struct perf_sample *sample, | 164 | struct perf_sample *sample, |
| 165 | struct perf_evsel *evsel, | ||
| 165 | struct perf_session *session, | 166 | struct perf_session *session, |
| 166 | struct thread *thread) | 167 | struct thread *thread) |
| 167 | { | 168 | { |
| 168 | struct perf_event_attr *attr; | 169 | struct perf_event_attr *attr = &evsel->attr; |
| 169 | struct perf_evsel *evsel; | ||
| 170 | |||
| 171 | evsel = perf_evlist__id2evsel(session->evlist, sample->id); | ||
| 172 | if (evsel == NULL) { | ||
| 173 | pr_err("Invalid data. Contains samples with id not in " | ||
| 174 | "its header!\n"); | ||
| 175 | return; | ||
| 176 | } | ||
| 177 | attr = &evsel->attr; | ||
| 178 | 170 | ||
| 179 | if (output_fields[attr->type] == 0) | 171 | if (output_fields[attr->type] == 0) |
| 180 | return; | 172 | return; |
| @@ -244,6 +236,7 @@ static char const *input_name = "perf.data"; | |||
| 244 | 236 | ||
| 245 | static int process_sample_event(union perf_event *event, | 237 | static int process_sample_event(union perf_event *event, |
| 246 | struct perf_sample *sample, | 238 | struct perf_sample *sample, |
| 239 | struct perf_evsel *evsel, | ||
| 247 | struct perf_session *session) | 240 | struct perf_session *session) |
| 248 | { | 241 | { |
| 249 | struct thread *thread = perf_session__findnew(session, event->ip.pid); | 242 | struct thread *thread = perf_session__findnew(session, event->ip.pid); |
| @@ -264,7 +257,7 @@ static int process_sample_event(union perf_event *event, | |||
| 264 | last_timestamp = sample->time; | 257 | last_timestamp = sample->time; |
| 265 | return 0; | 258 | return 0; |
| 266 | } | 259 | } |
| 267 | scripting_ops->process_event(event, sample, session, thread); | 260 | scripting_ops->process_event(event, sample, evsel, session, thread); |
| 268 | 261 | ||
| 269 | session->hists.stats.total_period += sample->period; | 262 | session->hists.stats.total_period += sample->period; |
| 270 | return 0; | 263 | return 0; |
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 67c0459dc325..aa26f4d66d10 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c | |||
| @@ -488,6 +488,7 @@ static void sched_switch(int cpu, u64 timestamp, struct trace_entry *te) | |||
| 488 | 488 | ||
| 489 | static int process_sample_event(union perf_event *event __used, | 489 | static int process_sample_event(union perf_event *event __used, |
| 490 | struct perf_sample *sample, | 490 | struct perf_sample *sample, |
| 491 | struct perf_evsel *evsel __used, | ||
| 491 | struct perf_session *session) | 492 | struct perf_session *session) |
| 492 | { | 493 | { |
| 493 | struct trace_entry *te; | 494 | struct trace_entry *te; |
| @@ -506,6 +507,16 @@ static int process_sample_event(union perf_event *event __used, | |||
| 506 | struct power_entry_old *peo; | 507 | struct power_entry_old *peo; |
| 507 | peo = (void *)te; | 508 | peo = (void *)te; |
| 508 | #endif | 509 | #endif |
| 510 | /* | ||
| 511 | * FIXME: use evsel, its already mapped from id to perf_evsel, | ||
| 512 | * remove perf_header__find_event infrastructure bits. | ||
| 513 | * Mapping all these "power:cpu_idle" strings to the tracepoint | ||
| 514 | * ID and then just comparing against evsel->attr.config. | ||
| 515 | * | ||
| 516 | * e.g.: | ||
| 517 | * | ||
| 518 | * if (evsel->attr.config == power_cpu_idle_id) | ||
| 519 | */ | ||
| 509 | event_str = perf_header__find_event(te->type); | 520 | event_str = perf_header__find_event(te->type); |
| 510 | 521 | ||
| 511 | if (!event_str) | 522 | if (!event_str) |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 70f1075cc5b0..676b4fb0070f 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
| @@ -515,7 +515,9 @@ static void handle_keypress(struct perf_session *session, int c) | |||
| 515 | break; | 515 | break; |
| 516 | case 'E': | 516 | case 'E': |
| 517 | if (top.evlist->nr_entries > 1) { | 517 | if (top.evlist->nr_entries > 1) { |
| 518 | int counter; | 518 | /* Select 0 as the default event: */ |
| 519 | int counter = 0; | ||
| 520 | |||
| 519 | fprintf(stderr, "\nAvailable events:"); | 521 | fprintf(stderr, "\nAvailable events:"); |
| 520 | 522 | ||
| 521 | list_for_each_entry(top.sym_evsel, &top.evlist->entries, node) | 523 | list_for_each_entry(top.sym_evsel, &top.evlist->entries, node) |
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 31f934af9861..a91cd99f26ea 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | 16 | ||
| 17 | static int build_id__mark_dso_hit(union perf_event *event, | 17 | static int build_id__mark_dso_hit(union perf_event *event, |
| 18 | struct perf_sample *sample __used, | 18 | struct perf_sample *sample __used, |
| 19 | struct perf_evsel *evsel __used, | ||
| 19 | struct perf_session *session) | 20 | struct perf_session *session) |
| 20 | { | 21 | { |
| 21 | struct addr_location al; | 22 | struct addr_location al; |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index e5230c0ef95b..93862a8027ea 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
| @@ -695,13 +695,50 @@ out: | |||
| 695 | return err; | 695 | return err; |
| 696 | } | 696 | } |
| 697 | 697 | ||
| 698 | static int perf_header__read_build_ids_abi_quirk(struct perf_header *header, | ||
| 699 | int input, u64 offset, u64 size) | ||
| 700 | { | ||
| 701 | struct perf_session *session = container_of(header, struct perf_session, header); | ||
| 702 | struct { | ||
| 703 | struct perf_event_header header; | ||
| 704 | u8 build_id[ALIGN(BUILD_ID_SIZE, sizeof(u64))]; | ||
| 705 | char filename[0]; | ||
| 706 | } old_bev; | ||
| 707 | struct build_id_event bev; | ||
| 708 | char filename[PATH_MAX]; | ||
| 709 | u64 limit = offset + size; | ||
| 710 | |||
| 711 | while (offset < limit) { | ||
| 712 | ssize_t len; | ||
| 713 | |||
| 714 | if (read(input, &old_bev, sizeof(old_bev)) != sizeof(old_bev)) | ||
| 715 | return -1; | ||
| 716 | |||
| 717 | if (header->needs_swap) | ||
| 718 | perf_event_header__bswap(&old_bev.header); | ||
| 719 | |||
| 720 | len = old_bev.header.size - sizeof(old_bev); | ||
| 721 | if (read(input, filename, len) != len) | ||
| 722 | return -1; | ||
| 723 | |||
| 724 | bev.header = old_bev.header; | ||
| 725 | bev.pid = 0; | ||
| 726 | memcpy(bev.build_id, old_bev.build_id, sizeof(bev.build_id)); | ||
| 727 | __event_process_build_id(&bev, filename, session); | ||
| 728 | |||
| 729 | offset += bev.header.size; | ||
| 730 | } | ||
| 731 | |||
| 732 | return 0; | ||
| 733 | } | ||
| 734 | |||
| 698 | static int perf_header__read_build_ids(struct perf_header *header, | 735 | static int perf_header__read_build_ids(struct perf_header *header, |
| 699 | int input, u64 offset, u64 size) | 736 | int input, u64 offset, u64 size) |
| 700 | { | 737 | { |
| 701 | struct perf_session *session = container_of(header, struct perf_session, header); | 738 | struct perf_session *session = container_of(header, struct perf_session, header); |
| 702 | struct build_id_event bev; | 739 | struct build_id_event bev; |
| 703 | char filename[PATH_MAX]; | 740 | char filename[PATH_MAX]; |
| 704 | u64 limit = offset + size; | 741 | u64 limit = offset + size, orig_offset = offset; |
| 705 | int err = -1; | 742 | int err = -1; |
| 706 | 743 | ||
| 707 | while (offset < limit) { | 744 | while (offset < limit) { |
| @@ -716,6 +753,24 @@ static int perf_header__read_build_ids(struct perf_header *header, | |||
| 716 | len = bev.header.size - sizeof(bev); | 753 | len = bev.header.size - sizeof(bev); |
| 717 | if (read(input, filename, len) != len) | 754 | if (read(input, filename, len) != len) |
| 718 | goto out; | 755 | goto out; |
| 756 | /* | ||
| 757 | * The a1645ce1 changeset: | ||
| 758 | * | ||
| 759 | * "perf: 'perf kvm' tool for monitoring guest performance from host" | ||
| 760 | * | ||
| 761 | * Added a field to struct build_id_event that broke the file | ||
| 762 | * format. | ||
| 763 | * | ||
| 764 | * Since the kernel build-id is the first entry, process the | ||
| 765 | * table using the old format if the well known | ||
| 766 | * '[kernel.kallsyms]' string for the kernel build-id has the | ||
| 767 | * first 4 characters chopped off (where the pid_t sits). | ||
| 768 | */ | ||
| 769 | if (memcmp(filename, "nel.kallsyms]", 13) == 0) { | ||
| 770 | if (lseek(input, orig_offset, SEEK_SET) == (off_t)-1) | ||
| 771 | return -1; | ||
| 772 | return perf_header__read_build_ids_abi_quirk(header, input, offset, size); | ||
| 773 | } | ||
| 719 | 774 | ||
| 720 | __event_process_build_id(&bev, filename, session); | 775 | __event_process_build_id(&bev, filename, session); |
| 721 | 776 | ||
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index cb6858a2f9a3..3beb97c4d822 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
| @@ -29,6 +29,7 @@ struct events_stats { | |||
| 29 | u32 nr_events[PERF_RECORD_HEADER_MAX]; | 29 | u32 nr_events[PERF_RECORD_HEADER_MAX]; |
| 30 | u32 nr_unknown_events; | 30 | u32 nr_unknown_events; |
| 31 | u32 nr_invalid_chains; | 31 | u32 nr_invalid_chains; |
| 32 | u32 nr_unknown_id; | ||
| 32 | }; | 33 | }; |
| 33 | 34 | ||
| 34 | enum hist_column { | 35 | enum hist_column { |
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index 621427212e86..74350ffb57fe 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c | |||
| @@ -247,6 +247,7 @@ static inline struct event *find_cache_event(int type) | |||
| 247 | 247 | ||
| 248 | static void perl_process_event(union perf_event *pevent __unused, | 248 | static void perl_process_event(union perf_event *pevent __unused, |
| 249 | struct perf_sample *sample, | 249 | struct perf_sample *sample, |
| 250 | struct perf_evsel *evsel, | ||
| 250 | struct perf_session *session __unused, | 251 | struct perf_session *session __unused, |
| 251 | struct thread *thread) | 252 | struct thread *thread) |
| 252 | { | 253 | { |
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 1b85d6055159..6ccf70e8d8f2 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c | |||
| @@ -206,6 +206,7 @@ static inline struct event *find_cache_event(int type) | |||
| 206 | 206 | ||
| 207 | static void python_process_event(union perf_event *pevent __unused, | 207 | static void python_process_event(union perf_event *pevent __unused, |
| 208 | struct perf_sample *sample, | 208 | struct perf_sample *sample, |
| 209 | struct perf_evsel *evsel __unused, | ||
| 209 | struct perf_session *session __unused, | 210 | struct perf_session *session __unused, |
| 210 | struct thread *thread) | 211 | struct thread *thread) |
| 211 | { | 212 | { |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index c68cf40764f9..caa224522fea 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
| @@ -280,6 +280,15 @@ static int process_event_synth_stub(union perf_event *event __used, | |||
| 280 | return 0; | 280 | return 0; |
| 281 | } | 281 | } |
| 282 | 282 | ||
| 283 | static int process_event_sample_stub(union perf_event *event __used, | ||
| 284 | struct perf_sample *sample __used, | ||
| 285 | struct perf_evsel *evsel __used, | ||
| 286 | struct perf_session *session __used) | ||
| 287 | { | ||
| 288 | dump_printf(": unhandled!\n"); | ||
| 289 | return 0; | ||
| 290 | } | ||
| 291 | |||
| 283 | static int process_event_stub(union perf_event *event __used, | 292 | static int process_event_stub(union perf_event *event __used, |
| 284 | struct perf_sample *sample __used, | 293 | struct perf_sample *sample __used, |
| 285 | struct perf_session *session __used) | 294 | struct perf_session *session __used) |
| @@ -303,7 +312,7 @@ static int process_finished_round(union perf_event *event, | |||
| 303 | static void perf_event_ops__fill_defaults(struct perf_event_ops *handler) | 312 | static void perf_event_ops__fill_defaults(struct perf_event_ops *handler) |
| 304 | { | 313 | { |
| 305 | if (handler->sample == NULL) | 314 | if (handler->sample == NULL) |
| 306 | handler->sample = process_event_stub; | 315 | handler->sample = process_event_sample_stub; |
| 307 | if (handler->mmap == NULL) | 316 | if (handler->mmap == NULL) |
| 308 | handler->mmap = process_event_stub; | 317 | handler->mmap = process_event_stub; |
| 309 | if (handler->comm == NULL) | 318 | if (handler->comm == NULL) |
| @@ -698,12 +707,19 @@ static int perf_session_deliver_event(struct perf_session *session, | |||
| 698 | struct perf_event_ops *ops, | 707 | struct perf_event_ops *ops, |
| 699 | u64 file_offset) | 708 | u64 file_offset) |
| 700 | { | 709 | { |
| 710 | struct perf_evsel *evsel; | ||
| 711 | |||
| 701 | dump_event(session, event, file_offset, sample); | 712 | dump_event(session, event, file_offset, sample); |
| 702 | 713 | ||
| 703 | switch (event->header.type) { | 714 | switch (event->header.type) { |
| 704 | case PERF_RECORD_SAMPLE: | 715 | case PERF_RECORD_SAMPLE: |
| 705 | dump_sample(session, event, sample); | 716 | dump_sample(session, event, sample); |
| 706 | return ops->sample(event, sample, session); | 717 | evsel = perf_evlist__id2evsel(session->evlist, sample->id); |
| 718 | if (evsel == NULL) { | ||
| 719 | ++session->hists.stats.nr_unknown_id; | ||
| 720 | return -1; | ||
| 721 | } | ||
| 722 | return ops->sample(event, sample, evsel, session); | ||
| 707 | case PERF_RECORD_MMAP: | 723 | case PERF_RECORD_MMAP: |
| 708 | return ops->mmap(event, sample, session); | 724 | return ops->mmap(event, sample, session); |
| 709 | case PERF_RECORD_COMM: | 725 | case PERF_RECORD_COMM: |
| @@ -845,6 +861,11 @@ static void perf_session__warn_about_errors(const struct perf_session *session, | |||
| 845 | session->hists.stats.nr_unknown_events); | 861 | session->hists.stats.nr_unknown_events); |
| 846 | } | 862 | } |
| 847 | 863 | ||
| 864 | if (session->hists.stats.nr_unknown_id != 0) { | ||
| 865 | ui__warning("%u samples with id not present in the header\n", | ||
| 866 | session->hists.stats.nr_unknown_id); | ||
| 867 | } | ||
| 868 | |||
| 848 | if (session->hists.stats.nr_invalid_chains != 0) { | 869 | if (session->hists.stats.nr_invalid_chains != 0) { |
| 849 | ui__warning("Found invalid callchains!\n\n" | 870 | ui__warning("Found invalid callchains!\n\n" |
| 850 | "%u out of %u events were discarded for this reason.\n\n" | 871 | "%u out of %u events were discarded for this reason.\n\n" |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 0b3c9afecaa9..1ac481fc1100 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
| @@ -55,8 +55,11 @@ struct perf_session { | |||
| 55 | char filename[0]; | 55 | char filename[0]; |
| 56 | }; | 56 | }; |
| 57 | 57 | ||
| 58 | struct perf_evsel; | ||
| 58 | struct perf_event_ops; | 59 | struct perf_event_ops; |
| 59 | 60 | ||
| 61 | typedef int (*event_sample)(union perf_event *event, struct perf_sample *sample, | ||
| 62 | struct perf_evsel *evsel, struct perf_session *session); | ||
| 60 | typedef int (*event_op)(union perf_event *self, struct perf_sample *sample, | 63 | typedef int (*event_op)(union perf_event *self, struct perf_sample *sample, |
| 61 | struct perf_session *session); | 64 | struct perf_session *session); |
| 62 | typedef int (*event_synth_op)(union perf_event *self, | 65 | typedef int (*event_synth_op)(union perf_event *self, |
| @@ -65,8 +68,8 @@ typedef int (*event_op2)(union perf_event *self, struct perf_session *session, | |||
| 65 | struct perf_event_ops *ops); | 68 | struct perf_event_ops *ops); |
| 66 | 69 | ||
| 67 | struct perf_event_ops { | 70 | struct perf_event_ops { |
| 68 | event_op sample, | 71 | event_sample sample; |
| 69 | mmap, | 72 | event_op mmap, |
| 70 | comm, | 73 | comm, |
| 71 | fork, | 74 | fork, |
| 72 | exit, | 75 | exit, |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 651dbfe7f4f3..17df793c8924 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
| @@ -1486,7 +1486,9 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | |||
| 1486 | * On the first pass, only load images if they have a full symtab. | 1486 | * On the first pass, only load images if they have a full symtab. |
| 1487 | * Failing that, do a second pass where we accept .dynsym also | 1487 | * Failing that, do a second pass where we accept .dynsym also |
| 1488 | */ | 1488 | */ |
| 1489 | for (self->symtab_type = SYMTAB__BUILD_ID_CACHE, want_symtab = 1; | 1489 | want_symtab = 1; |
| 1490 | restart: | ||
| 1491 | for (self->symtab_type = SYMTAB__BUILD_ID_CACHE; | ||
| 1490 | self->symtab_type != SYMTAB__NOT_FOUND; | 1492 | self->symtab_type != SYMTAB__NOT_FOUND; |
| 1491 | self->symtab_type++) { | 1493 | self->symtab_type++) { |
| 1492 | switch (self->symtab_type) { | 1494 | switch (self->symtab_type) { |
| @@ -1536,17 +1538,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | |||
| 1536 | snprintf(name, size, "%s%s", symbol_conf.symfs, | 1538 | snprintf(name, size, "%s%s", symbol_conf.symfs, |
| 1537 | self->long_name); | 1539 | self->long_name); |
| 1538 | break; | 1540 | break; |
| 1539 | 1541 | default:; | |
| 1540 | default: | ||
| 1541 | /* | ||
| 1542 | * If we wanted a full symtab but no image had one, | ||
| 1543 | * relax our requirements and repeat the search. | ||
| 1544 | */ | ||
| 1545 | if (want_symtab) { | ||
| 1546 | want_symtab = 0; | ||
| 1547 | self->symtab_type = SYMTAB__BUILD_ID_CACHE; | ||
| 1548 | } else | ||
| 1549 | continue; | ||
| 1550 | } | 1542 | } |
| 1551 | 1543 | ||
| 1552 | /* Name is now the name of the next image to try */ | 1544 | /* Name is now the name of the next image to try */ |
| @@ -1573,6 +1565,15 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | |||
| 1573 | } | 1565 | } |
| 1574 | } | 1566 | } |
| 1575 | 1567 | ||
| 1568 | /* | ||
| 1569 | * If we wanted a full symtab but no image had one, | ||
| 1570 | * relax our requirements and repeat the search. | ||
| 1571 | */ | ||
| 1572 | if (ret <= 0 && want_symtab) { | ||
| 1573 | want_symtab = 0; | ||
| 1574 | goto restart; | ||
| 1575 | } | ||
| 1576 | |||
| 1576 | free(name); | 1577 | free(name); |
| 1577 | if (ret < 0 && strstr(self->name, " (deleted)") != NULL) | 1578 | if (ret < 0 && strstr(self->name, " (deleted)") != NULL) |
| 1578 | return 0; | 1579 | return 0; |
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c index 66f4b78737ab..c9dcbec7d800 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c | |||
| @@ -38,6 +38,7 @@ static int stop_script_unsupported(void) | |||
| 38 | 38 | ||
| 39 | static void process_event_unsupported(union perf_event *event __unused, | 39 | static void process_event_unsupported(union perf_event *event __unused, |
| 40 | struct perf_sample *sample __unused, | 40 | struct perf_sample *sample __unused, |
| 41 | struct perf_evsel *evsel __unused, | ||
| 41 | struct perf_session *session __unused, | 42 | struct perf_session *session __unused, |
| 42 | struct thread *thread __unused) | 43 | struct thread *thread __unused) |
| 43 | { | 44 | { |
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index b04da5722437..f674dda3363b 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h | |||
| @@ -280,6 +280,7 @@ struct scripting_ops { | |||
| 280 | int (*stop_script) (void); | 280 | int (*stop_script) (void); |
| 281 | void (*process_event) (union perf_event *event, | 281 | void (*process_event) (union perf_event *event, |
| 282 | struct perf_sample *sample, | 282 | struct perf_sample *sample, |
| 283 | struct perf_evsel *evsel, | ||
| 283 | struct perf_session *session, | 284 | struct perf_session *session, |
| 284 | struct thread *thread); | 285 | struct thread *thread); |
| 285 | int (*generate_script) (const char *outfile); | 286 | int (*generate_script) (const char *outfile); |
