sample-parsing.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. // SPDX-License-Identifier: GPL-2.0
  2. #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. #include "map_symbol.h"
  10. #include "branch.h"
  11. #include "event.h"
  12. #include "evsel.h"
  13. #include "debug.h"
  14. #include "util/synthetic-events.h"
  15. #include "util/util.h"
  16. #include "tests.h"
  17. #define COMP(m) do { \
  18. if (s1->m != s2->m) { \
  19. pr_debug("Samples differ at '"#m"'\n"); \
  20. return false; \
  21. } \
  22. } while (0)
  23. #define MCOMP(m) do { \
  24. if (memcmp(&s1->m, &s2->m, sizeof(s1->m))) { \
  25. pr_debug("Samples differ at '"#m"'\n"); \
  26. return false; \
  27. } \
  28. } while (0)
  29. /*
  30. * Hardcode the expected values for branch_entry flags.
  31. * These are based on the input value (213) specified
  32. * in branch_stack variable.
  33. */
  34. #define BS_EXPECTED_BE 0xa000d00000000000
  35. #define BS_EXPECTED_LE 0x1aa00000000
  36. #define FLAG(s) s->branch_stack->entries[i].flags
  37. static bool samples_same(const struct perf_sample *s1,
  38. const struct perf_sample *s2,
  39. u64 type, u64 read_format, bool needs_swap)
  40. {
  41. size_t i;
  42. if (type & PERF_SAMPLE_IDENTIFIER)
  43. COMP(id);
  44. if (type & PERF_SAMPLE_IP)
  45. COMP(ip);
  46. if (type & PERF_SAMPLE_TID) {
  47. COMP(pid);
  48. COMP(tid);
  49. }
  50. if (type & PERF_SAMPLE_TIME)
  51. COMP(time);
  52. if (type & PERF_SAMPLE_ADDR)
  53. COMP(addr);
  54. if (type & PERF_SAMPLE_ID)
  55. COMP(id);
  56. if (type & PERF_SAMPLE_STREAM_ID)
  57. COMP(stream_id);
  58. if (type & PERF_SAMPLE_CPU)
  59. COMP(cpu);
  60. if (type & PERF_SAMPLE_PERIOD)
  61. COMP(period);
  62. if (type & PERF_SAMPLE_READ) {
  63. if (read_format & PERF_FORMAT_GROUP)
  64. COMP(read.group.nr);
  65. else
  66. COMP(read.one.value);
  67. if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
  68. COMP(read.time_enabled);
  69. if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
  70. COMP(read.time_running);
  71. /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
  72. if (read_format & PERF_FORMAT_GROUP) {
  73. for (i = 0; i < s1->read.group.nr; i++) {
  74. /* FIXME: check values without LOST */
  75. if (read_format & PERF_FORMAT_LOST)
  76. MCOMP(read.group.values[i]);
  77. }
  78. } else {
  79. COMP(read.one.id);
  80. if (read_format & PERF_FORMAT_LOST)
  81. COMP(read.one.lost);
  82. }
  83. }
  84. if (type & PERF_SAMPLE_CALLCHAIN) {
  85. COMP(callchain->nr);
  86. for (i = 0; i < s1->callchain->nr; i++)
  87. COMP(callchain->ips[i]);
  88. }
  89. if (type & PERF_SAMPLE_RAW) {
  90. COMP(raw_size);
  91. if (memcmp(s1->raw_data, s2->raw_data, s1->raw_size)) {
  92. pr_debug("Samples differ at 'raw_data'\n");
  93. return false;
  94. }
  95. }
  96. if (type & PERF_SAMPLE_BRANCH_STACK) {
  97. COMP(branch_stack->nr);
  98. COMP(branch_stack->hw_idx);
  99. for (i = 0; i < s1->branch_stack->nr; i++) {
  100. if (needs_swap)
  101. return ((host_is_bigendian()) ?
  102. (FLAG(s2).value == BS_EXPECTED_BE) :
  103. (FLAG(s2).value == BS_EXPECTED_LE));
  104. else
  105. MCOMP(branch_stack->entries[i]);
  106. }
  107. }
  108. if (type & PERF_SAMPLE_REGS_USER) {
  109. size_t sz = hweight_long(s1->user_regs.mask) * sizeof(u64);
  110. COMP(user_regs.mask);
  111. COMP(user_regs.abi);
  112. if (s1->user_regs.abi &&
  113. (!s1->user_regs.regs || !s2->user_regs.regs ||
  114. memcmp(s1->user_regs.regs, s2->user_regs.regs, sz))) {
  115. pr_debug("Samples differ at 'user_regs'\n");
  116. return false;
  117. }
  118. }
  119. if (type & PERF_SAMPLE_STACK_USER) {
  120. COMP(user_stack.size);
  121. if (memcmp(s1->user_stack.data, s2->user_stack.data,
  122. s1->user_stack.size)) {
  123. pr_debug("Samples differ at 'user_stack'\n");
  124. return false;
  125. }
  126. }
  127. if (type & PERF_SAMPLE_WEIGHT)
  128. COMP(weight);
  129. if (type & PERF_SAMPLE_DATA_SRC)
  130. COMP(data_src);
  131. if (type & PERF_SAMPLE_TRANSACTION)
  132. COMP(transaction);
  133. if (type & PERF_SAMPLE_REGS_INTR) {
  134. size_t sz = hweight_long(s1->intr_regs.mask) * sizeof(u64);
  135. COMP(intr_regs.mask);
  136. COMP(intr_regs.abi);
  137. if (s1->intr_regs.abi &&
  138. (!s1->intr_regs.regs || !s2->intr_regs.regs ||
  139. memcmp(s1->intr_regs.regs, s2->intr_regs.regs, sz))) {
  140. pr_debug("Samples differ at 'intr_regs'\n");
  141. return false;
  142. }
  143. }
  144. if (type & PERF_SAMPLE_PHYS_ADDR)
  145. COMP(phys_addr);
  146. if (type & PERF_SAMPLE_CGROUP)
  147. COMP(cgroup);
  148. if (type & PERF_SAMPLE_DATA_PAGE_SIZE)
  149. COMP(data_page_size);
  150. if (type & PERF_SAMPLE_CODE_PAGE_SIZE)
  151. COMP(code_page_size);
  152. if (type & PERF_SAMPLE_AUX) {
  153. COMP(aux_sample.size);
  154. if (memcmp(s1->aux_sample.data, s2->aux_sample.data,
  155. s1->aux_sample.size)) {
  156. pr_debug("Samples differ at 'aux_sample'\n");
  157. return false;
  158. }
  159. }
  160. return true;
  161. }
  162. static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
  163. {
  164. struct evsel evsel = {
  165. .needs_swap = false,
  166. .core = {
  167. . attr = {
  168. .sample_type = sample_type,
  169. .read_format = read_format,
  170. },
  171. },
  172. };
  173. union perf_event *event;
  174. union {
  175. struct ip_callchain callchain;
  176. u64 data[64];
  177. } callchain = {
  178. /* 3 ips */
  179. .data = {3, 201, 202, 203},
  180. };
  181. union {
  182. struct branch_stack branch_stack;
  183. u64 data[64];
  184. } branch_stack = {
  185. /* 1 branch_entry */
  186. .data = {1, -1ULL, 211, 212, 213},
  187. };
  188. u64 regs[64];
  189. const u32 raw_data[] = {0x12345678, 0x0a0b0c0d, 0x11020304, 0x05060708, 0 };
  190. const u64 data[] = {0x2211443366558877ULL, 0, 0xaabbccddeeff4321ULL};
  191. const u64 aux_data[] = {0xa55a, 0, 0xeeddee, 0x0282028202820282};
  192. struct perf_sample sample = {
  193. .ip = 101,
  194. .pid = 102,
  195. .tid = 103,
  196. .time = 104,
  197. .addr = 105,
  198. .id = 106,
  199. .stream_id = 107,
  200. .period = 108,
  201. .weight = 109,
  202. .cpu = 110,
  203. .raw_size = sizeof(raw_data),
  204. .data_src = 111,
  205. .transaction = 112,
  206. .raw_data = (void *)raw_data,
  207. .callchain = &callchain.callchain,
  208. .no_hw_idx = false,
  209. .branch_stack = &branch_stack.branch_stack,
  210. .user_regs = {
  211. .abi = PERF_SAMPLE_REGS_ABI_64,
  212. .mask = sample_regs,
  213. .regs = regs,
  214. },
  215. .user_stack = {
  216. .size = sizeof(data),
  217. .data = (void *)data,
  218. },
  219. .read = {
  220. .time_enabled = 0x030a59d664fca7deULL,
  221. .time_running = 0x011b6ae553eb98edULL,
  222. },
  223. .intr_regs = {
  224. .abi = PERF_SAMPLE_REGS_ABI_64,
  225. .mask = sample_regs,
  226. .regs = regs,
  227. },
  228. .phys_addr = 113,
  229. .cgroup = 114,
  230. .data_page_size = 115,
  231. .code_page_size = 116,
  232. .aux_sample = {
  233. .size = sizeof(aux_data),
  234. .data = (void *)aux_data,
  235. },
  236. };
  237. struct sample_read_value values[] = {{1, 5, 0}, {9, 3, 0}, {2, 7, 0}, {6, 4, 1},};
  238. struct perf_sample sample_out, sample_out_endian;
  239. size_t i, sz, bufsz;
  240. int err, ret = -1;
  241. if (sample_type & PERF_SAMPLE_REGS_USER)
  242. evsel.core.attr.sample_regs_user = sample_regs;
  243. if (sample_type & PERF_SAMPLE_REGS_INTR)
  244. evsel.core.attr.sample_regs_intr = sample_regs;
  245. if (sample_type & PERF_SAMPLE_BRANCH_STACK)
  246. evsel.core.attr.branch_sample_type |= PERF_SAMPLE_BRANCH_HW_INDEX;
  247. for (i = 0; i < sizeof(regs); i++)
  248. *(i + (u8 *)regs) = i & 0xfe;
  249. if (read_format & PERF_FORMAT_GROUP) {
  250. sample.read.group.nr = 4;
  251. sample.read.group.values = values;
  252. } else {
  253. sample.read.one.value = 0x08789faeb786aa87ULL;
  254. sample.read.one.id = 99;
  255. sample.read.one.lost = 1;
  256. }
  257. sz = perf_event__sample_event_size(&sample, sample_type, read_format);
  258. bufsz = sz + 4096; /* Add a bit for overrun checking */
  259. event = malloc(bufsz);
  260. if (!event) {
  261. pr_debug("malloc failed\n");
  262. return -1;
  263. }
  264. memset(event, 0xff, bufsz);
  265. event->header.type = PERF_RECORD_SAMPLE;
  266. event->header.misc = 0;
  267. event->header.size = sz;
  268. err = perf_event__synthesize_sample(event, sample_type, read_format,
  269. &sample);
  270. if (err) {
  271. pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
  272. "perf_event__synthesize_sample", sample_type, err);
  273. goto out_free;
  274. }
  275. /* The data does not contain 0xff so we use that to check the size */
  276. for (i = bufsz; i > 0; i--) {
  277. if (*(i - 1 + (u8 *)event) != 0xff)
  278. break;
  279. }
  280. if (i != sz) {
  281. pr_debug("Event size mismatch: actual %zu vs expected %zu\n",
  282. i, sz);
  283. goto out_free;
  284. }
  285. evsel.sample_size = __evsel__sample_size(sample_type);
  286. err = evsel__parse_sample(&evsel, event, &sample_out);
  287. if (err) {
  288. pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
  289. "evsel__parse_sample", sample_type, err);
  290. goto out_free;
  291. }
  292. if (!samples_same(&sample, &sample_out, sample_type, read_format, evsel.needs_swap)) {
  293. pr_debug("parsing failed for sample_type %#"PRIx64"\n",
  294. sample_type);
  295. goto out_free;
  296. }
  297. if (sample_type == PERF_SAMPLE_BRANCH_STACK) {
  298. evsel.needs_swap = true;
  299. evsel.sample_size = __evsel__sample_size(sample_type);
  300. err = evsel__parse_sample(&evsel, event, &sample_out_endian);
  301. if (err) {
  302. pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
  303. "evsel__parse_sample", sample_type, err);
  304. goto out_free;
  305. }
  306. if (!samples_same(&sample, &sample_out_endian, sample_type, read_format, evsel.needs_swap)) {
  307. pr_debug("parsing failed for sample_type %#"PRIx64"\n",
  308. sample_type);
  309. goto out_free;
  310. }
  311. }
  312. ret = 0;
  313. out_free:
  314. free(event);
  315. if (ret && read_format)
  316. pr_debug("read_format %#"PRIx64"\n", read_format);
  317. return ret;
  318. }
  319. /**
  320. * test__sample_parsing - test sample parsing.
  321. *
  322. * This function implements a test that synthesizes a sample event, parses it
  323. * and then checks that the parsed sample matches the original sample. The test
  324. * checks sample format bits separately and together. If the test passes %0 is
  325. * returned, otherwise %-1 is returned.
  326. */
  327. static int test__sample_parsing(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
  328. {
  329. const u64 rf[] = {4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 28, 29, 30, 31};
  330. u64 sample_type;
  331. u64 sample_regs;
  332. size_t i;
  333. int err;
  334. /*
  335. * Fail the test if it has not been updated when new sample format bits
  336. * were added. Please actually update the test rather than just change
  337. * the condition below.
  338. */
  339. if (PERF_SAMPLE_MAX > PERF_SAMPLE_WEIGHT_STRUCT << 1) {
  340. pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n");
  341. return -1;
  342. }
  343. /* Test each sample format bit separately */
  344. for (sample_type = 1; sample_type != PERF_SAMPLE_MAX;
  345. sample_type <<= 1) {
  346. /* Test read_format variations */
  347. if (sample_type == PERF_SAMPLE_READ) {
  348. for (i = 0; i < ARRAY_SIZE(rf); i++) {
  349. err = do_test(sample_type, 0, rf[i]);
  350. if (err)
  351. return err;
  352. }
  353. continue;
  354. }
  355. sample_regs = 0;
  356. if (sample_type == PERF_SAMPLE_REGS_USER)
  357. sample_regs = 0x3fff;
  358. if (sample_type == PERF_SAMPLE_REGS_INTR)
  359. sample_regs = 0xff0fff;
  360. err = do_test(sample_type, sample_regs, 0);
  361. if (err)
  362. return err;
  363. }
  364. /*
  365. * Test all sample format bits together
  366. * Note: PERF_SAMPLE_WEIGHT and PERF_SAMPLE_WEIGHT_STRUCT cannot
  367. * be set simultaneously.
  368. */
  369. sample_type = (PERF_SAMPLE_MAX - 1) & ~PERF_SAMPLE_WEIGHT;
  370. sample_regs = 0x3fff; /* shared yb intr and user regs */
  371. for (i = 0; i < ARRAY_SIZE(rf); i++) {
  372. err = do_test(sample_type, sample_regs, rf[i]);
  373. if (err)
  374. return err;
  375. }
  376. return 0;
  377. }
  378. DEFINE_SUITE("Sample parsing", sample_parsing);