diff options
author | Ingo Molnar <mingo@kernel.org> | 2018-05-31 06:37:07 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2018-05-31 06:37:07 -0400 |
commit | 6497bbc35ac5efce3bccd31d3719bae020282da6 (patch) | |
tree | c99f566cf166cced1961140ea30249e9babaded2 | |
parent | 786b71f5b754273ccef6d9462e52062b3e1f9877 (diff) | |
parent | 18a7057420f8b67f15d17087bf5c0863db752c8b (diff) |
Merge tag 'perf-urgent-for-mingo-4.17-20180531' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Pull perf/urgent fixes from Arnaldo Carvalho de Melo:
- Fix 'perf test Session topology' segfault on s390 (Thomas Richter)
- Fix NULL return handling in bpf__prepare_load() (YueHaibing)
- Fix indexing on Coresight ETM packet queue decoder (Mathieu Poirier)
- Fix perf.data format description of NRCPUS header (Arnaldo Carvalho de Melo)
- Update perf.data documentation section on cpu topology
- Handle uncore event aliases in small groups properly (Kan Liang)
- Add missing perf_sample.addr into python sample dictionary (Leo Yan)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | tools/perf/Documentation/perf.data-file-format.txt | 10 | ||||
-rw-r--r-- | tools/perf/tests/topology.c | 30 | ||||
-rw-r--r-- | tools/perf/util/bpf-loader.c | 6 | ||||
-rw-r--r-- | tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 12 | ||||
-rw-r--r-- | tools/perf/util/evsel.h | 1 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 130 | ||||
-rw-r--r-- | tools/perf/util/parse-events.h | 7 | ||||
-rw-r--r-- | tools/perf/util/parse-events.y | 8 | ||||
-rw-r--r-- | tools/perf/util/scripting-engines/trace-event-python.c | 2 |
9 files changed, 185 insertions, 21 deletions
diff --git a/tools/perf/Documentation/perf.data-file-format.txt b/tools/perf/Documentation/perf.data-file-format.txt index d00f0d51cab8..dfb218feaad9 100644 --- a/tools/perf/Documentation/perf.data-file-format.txt +++ b/tools/perf/Documentation/perf.data-file-format.txt | |||
@@ -111,8 +111,8 @@ A perf_header_string with the CPU architecture (uname -m) | |||
111 | A structure defining the number of CPUs. | 111 | A structure defining the number of CPUs. |
112 | 112 | ||
113 | struct nr_cpus { | 113 | struct nr_cpus { |
114 | uint32_t nr_cpus_online; | ||
115 | uint32_t nr_cpus_available; /* CPUs not yet onlined */ | 114 | uint32_t nr_cpus_available; /* CPUs not yet onlined */ |
115 | uint32_t nr_cpus_online; | ||
116 | }; | 116 | }; |
117 | 117 | ||
118 | HEADER_CPUDESC = 8, | 118 | HEADER_CPUDESC = 8, |
@@ -153,10 +153,18 @@ struct { | |||
153 | HEADER_CPU_TOPOLOGY = 13, | 153 | HEADER_CPU_TOPOLOGY = 13, |
154 | 154 | ||
155 | String lists defining the core and CPU threads topology. | 155 | String lists defining the core and CPU threads topology. |
156 | The string lists are followed by a variable length array | ||
157 | which contains core_id and socket_id of each cpu. | ||
158 | The number of entries can be determined by the size of the | ||
159 | section minus the sizes of both string lists. | ||
156 | 160 | ||
157 | struct { | 161 | struct { |
158 | struct perf_header_string_list cores; /* Variable length */ | 162 | struct perf_header_string_list cores; /* Variable length */ |
159 | struct perf_header_string_list threads; /* Variable length */ | 163 | struct perf_header_string_list threads; /* Variable length */ |
164 | struct { | ||
165 | uint32_t core_id; | ||
166 | uint32_t socket_id; | ||
167 | } cpus[nr]; /* Variable length records */ | ||
160 | }; | 168 | }; |
161 | 169 | ||
162 | Example: | 170 | Example: |
diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index 17cb1bb3448c..40e30a26b23c 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c | |||
@@ -70,6 +70,27 @@ static int check_cpu_topology(char *path, struct cpu_map *map) | |||
70 | session = perf_session__new(&data, false, NULL); | 70 | session = perf_session__new(&data, false, NULL); |
71 | TEST_ASSERT_VAL("can't get session", session); | 71 | TEST_ASSERT_VAL("can't get session", session); |
72 | 72 | ||
73 | /* On platforms with large numbers of CPUs process_cpu_topology() | ||
74 | * might issue an error while reading the perf.data file section | ||
75 | * HEADER_CPU_TOPOLOGY and the cpu_topology_map pointed to by member | ||
76 | * cpu is a NULL pointer. | ||
77 | * Example: On s390 | ||
78 | * CPU 0 is on core_id 0 and physical_package_id 6 | ||
79 | * CPU 1 is on core_id 1 and physical_package_id 3 | ||
80 | * | ||
81 | * Core_id and physical_package_id are platform and architecture | ||
82 | * dependend and might have higher numbers than the CPU id. | ||
83 | * This actually depends on the configuration. | ||
84 | * | ||
85 | * In this case process_cpu_topology() prints error message: | ||
86 | * "socket_id number is too big. You may need to upgrade the | ||
87 | * perf tool." | ||
88 | * | ||
89 | * This is the reason why this test might be skipped. | ||
90 | */ | ||
91 | if (!session->header.env.cpu) | ||
92 | return TEST_SKIP; | ||
93 | |||
73 | for (i = 0; i < session->header.env.nr_cpus_avail; i++) { | 94 | for (i = 0; i < session->header.env.nr_cpus_avail; i++) { |
74 | if (!cpu_map__has(map, i)) | 95 | if (!cpu_map__has(map, i)) |
75 | continue; | 96 | continue; |
@@ -95,7 +116,7 @@ int test__session_topology(struct test *test __maybe_unused, int subtest __maybe | |||
95 | { | 116 | { |
96 | char path[PATH_MAX]; | 117 | char path[PATH_MAX]; |
97 | struct cpu_map *map; | 118 | struct cpu_map *map; |
98 | int ret = -1; | 119 | int ret = TEST_FAIL; |
99 | 120 | ||
100 | TEST_ASSERT_VAL("can't get templ file", !get_temp(path)); | 121 | TEST_ASSERT_VAL("can't get templ file", !get_temp(path)); |
101 | 122 | ||
@@ -110,12 +131,9 @@ int test__session_topology(struct test *test __maybe_unused, int subtest __maybe | |||
110 | goto free_path; | 131 | goto free_path; |
111 | } | 132 | } |
112 | 133 | ||
113 | if (check_cpu_topology(path, map)) | 134 | ret = check_cpu_topology(path, map); |
114 | goto free_map; | ||
115 | ret = 0; | ||
116 | |||
117 | free_map: | ||
118 | cpu_map__put(map); | 135 | cpu_map__put(map); |
136 | |||
119 | free_path: | 137 | free_path: |
120 | unlink(path); | 138 | unlink(path); |
121 | return ret; | 139 | return ret; |
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index af7ad814b2c3..cee658733e2c 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c | |||
@@ -66,7 +66,7 @@ bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name) | |||
66 | } | 66 | } |
67 | 67 | ||
68 | obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, name); | 68 | obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, name); |
69 | if (IS_ERR(obj)) { | 69 | if (IS_ERR_OR_NULL(obj)) { |
70 | pr_debug("bpf: failed to load buffer\n"); | 70 | pr_debug("bpf: failed to load buffer\n"); |
71 | return ERR_PTR(-EINVAL); | 71 | return ERR_PTR(-EINVAL); |
72 | } | 72 | } |
@@ -102,14 +102,14 @@ struct bpf_object *bpf__prepare_load(const char *filename, bool source) | |||
102 | pr_debug("bpf: successfull builtin compilation\n"); | 102 | pr_debug("bpf: successfull builtin compilation\n"); |
103 | obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, filename); | 103 | obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, filename); |
104 | 104 | ||
105 | if (!IS_ERR(obj) && llvm_param.dump_obj) | 105 | if (!IS_ERR_OR_NULL(obj) && llvm_param.dump_obj) |
106 | llvm__dump_obj(filename, obj_buf, obj_buf_sz); | 106 | llvm__dump_obj(filename, obj_buf, obj_buf_sz); |
107 | 107 | ||
108 | free(obj_buf); | 108 | free(obj_buf); |
109 | } else | 109 | } else |
110 | obj = bpf_object__open(filename); | 110 | obj = bpf_object__open(filename); |
111 | 111 | ||
112 | if (IS_ERR(obj)) { | 112 | if (IS_ERR_OR_NULL(obj)) { |
113 | pr_debug("bpf: failed to load %s\n", filename); | 113 | pr_debug("bpf: failed to load %s\n", filename); |
114 | return obj; | 114 | return obj; |
115 | } | 115 | } |
diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c index c8b98fa22997..4d5fc374e730 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | |||
@@ -96,11 +96,19 @@ int cs_etm_decoder__get_packet(struct cs_etm_decoder *decoder, | |||
96 | /* Nothing to do, might as well just return */ | 96 | /* Nothing to do, might as well just return */ |
97 | if (decoder->packet_count == 0) | 97 | if (decoder->packet_count == 0) |
98 | return 0; | 98 | return 0; |
99 | /* | ||
100 | * The queueing process in function cs_etm_decoder__buffer_packet() | ||
101 | * increments the tail *before* using it. This is somewhat counter | ||
102 | * intuitive but it has the advantage of centralizing tail management | ||
103 | * at a single location. Because of that we need to follow the same | ||
104 | * heuristic with the head, i.e we increment it before using its | ||
105 | * value. Otherwise the first element of the packet queue is not | ||
106 | * used. | ||
107 | */ | ||
108 | decoder->head = (decoder->head + 1) & (MAX_BUFFER - 1); | ||
99 | 109 | ||
100 | *packet = decoder->packet_buffer[decoder->head]; | 110 | *packet = decoder->packet_buffer[decoder->head]; |
101 | 111 | ||
102 | decoder->head = (decoder->head + 1) & (MAX_BUFFER - 1); | ||
103 | |||
104 | decoder->packet_count--; | 112 | decoder->packet_count--; |
105 | 113 | ||
106 | return 1; | 114 | return 1; |
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 92ec009a292d..b13f5f234c8f 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
@@ -127,6 +127,7 @@ struct perf_evsel { | |||
127 | bool precise_max; | 127 | bool precise_max; |
128 | bool ignore_missing_thread; | 128 | bool ignore_missing_thread; |
129 | bool forced_leader; | 129 | bool forced_leader; |
130 | bool use_uncore_alias; | ||
130 | /* parse modifier helper */ | 131 | /* parse modifier helper */ |
131 | int exclude_GH; | 132 | int exclude_GH; |
132 | int nr_members; | 133 | int nr_members; |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index b8b8a9558d32..2fc4ee8b86c1 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -1219,13 +1219,16 @@ int parse_events_add_numeric(struct parse_events_state *parse_state, | |||
1219 | 1219 | ||
1220 | int parse_events_add_pmu(struct parse_events_state *parse_state, | 1220 | int parse_events_add_pmu(struct parse_events_state *parse_state, |
1221 | struct list_head *list, char *name, | 1221 | struct list_head *list, char *name, |
1222 | struct list_head *head_config, bool auto_merge_stats) | 1222 | struct list_head *head_config, |
1223 | bool auto_merge_stats, | ||
1224 | bool use_alias) | ||
1223 | { | 1225 | { |
1224 | struct perf_event_attr attr; | 1226 | struct perf_event_attr attr; |
1225 | struct perf_pmu_info info; | 1227 | struct perf_pmu_info info; |
1226 | struct perf_pmu *pmu; | 1228 | struct perf_pmu *pmu; |
1227 | struct perf_evsel *evsel; | 1229 | struct perf_evsel *evsel; |
1228 | struct parse_events_error *err = parse_state->error; | 1230 | struct parse_events_error *err = parse_state->error; |
1231 | bool use_uncore_alias; | ||
1229 | LIST_HEAD(config_terms); | 1232 | LIST_HEAD(config_terms); |
1230 | 1233 | ||
1231 | pmu = perf_pmu__find(name); | 1234 | pmu = perf_pmu__find(name); |
@@ -1244,11 +1247,14 @@ int parse_events_add_pmu(struct parse_events_state *parse_state, | |||
1244 | memset(&attr, 0, sizeof(attr)); | 1247 | memset(&attr, 0, sizeof(attr)); |
1245 | } | 1248 | } |
1246 | 1249 | ||
1250 | use_uncore_alias = (pmu->is_uncore && use_alias); | ||
1251 | |||
1247 | if (!head_config) { | 1252 | if (!head_config) { |
1248 | attr.type = pmu->type; | 1253 | attr.type = pmu->type; |
1249 | evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu, NULL, auto_merge_stats); | 1254 | evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu, NULL, auto_merge_stats); |
1250 | if (evsel) { | 1255 | if (evsel) { |
1251 | evsel->pmu_name = name; | 1256 | evsel->pmu_name = name; |
1257 | evsel->use_uncore_alias = use_uncore_alias; | ||
1252 | return 0; | 1258 | return 0; |
1253 | } else { | 1259 | } else { |
1254 | return -ENOMEM; | 1260 | return -ENOMEM; |
@@ -1282,6 +1288,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state, | |||
1282 | evsel->metric_expr = info.metric_expr; | 1288 | evsel->metric_expr = info.metric_expr; |
1283 | evsel->metric_name = info.metric_name; | 1289 | evsel->metric_name = info.metric_name; |
1284 | evsel->pmu_name = name; | 1290 | evsel->pmu_name = name; |
1291 | evsel->use_uncore_alias = use_uncore_alias; | ||
1285 | } | 1292 | } |
1286 | 1293 | ||
1287 | return evsel ? 0 : -ENOMEM; | 1294 | return evsel ? 0 : -ENOMEM; |
@@ -1317,7 +1324,8 @@ int parse_events_multi_pmu_add(struct parse_events_state *parse_state, | |||
1317 | list_add_tail(&term->list, head); | 1324 | list_add_tail(&term->list, head); |
1318 | 1325 | ||
1319 | if (!parse_events_add_pmu(parse_state, list, | 1326 | if (!parse_events_add_pmu(parse_state, list, |
1320 | pmu->name, head, true)) { | 1327 | pmu->name, head, |
1328 | true, true)) { | ||
1321 | pr_debug("%s -> %s/%s/\n", str, | 1329 | pr_debug("%s -> %s/%s/\n", str, |
1322 | pmu->name, alias->str); | 1330 | pmu->name, alias->str); |
1323 | ok++; | 1331 | ok++; |
@@ -1339,7 +1347,120 @@ int parse_events__modifier_group(struct list_head *list, | |||
1339 | return parse_events__modifier_event(list, event_mod, true); | 1347 | return parse_events__modifier_event(list, event_mod, true); |
1340 | } | 1348 | } |
1341 | 1349 | ||
1342 | void parse_events__set_leader(char *name, struct list_head *list) | 1350 | /* |
1351 | * Check if the two uncore PMUs are from the same uncore block | ||
1352 | * The format of the uncore PMU name is uncore_#blockname_#pmuidx | ||
1353 | */ | ||
1354 | static bool is_same_uncore_block(const char *pmu_name_a, const char *pmu_name_b) | ||
1355 | { | ||
1356 | char *end_a, *end_b; | ||
1357 | |||
1358 | end_a = strrchr(pmu_name_a, '_'); | ||
1359 | end_b = strrchr(pmu_name_b, '_'); | ||
1360 | |||
1361 | if (!end_a || !end_b) | ||
1362 | return false; | ||
1363 | |||
1364 | if ((end_a - pmu_name_a) != (end_b - pmu_name_b)) | ||
1365 | return false; | ||
1366 | |||
1367 | return (strncmp(pmu_name_a, pmu_name_b, end_a - pmu_name_a) == 0); | ||
1368 | } | ||
1369 | |||
1370 | static int | ||
1371 | parse_events__set_leader_for_uncore_aliase(char *name, struct list_head *list, | ||
1372 | struct parse_events_state *parse_state) | ||
1373 | { | ||
1374 | struct perf_evsel *evsel, *leader; | ||
1375 | uintptr_t *leaders; | ||
1376 | bool is_leader = true; | ||
1377 | int i, nr_pmu = 0, total_members, ret = 0; | ||
1378 | |||
1379 | leader = list_first_entry(list, struct perf_evsel, node); | ||
1380 | evsel = list_last_entry(list, struct perf_evsel, node); | ||
1381 | total_members = evsel->idx - leader->idx + 1; | ||
1382 | |||
1383 | leaders = calloc(total_members, sizeof(uintptr_t)); | ||
1384 | if (WARN_ON(!leaders)) | ||
1385 | return 0; | ||
1386 | |||
1387 | /* | ||
1388 | * Going through the whole group and doing sanity check. | ||
1389 | * All members must use alias, and be from the same uncore block. | ||
1390 | * Also, storing the leader events in an array. | ||
1391 | */ | ||
1392 | __evlist__for_each_entry(list, evsel) { | ||
1393 | |||
1394 | /* Only split the uncore group which members use alias */ | ||
1395 | if (!evsel->use_uncore_alias) | ||
1396 | goto out; | ||
1397 | |||
1398 | /* The events must be from the same uncore block */ | ||
1399 | if (!is_same_uncore_block(leader->pmu_name, evsel->pmu_name)) | ||
1400 | goto out; | ||
1401 | |||
1402 | if (!is_leader) | ||
1403 | continue; | ||
1404 | /* | ||
1405 | * If the event's PMU name starts to repeat, it must be a new | ||
1406 | * event. That can be used to distinguish the leader from | ||
1407 | * other members, even they have the same event name. | ||
1408 | */ | ||
1409 | if ((leader != evsel) && (leader->pmu_name == evsel->pmu_name)) { | ||
1410 | is_leader = false; | ||
1411 | continue; | ||
1412 | } | ||
1413 | /* The name is always alias name */ | ||
1414 | WARN_ON(strcmp(leader->name, evsel->name)); | ||
1415 | |||
1416 | /* Store the leader event for each PMU */ | ||
1417 | leaders[nr_pmu++] = (uintptr_t) evsel; | ||
1418 | } | ||
1419 | |||
1420 | /* only one event alias */ | ||
1421 | if (nr_pmu == total_members) { | ||
1422 | parse_state->nr_groups--; | ||
1423 | goto handled; | ||
1424 | } | ||
1425 | |||
1426 | /* | ||
1427 | * An uncore event alias is a joint name which means the same event | ||
1428 | * runs on all PMUs of a block. | ||
1429 | * Perf doesn't support mixed events from different PMUs in the same | ||
1430 | * group. The big group has to be split into multiple small groups | ||
1431 | * which only include the events from the same PMU. | ||
1432 | * | ||
1433 | * Here the uncore event aliases must be from the same uncore block. | ||
1434 | * The number of PMUs must be same for each alias. The number of new | ||
1435 | * small groups equals to the number of PMUs. | ||
1436 | * Setting the leader event for corresponding members in each group. | ||
1437 | */ | ||
1438 | i = 0; | ||
1439 | __evlist__for_each_entry(list, evsel) { | ||
1440 | if (i >= nr_pmu) | ||
1441 | i = 0; | ||
1442 | evsel->leader = (struct perf_evsel *) leaders[i++]; | ||
1443 | } | ||
1444 | |||
1445 | /* The number of members and group name are same for each group */ | ||
1446 | for (i = 0; i < nr_pmu; i++) { | ||
1447 | evsel = (struct perf_evsel *) leaders[i]; | ||
1448 | evsel->nr_members = total_members / nr_pmu; | ||
1449 | evsel->group_name = name ? strdup(name) : NULL; | ||
1450 | } | ||
1451 | |||
1452 | /* Take the new small groups into account */ | ||
1453 | parse_state->nr_groups += nr_pmu - 1; | ||
1454 | |||
1455 | handled: | ||
1456 | ret = 1; | ||
1457 | out: | ||
1458 | free(leaders); | ||
1459 | return ret; | ||
1460 | } | ||
1461 | |||
1462 | void parse_events__set_leader(char *name, struct list_head *list, | ||
1463 | struct parse_events_state *parse_state) | ||
1343 | { | 1464 | { |
1344 | struct perf_evsel *leader; | 1465 | struct perf_evsel *leader; |
1345 | 1466 | ||
@@ -1348,6 +1469,9 @@ void parse_events__set_leader(char *name, struct list_head *list) | |||
1348 | return; | 1469 | return; |
1349 | } | 1470 | } |
1350 | 1471 | ||
1472 | if (parse_events__set_leader_for_uncore_aliase(name, list, parse_state)) | ||
1473 | return; | ||
1474 | |||
1351 | __perf_evlist__set_leader(list); | 1475 | __perf_evlist__set_leader(list); |
1352 | leader = list_entry(list->next, struct perf_evsel, node); | 1476 | leader = list_entry(list->next, struct perf_evsel, node); |
1353 | leader->group_name = name ? strdup(name) : NULL; | 1477 | leader->group_name = name ? strdup(name) : NULL; |
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 5015cfd58277..4473dac27aee 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h | |||
@@ -167,7 +167,9 @@ int parse_events_add_breakpoint(struct list_head *list, int *idx, | |||
167 | void *ptr, char *type, u64 len); | 167 | void *ptr, char *type, u64 len); |
168 | int parse_events_add_pmu(struct parse_events_state *parse_state, | 168 | int parse_events_add_pmu(struct parse_events_state *parse_state, |
169 | struct list_head *list, char *name, | 169 | struct list_head *list, char *name, |
170 | struct list_head *head_config, bool auto_merge_stats); | 170 | struct list_head *head_config, |
171 | bool auto_merge_stats, | ||
172 | bool use_alias); | ||
171 | 173 | ||
172 | int parse_events_multi_pmu_add(struct parse_events_state *parse_state, | 174 | int parse_events_multi_pmu_add(struct parse_events_state *parse_state, |
173 | char *str, | 175 | char *str, |
@@ -178,7 +180,8 @@ int parse_events_copy_term_list(struct list_head *old, | |||
178 | 180 | ||
179 | enum perf_pmu_event_symbol_type | 181 | enum perf_pmu_event_symbol_type |
180 | perf_pmu__parse_check(const char *name); | 182 | perf_pmu__parse_check(const char *name); |
181 | void parse_events__set_leader(char *name, struct list_head *list); | 183 | void parse_events__set_leader(char *name, struct list_head *list, |
184 | struct parse_events_state *parse_state); | ||
182 | void parse_events_update_lists(struct list_head *list_event, | 185 | void parse_events_update_lists(struct list_head *list_event, |
183 | struct list_head *list_all); | 186 | struct list_head *list_all); |
184 | void parse_events_evlist_error(struct parse_events_state *parse_state, | 187 | void parse_events_evlist_error(struct parse_events_state *parse_state, |
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 7afeb80cc39e..e37608a87dba 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y | |||
@@ -161,7 +161,7 @@ PE_NAME '{' events '}' | |||
161 | struct list_head *list = $3; | 161 | struct list_head *list = $3; |
162 | 162 | ||
163 | inc_group_count(list, _parse_state); | 163 | inc_group_count(list, _parse_state); |
164 | parse_events__set_leader($1, list); | 164 | parse_events__set_leader($1, list, _parse_state); |
165 | $$ = list; | 165 | $$ = list; |
166 | } | 166 | } |
167 | | | 167 | | |
@@ -170,7 +170,7 @@ PE_NAME '{' events '}' | |||
170 | struct list_head *list = $2; | 170 | struct list_head *list = $2; |
171 | 171 | ||
172 | inc_group_count(list, _parse_state); | 172 | inc_group_count(list, _parse_state); |
173 | parse_events__set_leader(NULL, list); | 173 | parse_events__set_leader(NULL, list, _parse_state); |
174 | $$ = list; | 174 | $$ = list; |
175 | } | 175 | } |
176 | 176 | ||
@@ -232,7 +232,7 @@ PE_NAME opt_event_config | |||
232 | YYABORT; | 232 | YYABORT; |
233 | 233 | ||
234 | ALLOC_LIST(list); | 234 | ALLOC_LIST(list); |
235 | if (parse_events_add_pmu(_parse_state, list, $1, $2, false)) { | 235 | if (parse_events_add_pmu(_parse_state, list, $1, $2, false, false)) { |
236 | struct perf_pmu *pmu = NULL; | 236 | struct perf_pmu *pmu = NULL; |
237 | int ok = 0; | 237 | int ok = 0; |
238 | char *pattern; | 238 | char *pattern; |
@@ -251,7 +251,7 @@ PE_NAME opt_event_config | |||
251 | free(pattern); | 251 | free(pattern); |
252 | YYABORT; | 252 | YYABORT; |
253 | } | 253 | } |
254 | if (!parse_events_add_pmu(_parse_state, list, pmu->name, terms, true)) | 254 | if (!parse_events_add_pmu(_parse_state, list, pmu->name, terms, true, false)) |
255 | ok++; | 255 | ok++; |
256 | parse_events_terms__delete(terms); | 256 | parse_events_terms__delete(terms); |
257 | } | 257 | } |
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 10dd5fce082b..7f8afacd08ee 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c | |||
@@ -531,6 +531,8 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample, | |||
531 | PyLong_FromUnsignedLongLong(sample->period)); | 531 | PyLong_FromUnsignedLongLong(sample->period)); |
532 | pydict_set_item_string_decref(dict_sample, "phys_addr", | 532 | pydict_set_item_string_decref(dict_sample, "phys_addr", |
533 | PyLong_FromUnsignedLongLong(sample->phys_addr)); | 533 | PyLong_FromUnsignedLongLong(sample->phys_addr)); |
534 | pydict_set_item_string_decref(dict_sample, "addr", | ||
535 | PyLong_FromUnsignedLongLong(sample->addr)); | ||
534 | set_sample_read_in_dict(dict_sample, sample, evsel); | 536 | set_sample_read_in_dict(dict_sample, sample, evsel); |
535 | pydict_set_item_string_decref(dict, "sample", dict_sample); | 537 | pydict_set_item_string_decref(dict, "sample", dict_sample); |
536 | 538 | ||