keep-tracking.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/types.h>
  3. #include <unistd.h>
  4. #include <sys/prctl.h>
  5. #include "parse-events.h"
  6. #include "evlist.h"
  7. #include "evsel.h"
  8. #include "thread_map.h"
  9. #include "cpumap.h"
  10. #include "tests.h"
  11. #define CHECK__(x) { \
  12. while ((x) < 0) { \
  13. pr_debug(#x " failed!\n"); \
  14. goto out_err; \
  15. } \
  16. }
  17. #define CHECK_NOT_NULL__(x) { \
  18. while ((x) == NULL) { \
  19. pr_debug(#x " failed!\n"); \
  20. goto out_err; \
  21. } \
  22. }
  23. static int find_comm(struct perf_evlist *evlist, const char *comm)
  24. {
  25. union perf_event *event;
  26. struct perf_mmap *md;
  27. int i, found;
  28. found = 0;
  29. for (i = 0; i < evlist->nr_mmaps; i++) {
  30. md = &evlist->mmap[i];
  31. if (perf_mmap__read_init(md) < 0)
  32. continue;
  33. while ((event = perf_mmap__read_event(md)) != NULL) {
  34. if (event->header.type == PERF_RECORD_COMM &&
  35. (pid_t)event->comm.pid == getpid() &&
  36. (pid_t)event->comm.tid == getpid() &&
  37. strcmp(event->comm.comm, comm) == 0)
  38. found += 1;
  39. perf_mmap__consume(md);
  40. }
  41. perf_mmap__read_done(md);
  42. }
  43. return found;
  44. }
  45. /**
  46. * test__keep_tracking - test using a dummy software event to keep tracking.
  47. *
  48. * This function implements a test that checks that tracking events continue
  49. * when an event is disabled but a dummy software event is not disabled. If the
  50. * test passes %0 is returned, otherwise %-1 is returned.
  51. */
  52. int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_unused)
  53. {
  54. struct record_opts opts = {
  55. .mmap_pages = UINT_MAX,
  56. .user_freq = UINT_MAX,
  57. .user_interval = ULLONG_MAX,
  58. .target = {
  59. .uses_mmap = true,
  60. },
  61. };
  62. struct thread_map *threads = NULL;
  63. struct cpu_map *cpus = NULL;
  64. struct perf_evlist *evlist = NULL;
  65. struct perf_evsel *evsel = NULL;
  66. int found, err = -1;
  67. const char *comm;
  68. threads = thread_map__new(-1, getpid(), UINT_MAX);
  69. CHECK_NOT_NULL__(threads);
  70. cpus = cpu_map__new(NULL);
  71. CHECK_NOT_NULL__(cpus);
  72. evlist = perf_evlist__new();
  73. CHECK_NOT_NULL__(evlist);
  74. perf_evlist__set_maps(evlist, cpus, threads);
  75. CHECK__(parse_events(evlist, "dummy:u", NULL));
  76. CHECK__(parse_events(evlist, "cycles:u", NULL));
  77. perf_evlist__config(evlist, &opts, NULL);
  78. evsel = perf_evlist__first(evlist);
  79. evsel->attr.comm = 1;
  80. evsel->attr.disabled = 1;
  81. evsel->attr.enable_on_exec = 0;
  82. if (perf_evlist__open(evlist) < 0) {
  83. pr_debug("Unable to open dummy and cycles event\n");
  84. err = TEST_SKIP;
  85. goto out_err;
  86. }
  87. CHECK__(perf_evlist__mmap(evlist, UINT_MAX));
  88. /*
  89. * First, test that a 'comm' event can be found when the event is
  90. * enabled.
  91. */
  92. perf_evlist__enable(evlist);
  93. comm = "Test COMM 1";
  94. CHECK__(prctl(PR_SET_NAME, (unsigned long)comm, 0, 0, 0));
  95. perf_evlist__disable(evlist);
  96. found = find_comm(evlist, comm);
  97. if (found != 1) {
  98. pr_debug("First time, failed to find tracking event.\n");
  99. goto out_err;
  100. }
  101. /*
  102. * Secondly, test that a 'comm' event can be found when the event is
  103. * disabled with the dummy event still enabled.
  104. */
  105. perf_evlist__enable(evlist);
  106. evsel = perf_evlist__last(evlist);
  107. CHECK__(perf_evsel__disable(evsel));
  108. comm = "Test COMM 2";
  109. CHECK__(prctl(PR_SET_NAME, (unsigned long)comm, 0, 0, 0));
  110. perf_evlist__disable(evlist);
  111. found = find_comm(evlist, comm);
  112. if (found != 1) {
  113. pr_debug("Seconf time, failed to find tracking event.\n");
  114. goto out_err;
  115. }
  116. err = 0;
  117. out_err:
  118. if (evlist) {
  119. perf_evlist__disable(evlist);
  120. perf_evlist__delete(evlist);
  121. } else {
  122. cpu_map__put(cpus);
  123. thread_map__put(threads);
  124. }
  125. return err;
  126. }