Merge tag 'sound-3.17-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[deliverable/linux.git] / tools / perf / tests / hists_filter.c
1 #include "perf.h"
2 #include "util/debug.h"
3 #include "util/symbol.h"
4 #include "util/sort.h"
5 #include "util/evsel.h"
6 #include "util/evlist.h"
7 #include "util/machine.h"
8 #include "util/thread.h"
9 #include "util/parse-events.h"
10 #include "tests/tests.h"
11 #include "tests/hists_common.h"
12
13 struct sample {
14 u32 pid;
15 u64 ip;
16 struct thread *thread;
17 struct map *map;
18 struct symbol *sym;
19 };
20
21 /* For the numbers, see hists_common.c */
22 static struct sample fake_samples[] = {
23 /* perf [kernel] schedule() */
24 { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_KERNEL_SCHEDULE, },
25 /* perf [perf] main() */
26 { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_PERF_MAIN, },
27 /* perf [libc] malloc() */
28 { .pid = FAKE_PID_PERF1, .ip = FAKE_IP_LIBC_MALLOC, },
29 /* perf [perf] main() */
30 { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_PERF_MAIN, }, /* will be merged */
31 /* perf [perf] cmd_record() */
32 { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_PERF_CMD_RECORD, },
33 /* perf [kernel] page_fault() */
34 { .pid = FAKE_PID_PERF2, .ip = FAKE_IP_KERNEL_PAGE_FAULT, },
35 /* bash [bash] main() */
36 { .pid = FAKE_PID_BASH, .ip = FAKE_IP_BASH_MAIN, },
37 /* bash [bash] xmalloc() */
38 { .pid = FAKE_PID_BASH, .ip = FAKE_IP_BASH_XMALLOC, },
39 /* bash [libc] malloc() */
40 { .pid = FAKE_PID_BASH, .ip = FAKE_IP_LIBC_MALLOC, },
41 /* bash [kernel] page_fault() */
42 { .pid = FAKE_PID_BASH, .ip = FAKE_IP_KERNEL_PAGE_FAULT, },
43 };
44
45 static int add_hist_entries(struct perf_evlist *evlist,
46 struct machine *machine __maybe_unused)
47 {
48 struct perf_evsel *evsel;
49 struct addr_location al;
50 struct perf_sample sample = { .period = 100, };
51 size_t i;
52
53 /*
54 * each evsel will have 10 samples but the 4th sample
55 * (perf [perf] main) will be collapsed to an existing entry
56 * so total 9 entries will be in the tree.
57 */
58 evlist__for_each(evlist, evsel) {
59 for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {
60 const union perf_event event = {
61 .header = {
62 .misc = PERF_RECORD_MISC_USER,
63 },
64 };
65 struct hist_entry_iter iter = {
66 .ops = &hist_iter_normal,
67 .hide_unresolved = false,
68 };
69
70 /* make sure it has no filter at first */
71 evsel->hists.thread_filter = NULL;
72 evsel->hists.dso_filter = NULL;
73 evsel->hists.symbol_filter_str = NULL;
74
75 sample.pid = fake_samples[i].pid;
76 sample.tid = fake_samples[i].pid;
77 sample.ip = fake_samples[i].ip;
78
79 if (perf_event__preprocess_sample(&event, machine, &al,
80 &sample) < 0)
81 goto out;
82
83 if (hist_entry_iter__add(&iter, &al, evsel, &sample,
84 PERF_MAX_STACK_DEPTH, NULL) < 0)
85 goto out;
86
87 fake_samples[i].thread = al.thread;
88 fake_samples[i].map = al.map;
89 fake_samples[i].sym = al.sym;
90 }
91 }
92
93 return 0;
94
95 out:
96 pr_debug("Not enough memory for adding a hist entry\n");
97 return TEST_FAIL;
98 }
99
100 int test__hists_filter(void)
101 {
102 int err = TEST_FAIL;
103 struct machines machines;
104 struct machine *machine;
105 struct perf_evsel *evsel;
106 struct perf_evlist *evlist = perf_evlist__new();
107
108 TEST_ASSERT_VAL("No memory", evlist);
109
110 err = parse_events(evlist, "cpu-clock");
111 if (err)
112 goto out;
113 err = parse_events(evlist, "task-clock");
114 if (err)
115 goto out;
116
117 /* default sort order (comm,dso,sym) will be used */
118 if (setup_sorting() < 0)
119 goto out;
120
121 machines__init(&machines);
122
123 /* setup threads/dso/map/symbols also */
124 machine = setup_fake_machine(&machines);
125 if (!machine)
126 goto out;
127
128 if (verbose > 1)
129 machine__fprintf(machine, stderr);
130
131 /* process sample events */
132 err = add_hist_entries(evlist, machine);
133 if (err < 0)
134 goto out;
135
136 evlist__for_each(evlist, evsel) {
137 struct hists *hists = &evsel->hists;
138
139 hists__collapse_resort(hists, NULL);
140 hists__output_resort(hists);
141
142 if (verbose > 2) {
143 pr_info("Normal histogram\n");
144 print_hists_out(hists);
145 }
146
147 TEST_ASSERT_VAL("Invalid nr samples",
148 hists->stats.nr_events[PERF_RECORD_SAMPLE] == 10);
149 TEST_ASSERT_VAL("Invalid nr hist entries",
150 hists->nr_entries == 9);
151 TEST_ASSERT_VAL("Invalid total period",
152 hists->stats.total_period == 1000);
153 TEST_ASSERT_VAL("Unmatched nr samples",
154 hists->stats.nr_events[PERF_RECORD_SAMPLE] ==
155 hists->stats.nr_non_filtered_samples);
156 TEST_ASSERT_VAL("Unmatched nr hist entries",
157 hists->nr_entries == hists->nr_non_filtered_entries);
158 TEST_ASSERT_VAL("Unmatched total period",
159 hists->stats.total_period ==
160 hists->stats.total_non_filtered_period);
161
162 /* now applying thread filter for 'bash' */
163 evsel->hists.thread_filter = fake_samples[9].thread;
164 hists__filter_by_thread(hists);
165
166 if (verbose > 2) {
167 pr_info("Histogram for thread filter\n");
168 print_hists_out(hists);
169 }
170
171 /* normal stats should be invariant */
172 TEST_ASSERT_VAL("Invalid nr samples",
173 hists->stats.nr_events[PERF_RECORD_SAMPLE] == 10);
174 TEST_ASSERT_VAL("Invalid nr hist entries",
175 hists->nr_entries == 9);
176 TEST_ASSERT_VAL("Invalid total period",
177 hists->stats.total_period == 1000);
178
179 /* but filter stats are changed */
180 TEST_ASSERT_VAL("Unmatched nr samples for thread filter",
181 hists->stats.nr_non_filtered_samples == 4);
182 TEST_ASSERT_VAL("Unmatched nr hist entries for thread filter",
183 hists->nr_non_filtered_entries == 4);
184 TEST_ASSERT_VAL("Unmatched total period for thread filter",
185 hists->stats.total_non_filtered_period == 400);
186
187 /* remove thread filter first */
188 evsel->hists.thread_filter = NULL;
189 hists__filter_by_thread(hists);
190
191 /* now applying dso filter for 'kernel' */
192 evsel->hists.dso_filter = fake_samples[0].map->dso;
193 hists__filter_by_dso(hists);
194
195 if (verbose > 2) {
196 pr_info("Histogram for dso filter\n");
197 print_hists_out(hists);
198 }
199
200 /* normal stats should be invariant */
201 TEST_ASSERT_VAL("Invalid nr samples",
202 hists->stats.nr_events[PERF_RECORD_SAMPLE] == 10);
203 TEST_ASSERT_VAL("Invalid nr hist entries",
204 hists->nr_entries == 9);
205 TEST_ASSERT_VAL("Invalid total period",
206 hists->stats.total_period == 1000);
207
208 /* but filter stats are changed */
209 TEST_ASSERT_VAL("Unmatched nr samples for dso filter",
210 hists->stats.nr_non_filtered_samples == 3);
211 TEST_ASSERT_VAL("Unmatched nr hist entries for dso filter",
212 hists->nr_non_filtered_entries == 3);
213 TEST_ASSERT_VAL("Unmatched total period for dso filter",
214 hists->stats.total_non_filtered_period == 300);
215
216 /* remove dso filter first */
217 evsel->hists.dso_filter = NULL;
218 hists__filter_by_dso(hists);
219
220 /*
221 * now applying symbol filter for 'main'. Also note that
222 * there's 3 samples that have 'main' symbol but the 4th
223 * entry of fake_samples was collapsed already so it won't
224 * be counted as a separate entry but the sample count and
225 * total period will be remained.
226 */
227 evsel->hists.symbol_filter_str = "main";
228 hists__filter_by_symbol(hists);
229
230 if (verbose > 2) {
231 pr_info("Histogram for symbol filter\n");
232 print_hists_out(hists);
233 }
234
235 /* normal stats should be invariant */
236 TEST_ASSERT_VAL("Invalid nr samples",
237 hists->stats.nr_events[PERF_RECORD_SAMPLE] == 10);
238 TEST_ASSERT_VAL("Invalid nr hist entries",
239 hists->nr_entries == 9);
240 TEST_ASSERT_VAL("Invalid total period",
241 hists->stats.total_period == 1000);
242
243 /* but filter stats are changed */
244 TEST_ASSERT_VAL("Unmatched nr samples for symbol filter",
245 hists->stats.nr_non_filtered_samples == 3);
246 TEST_ASSERT_VAL("Unmatched nr hist entries for symbol filter",
247 hists->nr_non_filtered_entries == 2);
248 TEST_ASSERT_VAL("Unmatched total period for symbol filter",
249 hists->stats.total_non_filtered_period == 300);
250
251 /* now applying all filters at once. */
252 evsel->hists.thread_filter = fake_samples[1].thread;
253 evsel->hists.dso_filter = fake_samples[1].map->dso;
254 hists__filter_by_thread(hists);
255 hists__filter_by_dso(hists);
256
257 if (verbose > 2) {
258 pr_info("Histogram for all filters\n");
259 print_hists_out(hists);
260 }
261
262 /* normal stats should be invariant */
263 TEST_ASSERT_VAL("Invalid nr samples",
264 hists->stats.nr_events[PERF_RECORD_SAMPLE] == 10);
265 TEST_ASSERT_VAL("Invalid nr hist entries",
266 hists->nr_entries == 9);
267 TEST_ASSERT_VAL("Invalid total period",
268 hists->stats.total_period == 1000);
269
270 /* but filter stats are changed */
271 TEST_ASSERT_VAL("Unmatched nr samples for all filter",
272 hists->stats.nr_non_filtered_samples == 2);
273 TEST_ASSERT_VAL("Unmatched nr hist entries for all filter",
274 hists->nr_non_filtered_entries == 1);
275 TEST_ASSERT_VAL("Unmatched total period for all filter",
276 hists->stats.total_non_filtered_period == 200);
277 }
278
279
280 err = TEST_OK;
281
282 out:
283 /* tear down everything */
284 perf_evlist__delete(evlist);
285 reset_output_field();
286 machines__exit(&machines);
287
288 return err;
289 }
This page took 0.040433 seconds and 5 git commands to generate.