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