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