/* * evsel__config_leader_sampling() uses special rules for leader sampling. * However, if the leader is an AUX area event, then assume the event to sample * is the next event.
*/ staticstruct evsel *evsel__read_sampler(struct evsel *evsel, struct evlist *evlist)
{ struct evsel *leader = evsel__leader(evsel);
term_types = evsel__config_term_mask(evsel); /* * Disable sampling for all group members except those with explicit * config terms or the leader. In the case of an AUX area event, the 2nd * event in the group is the one that 'leads' the sampling.
*/
freq_mask = (1 << EVSEL__CONFIG_TERM_FREQ) | (1 << EVSEL__CONFIG_TERM_PERIOD); if ((term_types & freq_mask) == 0) {
attr->freq = 0;
attr->sample_freq = 0;
attr->sample_period = 0;
} if ((term_types & (1 << EVSEL__CONFIG_TERM_OVERWRITE)) == 0)
attr->write_backward = 0;
/* * We don't get a sample for slave events, we make them when delivering * the group leader sample. Set the slave event to follow the master * sample_type to ease up reporting. * An AUX area event also has sample_type requirements, so also include * the sample type bits from the leader's sample_type to cover that * case.
*/
attr->sample_type = read_sampler->core.attr.sample_type |
leader->core.attr.sample_type;
}
/* Configure leader sampling here now that the sample type is known */
evlist__for_each_entry(evlist, evsel)
evsel__config_leader_sampling(evsel, evlist);
if (opts->full_auxtrace || opts->sample_identifier) { /* * Need to be able to synthesize and parse selected events with * arbitrary sample types, which requires always being able to * match the id.
*/
use_sample_identifier = perf_can_sample_identifier();
sample_id = true;
} elseif (evlist->core.nr_entries > 1) { struct evsel *first = evlist__first(evlist);
if (user_interval && user_freq) {
pr_err("cannot set frequency and period at the same time\n"); return -1;
}
if (user_interval)
opts->default_interval = opts->user_interval; if (user_freq)
opts->freq = opts->user_freq;
/* * User specified count overrides default frequency.
*/ if (opts->default_interval)
opts->freq = 0; elseif (opts->freq) {
opts->default_interval = opts->freq;
} else {
pr_err("frequency and count are zero, aborting\n"); return -1;
}
if (get_max_rate(&max_rate)) return 0;
/* * User specified frequency is over current maximum.
*/ if (user_freq && (max_rate < opts->freq)) { if (opts->strict_freq) {
pr_err("error: Maximum frequency rate (%'u Hz) exceeded.\n" " Please use -F freq option with a lower value or consider\n" " tweaking /proc/sys/kernel/perf_event_max_sample_rate.\n",
max_rate); return -1;
} else {
pr_warning("warning: Maximum frequency rate (%'u Hz) exceeded, throttling from %'u Hz to %'u Hz.\n" " The limit can be raised via /proc/sys/kernel/perf_event_max_sample_rate.\n" " The kernel will lower it when perf's interrupts take too long.\n" " Use --strict-freq to disable this throttling, refusing to record.\n",
max_rate, opts->freq, max_rate);
opts->freq = max_rate;
}
}
/* * Default frequency is over current maximum.
*/ if (max_rate < opts->freq) {
pr_warning("Lowering default frequency rate from %u to %u.\n" "Please consider tweaking " "/proc/sys/kernel/perf_event_max_sample_rate.\n",
opts->freq, max_rate);
opts->freq = max_rate;
}
return 0;
}
int record_opts__config(struct record_opts *opts)
{ return record_opts__config_freq(opts);
}
int record__parse_freq(conststruct option *opt, constchar *str, int unset __maybe_unused)
{ unsignedint freq; struct record_opts *opts = opt->value;
if (!str) return -EINVAL;
if (strcasecmp(str, "max") == 0) { if (get_max_rate(&freq)) {
pr_err("couldn't read /proc/sys/kernel/perf_event_max_sample_rate\n"); return -1;
}
pr_info("info: Using a maximum frequency rate of %'d Hz\n", freq);
} else {
freq = atoi(str);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.