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