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