1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/kernel.h> 3 #include <linux/types.h> 4 #include <stddef.h> 5 6 #include "tests.h" 7 8 #include "event.h" 9 #include "evlist.h" 10 #include "header.h" 11 #include "util.h" 12 #include "debug.h" 13 14 static int process_event(struct perf_evlist **pevlist, union perf_event *event) 15 { 16 struct perf_sample sample; 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 if (perf_evlist__parse_sample(*pevlist, event, &sample)) { 33 pr_debug("perf_evlist__parse_sample failed\n"); 34 return -1; 35 } 36 37 return 0; 38 } 39 40 static int process_events(union perf_event **events, size_t count) 41 { 42 struct perf_evlist *evlist = NULL; 43 int err = 0; 44 size_t i; 45 46 for (i = 0; i < count && !err; i++) 47 err = process_event(&evlist, events[i]); 48 49 perf_evlist__delete(evlist); 50 51 return err; 52 } 53 54 struct test_attr_event { 55 struct perf_event_header header; 56 struct perf_event_attr attr; 57 u64 id; 58 }; 59 60 /** 61 * test__parse_no_sample_id_all - test parsing with no sample_id_all bit set. 62 * 63 * This function tests parsing data produced on kernel's that do not support the 64 * sample_id_all bit. Without the sample_id_all bit, non-sample events (such as 65 * mmap events) do not have an id sample appended, and consequently logic 66 * designed to determine the id will not work. That case happens when there is 67 * more than one selected event, so this test processes three events: 2 68 * attributes representing the selected events and one mmap event. 69 * 70 * Return: %0 on success, %-1 if the test fails. 71 */ 72 int test__parse_no_sample_id_all(struct test *test __maybe_unused, int subtest __maybe_unused) 73 { 74 int err; 75 76 struct test_attr_event event1 = { 77 .header = { 78 .type = PERF_RECORD_HEADER_ATTR, 79 .size = sizeof(struct test_attr_event), 80 }, 81 .id = 1, 82 }; 83 struct test_attr_event event2 = { 84 .header = { 85 .type = PERF_RECORD_HEADER_ATTR, 86 .size = sizeof(struct test_attr_event), 87 }, 88 .id = 2, 89 }; 90 struct mmap_event event3 = { 91 .header = { 92 .type = PERF_RECORD_MMAP, 93 .size = sizeof(struct mmap_event), 94 }, 95 }; 96 union perf_event *events[] = { 97 (union perf_event *)&event1, 98 (union perf_event *)&event2, 99 (union perf_event *)&event3, 100 }; 101 102 err = process_events(events, ARRAY_SIZE(events)); 103 if (err) 104 return -1; 105 106 return 0; 107 } 108