perf tools: Add support to parse event group syntax
Adding scanner/parser bits to parse event groups. The grammar for group is: groups: groups ',' group | group group: group_name '{' events '}' group_mod group_name: name | empty group_mod: ':' group_mods | empty group_mods: event_mod It's possible to use standard event modifier as a modifier for group. It'll be used as an update to existing event modifiers. It's necessary to use quoting ("'\) when specifying group on command line, since {} characters are interpreted by most of the shells. It is now possible to specify groups in event syntax like: '{cycles,faults}' - anonymous group 'group1{cycles,faults} - group with name 'group1' '{cycles,faults}:k - anonymous group with event modifier 'k' '{cpu-clock,task-clock},{minor-faults,major-faults}' - two anonymous groups The grouping functionality itself is coming shortly. Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Jiri Olsa <jolsa@redhat.com> Acked-by: Peter Zijlstra <peterz@infradead.org> Cc: Andi Kleen <andi@firstfloor.org> Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ulrich Drepper <drepper@gmail.com> Link: http://lkml.kernel.org/n/tip-p4j8bnvo879uokum4k4zk5q6@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Родитель
a619183672
Коммит
89efb02950
|
@ -611,19 +611,29 @@ int parse_events_add_pmu(struct list_head **list, int *idx,
|
||||||
pmu_event_name(head_config));
|
pmu_event_name(head_config));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int parse_events__modifier_group(struct list_head *list __used,
|
||||||
|
char *event_mod __used)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void parse_events__group(char *name __used, struct list_head *list __used)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void parse_events_update_lists(struct list_head *list_event,
|
void parse_events_update_lists(struct list_head *list_event,
|
||||||
struct list_head *list_all)
|
struct list_head *list_all)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Called for single event definition. Update the
|
* Called for single event definition. Update the
|
||||||
* 'all event' list, and reinit the 'signle event'
|
* 'all event' list, and reinit the 'single event'
|
||||||
* list, for next event definition.
|
* list, for next event definition.
|
||||||
*/
|
*/
|
||||||
list_splice_tail(list_event, list_all);
|
list_splice_tail(list_event, list_all);
|
||||||
free(list_event);
|
free(list_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_events_modifier(struct list_head *list, char *str)
|
int parse_events__modifier_event(struct list_head *list, char *str)
|
||||||
{
|
{
|
||||||
struct perf_evsel *evsel;
|
struct perf_evsel *evsel;
|
||||||
int exclude = 0, exclude_GH = 0;
|
int exclude = 0, exclude_GH = 0;
|
||||||
|
|
|
@ -79,7 +79,8 @@ int parse_events__term_str(struct parse_events__term **_term,
|
||||||
int parse_events__term_clone(struct parse_events__term **new,
|
int parse_events__term_clone(struct parse_events__term **new,
|
||||||
struct parse_events__term *term);
|
struct parse_events__term *term);
|
||||||
void parse_events__free_terms(struct list_head *terms);
|
void parse_events__free_terms(struct list_head *terms);
|
||||||
int parse_events_modifier(struct list_head *list, char *str);
|
int parse_events__modifier_event(struct list_head *list, char *str);
|
||||||
|
int parse_events__modifier_group(struct list_head *list, char *event_mod);
|
||||||
int parse_events_add_tracepoint(struct list_head **list, int *idx,
|
int parse_events_add_tracepoint(struct list_head **list, int *idx,
|
||||||
char *sys, char *event);
|
char *sys, char *event);
|
||||||
int parse_events_add_numeric(struct list_head **list, int *idx,
|
int parse_events_add_numeric(struct list_head **list, int *idx,
|
||||||
|
@ -91,6 +92,7 @@ int parse_events_add_breakpoint(struct list_head **list, int *idx,
|
||||||
void *ptr, char *type);
|
void *ptr, char *type);
|
||||||
int parse_events_add_pmu(struct list_head **list, int *idx,
|
int parse_events_add_pmu(struct list_head **list, int *idx,
|
||||||
char *pmu , struct list_head *head_config);
|
char *pmu , struct list_head *head_config);
|
||||||
|
void parse_events__group(char *name, struct list_head *list);
|
||||||
void parse_events_update_lists(struct list_head *list_event,
|
void parse_events_update_lists(struct list_head *list_event,
|
||||||
struct list_head *list_all);
|
struct list_head *list_all);
|
||||||
void parse_events_error(void *data, void *scanner, char const *msg);
|
void parse_events_error(void *data, void *scanner, char const *msg);
|
||||||
|
|
|
@ -151,6 +151,8 @@ r{num_raw_hex} { return raw(yyscanner); }
|
||||||
- { return '-'; }
|
- { return '-'; }
|
||||||
, { return ','; }
|
, { return ','; }
|
||||||
: { return ':'; }
|
: { return ':'; }
|
||||||
|
"{" { return '{'; }
|
||||||
|
"}" { return '}'; }
|
||||||
= { return '='; }
|
= { return '='; }
|
||||||
\n { }
|
\n { }
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ do { \
|
||||||
%token PE_NAME
|
%token PE_NAME
|
||||||
%token PE_MODIFIER_EVENT PE_MODIFIER_BP
|
%token PE_MODIFIER_EVENT PE_MODIFIER_BP
|
||||||
%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
|
%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
|
||||||
%token PE_PREFIX_MEM PE_PREFIX_RAW
|
%token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
|
||||||
%token PE_ERROR
|
%token PE_ERROR
|
||||||
%type <num> PE_VALUE
|
%type <num> PE_VALUE
|
||||||
%type <num> PE_VALUE_SYM_HW
|
%type <num> PE_VALUE_SYM_HW
|
||||||
|
@ -53,6 +53,11 @@ do { \
|
||||||
%type <head> event_legacy_numeric
|
%type <head> event_legacy_numeric
|
||||||
%type <head> event_legacy_raw
|
%type <head> event_legacy_raw
|
||||||
%type <head> event_def
|
%type <head> event_def
|
||||||
|
%type <head> event
|
||||||
|
%type <head> events
|
||||||
|
%type <head> group_def
|
||||||
|
%type <head> group
|
||||||
|
%type <head> groups
|
||||||
|
|
||||||
%union
|
%union
|
||||||
{
|
{
|
||||||
|
@ -64,33 +69,95 @@ do { \
|
||||||
%%
|
%%
|
||||||
|
|
||||||
start:
|
start:
|
||||||
PE_START_EVENTS events
|
PE_START_EVENTS start_events
|
||||||
|
|
|
|
||||||
PE_START_TERMS terms
|
PE_START_TERMS start_terms
|
||||||
|
|
||||||
|
start_events: groups
|
||||||
|
{
|
||||||
|
struct parse_events_data__events *data = _data;
|
||||||
|
|
||||||
|
parse_events_update_lists($1, &data->list);
|
||||||
|
}
|
||||||
|
|
||||||
|
groups:
|
||||||
|
groups ',' group
|
||||||
|
{
|
||||||
|
struct list_head *list = $1;
|
||||||
|
struct list_head *group = $3;
|
||||||
|
|
||||||
|
parse_events_update_lists(group, list);
|
||||||
|
$$ = list;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
groups ',' event
|
||||||
|
{
|
||||||
|
struct list_head *list = $1;
|
||||||
|
struct list_head *event = $3;
|
||||||
|
|
||||||
|
parse_events_update_lists(event, list);
|
||||||
|
$$ = list;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
group
|
||||||
|
|
|
||||||
|
event
|
||||||
|
|
||||||
|
group:
|
||||||
|
group_def ':' PE_MODIFIER_EVENT
|
||||||
|
{
|
||||||
|
struct list_head *list = $1;
|
||||||
|
|
||||||
|
ABORT_ON(parse_events__modifier_group(list, $3));
|
||||||
|
$$ = list;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
group_def
|
||||||
|
|
||||||
|
group_def:
|
||||||
|
PE_NAME '{' events '}'
|
||||||
|
{
|
||||||
|
struct list_head *list = $3;
|
||||||
|
|
||||||
|
parse_events__group($1, list);
|
||||||
|
$$ = list;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
'{' events '}'
|
||||||
|
{
|
||||||
|
struct list_head *list = $2;
|
||||||
|
|
||||||
|
parse_events__group(NULL, list);
|
||||||
|
$$ = list;
|
||||||
|
}
|
||||||
|
|
||||||
events:
|
events:
|
||||||
events ',' event | event
|
events ',' event
|
||||||
|
{
|
||||||
|
struct list_head *event = $3;
|
||||||
|
struct list_head *list = $1;
|
||||||
|
|
||||||
|
parse_events_update_lists(event, list);
|
||||||
|
$$ = list;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
event
|
||||||
|
|
||||||
event:
|
event:
|
||||||
event_def PE_MODIFIER_EVENT
|
event_def PE_MODIFIER_EVENT
|
||||||
{
|
{
|
||||||
struct parse_events_data__events *data = _data;
|
struct list_head *list = $1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Apply modifier on all events added by single event definition
|
* Apply modifier on all events added by single event definition
|
||||||
* (there could be more events added for multiple tracepoint
|
* (there could be more events added for multiple tracepoint
|
||||||
* definitions via '*?'.
|
* definitions via '*?'.
|
||||||
*/
|
*/
|
||||||
ABORT_ON(parse_events_modifier($1, $2));
|
ABORT_ON(parse_events__modifier_event(list, $2));
|
||||||
parse_events_update_lists($1, &data->list);
|
$$ = list;
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
event_def
|
event_def
|
||||||
{
|
|
||||||
struct parse_events_data__events *data = _data;
|
|
||||||
|
|
||||||
parse_events_update_lists($1, &data->list);
|
|
||||||
}
|
|
||||||
|
|
||||||
event_def: event_pmu |
|
event_def: event_pmu |
|
||||||
event_legacy_symbol |
|
event_legacy_symbol |
|
||||||
|
@ -222,7 +289,7 @@ PE_RAW
|
||||||
$$ = list;
|
$$ = list;
|
||||||
}
|
}
|
||||||
|
|
||||||
terms: event_config
|
start_terms: event_config
|
||||||
{
|
{
|
||||||
struct parse_events_data__terms *data = _data;
|
struct parse_events_data__terms *data = _data;
|
||||||
data->terms = $1;
|
data->terms = $1;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче