aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r--tools/perf/util/session.c132
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
16static int perf_session__open(struct perf_session *self, bool force) 17static 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
410static void perf_event__attr_swap(union perf_event *event) 416/* exported for swapping attributes in file header */
417void 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
431static 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
1205void perf_session__print_symbols(union perf_event *event, 1217void 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); 1293int 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}