per_event_excludes.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * Copyright 2014, Michael Ellerman, IBM Corp.
  3. * Licensed under GPLv2.
  4. */
  5. #define _GNU_SOURCE
  6. #include <elf.h>
  7. #include <limits.h>
  8. #include <stdio.h>
  9. #include <stdbool.h>
  10. #include <string.h>
  11. #include <sys/prctl.h>
  12. #include "event.h"
  13. #include "lib.h"
  14. #include "utils.h"
  15. /*
  16. * Test that per-event excludes work.
  17. */
  18. static int per_event_excludes(void)
  19. {
  20. struct event *e, events[4];
  21. char *platform;
  22. int i;
  23. platform = (char *)get_auxv_entry(AT_BASE_PLATFORM);
  24. FAIL_IF(!platform);
  25. SKIP_IF(strcmp(platform, "power8") != 0);
  26. /*
  27. * We need to create the events disabled, otherwise the running/enabled
  28. * counts don't match up.
  29. */
  30. e = &events[0];
  31. event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
  32. PERF_TYPE_HARDWARE, "instructions");
  33. e->attr.disabled = 1;
  34. e = &events[1];
  35. event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
  36. PERF_TYPE_HARDWARE, "instructions(k)");
  37. e->attr.disabled = 1;
  38. e->attr.exclude_user = 1;
  39. e->attr.exclude_hv = 1;
  40. e = &events[2];
  41. event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
  42. PERF_TYPE_HARDWARE, "instructions(h)");
  43. e->attr.disabled = 1;
  44. e->attr.exclude_user = 1;
  45. e->attr.exclude_kernel = 1;
  46. e = &events[3];
  47. event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS,
  48. PERF_TYPE_HARDWARE, "instructions(u)");
  49. e->attr.disabled = 1;
  50. e->attr.exclude_hv = 1;
  51. e->attr.exclude_kernel = 1;
  52. FAIL_IF(event_open(&events[0]));
  53. /*
  54. * The open here will fail if we don't have per event exclude support,
  55. * because the second event has an incompatible set of exclude settings
  56. * and we're asking for the events to be in a group.
  57. */
  58. for (i = 1; i < 4; i++)
  59. FAIL_IF(event_open_with_group(&events[i], events[0].fd));
  60. /*
  61. * Even though the above will fail without per-event excludes we keep
  62. * testing in order to be thorough.
  63. */
  64. prctl(PR_TASK_PERF_EVENTS_ENABLE);
  65. /* Spin for a while */
  66. for (i = 0; i < INT_MAX; i++)
  67. asm volatile("" : : : "memory");
  68. prctl(PR_TASK_PERF_EVENTS_DISABLE);
  69. for (i = 0; i < 4; i++) {
  70. FAIL_IF(event_read(&events[i]));
  71. event_report(&events[i]);
  72. }
  73. /*
  74. * We should see that all events have enabled == running. That
  75. * shows that they were all on the PMU at once.
  76. */
  77. for (i = 0; i < 4; i++)
  78. FAIL_IF(events[i].result.running != events[i].result.enabled);
  79. /*
  80. * We can also check that the result for instructions is >= all the
  81. * other counts. That's because it is counting all instructions while
  82. * the others are counting a subset.
  83. */
  84. for (i = 1; i < 4; i++)
  85. FAIL_IF(events[0].result.value < events[i].result.value);
  86. for (i = 0; i < 4; i++)
  87. event_close(&events[i]);
  88. return 0;
  89. }
  90. int main(void)
  91. {
  92. return test_harness(per_event_excludes, "per_event_excludes");
  93. }