auxtrace.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include <stdbool.h>
  2. #include <linux/kernel.h>
  3. #include <linux/types.h>
  4. #include <linux/bitops.h>
  5. #include <linux/log2.h>
  6. #include "../../util/evlist.h"
  7. #include "../../util/auxtrace.h"
  8. #include "../../util/evsel.h"
  9. #define PERF_EVENT_CPUM_SF 0xB0000 /* Event: Basic-sampling */
  10. #define PERF_EVENT_CPUM_SF_DIAG 0xBD000 /* Event: Combined-sampling */
  11. #define DEFAULT_AUX_PAGES 128
  12. #define DEFAULT_FREQ 4000
  13. static void cpumsf_free(struct auxtrace_record *itr)
  14. {
  15. free(itr);
  16. }
  17. static size_t cpumsf_info_priv_size(struct auxtrace_record *itr __maybe_unused,
  18. struct perf_evlist *evlist __maybe_unused)
  19. {
  20. return 0;
  21. }
  22. static int
  23. cpumsf_info_fill(struct auxtrace_record *itr __maybe_unused,
  24. struct perf_session *session __maybe_unused,
  25. struct auxtrace_info_event *auxtrace_info __maybe_unused,
  26. size_t priv_size __maybe_unused)
  27. {
  28. return 0;
  29. }
  30. static unsigned long
  31. cpumsf_reference(struct auxtrace_record *itr __maybe_unused)
  32. {
  33. return 0;
  34. }
  35. static int
  36. cpumsf_recording_options(struct auxtrace_record *ar __maybe_unused,
  37. struct perf_evlist *evlist __maybe_unused,
  38. struct record_opts *opts)
  39. {
  40. unsigned int factor = 1;
  41. unsigned int pages;
  42. opts->full_auxtrace = true;
  43. /*
  44. * The AUX buffer size should be set properly to avoid
  45. * overflow of samples if it is not set explicitly.
  46. * DEFAULT_AUX_PAGES is an proper size when sampling frequency
  47. * is DEFAULT_FREQ. It is expected to hold about 1/2 second
  48. * of sampling data. The size used for AUX buffer will scale
  49. * according to the specified frequency and DEFAULT_FREQ.
  50. */
  51. if (!opts->auxtrace_mmap_pages) {
  52. if (opts->user_freq != UINT_MAX)
  53. factor = (opts->user_freq + DEFAULT_FREQ
  54. - 1) / DEFAULT_FREQ;
  55. pages = DEFAULT_AUX_PAGES * factor;
  56. opts->auxtrace_mmap_pages = roundup_pow_of_two(pages);
  57. }
  58. return 0;
  59. }
  60. static int
  61. cpumsf_parse_snapshot_options(struct auxtrace_record *itr __maybe_unused,
  62. struct record_opts *opts __maybe_unused,
  63. const char *str __maybe_unused)
  64. {
  65. return 0;
  66. }
  67. /*
  68. * auxtrace_record__init is called when perf record
  69. * check if the event really need auxtrace
  70. */
  71. struct auxtrace_record *auxtrace_record__init(struct perf_evlist *evlist,
  72. int *err)
  73. {
  74. struct auxtrace_record *aux;
  75. struct perf_evsel *pos;
  76. int diagnose = 0;
  77. *err = 0;
  78. if (evlist->nr_entries == 0)
  79. return NULL;
  80. evlist__for_each_entry(evlist, pos) {
  81. if (pos->attr.config == PERF_EVENT_CPUM_SF_DIAG) {
  82. diagnose = 1;
  83. break;
  84. }
  85. }
  86. if (!diagnose)
  87. return NULL;
  88. /* sampling in diagnose mode. alloc aux buffer */
  89. aux = zalloc(sizeof(*aux));
  90. if (aux == NULL) {
  91. *err = -ENOMEM;
  92. return NULL;
  93. }
  94. aux->parse_snapshot_options = cpumsf_parse_snapshot_options;
  95. aux->recording_options = cpumsf_recording_options;
  96. aux->info_priv_size = cpumsf_info_priv_size;
  97. aux->info_fill = cpumsf_info_fill;
  98. aux->free = cpumsf_free;
  99. aux->reference = cpumsf_reference;
  100. return aux;
  101. }