diff options
Diffstat (limited to 'tools/perf/util/record.c')
-rw-r--r-- | tools/perf/util/record.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 18d73aa2f0f8..c8845b107f60 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c | |||
@@ -2,6 +2,8 @@ | |||
2 | #include "evsel.h" | 2 | #include "evsel.h" |
3 | #include "cpumap.h" | 3 | #include "cpumap.h" |
4 | #include "parse-events.h" | 4 | #include "parse-events.h" |
5 | #include "fs.h" | ||
6 | #include "util.h" | ||
5 | 7 | ||
6 | typedef void (*setup_probe_fn_t)(struct perf_evsel *evsel); | 8 | typedef void (*setup_probe_fn_t)(struct perf_evsel *evsel); |
7 | 9 | ||
@@ -106,3 +108,72 @@ void perf_evlist__config(struct perf_evlist *evlist, | |||
106 | 108 | ||
107 | perf_evlist__set_id_pos(evlist); | 109 | perf_evlist__set_id_pos(evlist); |
108 | } | 110 | } |
111 | |||
112 | static int get_max_rate(unsigned int *rate) | ||
113 | { | ||
114 | char path[PATH_MAX]; | ||
115 | const char *procfs = procfs__mountpoint(); | ||
116 | |||
117 | if (!procfs) | ||
118 | return -1; | ||
119 | |||
120 | snprintf(path, PATH_MAX, | ||
121 | "%s/sys/kernel/perf_event_max_sample_rate", procfs); | ||
122 | |||
123 | return filename__read_int(path, (int *) rate); | ||
124 | } | ||
125 | |||
126 | static int perf_record_opts__config_freq(struct perf_record_opts *opts) | ||
127 | { | ||
128 | bool user_freq = opts->user_freq != UINT_MAX; | ||
129 | unsigned int max_rate; | ||
130 | |||
131 | if (opts->user_interval != ULLONG_MAX) | ||
132 | opts->default_interval = opts->user_interval; | ||
133 | if (user_freq) | ||
134 | opts->freq = opts->user_freq; | ||
135 | |||
136 | /* | ||
137 | * User specified count overrides default frequency. | ||
138 | */ | ||
139 | if (opts->default_interval) | ||
140 | opts->freq = 0; | ||
141 | else if (opts->freq) { | ||
142 | opts->default_interval = opts->freq; | ||
143 | } else { | ||
144 | pr_err("frequency and count are zero, aborting\n"); | ||
145 | return -1; | ||
146 | } | ||
147 | |||
148 | if (get_max_rate(&max_rate)) | ||
149 | return 0; | ||
150 | |||
151 | /* | ||
152 | * User specified frequency is over current maximum. | ||
153 | */ | ||
154 | if (user_freq && (max_rate < opts->freq)) { | ||
155 | pr_err("Maximum frequency rate (%u) reached.\n" | ||
156 | "Please use -F freq option with lower value or consider\n" | ||
157 | "tweaking /proc/sys/kernel/perf_event_max_sample_rate.\n", | ||
158 | max_rate); | ||
159 | return -1; | ||
160 | } | ||
161 | |||
162 | /* | ||
163 | * Default frequency is over current maximum. | ||
164 | */ | ||
165 | if (max_rate < opts->freq) { | ||
166 | pr_warning("Lowering default frequency rate to %u.\n" | ||
167 | "Please consider tweaking " | ||
168 | "/proc/sys/kernel/perf_event_max_sample_rate.\n", | ||
169 | max_rate); | ||
170 | opts->freq = max_rate; | ||
171 | } | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | int perf_record_opts__config(struct perf_record_opts *opts) | ||
177 | { | ||
178 | return perf_record_opts__config_freq(opts); | ||
179 | } | ||