auxtrace.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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. auxtrace_info->type = PERF_AUXTRACE_S390_CPUMSF;
  29. return 0;
  30. }
  31. static unsigned long
  32. cpumsf_reference(struct auxtrace_record *itr __maybe_unused)
  33. {
  34. return 0;
  35. }
  36. static int
  37. cpumsf_recording_options(struct auxtrace_record *ar __maybe_unused,
  38. struct perf_evlist *evlist __maybe_unused,
  39. struct record_opts *opts)
  40. {
  41. unsigned int factor = 1;
  42. unsigned int pages;
  43. opts->full_auxtrace = true;
  44. /*
  45. * The AUX buffer size should be set properly to avoid
  46. * overflow of samples if it is not set explicitly.
  47. * DEFAULT_AUX_PAGES is an proper size when sampling frequency
  48. * is DEFAULT_FREQ. It is expected to hold about 1/2 second
  49. * of sampling data. The size used for AUX buffer will scale
  50. * according to the specified frequency and DEFAULT_FREQ.
  51. */
  52. if (!opts->auxtrace_mmap_pages) {
  53. if (opts->user_freq != UINT_MAX)
  54. factor = (opts->user_freq + DEFAULT_FREQ
  55. - 1) / DEFAULT_FREQ;
  56. pages = DEFAULT_AUX_PAGES * factor;
  57. opts->auxtrace_mmap_pages = roundup_pow_of_two(pages);
  58. }
  59. return 0;
  60. }
  61. static int
  62. cpumsf_parse_snapshot_options(struct auxtrace_record *itr __maybe_unused,
  63. struct record_opts *opts __maybe_unused,
  64. const char *str __maybe_unused)
  65. {
  66. return 0;
  67. }
  68. /*
  69. * auxtrace_record__init is called when perf record
  70. * check if the event really need auxtrace
  71. */
  72. struct auxtrace_record *auxtrace_record__init(struct perf_evlist *evlist,
  73. int *err)
  74. {
  75. struct auxtrace_record *aux;
  76. struct perf_evsel *pos;
  77. int diagnose = 0;
  78. *err = 0;
  79. if (evlist->nr_entries == 0)
  80. return NULL;
  81. evlist__for_each_entry(evlist, pos) {
  82. if (pos->attr.config == PERF_EVENT_CPUM_SF_DIAG) {
  83. diagnose = 1;
  84. break;
  85. }
  86. }
  87. if (!diagnose)
  88. return NULL;
  89. /* sampling in diagnose mode. alloc aux buffer */
  90. aux = zalloc(sizeof(*aux));
  91. if (aux == NULL) {
  92. *err = -ENOMEM;
  93. return NULL;
  94. }
  95. aux->parse_snapshot_options = cpumsf_parse_snapshot_options;
  96. aux->recording_options = cpumsf_recording_options;
  97. aux->info_priv_size = cpumsf_info_priv_size;
  98. aux->info_fill = cpumsf_info_fill;
  99. aux->free = cpumsf_free;
  100. aux->reference = cpumsf_reference;
  101. return aux;
  102. }