xref: /linux/tools/perf/tests/parse-no-sample-id-all.c (revision 4f9786035f9e519db41375818e1d0b5f20da2f10)
1 #include <linux/kernel.h>
2 #include <linux/types.h>
3 #include <stddef.h>
4 
5 #include "tests.h"
6 
7 #include "event.h"
8 #include "evlist.h"
9 #include "header.h"
10 #include "debug.h"
11 #include "util/sample.h"
12 
13 static int process_event(struct evlist **pevlist, union perf_event *event)
14 {
15 	struct perf_sample sample;
16 	int ret;
17 
18 	if (event->header.type == PERF_RECORD_HEADER_ATTR) {
19 		if (perf_event__process_attr(NULL, event, pevlist)) {
20 			pr_debug("perf_event__process_attr failed\n");
21 			return -1;
22 		}
23 		return 0;
24 	}
25 
26 	if (event->header.type >= PERF_RECORD_USER_TYPE_START)
27 		return -1;
28 
29 	if (!*pevlist)
30 		return -1;
31 
32 	perf_sample__init(&sample, /*all=*/false);
33 	ret = evlist__parse_sample(*pevlist, event, &sample);
34 	perf_sample__exit(&sample);
35 	if (ret) {
36 		pr_debug("evlist__parse_sample failed\n");
37 		return -1;
38 	}
39 
40 	return 0;
41 }
42 
43 static int process_events(union perf_event **events, size_t count)
44 {
45 	struct evlist *evlist = NULL;
46 	int err = 0;
47 	size_t i;
48 
49 	for (i = 0; i < count && !err; i++)
50 		err = process_event(&evlist, events[i]);
51 
52 	evlist__delete(evlist);
53 
54 	return err;
55 }
56 
57 struct test_attr_event {
58 	struct perf_event_header header;
59 	struct perf_event_attr	 attr;
60 	u64 id;
61 };
62 
63 /**
64  * test__parse_no_sample_id_all - test parsing with no sample_id_all bit set.
65  *
66  * This function tests parsing data produced on kernel's that do not support the
67  * sample_id_all bit.  Without the sample_id_all bit, non-sample events (such as
68  * mmap events) do not have an id sample appended, and consequently logic
69  * designed to determine the id will not work.  That case happens when there is
70  * more than one selected event, so this test processes three events: 2
71  * attributes representing the selected events and one mmap event.
72  *
73  * Return: %0 on success, %-1 if the test fails.
74  */
75 static int test__parse_no_sample_id_all(struct test_suite *test __maybe_unused,
76 					int subtest __maybe_unused)
77 {
78 	int err;
79 
80 	struct test_attr_event event1 = {
81 		.header = {
82 			.type = PERF_RECORD_HEADER_ATTR,
83 			.size = sizeof(struct test_attr_event),
84 		},
85 		.id = 1,
86 	};
87 	struct test_attr_event event2 = {
88 		.header = {
89 			.type = PERF_RECORD_HEADER_ATTR,
90 			.size = sizeof(struct test_attr_event),
91 		},
92 		.id = 2,
93 	};
94 	struct perf_record_mmap event3 = {
95 		.header = {
96 			.type = PERF_RECORD_MMAP,
97 			.size = sizeof(struct perf_record_mmap),
98 		},
99 	};
100 	union perf_event *events[] = {
101 		(union perf_event *)&event1,
102 		(union perf_event *)&event2,
103 		(union perf_event *)&event3,
104 	};
105 
106 	err = process_events(events, ARRAY_SIZE(events));
107 	if (err)
108 		return -1;
109 
110 	return 0;
111 }
112 
113 DEFINE_SUITE("Parse with no sample_id_all bit set", parse_no_sample_id_all);
114