diff options
author | Patrick McHardy <kaber@trash.net> | 2011-04-13 07:32:28 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2011-04-13 07:32:28 -0400 |
commit | b32e3dc7860d00124fa432dba09667e647cb9bcc (patch) | |
tree | 2fa6e56f389431dfb84609d3d7572cad76e88e71 /tools | |
parent | 6604271c5bc658a6067ed0c3deba4d89e0e50382 (diff) | |
parent | 96120d86fe302c006259baee9061eea9e1b9e486 (diff) |
Merge branch 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6
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 | ||||
-rwxr-xr-x | tools/testing/ktest/ktest.pl | 139 | ||||
-rw-r--r-- | tools/testing/ktest/sample.conf | 42 |
22 files changed, 306 insertions, 80 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); |
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index ba7c63af6f3b..8ce792ea08e9 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl | |||
@@ -37,6 +37,8 @@ $default{"POWEROFF_ON_SUCCESS"} = 0; | |||
37 | $default{"BUILD_OPTIONS"} = ""; | 37 | $default{"BUILD_OPTIONS"} = ""; |
38 | $default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects | 38 | $default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects |
39 | $default{"CLEAR_LOG"} = 0; | 39 | $default{"CLEAR_LOG"} = 0; |
40 | $default{"BISECT_MANUAL"} = 0; | ||
41 | $default{"BISECT_SKIP"} = 1; | ||
40 | $default{"SUCCESS_LINE"} = "login:"; | 42 | $default{"SUCCESS_LINE"} = "login:"; |
41 | $default{"BOOTED_TIMEOUT"} = 1; | 43 | $default{"BOOTED_TIMEOUT"} = 1; |
42 | $default{"DIE_ON_FAILURE"} = 1; | 44 | $default{"DIE_ON_FAILURE"} = 1; |
@@ -45,6 +47,7 @@ $default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE"; | |||
45 | $default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot"; | 47 | $default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot"; |
46 | $default{"STOP_AFTER_SUCCESS"} = 10; | 48 | $default{"STOP_AFTER_SUCCESS"} = 10; |
47 | $default{"STOP_AFTER_FAILURE"} = 60; | 49 | $default{"STOP_AFTER_FAILURE"} = 60; |
50 | $default{"STOP_TEST_AFTER"} = 600; | ||
48 | $default{"LOCALVERSION"} = "-test"; | 51 | $default{"LOCALVERSION"} = "-test"; |
49 | 52 | ||
50 | my $ktest_config; | 53 | my $ktest_config; |
@@ -81,6 +84,8 @@ my $addconfig; | |||
81 | my $in_bisect = 0; | 84 | my $in_bisect = 0; |
82 | my $bisect_bad = ""; | 85 | my $bisect_bad = ""; |
83 | my $reverse_bisect; | 86 | my $reverse_bisect; |
87 | my $bisect_manual; | ||
88 | my $bisect_skip; | ||
84 | my $in_patchcheck = 0; | 89 | my $in_patchcheck = 0; |
85 | my $run_test; | 90 | my $run_test; |
86 | my $redirect; | 91 | my $redirect; |
@@ -98,6 +103,7 @@ my $console; | |||
98 | my $success_line; | 103 | my $success_line; |
99 | my $stop_after_success; | 104 | my $stop_after_success; |
100 | my $stop_after_failure; | 105 | my $stop_after_failure; |
106 | my $stop_test_after; | ||
101 | my $build_target; | 107 | my $build_target; |
102 | my $target_image; | 108 | my $target_image; |
103 | my $localversion; | 109 | my $localversion; |
@@ -462,6 +468,10 @@ sub dodie { | |||
462 | `$power_off`; | 468 | `$power_off`; |
463 | } | 469 | } |
464 | 470 | ||
471 | if (defined($opt{"LOG_FILE"})) { | ||
472 | print " See $opt{LOG_FILE} for more info.\n"; | ||
473 | } | ||
474 | |||
465 | die @_, "\n"; | 475 | die @_, "\n"; |
466 | } | 476 | } |
467 | 477 | ||
@@ -760,8 +770,10 @@ sub monitor { | |||
760 | 770 | ||
761 | my $success_start; | 771 | my $success_start; |
762 | my $failure_start; | 772 | my $failure_start; |
773 | my $monitor_start = time; | ||
774 | my $done = 0; | ||
763 | 775 | ||
764 | for (;;) { | 776 | while (!$done) { |
765 | 777 | ||
766 | if ($booted) { | 778 | if ($booted) { |
767 | $line = wait_for_input($monitor_fp, $booted_timeout); | 779 | $line = wait_for_input($monitor_fp, $booted_timeout); |
@@ -796,7 +808,7 @@ sub monitor { | |||
796 | } | 808 | } |
797 | 809 | ||
798 | if ($full_line =~ /call trace:/i) { | 810 | if ($full_line =~ /call trace:/i) { |
799 | if (!$skip_call_trace) { | 811 | if (!$bug && !$skip_call_trace) { |
800 | $bug = 1; | 812 | $bug = 1; |
801 | $failure_start = time; | 813 | $failure_start = time; |
802 | } | 814 | } |
@@ -816,12 +828,19 @@ sub monitor { | |||
816 | } | 828 | } |
817 | 829 | ||
818 | if ($full_line =~ /Kernel panic -/) { | 830 | if ($full_line =~ /Kernel panic -/) { |
831 | $failure_start = time; | ||
819 | $bug = 1; | 832 | $bug = 1; |
820 | } | 833 | } |
821 | 834 | ||
822 | if ($line =~ /\n/) { | 835 | if ($line =~ /\n/) { |
823 | $full_line = ""; | 836 | $full_line = ""; |
824 | } | 837 | } |
838 | |||
839 | if ($stop_test_after > 0 && !$booted && !$bug) { | ||
840 | if (time - $monitor_start > $stop_test_after) { | ||
841 | $done = 1; | ||
842 | } | ||
843 | } | ||
825 | } | 844 | } |
826 | 845 | ||
827 | close(DMESG); | 846 | close(DMESG); |
@@ -925,6 +944,18 @@ sub check_buildlog { | |||
925 | return 1; | 944 | return 1; |
926 | } | 945 | } |
927 | 946 | ||
947 | sub make_oldconfig { | ||
948 | my ($defconfig) = @_; | ||
949 | |||
950 | if (!run_command "$defconfig $make oldnoconfig") { | ||
951 | # Perhaps oldnoconfig doesn't exist in this version of the kernel | ||
952 | # try a yes '' | oldconfig | ||
953 | doprint "oldnoconfig failed, trying yes '' | make oldconfig\n"; | ||
954 | run_command "yes '' | $defconfig $make oldconfig" or | ||
955 | dodie "failed make config oldconfig"; | ||
956 | } | ||
957 | } | ||
958 | |||
928 | sub build { | 959 | sub build { |
929 | my ($type) = @_; | 960 | my ($type) = @_; |
930 | my $defconfig = ""; | 961 | my $defconfig = ""; |
@@ -970,8 +1001,12 @@ sub build { | |||
970 | $defconfig = "KCONFIG_ALLCONFIG=$minconfig"; | 1001 | $defconfig = "KCONFIG_ALLCONFIG=$minconfig"; |
971 | } | 1002 | } |
972 | 1003 | ||
973 | run_command "$defconfig $make $type" or | 1004 | if ($type eq "oldnoconfig") { |
974 | dodie "failed make config"; | 1005 | make_oldconfig $defconfig; |
1006 | } else { | ||
1007 | run_command "$defconfig $make $type" or | ||
1008 | dodie "failed make config"; | ||
1009 | } | ||
975 | 1010 | ||
976 | $redirect = "$buildlog"; | 1011 | $redirect = "$buildlog"; |
977 | if (!run_command "$make $build_options") { | 1012 | if (!run_command "$make $build_options") { |
@@ -1025,6 +1060,21 @@ sub get_version { | |||
1025 | doprint "$version\n"; | 1060 | doprint "$version\n"; |
1026 | } | 1061 | } |
1027 | 1062 | ||
1063 | sub answer_bisect { | ||
1064 | for (;;) { | ||
1065 | doprint "Pass or fail? [p/f]"; | ||
1066 | my $ans = <STDIN>; | ||
1067 | chomp $ans; | ||
1068 | if ($ans eq "p" || $ans eq "P") { | ||
1069 | return 1; | ||
1070 | } elsif ($ans eq "f" || $ans eq "F") { | ||
1071 | return 0; | ||
1072 | } else { | ||
1073 | print "Please answer 'P' or 'F'\n"; | ||
1074 | } | ||
1075 | } | ||
1076 | } | ||
1077 | |||
1028 | sub child_run_test { | 1078 | sub child_run_test { |
1029 | my $failed = 0; | 1079 | my $failed = 0; |
1030 | 1080 | ||
@@ -1070,6 +1120,7 @@ sub do_run_test { | |||
1070 | 1120 | ||
1071 | # we are not guaranteed to get a full line | 1121 | # we are not guaranteed to get a full line |
1072 | $full_line .= $line; | 1122 | $full_line .= $line; |
1123 | doprint $line; | ||
1073 | 1124 | ||
1074 | if ($full_line =~ /call trace:/i) { | 1125 | if ($full_line =~ /call trace:/i) { |
1075 | $bug = 1; | 1126 | $bug = 1; |
@@ -1086,6 +1137,19 @@ sub do_run_test { | |||
1086 | } while (!$child_done && !$bug); | 1137 | } while (!$child_done && !$bug); |
1087 | 1138 | ||
1088 | if ($bug) { | 1139 | if ($bug) { |
1140 | my $failure_start = time; | ||
1141 | my $now; | ||
1142 | do { | ||
1143 | $line = wait_for_input($monitor_fp, 1); | ||
1144 | if (defined($line)) { | ||
1145 | doprint $line; | ||
1146 | } | ||
1147 | $now = time; | ||
1148 | if ($now - $failure_start >= $stop_after_failure) { | ||
1149 | last; | ||
1150 | } | ||
1151 | } while (defined($line)); | ||
1152 | |||
1089 | doprint "Detected kernel crash!\n"; | 1153 | doprint "Detected kernel crash!\n"; |
1090 | # kill the child with extreme prejudice | 1154 | # kill the child with extreme prejudice |
1091 | kill 9, $child_pid; | 1155 | kill 9, $child_pid; |
@@ -1131,7 +1195,15 @@ sub run_git_bisect { | |||
1131 | return 1; | 1195 | return 1; |
1132 | } | 1196 | } |
1133 | 1197 | ||
1134 | # returns 1 on success, 0 on failure | 1198 | sub bisect_reboot { |
1199 | doprint "Reboot and sleep $bisect_sleep_time seconds\n"; | ||
1200 | reboot; | ||
1201 | start_monitor; | ||
1202 | wait_for_monitor $bisect_sleep_time; | ||
1203 | end_monitor; | ||
1204 | } | ||
1205 | |||
1206 | # returns 1 on success, 0 on failure, -1 on skip | ||
1135 | sub run_bisect_test { | 1207 | sub run_bisect_test { |
1136 | my ($type, $buildtype) = @_; | 1208 | my ($type, $buildtype) = @_; |
1137 | 1209 | ||
@@ -1145,6 +1217,10 @@ sub run_bisect_test { | |||
1145 | build $buildtype or $failed = 1; | 1217 | build $buildtype or $failed = 1; |
1146 | 1218 | ||
1147 | if ($type ne "build") { | 1219 | if ($type ne "build") { |
1220 | if ($failed && $bisect_skip) { | ||
1221 | $in_bisect = 0; | ||
1222 | return -1; | ||
1223 | } | ||
1148 | dodie "Failed on build" if $failed; | 1224 | dodie "Failed on build" if $failed; |
1149 | 1225 | ||
1150 | # Now boot the box | 1226 | # Now boot the box |
@@ -1156,6 +1232,12 @@ sub run_bisect_test { | |||
1156 | monitor or $failed = 1; | 1232 | monitor or $failed = 1; |
1157 | 1233 | ||
1158 | if ($type ne "boot") { | 1234 | if ($type ne "boot") { |
1235 | if ($failed && $bisect_skip) { | ||
1236 | end_monitor; | ||
1237 | bisect_reboot; | ||
1238 | $in_bisect = 0; | ||
1239 | return -1; | ||
1240 | } | ||
1159 | dodie "Failed on boot" if $failed; | 1241 | dodie "Failed on boot" if $failed; |
1160 | 1242 | ||
1161 | do_run_test or $failed = 1; | 1243 | do_run_test or $failed = 1; |
@@ -1168,11 +1250,7 @@ sub run_bisect_test { | |||
1168 | 1250 | ||
1169 | # reboot the box to a good kernel | 1251 | # reboot the box to a good kernel |
1170 | if ($type ne "build") { | 1252 | if ($type ne "build") { |
1171 | doprint "Reboot and sleep $bisect_sleep_time seconds\n"; | 1253 | bisect_reboot; |
1172 | reboot; | ||
1173 | start_monitor; | ||
1174 | wait_for_monitor $bisect_sleep_time; | ||
1175 | end_monitor; | ||
1176 | } | 1254 | } |
1177 | } else { | 1255 | } else { |
1178 | $result = 1; | 1256 | $result = 1; |
@@ -1193,16 +1271,22 @@ sub run_bisect { | |||
1193 | 1271 | ||
1194 | my $ret = run_bisect_test $type, $buildtype; | 1272 | my $ret = run_bisect_test $type, $buildtype; |
1195 | 1273 | ||
1274 | if ($bisect_manual) { | ||
1275 | $ret = answer_bisect; | ||
1276 | } | ||
1196 | 1277 | ||
1197 | # Are we looking for where it worked, not failed? | 1278 | # Are we looking for where it worked, not failed? |
1198 | if ($reverse_bisect) { | 1279 | if ($reverse_bisect) { |
1199 | $ret = !$ret; | 1280 | $ret = !$ret; |
1200 | } | 1281 | } |
1201 | 1282 | ||
1202 | if ($ret) { | 1283 | if ($ret > 0) { |
1203 | return "good"; | 1284 | return "good"; |
1204 | } else { | 1285 | } elsif ($ret == 0) { |
1205 | return "bad"; | 1286 | return "bad"; |
1287 | } elsif ($bisect_skip) { | ||
1288 | doprint "HIT A BAD COMMIT ... SKIPPING\n"; | ||
1289 | return "skip"; | ||
1206 | } | 1290 | } |
1207 | } | 1291 | } |
1208 | 1292 | ||
@@ -1220,6 +1304,13 @@ sub bisect { | |||
1220 | my $type = $opt{"BISECT_TYPE[$i]"}; | 1304 | my $type = $opt{"BISECT_TYPE[$i]"}; |
1221 | my $start = $opt{"BISECT_START[$i]"}; | 1305 | my $start = $opt{"BISECT_START[$i]"}; |
1222 | my $replay = $opt{"BISECT_REPLAY[$i]"}; | 1306 | my $replay = $opt{"BISECT_REPLAY[$i]"}; |
1307 | my $start_files = $opt{"BISECT_FILES[$i]"}; | ||
1308 | |||
1309 | if (defined($start_files)) { | ||
1310 | $start_files = " -- " . $start_files; | ||
1311 | } else { | ||
1312 | $start_files = ""; | ||
1313 | } | ||
1223 | 1314 | ||
1224 | # convert to true sha1's | 1315 | # convert to true sha1's |
1225 | $good = get_sha1($good); | 1316 | $good = get_sha1($good); |
@@ -1273,7 +1364,7 @@ sub bisect { | |||
1273 | die "Failed to checkout $head"; | 1364 | die "Failed to checkout $head"; |
1274 | } | 1365 | } |
1275 | 1366 | ||
1276 | run_command "git bisect start" or | 1367 | run_command "git bisect start$start_files" or |
1277 | dodie "could not start bisect"; | 1368 | dodie "could not start bisect"; |
1278 | 1369 | ||
1279 | run_command "git bisect good $good" or | 1370 | run_command "git bisect good $good" or |
@@ -1390,9 +1481,7 @@ sub create_config { | |||
1390 | close(OUT); | 1481 | close(OUT); |
1391 | 1482 | ||
1392 | # exit; | 1483 | # exit; |
1393 | run_command "$make oldnoconfig" or | 1484 | make_oldconfig ""; |
1394 | dodie "failed make config oldconfig"; | ||
1395 | |||
1396 | } | 1485 | } |
1397 | 1486 | ||
1398 | sub compare_configs { | 1487 | sub compare_configs { |
@@ -1505,7 +1594,9 @@ sub run_config_bisect { | |||
1505 | } | 1594 | } |
1506 | 1595 | ||
1507 | $ret = run_config_bisect_test $type; | 1596 | $ret = run_config_bisect_test $type; |
1508 | 1597 | if ($bisect_manual) { | |
1598 | $ret = answer_bisect; | ||
1599 | } | ||
1509 | if ($ret) { | 1600 | if ($ret) { |
1510 | process_passed %current_config; | 1601 | process_passed %current_config; |
1511 | return 0; | 1602 | return 0; |
@@ -1536,7 +1627,13 @@ sub run_config_bisect { | |||
1536 | $half = int($#start_list / 2); | 1627 | $half = int($#start_list / 2); |
1537 | } while ($half > 0); | 1628 | } while ($half > 0); |
1538 | 1629 | ||
1539 | # we found a single config, try it again | 1630 | # we found a single config, try it again unless we are running manually |
1631 | |||
1632 | if ($bisect_manual) { | ||
1633 | process_failed $start_list[0]; | ||
1634 | return 1; | ||
1635 | } | ||
1636 | |||
1540 | my @tophalf = @start_list[0 .. 0]; | 1637 | my @tophalf = @start_list[0 .. 0]; |
1541 | 1638 | ||
1542 | $ret = run_config_bisect_test $type; | 1639 | $ret = run_config_bisect_test $type; |
@@ -1594,8 +1691,7 @@ sub config_bisect { | |||
1594 | close(IN); | 1691 | close(IN); |
1595 | 1692 | ||
1596 | # Now run oldconfig with the minconfig (and addconfigs) | 1693 | # Now run oldconfig with the minconfig (and addconfigs) |
1597 | run_command "$defconfig $make oldnoconfig" or | 1694 | make_oldconfig $defconfig; |
1598 | dodie "failed make config oldconfig"; | ||
1599 | 1695 | ||
1600 | # check to see what we lost (or gained) | 1696 | # check to see what we lost (or gained) |
1601 | open (IN, $output_config) | 1697 | open (IN, $output_config) |
@@ -1907,6 +2003,8 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { | |||
1907 | $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i); | 2003 | $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i); |
1908 | $sleep_time = set_test_option("SLEEP_TIME", $i); | 2004 | $sleep_time = set_test_option("SLEEP_TIME", $i); |
1909 | $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i); | 2005 | $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i); |
2006 | $bisect_manual = set_test_option("BISECT_MANUAL", $i); | ||
2007 | $bisect_skip = set_test_option("BISECT_SKIP", $i); | ||
1910 | $store_failures = set_test_option("STORE_FAILURES", $i); | 2008 | $store_failures = set_test_option("STORE_FAILURES", $i); |
1911 | $timeout = set_test_option("TIMEOUT", $i); | 2009 | $timeout = set_test_option("TIMEOUT", $i); |
1912 | $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i); | 2010 | $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i); |
@@ -1914,6 +2012,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { | |||
1914 | $success_line = set_test_option("SUCCESS_LINE", $i); | 2012 | $success_line = set_test_option("SUCCESS_LINE", $i); |
1915 | $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i); | 2013 | $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i); |
1916 | $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i); | 2014 | $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i); |
2015 | $stop_test_after = set_test_option("STOP_TEST_AFTER", $i); | ||
1917 | $build_target = set_test_option("BUILD_TARGET", $i); | 2016 | $build_target = set_test_option("BUILD_TARGET", $i); |
1918 | $ssh_exec = set_test_option("SSH_EXEC", $i); | 2017 | $ssh_exec = set_test_option("SSH_EXEC", $i); |
1919 | $scp_to_target = set_test_option("SCP_TO_TARGET", $i); | 2018 | $scp_to_target = set_test_option("SCP_TO_TARGET", $i); |
diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index 3408c594b2de..4c5d6bd74a02 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf | |||
@@ -306,6 +306,14 @@ | |||
306 | # (default 60) | 306 | # (default 60) |
307 | #STOP_AFTER_FAILURE = 60 | 307 | #STOP_AFTER_FAILURE = 60 |
308 | 308 | ||
309 | # In case the console constantly fills the screen, having | ||
310 | # a specified time to stop the test if it never succeeds nor fails | ||
311 | # is recommended. | ||
312 | # Note: this is ignored if a success or failure is detected. | ||
313 | # (in seconds) | ||
314 | # (default 600, -1 is to never stop) | ||
315 | #STOP_TEST_AFTER = 600 | ||
316 | |||
309 | # Stop testing if a build fails. If set, the script will end if | 317 | # Stop testing if a build fails. If set, the script will end if |
310 | # a failure is detected, otherwise it will save off the .config, | 318 | # a failure is detected, otherwise it will save off the .config, |
311 | # dmesg and bootlog in a directory called | 319 | # dmesg and bootlog in a directory called |
@@ -519,6 +527,24 @@ | |||
519 | # git bisect good, git bisect bad, and running the git bisect replay | 527 | # git bisect good, git bisect bad, and running the git bisect replay |
520 | # if the BISECT_REPLAY is set. | 528 | # if the BISECT_REPLAY is set. |
521 | # | 529 | # |
530 | # BISECT_SKIP = 1 (optional, default 0) | ||
531 | # | ||
532 | # If BISECT_TYPE is set to test but the build fails, ktest will | ||
533 | # simply fail the test and end their. You could use BISECT_REPLAY | ||
534 | # and BISECT_START to resume after you found a new starting point, | ||
535 | # or you could set BISECT_SKIP to 1. If BISECT_SKIP is set to 1, | ||
536 | # when something other than the BISECT_TYPE fails, ktest.pl will | ||
537 | # run "git bisect skip" and try again. | ||
538 | # | ||
539 | # BISECT_FILES = <path> (optional, default undefined) | ||
540 | # | ||
541 | # To just run the git bisect on a specific path, set BISECT_FILES. | ||
542 | # For example: | ||
543 | # | ||
544 | # BISECT_FILES = arch/x86 kernel/time | ||
545 | # | ||
546 | # Will run the bisect with "git bisect start -- arch/x86 kernel/time" | ||
547 | # | ||
522 | # BISECT_REVERSE = 1 (optional, default 0) | 548 | # BISECT_REVERSE = 1 (optional, default 0) |
523 | # | 549 | # |
524 | # In those strange instances where it was broken forever | 550 | # In those strange instances where it was broken forever |
@@ -528,6 +554,15 @@ | |||
528 | # With BISECT_REVERSE = 1, The test will consider failures as | 554 | # With BISECT_REVERSE = 1, The test will consider failures as |
529 | # good, and success as bad. | 555 | # good, and success as bad. |
530 | # | 556 | # |
557 | # BISECT_MANUAL = 1 (optional, default 0) | ||
558 | # | ||
559 | # In case there's a problem with automating the bisect for | ||
560 | # whatever reason. (Can't reboot, want to inspect each iteration) | ||
561 | # Doing a BISECT_MANUAL will have the test wait for you to | ||
562 | # tell it if the test passed or failed after each iteration. | ||
563 | # This is basicall the same as running git bisect yourself | ||
564 | # but ktest will rebuild and install the kernel for you. | ||
565 | # | ||
531 | # BISECT_CHECK = 1 (optional, default 0) | 566 | # BISECT_CHECK = 1 (optional, default 0) |
532 | # | 567 | # |
533 | # Just to be sure the good is good and bad is bad, setting | 568 | # Just to be sure the good is good and bad is bad, setting |
@@ -613,10 +648,17 @@ | |||
613 | # | 648 | # |
614 | # CONFIG_BISECT is the config that failed to boot | 649 | # CONFIG_BISECT is the config that failed to boot |
615 | # | 650 | # |
651 | # If BISECT_MANUAL is set, it will pause between iterations. | ||
652 | # This is useful to use just ktest.pl just for the config bisect. | ||
653 | # If you set it to build, it will run the bisect and you can | ||
654 | # control what happens in between iterations. It will ask you if | ||
655 | # the test succeeded or not and continue the config bisect. | ||
656 | # | ||
616 | # Example: | 657 | # Example: |
617 | # TEST_START | 658 | # TEST_START |
618 | # TEST_TYPE = config_bisect | 659 | # TEST_TYPE = config_bisect |
619 | # CONFIG_BISECT_TYPE = build | 660 | # CONFIG_BISECT_TYPE = build |
620 | # CONFIG_BISECT = /home/test/˘onfig-bad | 661 | # CONFIG_BISECT = /home/test/˘onfig-bad |
621 | # MIN_CONFIG = /home/test/config-min | 662 | # MIN_CONFIG = /home/test/config-min |
663 | # BISECT_MANUAL = 1 | ||
622 | # | 664 | # |