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