mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 15:03:53 +02:00
perf tools: Parse aux-action
Add parsing for aux-action to accept "pause", "resume" or "start-paused" values. "start-paused" is valid only for AUX area events. "pause" and "resume" are valid only for events grouped with an AUX area event as the group leader. However, like with aux-output, the events will be automatically grouped if they are not currently in a group, and the AUX area event precedes the other events. Reviewed-by: Andi Kleen <ak@linux.intel.com> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Acked-by: Ian Rogers <irogers@google.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Leo Yan <leo.yan@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Link: https://lore.kernel.org/r/20241216070244.14450-4-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
314bf84e03
commit
8a0f49a7f1
|
@ -68,6 +68,10 @@ OPTIONS
|
|||
like this: name=\'CPU_CLK_UNHALTED.THREAD:cmask=0x1\'.
|
||||
- 'aux-output': Generate AUX records instead of events. This requires
|
||||
that an AUX area event is also provided.
|
||||
- 'aux-action': "pause" or "resume" to pause or resume an AUX
|
||||
area event (the group leader) when this event occurs.
|
||||
"start-paused" on an AUX area event itself, will
|
||||
start in a paused state.
|
||||
- 'aux-sample-size': Set sample size for AUX area sampling. If the
|
||||
'--aux-sample' option has been used, set aux-sample-size=0 to disable
|
||||
AUX area sampling for the event.
|
||||
|
|
|
@ -860,7 +860,9 @@ static int record__auxtrace_init(struct record *rec)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
auxtrace_regroup_aux_output(rec->evlist);
|
||||
err = auxtrace_parse_aux_action(rec->evlist);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return auxtrace_parse_filters(rec->evlist);
|
||||
}
|
||||
|
|
|
@ -810,19 +810,76 @@ no_opt:
|
|||
return auxtrace_validate_aux_sample_size(evlist, opts);
|
||||
}
|
||||
|
||||
void auxtrace_regroup_aux_output(struct evlist *evlist)
|
||||
static struct aux_action_opt {
|
||||
const char *str;
|
||||
u32 aux_action;
|
||||
bool aux_event_opt;
|
||||
} aux_action_opts[] = {
|
||||
{"start-paused", BIT(0), true},
|
||||
{"pause", BIT(1), false},
|
||||
{"resume", BIT(2), false},
|
||||
{.str = NULL},
|
||||
};
|
||||
|
||||
static const struct aux_action_opt *auxtrace_parse_aux_action_str(const char *str)
|
||||
{
|
||||
const struct aux_action_opt *opt;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
for (opt = aux_action_opts; opt->str; opt++)
|
||||
if (!strcmp(str, opt->str))
|
||||
return opt;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int auxtrace_parse_aux_action(struct evlist *evlist)
|
||||
{
|
||||
struct evsel *evsel, *aux_evsel = NULL;
|
||||
struct evsel_config_term *term;
|
||||
struct evsel *aux_evsel = NULL;
|
||||
struct evsel *evsel;
|
||||
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (evsel__is_aux_event(evsel))
|
||||
bool is_aux_event = evsel__is_aux_event(evsel);
|
||||
const struct aux_action_opt *opt;
|
||||
|
||||
if (is_aux_event)
|
||||
aux_evsel = evsel;
|
||||
term = evsel__get_config_term(evsel, AUX_OUTPUT);
|
||||
term = evsel__get_config_term(evsel, AUX_ACTION);
|
||||
if (!term) {
|
||||
if (evsel__get_config_term(evsel, AUX_OUTPUT))
|
||||
goto regroup;
|
||||
continue;
|
||||
}
|
||||
opt = auxtrace_parse_aux_action_str(term->val.str);
|
||||
if (!opt) {
|
||||
pr_err("Bad aux-action '%s'\n", term->val.str);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (opt->aux_event_opt && !is_aux_event) {
|
||||
pr_err("aux-action '%s' can only be used with AUX area event\n",
|
||||
term->val.str);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!opt->aux_event_opt && is_aux_event) {
|
||||
pr_err("aux-action '%s' cannot be used for AUX area event itself\n",
|
||||
term->val.str);
|
||||
return -EINVAL;
|
||||
}
|
||||
evsel->core.attr.aux_action = opt->aux_action;
|
||||
regroup:
|
||||
/* If possible, group with the AUX event */
|
||||
if (term && aux_evsel)
|
||||
if (aux_evsel)
|
||||
evlist__regroup(evlist, aux_evsel, evsel);
|
||||
if (!evsel__is_aux_event(evsel__leader(evsel))) {
|
||||
pr_err("Events with aux-action must have AUX area event group leader\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct auxtrace_record *__weak
|
||||
|
|
|
@ -578,7 +578,7 @@ int auxtrace_parse_snapshot_options(struct auxtrace_record *itr,
|
|||
int auxtrace_parse_sample_options(struct auxtrace_record *itr,
|
||||
struct evlist *evlist,
|
||||
struct record_opts *opts, const char *str);
|
||||
void auxtrace_regroup_aux_output(struct evlist *evlist);
|
||||
int auxtrace_parse_aux_action(struct evlist *evlist);
|
||||
int auxtrace_record__options(struct auxtrace_record *itr,
|
||||
struct evlist *evlist,
|
||||
struct record_opts *opts);
|
||||
|
@ -799,8 +799,10 @@ int auxtrace_parse_sample_options(struct auxtrace_record *itr __maybe_unused,
|
|||
}
|
||||
|
||||
static inline
|
||||
void auxtrace_regroup_aux_output(struct evlist *evlist __maybe_unused)
|
||||
int auxtrace_parse_aux_action(struct evlist *evlist __maybe_unused)
|
||||
{
|
||||
pr_err("AUX area tracing not supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline
|
||||
|
|
|
@ -1152,6 +1152,7 @@ static void evsel__apply_config_terms(struct evsel *evsel,
|
|||
attr->aux_output = term->val.aux_output ? 1 : 0;
|
||||
break;
|
||||
case EVSEL__CONFIG_TERM_AUX_ACTION:
|
||||
/* Already applied by auxtrace */
|
||||
break;
|
||||
case EVSEL__CONFIG_TERM_AUX_SAMPLE_SIZE:
|
||||
/* Already applied by auxtrace */
|
||||
|
|
Loading…
Reference in New Issue
Block a user