diff options
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r-- | tools/perf/util/session.c | 132 |
1 files changed, 98 insertions, 34 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index f5a8fbdd3f7..72458d9da5b 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include "session.h" | 12 | #include "session.h" |
13 | #include "sort.h" | 13 | #include "sort.h" |
14 | #include "util.h" | 14 | #include "util.h" |
15 | #include "cpumap.h" | ||
15 | 16 | ||
16 | static int perf_session__open(struct perf_session *self, bool force) | 17 | static int perf_session__open(struct perf_session *self, bool force) |
17 | { | 18 | { |
@@ -247,9 +248,14 @@ int perf_session__resolve_callchain(struct perf_session *self, | |||
247 | callchain_cursor_reset(&self->callchain_cursor); | 248 | callchain_cursor_reset(&self->callchain_cursor); |
248 | 249 | ||
249 | for (i = 0; i < chain->nr; i++) { | 250 | for (i = 0; i < chain->nr; i++) { |
250 | u64 ip = chain->ips[i]; | 251 | u64 ip; |
251 | struct addr_location al; | 252 | struct addr_location al; |
252 | 253 | ||
254 | if (callchain_param.order == ORDER_CALLEE) | ||
255 | ip = chain->ips[i]; | ||
256 | else | ||
257 | ip = chain->ips[chain->nr - i - 1]; | ||
258 | |||
253 | if (ip >= PERF_CONTEXT_MAX) { | 259 | if (ip >= PERF_CONTEXT_MAX) { |
254 | switch (ip) { | 260 | switch (ip) { |
255 | case PERF_CONTEXT_HV: | 261 | case PERF_CONTEXT_HV: |
@@ -407,20 +413,26 @@ static void perf_event__read_swap(union perf_event *event) | |||
407 | event->read.id = bswap_64(event->read.id); | 413 | event->read.id = bswap_64(event->read.id); |
408 | } | 414 | } |
409 | 415 | ||
410 | static void perf_event__attr_swap(union perf_event *event) | 416 | /* exported for swapping attributes in file header */ |
417 | void perf_event__attr_swap(struct perf_event_attr *attr) | ||
418 | { | ||
419 | attr->type = bswap_32(attr->type); | ||
420 | attr->size = bswap_32(attr->size); | ||
421 | attr->config = bswap_64(attr->config); | ||
422 | attr->sample_period = bswap_64(attr->sample_period); | ||
423 | attr->sample_type = bswap_64(attr->sample_type); | ||
424 | attr->read_format = bswap_64(attr->read_format); | ||
425 | attr->wakeup_events = bswap_32(attr->wakeup_events); | ||
426 | attr->bp_type = bswap_32(attr->bp_type); | ||
427 | attr->bp_addr = bswap_64(attr->bp_addr); | ||
428 | attr->bp_len = bswap_64(attr->bp_len); | ||
429 | } | ||
430 | |||
431 | static void perf_event__hdr_attr_swap(union perf_event *event) | ||
411 | { | 432 | { |
412 | size_t size; | 433 | size_t size; |
413 | 434 | ||
414 | event->attr.attr.type = bswap_32(event->attr.attr.type); | 435 | perf_event__attr_swap(&event->attr.attr); |
415 | event->attr.attr.size = bswap_32(event->attr.attr.size); | ||
416 | event->attr.attr.config = bswap_64(event->attr.attr.config); | ||
417 | event->attr.attr.sample_period = bswap_64(event->attr.attr.sample_period); | ||
418 | event->attr.attr.sample_type = bswap_64(event->attr.attr.sample_type); | ||
419 | event->attr.attr.read_format = bswap_64(event->attr.attr.read_format); | ||
420 | event->attr.attr.wakeup_events = bswap_32(event->attr.attr.wakeup_events); | ||
421 | event->attr.attr.bp_type = bswap_32(event->attr.attr.bp_type); | ||
422 | event->attr.attr.bp_addr = bswap_64(event->attr.attr.bp_addr); | ||
423 | event->attr.attr.bp_len = bswap_64(event->attr.attr.bp_len); | ||
424 | 436 | ||
425 | size = event->header.size; | 437 | size = event->header.size; |
426 | size -= (void *)&event->attr.id - (void *)event; | 438 | size -= (void *)&event->attr.id - (void *)event; |
@@ -448,7 +460,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { | |||
448 | [PERF_RECORD_LOST] = perf_event__all64_swap, | 460 | [PERF_RECORD_LOST] = perf_event__all64_swap, |
449 | [PERF_RECORD_READ] = perf_event__read_swap, | 461 | [PERF_RECORD_READ] = perf_event__read_swap, |
450 | [PERF_RECORD_SAMPLE] = perf_event__all64_swap, | 462 | [PERF_RECORD_SAMPLE] = perf_event__all64_swap, |
451 | [PERF_RECORD_HEADER_ATTR] = perf_event__attr_swap, | 463 | [PERF_RECORD_HEADER_ATTR] = perf_event__hdr_attr_swap, |
452 | [PERF_RECORD_HEADER_EVENT_TYPE] = perf_event__event_type_swap, | 464 | [PERF_RECORD_HEADER_EVENT_TYPE] = perf_event__event_type_swap, |
453 | [PERF_RECORD_HEADER_TRACING_DATA] = perf_event__tracing_data_swap, | 465 | [PERF_RECORD_HEADER_TRACING_DATA] = perf_event__tracing_data_swap, |
454 | [PERF_RECORD_HEADER_BUILD_ID] = NULL, | 466 | [PERF_RECORD_HEADER_BUILD_ID] = NULL, |
@@ -708,9 +720,9 @@ static void dump_sample(struct perf_session *session, union perf_event *event, | |||
708 | if (!dump_trace) | 720 | if (!dump_trace) |
709 | return; | 721 | return; |
710 | 722 | ||
711 | printf("(IP, %d): %d/%d: %#" PRIx64 " period: %" PRIu64 "\n", | 723 | printf("(IP, %d): %d/%d: %#" PRIx64 " period: %" PRIu64 " addr: %#" PRIx64 "\n", |
712 | event->header.misc, sample->pid, sample->tid, sample->ip, | 724 | event->header.misc, sample->pid, sample->tid, sample->ip, |
713 | sample->period); | 725 | sample->period, sample->addr); |
714 | 726 | ||
715 | if (session->sample_type & PERF_SAMPLE_CALLCHAIN) | 727 | if (session->sample_type & PERF_SAMPLE_CALLCHAIN) |
716 | callchain__printf(sample); | 728 | callchain__printf(sample); |
@@ -1202,9 +1214,10 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, | |||
1202 | return NULL; | 1214 | return NULL; |
1203 | } | 1215 | } |
1204 | 1216 | ||
1205 | void perf_session__print_symbols(union perf_event *event, | 1217 | void perf_session__print_ip(union perf_event *event, |
1206 | struct perf_sample *sample, | 1218 | struct perf_sample *sample, |
1207 | struct perf_session *session) | 1219 | struct perf_session *session, |
1220 | int print_sym, int print_dso) | ||
1208 | { | 1221 | { |
1209 | struct addr_location al; | 1222 | struct addr_location al; |
1210 | const char *symname, *dsoname; | 1223 | const char *symname, *dsoname; |
@@ -1233,32 +1246,83 @@ void perf_session__print_symbols(union perf_event *event, | |||
1233 | if (!node) | 1246 | if (!node) |
1234 | break; | 1247 | break; |
1235 | 1248 | ||
1236 | if (node->sym && node->sym->name) | 1249 | printf("\t%16" PRIx64, node->ip); |
1237 | symname = node->sym->name; | 1250 | if (print_sym) { |
1251 | if (node->sym && node->sym->name) | ||
1252 | symname = node->sym->name; | ||
1253 | else | ||
1254 | symname = ""; | ||
1255 | |||
1256 | printf(" %s", symname); | ||
1257 | } | ||
1258 | if (print_dso) { | ||
1259 | if (node->map && node->map->dso && node->map->dso->name) | ||
1260 | dsoname = node->map->dso->name; | ||
1261 | else | ||
1262 | dsoname = ""; | ||
1263 | |||
1264 | printf(" (%s)", dsoname); | ||
1265 | } | ||
1266 | printf("\n"); | ||
1267 | |||
1268 | callchain_cursor_advance(cursor); | ||
1269 | } | ||
1270 | |||
1271 | } else { | ||
1272 | printf("%16" PRIx64, sample->ip); | ||
1273 | if (print_sym) { | ||
1274 | if (al.sym && al.sym->name) | ||
1275 | symname = al.sym->name; | ||
1238 | else | 1276 | else |
1239 | symname = ""; | 1277 | symname = ""; |
1240 | 1278 | ||
1241 | if (node->map && node->map->dso && node->map->dso->name) | 1279 | printf(" %s", symname); |
1242 | dsoname = node->map->dso->name; | 1280 | } |
1281 | |||
1282 | if (print_dso) { | ||
1283 | if (al.map && al.map->dso && al.map->dso->name) | ||
1284 | dsoname = al.map->dso->name; | ||
1243 | else | 1285 | else |
1244 | dsoname = ""; | 1286 | dsoname = ""; |
1245 | 1287 | ||
1246 | printf("\t%16" PRIx64 " %s (%s)\n", node->ip, symname, dsoname); | 1288 | printf(" (%s)", dsoname); |
1289 | } | ||
1290 | } | ||
1291 | } | ||
1247 | 1292 | ||
1248 | callchain_cursor_advance(cursor); | 1293 | int perf_session__cpu_bitmap(struct perf_session *session, |
1294 | const char *cpu_list, unsigned long *cpu_bitmap) | ||
1295 | { | ||
1296 | int i; | ||
1297 | struct cpu_map *map; | ||
1298 | |||
1299 | for (i = 0; i < PERF_TYPE_MAX; ++i) { | ||
1300 | struct perf_evsel *evsel; | ||
1301 | |||
1302 | evsel = perf_session__find_first_evtype(session, i); | ||
1303 | if (!evsel) | ||
1304 | continue; | ||
1305 | |||
1306 | if (!(evsel->attr.sample_type & PERF_SAMPLE_CPU)) { | ||
1307 | pr_err("File does not contain CPU events. " | ||
1308 | "Remove -c option to proceed.\n"); | ||
1309 | return -1; | ||
1249 | } | 1310 | } |
1311 | } | ||
1250 | 1312 | ||
1251 | } else { | 1313 | map = cpu_map__new(cpu_list); |
1252 | if (al.sym && al.sym->name) | ||
1253 | symname = al.sym->name; | ||
1254 | else | ||
1255 | symname = ""; | ||
1256 | 1314 | ||
1257 | if (al.map && al.map->dso && al.map->dso->name) | 1315 | for (i = 0; i < map->nr; i++) { |
1258 | dsoname = al.map->dso->name; | 1316 | int cpu = map->map[i]; |
1259 | else | 1317 | |
1260 | dsoname = ""; | 1318 | if (cpu >= MAX_NR_CPUS) { |
1319 | pr_err("Requested CPU %d too large. " | ||
1320 | "Consider raising MAX_NR_CPUS\n", cpu); | ||
1321 | return -1; | ||
1322 | } | ||
1261 | 1323 | ||
1262 | printf("%16" PRIx64 " %s (%s)", al.addr, symname, dsoname); | 1324 | set_bit(cpu, cpu_bitmap); |
1263 | } | 1325 | } |
1326 | |||
1327 | return 0; | ||
1264 | } | 1328 | } |