提交 8f707d84 编写于 作者: J Jiri Olsa 提交者: Arnaldo Carvalho de Melo

perf tools: Add config options support for event parsing

Adding a new rule to the event grammar to be able to specify
values of additional attributes of symbolic event.

The new syntax for event symbolic definition is:

event_legacy_symbol:  PE_NAME_SYM '/' event_config '/' |
                      PE_NAME_SYM sep_slash_dc

event_config:         event_config ',' event_term | event_term

event_term:           PE_NAME '=' PE_NAME |
                      PE_NAME '=' PE_VALUE
                      PE_NAME

sep_slash_dc: '/' | ':' |

At the moment the config options are hardcoded to be used for legacy
symbol events to define several perf_event_attr fields. It is:

  'config'   to define perf_event_attr::config
  'config1'  to define perf_event_attr::config1
  'config2'  to define perf_event_attr::config2
  'period'   to define perf_event_attr::sample_period

Legacy events could be now specified as:
  cycles/period=100000/

If term is specified without the value assignment, then 1 is
assigned by default.
Acked-by: NPeter Zijlstra <peterz@infradead.org>
Signed-off-by: NJiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/n/tip-mgkavww9790jbt2jdkooyv4q@git.kernel.orgSigned-off-by: NArnaldo Carvalho de Melo <acme@redhat.com>
上级 89812fc8
......@@ -677,6 +677,24 @@ static int test__checkevent_symbolic_name(struct perf_evlist *evlist)
return 0;
}
static int test__checkevent_symbolic_name_config(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
struct perf_evsel, node);
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
TEST_ASSERT_VAL("wrong config",
PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
TEST_ASSERT_VAL("wrong period",
100000 == evsel->attr.sample_period);
TEST_ASSERT_VAL("wrong config1",
0 == evsel->attr.config1);
TEST_ASSERT_VAL("wrong config2",
1 == evsel->attr.config2);
return 0;
}
static int test__checkevent_symbolic_alias(struct perf_evlist *evlist)
{
struct perf_evsel *evsel = list_entry(evlist->entries.next,
......@@ -883,6 +901,10 @@ static struct test__event_st {
.name = "instructions",
.check = test__checkevent_symbolic_name,
},
{
.name = "cycles/period=100000,config2/",
.check = test__checkevent_symbolic_name_config,
},
{
.name = "faults",
.check = test__checkevent_symbolic_alias,
......
......@@ -127,14 +127,15 @@ do { \
PE_VALUE = 258,
PE_VALUE_SYM = 259,
PE_RAW = 260,
PE_NAME = 261,
PE_MODIFIER_EVENT = 262,
PE_MODIFIER_BP = 263,
PE_NAME_CACHE_TYPE = 264,
PE_NAME_CACHE_OP_RESULT = 265,
PE_PREFIX_MEM = 266,
PE_PREFIX_RAW = 267,
PE_ERROR = 268
PE_TERM = 261,
PE_NAME = 262,
PE_MODIFIER_EVENT = 263,
PE_MODIFIER_BP = 264,
PE_NAME_CACHE_TYPE = 265,
PE_NAME_CACHE_OP_RESULT = 266,
PE_PREFIX_MEM = 267,
PE_PREFIX_RAW = 268,
PE_ERROR = 269
};
#endif
......@@ -145,15 +146,17 @@ typedef union YYSTYPE
{
/* Line 214 of yacc.c */
#line 42 "util/parse-events.y"
#line 45 "util/parse-events.y"
char *str;
unsigned long num;
struct list_head *head;
struct parse_events__term *term;
/* Line 214 of yacc.c */
#line 157 "util/parse-events-bison.c"
#line 160 "util/parse-events-bison.c"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
......@@ -165,7 +168,7 @@ typedef union YYSTYPE
/* Line 264 of yacc.c */
#line 169 "util/parse-events-bison.c"
#line 172 "util/parse-events-bison.c"
#ifdef short
# undef short
......@@ -378,22 +381,22 @@ union yyalloc
#endif
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 20
#define YYFINAL 23
/* YYLAST -- Last index in YYTABLE. */
#define YYLAST 27
#define YYLAST 38
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 17
#define YYNTOKENS 20
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 11
#define YYNNTS 14
/* YYNRULES -- Number of rules. */
#define YYNRULES 22
#define YYNRULES 33
/* YYNRULES -- Number of states. */
#define YYNSTATES 39
#define YYNSTATES 53
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
#define YYMAXUTOK 268
#define YYMAXUTOK 269
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
......@@ -405,9 +408,9 @@ static const yytype_uint8 yytranslate[] =
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 14, 15, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 16, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 15, 17, 2, 16, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 18, 2,
2, 19, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
......@@ -427,7 +430,7 @@ static const yytype_uint8 yytranslate[] =
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13
5, 6, 7, 8, 9, 10, 11, 12, 13, 14
};
#if YYDEBUG
......@@ -435,29 +438,34 @@ static const yytype_uint8 yytranslate[] =
YYRHS. */
static const yytype_uint8 yyprhs[] =
{
0, 0, 3, 7, 9, 12, 14, 17, 20, 22,
25, 28, 31, 33, 39, 43, 45, 51, 55, 59,
63, 65, 67
0, 0, 3, 7, 9, 12, 14, 16, 19, 21,
24, 27, 30, 35, 38, 44, 48, 50, 56, 60,
64, 68, 70, 74, 76, 80, 84, 86, 90, 92,
94, 95, 97, 99
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yytype_int8 yyrhs[] =
{
18, 0, -1, 18, 14, 19, -1, 19, -1, 20,
7, -1, 20, -1, 21, 27, -1, 22, 27, -1,
23, -1, 24, 27, -1, 25, 27, -1, 26, 27,
-1, 4, -1, 9, 15, 10, 15, 10, -1, 9,
15, 10, -1, 9, -1, 11, 3, 16, 8, 27,
-1, 11, 3, 27, -1, 6, 16, 6, -1, 3,
16, 3, -1, 5, -1, 16, -1, -1
21, 0, -1, 21, 15, 22, -1, 22, -1, 23,
8, -1, 23, -1, 24, -1, 25, 32, -1, 26,
-1, 27, 32, -1, 28, 32, -1, 29, 32, -1,
4, 16, 30, 16, -1, 4, 33, -1, 10, 17,
11, 17, 11, -1, 10, 17, 11, -1, 10, -1,
12, 3, 18, 9, 32, -1, 12, 3, 32, -1,
7, 18, 7, -1, 3, 18, 3, -1, 5, -1,
30, 15, 31, -1, 31, -1, 7, 19, 7, -1,
7, 19, 3, -1, 7, -1, 6, 19, 3, -1,
6, -1, 18, -1, -1, 16, -1, 18, -1, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
0, 49, 49, 49, 52, 57, 59, 60, 61, 62,
63, 64, 67, 76, 81, 86, 92, 97, 103, 109,
115, 120, 120
0, 54, 54, 54, 57, 62, 64, 65, 66, 67,
68, 69, 72, 81, 90, 95, 100, 106, 111, 117,
123, 129, 135, 145, 157, 166, 175, 184, 192, 200,
200, 202, 202, 202
};
#endif
......@@ -467,12 +475,13 @@ static const yytype_uint8 yyrline[] =
static const char *const yytname[] =
{
"$end", "error", "$undefined", "PE_VALUE", "PE_VALUE_SYM", "PE_RAW",
"PE_NAME", "PE_MODIFIER_EVENT", "PE_MODIFIER_BP", "PE_NAME_CACHE_TYPE",
"PE_NAME_CACHE_OP_RESULT", "PE_PREFIX_MEM", "PE_PREFIX_RAW", "PE_ERROR",
"','", "'-'", "':'", "$accept", "events", "event", "event_def",
"event_legacy_symbol", "event_legacy_cache", "event_legacy_mem",
"event_legacy_tracepoint", "event_legacy_numeric", "event_legacy_raw",
"sep_dc", 0
"PE_TERM", "PE_NAME", "PE_MODIFIER_EVENT", "PE_MODIFIER_BP",
"PE_NAME_CACHE_TYPE", "PE_NAME_CACHE_OP_RESULT", "PE_PREFIX_MEM",
"PE_PREFIX_RAW", "PE_ERROR", "','", "'/'", "'-'", "':'", "'='",
"$accept", "events", "event", "event_def", "event_legacy_symbol",
"event_legacy_cache", "event_legacy_mem", "event_legacy_tracepoint",
"event_legacy_numeric", "event_legacy_raw", "event_config", "event_term",
"sep_dc", "sep_slash_dc", 0
};
#endif
......@@ -482,24 +491,26 @@ static const char *const yytname[] =
static const yytype_uint16 yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 44, 45, 58
265, 266, 267, 268, 269, 44, 47, 45, 58, 61
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] =
{
0, 17, 18, 18, 19, 19, 20, 20, 20, 20,
20, 20, 21, 22, 22, 22, 23, 23, 24, 25,
26, 27, 27
0, 20, 21, 21, 22, 22, 23, 23, 23, 23,
23, 23, 24, 24, 25, 25, 25, 26, 26, 27,
28, 29, 30, 30, 31, 31, 31, 31, 31, 32,
32, 33, 33, 33
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
static const yytype_uint8 yyr2[] =
{
0, 2, 3, 1, 2, 1, 2, 2, 1, 2,
2, 2, 1, 5, 3, 1, 5, 3, 3, 3,
1, 1, 0
0, 2, 3, 1, 2, 1, 1, 2, 1, 2,
2, 2, 4, 2, 5, 3, 1, 5, 3, 3,
3, 1, 3, 1, 3, 3, 1, 3, 1, 1,
0, 1, 1, 0
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
......@@ -507,35 +518,39 @@ static const yytype_uint8 yyr2[] =
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
0, 0, 12, 20, 0, 15, 0, 0, 3, 5,
22, 22, 8, 22, 22, 22, 0, 0, 0, 22,
1, 0, 4, 21, 6, 7, 9, 10, 11, 19,
18, 14, 21, 17, 2, 0, 22, 13, 16
0, 0, 33, 21, 0, 16, 0, 0, 3, 5,
6, 30, 8, 30, 30, 30, 0, 31, 32, 13,
0, 0, 30, 1, 0, 4, 29, 7, 9, 10,
11, 20, 28, 26, 0, 23, 19, 15, 29, 18,
2, 0, 0, 0, 12, 0, 30, 27, 25, 24,
22, 14, 17
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
-1, 7, 8, 9, 10, 11, 12, 13, 14, 15,
24
34, 35, 27, 19
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
#define YYPACT_NINF -12
#define YYPACT_NINF -14
static const yytype_int8 yypact[] =
{
7, -10, -12, -12, -9, -6, 2, 1, -12, 10,
-2, -2, -12, -2, -2, -2, 16, 14, 11, 6,
-12, 7, -12, -12, -12, -12, -12, -12, -12, -12,
-12, 8, 18, -12, -12, 17, -2, -12, -12
1, -11, -1, -14, -6, 8, 20, 3, -14, 16,
-14, -2, -14, -2, -2, -2, 23, 13, -14, -14,
21, 18, 9, -14, 1, -14, -14, -14, -14, -14,
-14, -14, 11, 12, 6, -14, -14, 15, 25, -14,
-14, 32, 7, 13, -14, 26, -2, -14, -14, -14,
-14, -14, -14
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
-12, -12, 3, -12, -12, -12, -12, -12, -12, -12,
-11
-14, -14, 14, -14, -14, -14, -14, -14, -14, -14,
-14, -7, -13, -14
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
......@@ -545,26 +560,30 @@ static const yytype_int8 yypgoto[] =
#define YYTABLE_NINF -1
static const yytype_uint8 yytable[] =
{
25, 20, 26, 27, 28, 19, 16, 17, 33, 18,
1, 2, 3, 4, 23, 21, 5, 22, 6, 29,
30, 31, 32, 35, 34, 38, 36, 37
28, 29, 30, 23, 1, 2, 3, 16, 4, 39,
48, 5, 20, 6, 49, 17, 26, 18, 24, 32,
33, 43, 44, 22, 25, 21, 31, 38, 36, 37,
41, 42, 45, 52, 46, 47, 50, 51, 40
};
static const yytype_uint8 yycheck[] =
{
11, 0, 13, 14, 15, 3, 16, 16, 19, 15,
3, 4, 5, 6, 16, 14, 9, 7, 11, 3,
6, 10, 16, 15, 21, 36, 8, 10
13, 14, 15, 0, 3, 4, 5, 18, 7, 22,
3, 10, 18, 12, 7, 16, 18, 18, 15, 6,
7, 15, 16, 3, 8, 17, 3, 18, 7, 11,
19, 19, 17, 46, 9, 3, 43, 11, 24
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] =
{
0, 3, 4, 5, 6, 9, 11, 18, 19, 20,
21, 22, 23, 24, 25, 26, 16, 16, 15, 3,
0, 14, 7, 16, 27, 27, 27, 27, 27, 3,
6, 10, 16, 27, 19, 15, 8, 10, 27
0, 3, 4, 5, 7, 10, 12, 21, 22, 23,
24, 25, 26, 27, 28, 29, 18, 16, 18, 33,
18, 17, 3, 0, 15, 8, 18, 32, 32, 32,
32, 3, 6, 7, 30, 31, 7, 11, 18, 32,
22, 19, 19, 15, 16, 17, 9, 3, 3, 7,
31, 11, 32
};
#define yyerrok (yyerrstatus = 0)
......@@ -1400,7 +1419,7 @@ yyparse (list, idx)
case 4:
/* Line 1464 of yacc.c */
#line 53 "util/parse-events.y"
#line 58 "util/parse-events.y"
{
ABORT_ON(parse_events_modifier(list, (yyvsp[(2) - (2)].str)));
;}
......@@ -1409,91 +1428,196 @@ yyparse (list, idx)
case 12:
/* Line 1464 of yacc.c */
#line 68 "util/parse-events.y"
#line 73 "util/parse-events.y"
{
int type = (yyvsp[(1) - (1)].num) >> 16;
int config = (yyvsp[(1) - (1)].num) & 255;
int type = (yyvsp[(1) - (4)].num) >> 16;
int config = (yyvsp[(1) - (4)].num) & 255;
ABORT_ON(parse_events_add_numeric(list, idx, type, config));
ABORT_ON(parse_events_add_numeric(list, idx, type, config, (yyvsp[(3) - (4)].head)));
parse_events__free_terms((yyvsp[(3) - (4)].head));
;}
break;
case 13:
/* Line 1464 of yacc.c */
#line 77 "util/parse-events.y"
#line 82 "util/parse-events.y"
{
ABORT_ON(parse_events_add_cache(list, idx, (yyvsp[(1) - (5)].str), (yyvsp[(3) - (5)].str), (yyvsp[(5) - (5)].str)));
int type = (yyvsp[(1) - (2)].num) >> 16;
int config = (yyvsp[(1) - (2)].num) & 255;
ABORT_ON(parse_events_add_numeric(list, idx, type, config, NULL));
;}
break;
case 14:
/* Line 1464 of yacc.c */
#line 82 "util/parse-events.y"
#line 91 "util/parse-events.y"
{
ABORT_ON(parse_events_add_cache(list, idx, (yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str), NULL));
ABORT_ON(parse_events_add_cache(list, idx, (yyvsp[(1) - (5)].str), (yyvsp[(3) - (5)].str), (yyvsp[(5) - (5)].str)));
;}
break;
case 15:
/* Line 1464 of yacc.c */
#line 87 "util/parse-events.y"
#line 96 "util/parse-events.y"
{
ABORT_ON(parse_events_add_cache(list, idx, (yyvsp[(1) - (1)].str), NULL, NULL));
ABORT_ON(parse_events_add_cache(list, idx, (yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str), NULL));
;}
break;
case 16:
/* Line 1464 of yacc.c */
#line 93 "util/parse-events.y"
#line 101 "util/parse-events.y"
{
ABORT_ON(parse_events_add_breakpoint(list, idx, (void *) (yyvsp[(2) - (5)].num), (yyvsp[(4) - (5)].str)));
ABORT_ON(parse_events_add_cache(list, idx, (yyvsp[(1) - (1)].str), NULL, NULL));
;}
break;
case 17:
/* Line 1464 of yacc.c */
#line 98 "util/parse-events.y"
#line 107 "util/parse-events.y"
{
ABORT_ON(parse_events_add_breakpoint(list, idx, (void *) (yyvsp[(2) - (3)].num), NULL));
ABORT_ON(parse_events_add_breakpoint(list, idx, (void *) (yyvsp[(2) - (5)].num), (yyvsp[(4) - (5)].str)));
;}
break;
case 18:
/* Line 1464 of yacc.c */
#line 104 "util/parse-events.y"
#line 112 "util/parse-events.y"
{
ABORT_ON(parse_events_add_tracepoint(list, idx, (yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str)));
ABORT_ON(parse_events_add_breakpoint(list, idx, (void *) (yyvsp[(2) - (3)].num), NULL));
;}
break;
case 19:
/* Line 1464 of yacc.c */
#line 110 "util/parse-events.y"
#line 118 "util/parse-events.y"
{
ABORT_ON(parse_events_add_numeric(list, idx, (yyvsp[(1) - (3)].num), (yyvsp[(3) - (3)].num)));
ABORT_ON(parse_events_add_tracepoint(list, idx, (yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str)));
;}
break;
case 20:
/* Line 1464 of yacc.c */
#line 116 "util/parse-events.y"
#line 124 "util/parse-events.y"
{
ABORT_ON(parse_events_add_numeric(list, idx, (yyvsp[(1) - (3)].num), (yyvsp[(3) - (3)].num), NULL));
;}
break;
case 21:
/* Line 1464 of yacc.c */
#line 130 "util/parse-events.y"
{
ABORT_ON(parse_events_add_numeric(list, idx, PERF_TYPE_RAW, (yyvsp[(1) - (1)].num), NULL));
;}
break;
case 22:
/* Line 1464 of yacc.c */
#line 136 "util/parse-events.y"
{
ABORT_ON(parse_events_add_numeric(list, idx, PERF_TYPE_RAW, (yyvsp[(1) - (1)].num)));
struct list_head *head = (yyvsp[(1) - (3)].head);
struct parse_events__term *term = (yyvsp[(3) - (3)].term);
ABORT_ON(!head);
list_add_tail(&term->list, head);
(yyval.head) = (yyvsp[(1) - (3)].head);
;}
break;
case 23:
/* Line 1464 of yacc.c */
#line 146 "util/parse-events.y"
{
struct list_head *head = malloc(sizeof(*head));
struct parse_events__term *term = (yyvsp[(1) - (1)].term);
ABORT_ON(!head);
INIT_LIST_HEAD(head);
list_add_tail(&term->list, head);
(yyval.head) = head;
;}
break;
case 24:
/* Line 1464 of yacc.c */
#line 158 "util/parse-events.y"
{
struct parse_events__term *term;
ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_STR,
(yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str), 0));
(yyval.term) = term;
;}
break;
case 25:
/* Line 1464 of yacc.c */
#line 167 "util/parse-events.y"
{
struct parse_events__term *term;
ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_NUM,
(yyvsp[(1) - (3)].str), NULL, (yyvsp[(3) - (3)].num)));
(yyval.term) = term;
;}
break;
case 26:
/* Line 1464 of yacc.c */
#line 176 "util/parse-events.y"
{
struct parse_events__term *term;
ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_NUM,
(yyvsp[(1) - (1)].str), NULL, 1));
(yyval.term) = term;
;}
break;
case 27:
/* Line 1464 of yacc.c */
#line 185 "util/parse-events.y"
{
struct parse_events__term *term;
ABORT_ON(parse_events__new_term(&term, (yyvsp[(1) - (3)].num), NULL, NULL, (yyvsp[(3) - (3)].num)));
(yyval.term) = term;
;}
break;
case 28:
/* Line 1464 of yacc.c */
#line 193 "util/parse-events.y"
{
struct parse_events__term *term;
ABORT_ON(parse_events__new_term(&term, (yyvsp[(1) - (1)].num), NULL, NULL, 1));
(yyval.term) = term;
;}
break;
/* Line 1464 of yacc.c */
#line 1497 "util/parse-events-bison.c"
#line 1621 "util/parse-events-bison.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
......@@ -1705,7 +1829,7 @@ yyparse (list, idx)
/* Line 1684 of yacc.c */
#line 122 "util/parse-events.y"
#line 204 "util/parse-events.y"
void parse_events_error(struct list_head *list __used, int *idx __used,
......
......@@ -41,14 +41,15 @@
PE_VALUE = 258,
PE_VALUE_SYM = 259,
PE_RAW = 260,
PE_NAME = 261,
PE_MODIFIER_EVENT = 262,
PE_MODIFIER_BP = 263,
PE_NAME_CACHE_TYPE = 264,
PE_NAME_CACHE_OP_RESULT = 265,
PE_PREFIX_MEM = 266,
PE_PREFIX_RAW = 267,
PE_ERROR = 268
PE_TERM = 261,
PE_NAME = 262,
PE_MODIFIER_EVENT = 263,
PE_MODIFIER_BP = 264,
PE_NAME_CACHE_TYPE = 265,
PE_NAME_CACHE_OP_RESULT = 266,
PE_PREFIX_MEM = 267,
PE_PREFIX_RAW = 268,
PE_ERROR = 269
};
#endif
......@@ -59,15 +60,17 @@ typedef union YYSTYPE
{
/* Line 1685 of yacc.c */
#line 42 "util/parse-events.y"
#line 45 "util/parse-events.y"
char *str;
unsigned long num;
struct list_head *head;
struct parse_events__term *term;
/* Line 1685 of yacc.c */
#line 71 "util/parse-events-bison.h"
#line 74 "util/parse-events-bison.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
......
此差异已折叠。
......@@ -308,7 +308,7 @@ extern int parse_events_lex (void);
#undef YY_DECL
#endif
#line 102 "util/parse-events.l"
#line 121 "util/parse-events.l"
#line 315 "util/parse-events-flex.h"
......
......@@ -588,15 +588,60 @@ int parse_events_add_breakpoint(struct list_head *list, int *idx,
return add_event(list, idx, &attr, name);
}
int
parse_events_add_numeric(struct list_head *list, int *idx,
unsigned long type, unsigned long config)
static int config_term(struct perf_event_attr *attr,
struct parse_events__term *term)
{
switch (term->type) {
case PARSE_EVENTS__TERM_TYPE_CONFIG:
attr->config = term->val.num;
break;
case PARSE_EVENTS__TERM_TYPE_CONFIG1:
attr->config1 = term->val.num;
break;
case PARSE_EVENTS__TERM_TYPE_CONFIG2:
attr->config2 = term->val.num;
break;
case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
attr->sample_period = term->val.num;
break;
case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
/*
* TODO uncomment when the field is available
* attr->branch_sample_type = term->val.num;
*/
break;
default:
return -EINVAL;
}
return 0;
}
static int config_attr(struct perf_event_attr *attr,
struct list_head *head, int fail)
{
struct parse_events__term *term;
list_for_each_entry(term, head, list)
if (config_term(attr, term) && fail)
return -EINVAL;
return 0;
}
int parse_events_add_numeric(struct list_head *list, int *idx,
unsigned long type, unsigned long config,
struct list_head *head_config)
{
struct perf_event_attr attr;
memset(&attr, 0, sizeof(attr));
attr.type = type;
attr.config = config;
if (head_config &&
config_attr(&attr, head_config, 1))
return -EINVAL;
return add_event(list, idx, &attr,
(char *) __event_name(type, config));
}
......@@ -923,3 +968,51 @@ void print_events(const char *event_glob)
print_tracepoint_events(NULL, NULL);
}
int parse_events__is_hardcoded_term(struct parse_events__term *term)
{
return term->type <= PARSE_EVENTS__TERM_TYPE_HARDCODED_MAX;
}
int parse_events__new_term(struct parse_events__term **_term, int type,
char *config, char *str, long num)
{
struct parse_events__term *term;
term = zalloc(sizeof(*term));
if (!term)
return -ENOMEM;
INIT_LIST_HEAD(&term->list);
term->type = type;
term->config = config;
switch (type) {
case PARSE_EVENTS__TERM_TYPE_CONFIG:
case PARSE_EVENTS__TERM_TYPE_CONFIG1:
case PARSE_EVENTS__TERM_TYPE_CONFIG2:
case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
case PARSE_EVENTS__TERM_TYPE_NUM:
term->val.num = num;
break;
case PARSE_EVENTS__TERM_TYPE_STR:
term->val.str = str;
break;
default:
return -EINVAL;
}
*_term = term;
return 0;
}
void parse_events__free_terms(struct list_head *terms)
{
struct parse_events__term *term, *h;
list_for_each_entry_safe(term, h, terms, list)
free(term);
free(terms);
}
......@@ -33,6 +33,34 @@ extern int parse_filter(const struct option *opt, const char *str, int unset);
#define EVENTS_HELP_MAX (128*1024)
enum {
PARSE_EVENTS__TERM_TYPE_CONFIG,
PARSE_EVENTS__TERM_TYPE_CONFIG1,
PARSE_EVENTS__TERM_TYPE_CONFIG2,
PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD,
PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE,
PARSE_EVENTS__TERM_TYPE_NUM,
PARSE_EVENTS__TERM_TYPE_STR,
PARSE_EVENTS__TERM_TYPE_HARDCODED_MAX =
PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE,
};
struct parse_events__term {
char *config;
union {
char *str;
long num;
} val;
int type;
struct list_head list;
};
int parse_events__is_hardcoded_term(struct parse_events__term *term);
int parse_events__new_term(struct parse_events__term **term, int type,
char *config, char *str, long num);
void parse_events__free_terms(struct list_head *terms);
int parse_events_modifier(struct list_head *list __used, char *str __used);
int parse_events_add_tracepoint(struct list_head *list, int *idx,
char *sys, char *event);
......@@ -40,7 +68,8 @@ int parse_events_add_raw(struct perf_evlist *evlist, unsigned long config,
unsigned long config1, unsigned long config2,
char *mod);
int parse_events_add_numeric(struct list_head *list, int *idx,
unsigned long type, unsigned long config);
unsigned long type, unsigned long config,
struct list_head *head_config);
int parse_events_add_cache(struct list_head *list, int *idx,
char *type, char *op_result1, char *op_result2);
int parse_events_add_breakpoint(struct list_head *list, int *idx,
......
......@@ -5,6 +5,7 @@
#include <errno.h>
#include "../perf.h"
#include "parse-events-bison.h"
#include "parse-events.h"
static int __value(char *str, int base, int token)
{
......@@ -41,6 +42,12 @@ static int sym(int type, int config)
return PE_VALUE_SYM;
}
static int term(int type)
{
parse_events_lval.num = type;
return PE_TERM;
}
%}
num_dec [0-9]+
......@@ -85,6 +92,18 @@ speculative-read|speculative-load |
refs|Reference|ops|access |
misses|miss { return str(PE_NAME_CACHE_OP_RESULT); }
/*
* These are event config hardcoded term names to be specified
* within xxx/.../ syntax. So far we dont clash with other names,
* so we can put them here directly. In case the we have a conflict
* in future, this needs to go into '//' condition block.
*/
config { return term(PARSE_EVENTS__TERM_TYPE_CONFIG); }
config1 { return term(PARSE_EVENTS__TERM_TYPE_CONFIG1); }
config2 { return term(PARSE_EVENTS__TERM_TYPE_CONFIG2); }
period { return term(PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); }
branch_type { return term(PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); }
mem: { return PE_PREFIX_MEM; }
r{num_raw_hex} { return raw(); }
{num_dec} { return value(10); }
......
......@@ -23,7 +23,7 @@ do { \
%}
%token PE_VALUE PE_VALUE_SYM PE_RAW
%token PE_VALUE PE_VALUE_SYM PE_RAW PE_TERM
%token PE_NAME
%token PE_MODIFIER_EVENT PE_MODIFIER_BP
%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
......@@ -32,16 +32,21 @@ do { \
%type <num> PE_VALUE
%type <num> PE_VALUE_SYM
%type <num> PE_RAW
%type <num> PE_TERM
%type <str> PE_NAME
%type <str> PE_NAME_CACHE_TYPE
%type <str> PE_NAME_CACHE_OP_RESULT
%type <str> PE_MODIFIER_EVENT
%type <str> PE_MODIFIER_BP
%type <head> event_config
%type <term> event_term
%union
{
char *str;
unsigned long num;
struct list_head *head;
struct parse_events__term *term;
}
%%
......@@ -56,7 +61,7 @@ event_def PE_MODIFIER_EVENT
|
event_def
event_def: event_legacy_symbol sep_dc |
event_def: event_legacy_symbol |
event_legacy_cache sep_dc |
event_legacy_mem |
event_legacy_tracepoint sep_dc |
......@@ -64,12 +69,21 @@ event_def: event_legacy_symbol sep_dc |
event_legacy_raw sep_dc
event_legacy_symbol:
PE_VALUE_SYM
PE_VALUE_SYM '/' event_config '/'
{
int type = $1 >> 16;
int config = $1 & 255;
ABORT_ON(parse_events_add_numeric(list, idx, type, config));
ABORT_ON(parse_events_add_numeric(list, idx, type, config, $3));
parse_events__free_terms($3);
}
|
PE_VALUE_SYM sep_slash_dc
{
int type = $1 >> 16;
int config = $1 & 255;
ABORT_ON(parse_events_add_numeric(list, idx, type, config, NULL));
}
event_legacy_cache:
......@@ -108,17 +122,85 @@ PE_NAME ':' PE_NAME
event_legacy_numeric:
PE_VALUE ':' PE_VALUE
{
ABORT_ON(parse_events_add_numeric(list, idx, $1, $3));
ABORT_ON(parse_events_add_numeric(list, idx, $1, $3, NULL));
}
event_legacy_raw:
PE_RAW
{
ABORT_ON(parse_events_add_numeric(list, idx, PERF_TYPE_RAW, $1));
ABORT_ON(parse_events_add_numeric(list, idx, PERF_TYPE_RAW, $1, NULL));
}
event_config:
event_config ',' event_term
{
struct list_head *head = $1;
struct parse_events__term *term = $3;
ABORT_ON(!head);
list_add_tail(&term->list, head);
$$ = $1;
}
|
event_term
{
struct list_head *head = malloc(sizeof(*head));
struct parse_events__term *term = $1;
ABORT_ON(!head);
INIT_LIST_HEAD(head);
list_add_tail(&term->list, head);
$$ = head;
}
event_term:
PE_NAME '=' PE_NAME
{
struct parse_events__term *term;
ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_STR,
$1, $3, 0));
$$ = term;
}
|
PE_NAME '=' PE_VALUE
{
struct parse_events__term *term;
ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_NUM,
$1, NULL, $3));
$$ = term;
}
|
PE_NAME
{
struct parse_events__term *term;
ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_NUM,
$1, NULL, 1));
$$ = term;
}
|
PE_TERM '=' PE_VALUE
{
struct parse_events__term *term;
ABORT_ON(parse_events__new_term(&term, $1, NULL, NULL, $3));
$$ = term;
}
|
PE_TERM
{
struct parse_events__term *term;
ABORT_ON(parse_events__new_term(&term, $1, NULL, NULL, 1));
$$ = term;
}
sep_dc: ':' |
sep_slash_dc: '/' | ':' |
%%
void parse_events_error(struct list_head *list __used, int *idx __used,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册