18c2ecf20Sopenharmony_ci#include <linux/kernel.h> 28c2ecf20Sopenharmony_ci#include <linux/types.h> 38c2ecf20Sopenharmony_ci#include <stddef.h> 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include "tests.h" 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include "event.h" 88c2ecf20Sopenharmony_ci#include "evlist.h" 98c2ecf20Sopenharmony_ci#include "header.h" 108c2ecf20Sopenharmony_ci#include "debug.h" 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_cistatic int process_event(struct evlist **pevlist, union perf_event *event) 138c2ecf20Sopenharmony_ci{ 148c2ecf20Sopenharmony_ci struct perf_sample sample; 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci if (event->header.type == PERF_RECORD_HEADER_ATTR) { 178c2ecf20Sopenharmony_ci if (perf_event__process_attr(NULL, event, pevlist)) { 188c2ecf20Sopenharmony_ci pr_debug("perf_event__process_attr failed\n"); 198c2ecf20Sopenharmony_ci return -1; 208c2ecf20Sopenharmony_ci } 218c2ecf20Sopenharmony_ci return 0; 228c2ecf20Sopenharmony_ci } 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci if (event->header.type >= PERF_RECORD_USER_TYPE_START) 258c2ecf20Sopenharmony_ci return -1; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci if (!*pevlist) 288c2ecf20Sopenharmony_ci return -1; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci if (perf_evlist__parse_sample(*pevlist, event, &sample)) { 318c2ecf20Sopenharmony_ci pr_debug("perf_evlist__parse_sample failed\n"); 328c2ecf20Sopenharmony_ci return -1; 338c2ecf20Sopenharmony_ci } 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci return 0; 368c2ecf20Sopenharmony_ci} 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_cistatic int process_events(union perf_event **events, size_t count) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci struct evlist *evlist = NULL; 418c2ecf20Sopenharmony_ci int err = 0; 428c2ecf20Sopenharmony_ci size_t i; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci for (i = 0; i < count && !err; i++) 458c2ecf20Sopenharmony_ci err = process_event(&evlist, events[i]); 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci evlist__delete(evlist); 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci return err; 508c2ecf20Sopenharmony_ci} 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_cistruct test_attr_event { 538c2ecf20Sopenharmony_ci struct perf_event_header header; 548c2ecf20Sopenharmony_ci struct perf_event_attr attr; 558c2ecf20Sopenharmony_ci u64 id; 568c2ecf20Sopenharmony_ci}; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci/** 598c2ecf20Sopenharmony_ci * test__parse_no_sample_id_all - test parsing with no sample_id_all bit set. 608c2ecf20Sopenharmony_ci * 618c2ecf20Sopenharmony_ci * This function tests parsing data produced on kernel's that do not support the 628c2ecf20Sopenharmony_ci * sample_id_all bit. Without the sample_id_all bit, non-sample events (such as 638c2ecf20Sopenharmony_ci * mmap events) do not have an id sample appended, and consequently logic 648c2ecf20Sopenharmony_ci * designed to determine the id will not work. That case happens when there is 658c2ecf20Sopenharmony_ci * more than one selected event, so this test processes three events: 2 668c2ecf20Sopenharmony_ci * attributes representing the selected events and one mmap event. 678c2ecf20Sopenharmony_ci * 688c2ecf20Sopenharmony_ci * Return: %0 on success, %-1 if the test fails. 698c2ecf20Sopenharmony_ci */ 708c2ecf20Sopenharmony_ciint test__parse_no_sample_id_all(struct test *test __maybe_unused, int subtest __maybe_unused) 718c2ecf20Sopenharmony_ci{ 728c2ecf20Sopenharmony_ci int err; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci struct test_attr_event event1 = { 758c2ecf20Sopenharmony_ci .header = { 768c2ecf20Sopenharmony_ci .type = PERF_RECORD_HEADER_ATTR, 778c2ecf20Sopenharmony_ci .size = sizeof(struct test_attr_event), 788c2ecf20Sopenharmony_ci }, 798c2ecf20Sopenharmony_ci .id = 1, 808c2ecf20Sopenharmony_ci }; 818c2ecf20Sopenharmony_ci struct test_attr_event event2 = { 828c2ecf20Sopenharmony_ci .header = { 838c2ecf20Sopenharmony_ci .type = PERF_RECORD_HEADER_ATTR, 848c2ecf20Sopenharmony_ci .size = sizeof(struct test_attr_event), 858c2ecf20Sopenharmony_ci }, 868c2ecf20Sopenharmony_ci .id = 2, 878c2ecf20Sopenharmony_ci }; 888c2ecf20Sopenharmony_ci struct perf_record_mmap event3 = { 898c2ecf20Sopenharmony_ci .header = { 908c2ecf20Sopenharmony_ci .type = PERF_RECORD_MMAP, 918c2ecf20Sopenharmony_ci .size = sizeof(struct perf_record_mmap), 928c2ecf20Sopenharmony_ci }, 938c2ecf20Sopenharmony_ci }; 948c2ecf20Sopenharmony_ci union perf_event *events[] = { 958c2ecf20Sopenharmony_ci (union perf_event *)&event1, 968c2ecf20Sopenharmony_ci (union perf_event *)&event2, 978c2ecf20Sopenharmony_ci (union perf_event *)&event3, 988c2ecf20Sopenharmony_ci }; 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci err = process_events(events, ARRAY_SIZE(events)); 1018c2ecf20Sopenharmony_ci if (err) 1028c2ecf20Sopenharmony_ci return -1; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci return 0; 1058c2ecf20Sopenharmony_ci} 106