126 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2#include <stdbool.h>3#include <inttypes.h>4#include <stdlib.h>5#include <string.h>6#include <linux/bitops.h>7#include <linux/kernel.h>8#include <linux/types.h>9 10#include "event.h"11#include "evsel.h"12#include "debug.h"13#include "util/sample.h"14#include "util/synthetic-events.h"15 16#include "tests/tests.h"17#include "arch-tests.h"18 19#define COMP(m) do { \20 if (s1->m != s2->m) { \21 pr_debug("Samples differ at '"#m"'\n"); \22 return false; \23 } \24} while (0)25 26static bool samples_same(const struct perf_sample *s1,27 const struct perf_sample *s2,28 u64 type)29{30 if (type & PERF_SAMPLE_WEIGHT_STRUCT) {31 COMP(ins_lat);32 COMP(retire_lat);33 }34 35 return true;36}37 38static int do_test(u64 sample_type)39{40 struct evsel evsel = {41 .needs_swap = false,42 .core = {43 . attr = {44 .sample_type = sample_type,45 .read_format = 0,46 },47 },48 };49 union perf_event *event;50 struct perf_sample sample = {51 .weight = 101,52 .ins_lat = 102,53 .retire_lat = 103,54 };55 struct perf_sample sample_out;56 size_t i, sz, bufsz;57 int err, ret = -1;58 59 sz = perf_event__sample_event_size(&sample, sample_type, 0);60 bufsz = sz + 4096; /* Add a bit for overrun checking */61 event = malloc(bufsz);62 if (!event) {63 pr_debug("malloc failed\n");64 return -1;65 }66 67 memset(event, 0xff, bufsz);68 event->header.type = PERF_RECORD_SAMPLE;69 event->header.misc = 0;70 event->header.size = sz;71 72 err = perf_event__synthesize_sample(event, sample_type, 0, &sample);73 if (err) {74 pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",75 "perf_event__synthesize_sample", sample_type, err);76 goto out_free;77 }78 79 /* The data does not contain 0xff so we use that to check the size */80 for (i = bufsz; i > 0; i--) {81 if (*(i - 1 + (u8 *)event) != 0xff)82 break;83 }84 if (i != sz) {85 pr_debug("Event size mismatch: actual %zu vs expected %zu\n",86 i, sz);87 goto out_free;88 }89 90 evsel.sample_size = __evsel__sample_size(sample_type);91 92 err = evsel__parse_sample(&evsel, event, &sample_out);93 if (err) {94 pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",95 "evsel__parse_sample", sample_type, err);96 goto out_free;97 }98 99 if (!samples_same(&sample, &sample_out, sample_type)) {100 pr_debug("parsing failed for sample_type %#"PRIx64"\n",101 sample_type);102 goto out_free;103 }104 105 ret = 0;106out_free:107 free(event);108 109 return ret;110}111 112/**113 * test__x86_sample_parsing - test X86 specific sample parsing114 *115 * This function implements a test that synthesizes a sample event, parses it116 * and then checks that the parsed sample matches the original sample. If the117 * test passes %0 is returned, otherwise %-1 is returned.118 *119 * For now, the PERF_SAMPLE_WEIGHT_STRUCT is the only X86 specific sample type.120 * The test only checks the PERF_SAMPLE_WEIGHT_STRUCT type.121 */122int test__x86_sample_parsing(struct test_suite *test __maybe_unused, int subtest __maybe_unused)123{124 return do_test(PERF_SAMPLE_WEIGHT_STRUCT);125}126