sample-parsing.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  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(struct perf_sample *s1,
  38. 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. struct regs_dump *s1_regs = perf_sample__user_regs(s1);
  110. struct regs_dump *s2_regs = perf_sample__user_regs(s2);
  111. size_t sz = hweight_long(s1_regs->mask) * sizeof(u64);
  112. COMP(user_regs->mask);
  113. COMP(user_regs->abi);
  114. if (s1_regs->abi &&
  115. (!s1_regs->regs || !s2_regs->regs ||
  116. memcmp(s1_regs->regs, s2_regs->regs, sz))) {
  117. pr_debug("Samples differ at 'user_regs'\n");
  118. return false;
  119. }
  120. }
  121. if (type & PERF_SAMPLE_STACK_USER) {
  122. COMP(user_stack.size);
  123. if (memcmp(s1->user_stack.data, s2->user_stack.data,
  124. s1->user_stack.size)) {
  125. pr_debug("Samples differ at 'user_stack'\n");
  126. return false;
  127. }
  128. }
  129. if (type & PERF_SAMPLE_WEIGHT)
  130. COMP(weight);
  131. if (type & PERF_SAMPLE_WEIGHT_STRUCT) {
  132. COMP(weight);
  133. COMP(ins_lat);
  134. COMP(weight3);
  135. }
  136. if (type & PERF_SAMPLE_DATA_SRC)
  137. COMP(data_src);
  138. if (type & PERF_SAMPLE_TRANSACTION)
  139. COMP(transaction);
  140. if (type & PERF_SAMPLE_REGS_INTR) {
  141. struct regs_dump *s1_regs = perf_sample__intr_regs(s1);
  142. struct regs_dump *s2_regs = perf_sample__intr_regs(s2);
  143. size_t sz = hweight_long(s1_regs->mask) * sizeof(u64);
  144. COMP(intr_regs->mask);
  145. COMP(intr_regs->abi);
  146. if (s1_regs->abi &&
  147. (!s1_regs->regs || !s2_regs->regs ||
  148. memcmp(s1_regs->regs, s2_regs->regs, sz))) {
  149. pr_debug("Samples differ at 'intr_regs'\n");
  150. return false;
  151. }
  152. }
  153. if (type & PERF_SAMPLE_PHYS_ADDR)
  154. COMP(phys_addr);
  155. if (type & PERF_SAMPLE_CGROUP)
  156. COMP(cgroup);
  157. if (type & PERF_SAMPLE_DATA_PAGE_SIZE)
  158. COMP(data_page_size);
  159. if (type & PERF_SAMPLE_CODE_PAGE_SIZE)
  160. COMP(code_page_size);
  161. if (type & PERF_SAMPLE_AUX) {
  162. COMP(aux_sample.size);
  163. if (memcmp(s1->aux_sample.data, s2->aux_sample.data,
  164. s1->aux_sample.size)) {
  165. pr_debug("Samples differ at 'aux_sample'\n");
  166. return false;
  167. }
  168. }
  169. return true;
  170. }
  171. static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
  172. {
  173. struct evsel evsel = {
  174. .needs_swap = false,
  175. .core = {
  176. . attr = {
  177. .sample_type = sample_type,
  178. .read_format = read_format,
  179. },
  180. },
  181. };
  182. union perf_event *event;
  183. union {
  184. struct ip_callchain callchain;
  185. u64 data[64];
  186. } callchain = {
  187. /* 3 ips */
  188. .data = {3, 201, 202, 203},
  189. };
  190. union {
  191. struct branch_stack branch_stack;
  192. u64 data[64];
  193. } branch_stack = {
  194. /* 1 branch_entry */
  195. .data = {1, -1ULL, 211, 212, 213},
  196. };
  197. u64 regs[64];
  198. const u32 raw_data[] = {0x12345678, 0x0a0b0c0d, 0x11020304, 0x05060708, 0 };
  199. const u64 data[] = {0x2211443366558877ULL, 0, 0xaabbccddeeff4321ULL};
  200. const u64 aux_data[] = {0xa55a, 0, 0xeeddee, 0x0282028202820282};
  201. struct regs_dump user_regs = {
  202. .abi = PERF_SAMPLE_REGS_ABI_64,
  203. .mask = sample_regs,
  204. .regs = regs,
  205. };
  206. struct regs_dump intr_regs = {
  207. .abi = PERF_SAMPLE_REGS_ABI_64,
  208. .mask = sample_regs,
  209. .regs = regs,
  210. };
  211. struct perf_sample sample = {
  212. .ip = 101,
  213. .pid = 102,
  214. .tid = 103,
  215. .time = 104,
  216. .addr = 105,
  217. .id = 106,
  218. .stream_id = 107,
  219. .period = 108,
  220. .weight = 109,
  221. .cpu = 110,
  222. .raw_size = sizeof(raw_data),
  223. .data_src = 111,
  224. .transaction = 112,
  225. .raw_data = (void *)raw_data,
  226. .callchain = &callchain.callchain,
  227. .no_hw_idx = false,
  228. .branch_stack = &branch_stack.branch_stack,
  229. .user_regs = &user_regs,
  230. .user_stack = {
  231. .size = sizeof(data),
  232. .data = (void *)data,
  233. },
  234. .read = {
  235. .time_enabled = 0x030a59d664fca7deULL,
  236. .time_running = 0x011b6ae553eb98edULL,
  237. },
  238. .intr_regs = &intr_regs,
  239. .phys_addr = 113,
  240. .cgroup = 114,
  241. .data_page_size = 115,
  242. .code_page_size = 116,
  243. .ins_lat = 117,
  244. .weight3 = 118,
  245. .aux_sample = {
  246. .size = sizeof(aux_data),
  247. .data = (void *)aux_data,
  248. },
  249. };
  250. struct sample_read_value values[] = {{1, 5, 0}, {9, 3, 0}, {2, 7, 0}, {6, 4, 1},};
  251. struct perf_sample sample_out, sample_out_endian;
  252. size_t i, sz, bufsz;
  253. int err, ret = -1;
  254. perf_sample__init(&sample_out, /*all=*/false);
  255. perf_sample__init(&sample_out_endian, /*all=*/false);
  256. if (sample_type & PERF_SAMPLE_REGS_USER)
  257. evsel.core.attr.sample_regs_user = sample_regs;
  258. if (sample_type & PERF_SAMPLE_REGS_INTR)
  259. evsel.core.attr.sample_regs_intr = sample_regs;
  260. if (sample_type & PERF_SAMPLE_BRANCH_STACK)
  261. evsel.core.attr.branch_sample_type |= PERF_SAMPLE_BRANCH_HW_INDEX;
  262. for (i = 0; i < sizeof(regs); i++)
  263. *(i + (u8 *)regs) = i & 0xfe;
  264. if (read_format & PERF_FORMAT_GROUP) {
  265. sample.read.group.nr = 4;
  266. sample.read.group.values = values;
  267. } else {
  268. sample.read.one.value = 0x08789faeb786aa87ULL;
  269. sample.read.one.id = 99;
  270. sample.read.one.lost = 1;
  271. }
  272. sz = perf_event__sample_event_size(&sample, sample_type, read_format);
  273. bufsz = sz + 4096; /* Add a bit for overrun checking */
  274. event = malloc(bufsz);
  275. if (!event) {
  276. pr_debug("malloc failed\n");
  277. return -1;
  278. }
  279. memset(event, 0xff, bufsz);
  280. event->header.type = PERF_RECORD_SAMPLE;
  281. event->header.misc = 0;
  282. event->header.size = sz;
  283. err = perf_event__synthesize_sample(event, sample_type, read_format,
  284. &sample);
  285. if (err) {
  286. pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
  287. "perf_event__synthesize_sample", sample_type, err);
  288. goto out_free;
  289. }
  290. /* The data does not contain 0xff so we use that to check the size */
  291. for (i = bufsz; i > 0; i--) {
  292. if (*(i - 1 + (u8 *)event) != 0xff)
  293. break;
  294. }
  295. if (i != sz) {
  296. pr_debug("Event size mismatch: actual %zu vs expected %zu\n",
  297. i, sz);
  298. goto out_free;
  299. }
  300. evsel.sample_size = __evsel__sample_size(sample_type);
  301. err = evsel__parse_sample(&evsel, event, &sample_out);
  302. if (err) {
  303. pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
  304. "evsel__parse_sample", sample_type, err);
  305. goto out_free;
  306. }
  307. if (!samples_same(&sample, &sample_out, sample_type, read_format, evsel.needs_swap)) {
  308. pr_debug("parsing failed for sample_type %#"PRIx64"\n",
  309. sample_type);
  310. goto out_free;
  311. }
  312. if (sample_type == PERF_SAMPLE_BRANCH_STACK) {
  313. evsel.needs_swap = true;
  314. evsel.sample_size = __evsel__sample_size(sample_type);
  315. err = evsel__parse_sample(&evsel, event, &sample_out_endian);
  316. if (err) {
  317. pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
  318. "evsel__parse_sample", sample_type, err);
  319. goto out_free;
  320. }
  321. if (!samples_same(&sample, &sample_out_endian, sample_type, read_format, evsel.needs_swap)) {
  322. pr_debug("parsing failed for sample_type %#"PRIx64"\n",
  323. sample_type);
  324. goto out_free;
  325. }
  326. }
  327. ret = 0;
  328. out_free:
  329. free(event);
  330. perf_sample__exit(&sample_out_endian);
  331. perf_sample__exit(&sample_out);
  332. if (ret && read_format)
  333. pr_debug("read_format %#"PRIx64"\n", read_format);
  334. return ret;
  335. }
  336. /**
  337. * test__sample_parsing - test sample parsing.
  338. *
  339. * This function implements a test that synthesizes a sample event, parses it
  340. * and then checks that the parsed sample matches the original sample. The test
  341. * checks sample format bits separately and together. If the test passes %0 is
  342. * returned, otherwise %-1 is returned.
  343. */
  344. static int test__sample_parsing(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
  345. {
  346. const u64 rf[] = {4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 28, 29, 30, 31};
  347. u64 sample_type;
  348. u64 sample_regs;
  349. size_t i;
  350. int err;
  351. /*
  352. * Fail the test if it has not been updated when new sample format bits
  353. * were added. Please actually update the test rather than just change
  354. * the condition below.
  355. */
  356. if (PERF_SAMPLE_MAX > PERF_SAMPLE_WEIGHT_STRUCT << 1) {
  357. pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n");
  358. return -1;
  359. }
  360. /* Test each sample format bit separately */
  361. for (sample_type = 1; sample_type != PERF_SAMPLE_MAX;
  362. sample_type <<= 1) {
  363. /* Test read_format variations */
  364. if (sample_type == PERF_SAMPLE_READ) {
  365. for (i = 0; i < ARRAY_SIZE(rf); i++) {
  366. err = do_test(sample_type, 0, rf[i]);
  367. if (err)
  368. return err;
  369. }
  370. continue;
  371. }
  372. sample_regs = 0;
  373. if (sample_type == PERF_SAMPLE_REGS_USER)
  374. sample_regs = 0x3fff;
  375. if (sample_type == PERF_SAMPLE_REGS_INTR)
  376. sample_regs = 0xff0fff;
  377. err = do_test(sample_type, sample_regs, 0);
  378. if (err)
  379. return err;
  380. }
  381. /*
  382. * Test all sample format bits together
  383. * Note: PERF_SAMPLE_WEIGHT and PERF_SAMPLE_WEIGHT_STRUCT cannot
  384. * be set simultaneously.
  385. */
  386. sample_type = (PERF_SAMPLE_MAX - 1) & ~PERF_SAMPLE_WEIGHT;
  387. sample_regs = 0x3fff; /* shared yb intr and user regs */
  388. for (i = 0; i < ARRAY_SIZE(rf); i++) {
  389. err = do_test(sample_type, sample_regs, rf[i]);
  390. if (err)
  391. return err;
  392. }
  393. sample_type = (PERF_SAMPLE_MAX - 1) & ~PERF_SAMPLE_WEIGHT_STRUCT;
  394. for (i = 0; i < ARRAY_SIZE(rf); i++) {
  395. err = do_test(sample_type, sample_regs, rf[i]);
  396. if (err)
  397. return err;
  398. }
  399. return 0;
  400. }
  401. DEFINE_SUITE("Sample parsing", sample_parsing);