0001
0002 #include <stdbool.h>
0003 #include <inttypes.h>
0004 #include <stdlib.h>
0005 #include <string.h>
0006 #include <linux/bitops.h>
0007 #include <linux/kernel.h>
0008 #include <linux/types.h>
0009
0010 #include "event.h"
0011 #include "evsel.h"
0012 #include "debug.h"
0013 #include "util/synthetic-events.h"
0014
0015 #include "tests/tests.h"
0016 #include "arch-tests.h"
0017
0018 #define COMP(m) do { \
0019 if (s1->m != s2->m) { \
0020 pr_debug("Samples differ at '"#m"'\n"); \
0021 return false; \
0022 } \
0023 } while (0)
0024
0025 static bool samples_same(const struct perf_sample *s1,
0026 const struct perf_sample *s2,
0027 u64 type)
0028 {
0029 if (type & PERF_SAMPLE_WEIGHT_STRUCT)
0030 COMP(ins_lat);
0031
0032 return true;
0033 }
0034
0035 static int do_test(u64 sample_type)
0036 {
0037 struct evsel evsel = {
0038 .needs_swap = false,
0039 .core = {
0040 . attr = {
0041 .sample_type = sample_type,
0042 .read_format = 0,
0043 },
0044 },
0045 };
0046 union perf_event *event;
0047 struct perf_sample sample = {
0048 .weight = 101,
0049 .ins_lat = 102,
0050 };
0051 struct perf_sample sample_out;
0052 size_t i, sz, bufsz;
0053 int err, ret = -1;
0054
0055 sz = perf_event__sample_event_size(&sample, sample_type, 0);
0056 bufsz = sz + 4096;
0057 event = malloc(bufsz);
0058 if (!event) {
0059 pr_debug("malloc failed\n");
0060 return -1;
0061 }
0062
0063 memset(event, 0xff, bufsz);
0064 event->header.type = PERF_RECORD_SAMPLE;
0065 event->header.misc = 0;
0066 event->header.size = sz;
0067
0068 err = perf_event__synthesize_sample(event, sample_type, 0, &sample);
0069 if (err) {
0070 pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
0071 "perf_event__synthesize_sample", sample_type, err);
0072 goto out_free;
0073 }
0074
0075
0076 for (i = bufsz; i > 0; i--) {
0077 if (*(i - 1 + (u8 *)event) != 0xff)
0078 break;
0079 }
0080 if (i != sz) {
0081 pr_debug("Event size mismatch: actual %zu vs expected %zu\n",
0082 i, sz);
0083 goto out_free;
0084 }
0085
0086 evsel.sample_size = __evsel__sample_size(sample_type);
0087
0088 err = evsel__parse_sample(&evsel, event, &sample_out);
0089 if (err) {
0090 pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
0091 "evsel__parse_sample", sample_type, err);
0092 goto out_free;
0093 }
0094
0095 if (!samples_same(&sample, &sample_out, sample_type)) {
0096 pr_debug("parsing failed for sample_type %#"PRIx64"\n",
0097 sample_type);
0098 goto out_free;
0099 }
0100
0101 ret = 0;
0102 out_free:
0103 free(event);
0104
0105 return ret;
0106 }
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118 int test__x86_sample_parsing(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
0119 {
0120 return do_test(PERF_SAMPLE_WEIGHT_STRUCT);
0121 }