Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
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; /* Add a bit for overrun checking */
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     /* The data does not contain 0xff so we use that to check the size */
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  * test__x86_sample_parsing - test X86 specific sample parsing
0110  *
0111  * This function implements a test that synthesizes a sample event, parses it
0112  * and then checks that the parsed sample matches the original sample. If the
0113  * test passes %0 is returned, otherwise %-1 is returned.
0114  *
0115  * For now, the PERF_SAMPLE_WEIGHT_STRUCT is the only X86 specific sample type.
0116  * The test only checks the PERF_SAMPLE_WEIGHT_STRUCT type.
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 }