test-evsel.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <stdarg.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <linux/perf_event.h>
  6. #include <linux/kernel.h>
  7. #include <perf/cpumap.h>
  8. #include <perf/threadmap.h>
  9. #include <perf/evsel.h>
  10. #include <internal/evsel.h>
  11. #include <internal/tests.h>
  12. #include "tests.h"
  13. static int libperf_print(enum libperf_print_level level,
  14. const char *fmt, va_list ap)
  15. {
  16. return vfprintf(stderr, fmt, ap);
  17. }
  18. static int test_stat_cpu(void)
  19. {
  20. struct perf_cpu_map *cpus;
  21. struct perf_evsel *evsel;
  22. struct perf_event_attr attr = {
  23. .type = PERF_TYPE_SOFTWARE,
  24. .config = PERF_COUNT_SW_CPU_CLOCK,
  25. };
  26. int err, idx;
  27. cpus = perf_cpu_map__new(NULL);
  28. __T("failed to create cpus", cpus);
  29. evsel = perf_evsel__new(&attr);
  30. __T("failed to create evsel", evsel);
  31. err = perf_evsel__open(evsel, cpus, NULL);
  32. __T("failed to open evsel", err == 0);
  33. for (idx = 0; idx < perf_cpu_map__nr(cpus); idx++) {
  34. struct perf_counts_values counts = { .val = 0 };
  35. perf_evsel__read(evsel, idx, 0, &counts);
  36. __T("failed to read value for evsel", counts.val != 0);
  37. }
  38. perf_evsel__close(evsel);
  39. perf_evsel__delete(evsel);
  40. perf_cpu_map__put(cpus);
  41. return 0;
  42. }
  43. static int test_stat_thread(void)
  44. {
  45. struct perf_counts_values counts = { .val = 0 };
  46. struct perf_thread_map *threads;
  47. struct perf_evsel *evsel;
  48. struct perf_event_attr attr = {
  49. .type = PERF_TYPE_SOFTWARE,
  50. .config = PERF_COUNT_SW_TASK_CLOCK,
  51. };
  52. int err;
  53. threads = perf_thread_map__new_dummy();
  54. __T("failed to create threads", threads);
  55. perf_thread_map__set_pid(threads, 0, 0);
  56. evsel = perf_evsel__new(&attr);
  57. __T("failed to create evsel", evsel);
  58. err = perf_evsel__open(evsel, NULL, threads);
  59. __T("failed to open evsel", err == 0);
  60. perf_evsel__read(evsel, 0, 0, &counts);
  61. __T("failed to read value for evsel", counts.val != 0);
  62. perf_evsel__close(evsel);
  63. perf_evsel__delete(evsel);
  64. perf_thread_map__put(threads);
  65. return 0;
  66. }
  67. static int test_stat_thread_enable(void)
  68. {
  69. struct perf_counts_values counts = { .val = 0 };
  70. struct perf_thread_map *threads;
  71. struct perf_evsel *evsel;
  72. struct perf_event_attr attr = {
  73. .type = PERF_TYPE_SOFTWARE,
  74. .config = PERF_COUNT_SW_TASK_CLOCK,
  75. .disabled = 1,
  76. };
  77. int err;
  78. threads = perf_thread_map__new_dummy();
  79. __T("failed to create threads", threads);
  80. perf_thread_map__set_pid(threads, 0, 0);
  81. evsel = perf_evsel__new(&attr);
  82. __T("failed to create evsel", evsel);
  83. err = perf_evsel__open(evsel, NULL, threads);
  84. __T("failed to open evsel", err == 0);
  85. perf_evsel__read(evsel, 0, 0, &counts);
  86. __T("failed to read value for evsel", counts.val == 0);
  87. err = perf_evsel__enable(evsel);
  88. __T("failed to enable evsel", err == 0);
  89. perf_evsel__read(evsel, 0, 0, &counts);
  90. __T("failed to read value for evsel", counts.val != 0);
  91. err = perf_evsel__disable(evsel);
  92. __T("failed to enable evsel", err == 0);
  93. perf_evsel__close(evsel);
  94. perf_evsel__delete(evsel);
  95. perf_thread_map__put(threads);
  96. return 0;
  97. }
  98. static int test_stat_user_read(int event)
  99. {
  100. struct perf_counts_values counts = { .val = 0 };
  101. struct perf_thread_map *threads;
  102. struct perf_evsel *evsel;
  103. struct perf_event_mmap_page *pc;
  104. struct perf_event_attr attr = {
  105. .type = PERF_TYPE_HARDWARE,
  106. .config = event,
  107. #ifdef __aarch64__
  108. .config1 = 0x2, /* Request user access */
  109. #endif
  110. };
  111. int err, i;
  112. threads = perf_thread_map__new_dummy();
  113. __T("failed to create threads", threads);
  114. perf_thread_map__set_pid(threads, 0, 0);
  115. evsel = perf_evsel__new(&attr);
  116. __T("failed to create evsel", evsel);
  117. err = perf_evsel__open(evsel, NULL, threads);
  118. __T("failed to open evsel", err == 0);
  119. err = perf_evsel__mmap(evsel, 0);
  120. __T("failed to mmap evsel", err == 0);
  121. pc = perf_evsel__mmap_base(evsel, 0, 0);
  122. __T("failed to get mmapped address", pc);
  123. #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
  124. __T("userspace counter access not supported", pc->cap_user_rdpmc);
  125. __T("userspace counter access not enabled", pc->index);
  126. __T("userspace counter width not set", pc->pmc_width >= 32);
  127. #endif
  128. perf_evsel__read(evsel, 0, 0, &counts);
  129. __T("failed to read value for evsel", counts.val != 0);
  130. for (i = 0; i < 5; i++) {
  131. volatile int count = 0x10000 << i;
  132. __u64 start, end, last = 0;
  133. __T_VERBOSE("\tloop = %u, ", count);
  134. perf_evsel__read(evsel, 0, 0, &counts);
  135. start = counts.val;
  136. while (count--) ;
  137. perf_evsel__read(evsel, 0, 0, &counts);
  138. end = counts.val;
  139. __T("invalid counter data", (end - start) > last);
  140. last = end - start;
  141. __T_VERBOSE("count = %llu\n", end - start);
  142. }
  143. perf_evsel__munmap(evsel);
  144. perf_evsel__close(evsel);
  145. perf_evsel__delete(evsel);
  146. perf_thread_map__put(threads);
  147. return 0;
  148. }
  149. static int test_stat_read_format_single(struct perf_event_attr *attr, struct perf_thread_map *threads)
  150. {
  151. struct perf_evsel *evsel;
  152. struct perf_counts_values counts;
  153. volatile int count = 0x100000;
  154. int err;
  155. evsel = perf_evsel__new(attr);
  156. __T("failed to create evsel", evsel);
  157. /* skip old kernels that don't support the format */
  158. err = perf_evsel__open(evsel, NULL, threads);
  159. if (err < 0)
  160. return 0;
  161. while (count--) ;
  162. memset(&counts, -1, sizeof(counts));
  163. perf_evsel__read(evsel, 0, 0, &counts);
  164. __T("failed to read value", counts.val);
  165. if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
  166. __T("failed to read TOTAL_TIME_ENABLED", counts.ena);
  167. if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
  168. __T("failed to read TOTAL_TIME_RUNNING", counts.run);
  169. if (attr->read_format & PERF_FORMAT_ID)
  170. __T("failed to read ID", counts.id);
  171. if (attr->read_format & PERF_FORMAT_LOST)
  172. __T("failed to read LOST", counts.lost == 0);
  173. perf_evsel__close(evsel);
  174. perf_evsel__delete(evsel);
  175. return 0;
  176. }
  177. static int test_stat_read_format_group(struct perf_event_attr *attr, struct perf_thread_map *threads)
  178. {
  179. struct perf_evsel *leader, *member;
  180. struct perf_counts_values counts;
  181. volatile int count = 0x100000;
  182. int err;
  183. attr->read_format |= PERF_FORMAT_GROUP;
  184. leader = perf_evsel__new(attr);
  185. __T("failed to create leader", leader);
  186. attr->read_format &= ~PERF_FORMAT_GROUP;
  187. member = perf_evsel__new(attr);
  188. __T("failed to create member", member);
  189. member->leader = leader;
  190. leader->nr_members = 2;
  191. /* skip old kernels that don't support the format */
  192. err = perf_evsel__open(leader, NULL, threads);
  193. if (err < 0)
  194. return 0;
  195. err = perf_evsel__open(member, NULL, threads);
  196. if (err < 0)
  197. return 0;
  198. while (count--) ;
  199. memset(&counts, -1, sizeof(counts));
  200. perf_evsel__read(leader, 0, 0, &counts);
  201. __T("failed to read leader value", counts.val);
  202. if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
  203. __T("failed to read leader TOTAL_TIME_ENABLED", counts.ena);
  204. if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
  205. __T("failed to read leader TOTAL_TIME_RUNNING", counts.run);
  206. if (attr->read_format & PERF_FORMAT_ID)
  207. __T("failed to read leader ID", counts.id);
  208. if (attr->read_format & PERF_FORMAT_LOST)
  209. __T("failed to read leader LOST", counts.lost == 0);
  210. memset(&counts, -1, sizeof(counts));
  211. perf_evsel__read(member, 0, 0, &counts);
  212. __T("failed to read member value", counts.val);
  213. if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
  214. __T("failed to read member TOTAL_TIME_ENABLED", counts.ena);
  215. if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
  216. __T("failed to read member TOTAL_TIME_RUNNING", counts.run);
  217. if (attr->read_format & PERF_FORMAT_ID)
  218. __T("failed to read member ID", counts.id);
  219. if (attr->read_format & PERF_FORMAT_LOST)
  220. __T("failed to read member LOST", counts.lost == 0);
  221. perf_evsel__close(member);
  222. perf_evsel__close(leader);
  223. perf_evsel__delete(member);
  224. perf_evsel__delete(leader);
  225. return 0;
  226. }
  227. static int test_stat_read_format(void)
  228. {
  229. struct perf_thread_map *threads;
  230. struct perf_event_attr attr = {
  231. .type = PERF_TYPE_SOFTWARE,
  232. .config = PERF_COUNT_SW_TASK_CLOCK,
  233. };
  234. int err, i;
  235. #define FMT(_fmt) PERF_FORMAT_ ## _fmt
  236. #define FMT_TIME (FMT(TOTAL_TIME_ENABLED) | FMT(TOTAL_TIME_RUNNING))
  237. uint64_t test_formats [] = {
  238. 0,
  239. FMT_TIME,
  240. FMT(ID),
  241. FMT(LOST),
  242. FMT_TIME | FMT(ID),
  243. FMT_TIME | FMT(LOST),
  244. FMT_TIME | FMT(ID) | FMT(LOST),
  245. FMT(ID) | FMT(LOST),
  246. };
  247. #undef FMT
  248. #undef FMT_TIME
  249. threads = perf_thread_map__new_dummy();
  250. __T("failed to create threads", threads);
  251. perf_thread_map__set_pid(threads, 0, 0);
  252. for (i = 0; i < (int)ARRAY_SIZE(test_formats); i++) {
  253. attr.read_format = test_formats[i];
  254. __T_VERBOSE("testing single read with read_format: %lx\n",
  255. (unsigned long)test_formats[i]);
  256. err = test_stat_read_format_single(&attr, threads);
  257. __T("failed to read single format", err == 0);
  258. }
  259. perf_thread_map__put(threads);
  260. threads = perf_thread_map__new_array(2, NULL);
  261. __T("failed to create threads", threads);
  262. perf_thread_map__set_pid(threads, 0, 0);
  263. perf_thread_map__set_pid(threads, 1, 0);
  264. for (i = 0; i < (int)ARRAY_SIZE(test_formats); i++) {
  265. attr.read_format = test_formats[i];
  266. __T_VERBOSE("testing group read with read_format: %lx\n",
  267. (unsigned long)test_formats[i]);
  268. err = test_stat_read_format_group(&attr, threads);
  269. __T("failed to read group format", err == 0);
  270. }
  271. perf_thread_map__put(threads);
  272. return 0;
  273. }
  274. int test_evsel(int argc, char **argv)
  275. {
  276. __T_START;
  277. libperf_init(libperf_print);
  278. test_stat_cpu();
  279. test_stat_thread();
  280. test_stat_thread_enable();
  281. test_stat_user_read(PERF_COUNT_HW_INSTRUCTIONS);
  282. test_stat_user_read(PERF_COUNT_HW_CPU_CYCLES);
  283. test_stat_read_format();
  284. __T_END;
  285. return tests_failed == 0 ? 0 : -1;
  286. }