ACPI / button: remove pointer to old lid_sysfs on unbind
[cascardo/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                         struct hist_entry_iter iter = {
62                                 .evsel = evsel,
63                                 .sample = &sample,
64                                 .ops = &hist_iter_normal,
65                                 .hide_unresolved = false,
66                         };
67                         struct hists *hists = evsel__hists(evsel);
68
69                         /* make sure it has no filter at first */
70                         hists->thread_filter = NULL;
71                         hists->dso_filter = NULL;
72                         hists->symbol_filter_str = NULL;
73
74                         sample.cpumode = PERF_RECORD_MISC_USER;
75                         sample.pid = fake_samples[i].pid;
76                         sample.tid = fake_samples[i].pid;
77                         sample.ip = fake_samples[i].ip;
78
79                         if (machine__resolve(machine, &al, &sample) < 0)
80                                 goto out;
81
82                         al.socket = fake_samples[i].socket;
83                         if (hist_entry_iter__add(&iter, &al,
84                                                  sysctl_perf_event_max_stack, NULL) < 0) {
85                                 addr_location__put(&al);
86                                 goto out;
87                         }
88
89                         fake_samples[i].thread = al.thread;
90                         fake_samples[i].map = al.map;
91                         fake_samples[i].sym = al.sym;
92                 }
93         }
94
95         return 0;
96
97 out:
98         pr_debug("Not enough memory for adding a hist entry\n");
99         return TEST_FAIL;
100 }
101
102 int test__hists_filter(int subtest __maybe_unused)
103 {
104         int err = TEST_FAIL;
105         struct machines machines;
106         struct machine *machine;
107         struct perf_evsel *evsel;
108         struct perf_evlist *evlist = perf_evlist__new();
109
110         TEST_ASSERT_VAL("No memory", evlist);
111
112         err = parse_events(evlist, "cpu-clock", NULL);
113         if (err)
114                 goto out;
115         err = parse_events(evlist, "task-clock", NULL);
116         if (err)
117                 goto out;
118         err = TEST_FAIL;
119
120         /* default sort order (comm,dso,sym) will be used */
121         if (setup_sorting(NULL) < 0)
122                 goto out;
123
124         machines__init(&machines);
125
126         /* setup threads/dso/map/symbols also */
127         machine = setup_fake_machine(&machines);
128         if (!machine)
129                 goto out;
130
131         if (verbose > 1)
132                 machine__fprintf(machine, stderr);
133
134         /* process sample events */
135         err = add_hist_entries(evlist, machine);
136         if (err < 0)
137                 goto out;
138
139         evlist__for_each(evlist, evsel) {
140                 struct hists *hists = evsel__hists(evsel);
141
142                 hists__collapse_resort(hists, NULL);
143                 perf_evsel__output_resort(evsel, NULL);
144
145                 if (verbose > 2) {
146                         pr_info("Normal histogram\n");
147                         print_hists_out(hists);
148                 }
149
150                 TEST_ASSERT_VAL("Invalid nr samples",
151                                 hists->stats.nr_events[PERF_RECORD_SAMPLE] == 10);
152                 TEST_ASSERT_VAL("Invalid nr hist entries",
153                                 hists->nr_entries == 9);
154                 TEST_ASSERT_VAL("Invalid total period",
155                                 hists->stats.total_period == 1000);
156                 TEST_ASSERT_VAL("Unmatched nr samples",
157                                 hists->stats.nr_events[PERF_RECORD_SAMPLE] ==
158                                 hists->stats.nr_non_filtered_samples);
159                 TEST_ASSERT_VAL("Unmatched nr hist entries",
160                                 hists->nr_entries == hists->nr_non_filtered_entries);
161                 TEST_ASSERT_VAL("Unmatched total period",
162                                 hists->stats.total_period ==
163                                 hists->stats.total_non_filtered_period);
164
165                 /* now applying thread filter for 'bash' */
166                 hists->thread_filter = fake_samples[9].thread;
167                 hists__filter_by_thread(hists);
168
169                 if (verbose > 2) {
170                         pr_info("Histogram for thread filter\n");
171                         print_hists_out(hists);
172                 }
173
174                 /* normal stats should be invariant */
175                 TEST_ASSERT_VAL("Invalid nr samples",
176                                 hists->stats.nr_events[PERF_RECORD_SAMPLE] == 10);
177                 TEST_ASSERT_VAL("Invalid nr hist entries",
178                                 hists->nr_entries == 9);
179                 TEST_ASSERT_VAL("Invalid total period",
180                                 hists->stats.total_period == 1000);
181
182                 /* but filter stats are changed */
183                 TEST_ASSERT_VAL("Unmatched nr samples for thread filter",
184                                 hists->stats.nr_non_filtered_samples == 4);
185                 TEST_ASSERT_VAL("Unmatched nr hist entries for thread filter",
186                                 hists->nr_non_filtered_entries == 4);
187                 TEST_ASSERT_VAL("Unmatched total period for thread filter",
188                                 hists->stats.total_non_filtered_period == 400);
189
190                 /* remove thread filter first */
191                 hists->thread_filter = NULL;
192                 hists__filter_by_thread(hists);
193
194                 /* now applying dso filter for 'kernel' */
195                 hists->dso_filter = fake_samples[0].map->dso;
196                 hists__filter_by_dso(hists);
197
198                 if (verbose > 2) {
199                         pr_info("Histogram for dso filter\n");
200                         print_hists_out(hists);
201                 }
202
203                 /* normal stats should be invariant */
204                 TEST_ASSERT_VAL("Invalid nr samples",
205                                 hists->stats.nr_events[PERF_RECORD_SAMPLE] == 10);
206                 TEST_ASSERT_VAL("Invalid nr hist entries",
207                                 hists->nr_entries == 9);
208                 TEST_ASSERT_VAL("Invalid total period",
209                                 hists->stats.total_period == 1000);
210
211                 /* but filter stats are changed */
212                 TEST_ASSERT_VAL("Unmatched nr samples for dso filter",
213                                 hists->stats.nr_non_filtered_samples == 3);
214                 TEST_ASSERT_VAL("Unmatched nr hist entries for dso filter",
215                                 hists->nr_non_filtered_entries == 3);
216                 TEST_ASSERT_VAL("Unmatched total period for dso filter",
217                                 hists->stats.total_non_filtered_period == 300);
218
219                 /* remove dso filter first */
220                 hists->dso_filter = NULL;
221                 hists__filter_by_dso(hists);
222
223                 /*
224                  * now applying symbol filter for 'main'.  Also note that
225                  * there's 3 samples that have 'main' symbol but the 4th
226                  * entry of fake_samples was collapsed already so it won't
227                  * be counted as a separate entry but the sample count and
228                  * total period will be remained.
229                  */
230                 hists->symbol_filter_str = "main";
231                 hists__filter_by_symbol(hists);
232
233                 if (verbose > 2) {
234                         pr_info("Histogram for symbol filter\n");
235                         print_hists_out(hists);
236                 }
237
238                 /* normal stats should be invariant */
239                 TEST_ASSERT_VAL("Invalid nr samples",
240                                 hists->stats.nr_events[PERF_RECORD_SAMPLE] == 10);
241                 TEST_ASSERT_VAL("Invalid nr hist entries",
242                                 hists->nr_entries == 9);
243                 TEST_ASSERT_VAL("Invalid total period",
244                                 hists->stats.total_period == 1000);
245
246                 /* but filter stats are changed */
247                 TEST_ASSERT_VAL("Unmatched nr samples for symbol filter",
248                                 hists->stats.nr_non_filtered_samples == 3);
249                 TEST_ASSERT_VAL("Unmatched nr hist entries for symbol filter",
250                                 hists->nr_non_filtered_entries == 2);
251                 TEST_ASSERT_VAL("Unmatched total period for symbol filter",
252                                 hists->stats.total_non_filtered_period == 300);
253
254                 /* remove symbol filter first */
255                 hists->symbol_filter_str = NULL;
256                 hists__filter_by_symbol(hists);
257
258                 /* now applying socket filters */
259                 hists->socket_filter = 2;
260                 hists__filter_by_socket(hists);
261
262                 if (verbose > 2) {
263                         pr_info("Histogram for socket filters\n");
264                         print_hists_out(hists);
265                 }
266
267                 /* normal stats should be invariant */
268                 TEST_ASSERT_VAL("Invalid nr samples",
269                                 hists->stats.nr_events[PERF_RECORD_SAMPLE] == 10);
270                 TEST_ASSERT_VAL("Invalid nr hist entries",
271                                 hists->nr_entries == 9);
272                 TEST_ASSERT_VAL("Invalid total period",
273                                 hists->stats.total_period == 1000);
274
275                 /* but filter stats are changed */
276                 TEST_ASSERT_VAL("Unmatched nr samples for socket filter",
277                                 hists->stats.nr_non_filtered_samples == 2);
278                 TEST_ASSERT_VAL("Unmatched nr hist entries for socket filter",
279                                 hists->nr_non_filtered_entries == 2);
280                 TEST_ASSERT_VAL("Unmatched total period for socket filter",
281                                 hists->stats.total_non_filtered_period == 200);
282
283                 /* remove socket filter first */
284                 hists->socket_filter = -1;
285                 hists__filter_by_socket(hists);
286
287                 /* now applying all filters at once. */
288                 hists->thread_filter = fake_samples[1].thread;
289                 hists->dso_filter = fake_samples[1].map->dso;
290                 hists__filter_by_thread(hists);
291                 hists__filter_by_dso(hists);
292
293                 if (verbose > 2) {
294                         pr_info("Histogram for all filters\n");
295                         print_hists_out(hists);
296                 }
297
298                 /* normal stats should be invariant */
299                 TEST_ASSERT_VAL("Invalid nr samples",
300                                 hists->stats.nr_events[PERF_RECORD_SAMPLE] == 10);
301                 TEST_ASSERT_VAL("Invalid nr hist entries",
302                                 hists->nr_entries == 9);
303                 TEST_ASSERT_VAL("Invalid total period",
304                                 hists->stats.total_period == 1000);
305
306                 /* but filter stats are changed */
307                 TEST_ASSERT_VAL("Unmatched nr samples for all filter",
308                                 hists->stats.nr_non_filtered_samples == 2);
309                 TEST_ASSERT_VAL("Unmatched nr hist entries for all filter",
310                                 hists->nr_non_filtered_entries == 1);
311                 TEST_ASSERT_VAL("Unmatched total period for all filter",
312                                 hists->stats.total_non_filtered_period == 200);
313         }
314
315
316         err = TEST_OK;
317
318 out:
319         /* tear down everything */
320         perf_evlist__delete(evlist);
321         reset_output_field();
322         machines__exit(&machines);
323
324         return err;
325 }