diff options
author | Jiri Olsa <jolsa@redhat.com> | 2014-01-07 07:47:25 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-02-18 07:34:48 -0500 |
commit | 352ea45a7229df8f5ae83c0757f6d426ba0f41b5 (patch) | |
tree | 594983cc1b5917b4e7b116cc51d388f81cd190b9 /tools | |
parent | 1cf0382af98f6365b01b59453fe18dffe3c73d2f (diff) |
perf callchain: Add mask into struct regs_dump
Adding mask info into struct regs_dump to make the registers information
compact.
The mask was always passed along, so logically the mask info fits more
into the struct regs_dump.
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Jean Pihet <jean.pihet@linaro.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1389098853-14466-9-git-send-email-jolsa@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/arch/x86/tests/dwarf-unwind.c | 1 | ||||
-rw-r--r-- | tools/perf/builtin-inject.c | 1 | ||||
-rw-r--r-- | tools/perf/tests/dwarf-unwind.c | 2 | ||||
-rw-r--r-- | tools/perf/tests/sample-parsing.c | 17 | ||||
-rw-r--r-- | tools/perf/util/event.h | 5 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 13 | ||||
-rw-r--r-- | tools/perf/util/machine.c | 3 | ||||
-rw-r--r-- | tools/perf/util/session.c | 5 | ||||
-rw-r--r-- | tools/perf/util/unwind.c | 20 | ||||
-rw-r--r-- | tools/perf/util/unwind.h | 2 |
10 files changed, 32 insertions, 37 deletions
diff --git a/tools/perf/arch/x86/tests/dwarf-unwind.c b/tools/perf/arch/x86/tests/dwarf-unwind.c index 371f8493dcfd..b602ad93ce63 100644 --- a/tools/perf/arch/x86/tests/dwarf-unwind.c +++ b/tools/perf/arch/x86/tests/dwarf-unwind.c | |||
@@ -53,6 +53,7 @@ int test__arch_unwind_sample(struct perf_sample *sample, | |||
53 | perf_regs_load(buf); | 53 | perf_regs_load(buf); |
54 | regs->abi = PERF_SAMPLE_REGS_ABI; | 54 | regs->abi = PERF_SAMPLE_REGS_ABI; |
55 | regs->regs = buf; | 55 | regs->regs = buf; |
56 | regs->mask = PERF_REGS_MASK; | ||
56 | 57 | ||
57 | return sample_ustack(sample, thread, buf); | 58 | return sample_ustack(sample, thread, buf); |
58 | } | 59 | } |
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index b3466018bbd7..3a7387551369 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c | |||
@@ -312,7 +312,6 @@ found: | |||
312 | sample_sw.period = sample->period; | 312 | sample_sw.period = sample->period; |
313 | sample_sw.time = sample->time; | 313 | sample_sw.time = sample->time; |
314 | perf_event__synthesize_sample(event_sw, evsel->attr.sample_type, | 314 | perf_event__synthesize_sample(event_sw, evsel->attr.sample_type, |
315 | evsel->attr.sample_regs_user, | ||
316 | evsel->attr.read_format, &sample_sw, | 315 | evsel->attr.read_format, &sample_sw, |
317 | false); | 316 | false); |
318 | build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine); | 317 | build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine); |
diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c index a203c0caaf8a..f16ea2808a75 100644 --- a/tools/perf/tests/dwarf-unwind.c +++ b/tools/perf/tests/dwarf-unwind.c | |||
@@ -72,7 +72,7 @@ static int unwind_thread(struct thread *thread, struct machine *machine) | |||
72 | } | 72 | } |
73 | 73 | ||
74 | err = unwind__get_entries(unwind_entry, &cnt, machine, thread, | 74 | err = unwind__get_entries(unwind_entry, &cnt, machine, thread, |
75 | PERF_REGS_MASK, &sample, MAX_STACK); | 75 | &sample, MAX_STACK); |
76 | if (err) | 76 | if (err) |
77 | pr_debug("unwind failed\n"); | 77 | pr_debug("unwind failed\n"); |
78 | else if (cnt != MAX_STACK) { | 78 | else if (cnt != MAX_STACK) { |
diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c index 1b677202638d..0014d3c8c21c 100644 --- a/tools/perf/tests/sample-parsing.c +++ b/tools/perf/tests/sample-parsing.c | |||
@@ -22,8 +22,8 @@ | |||
22 | } while (0) | 22 | } while (0) |
23 | 23 | ||
24 | static bool samples_same(const struct perf_sample *s1, | 24 | static bool samples_same(const struct perf_sample *s1, |
25 | const struct perf_sample *s2, u64 type, u64 regs_user, | 25 | const struct perf_sample *s2, |
26 | u64 read_format) | 26 | u64 type, u64 read_format) |
27 | { | 27 | { |
28 | size_t i; | 28 | size_t i; |
29 | 29 | ||
@@ -95,8 +95,9 @@ static bool samples_same(const struct perf_sample *s1, | |||
95 | } | 95 | } |
96 | 96 | ||
97 | if (type & PERF_SAMPLE_REGS_USER) { | 97 | if (type & PERF_SAMPLE_REGS_USER) { |
98 | size_t sz = hweight_long(regs_user) * sizeof(u64); | 98 | size_t sz = hweight_long(s1->user_regs.mask) * sizeof(u64); |
99 | 99 | ||
100 | COMP(user_regs.mask); | ||
100 | COMP(user_regs.abi); | 101 | COMP(user_regs.abi); |
101 | if (s1->user_regs.abi && | 102 | if (s1->user_regs.abi && |
102 | (!s1->user_regs.regs || !s2->user_regs.regs || | 103 | (!s1->user_regs.regs || !s2->user_regs.regs || |
@@ -174,6 +175,7 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format) | |||
174 | .branch_stack = &branch_stack.branch_stack, | 175 | .branch_stack = &branch_stack.branch_stack, |
175 | .user_regs = { | 176 | .user_regs = { |
176 | .abi = PERF_SAMPLE_REGS_ABI_64, | 177 | .abi = PERF_SAMPLE_REGS_ABI_64, |
178 | .mask = sample_regs_user, | ||
177 | .regs = user_regs, | 179 | .regs = user_regs, |
178 | }, | 180 | }, |
179 | .user_stack = { | 181 | .user_stack = { |
@@ -201,8 +203,7 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format) | |||
201 | sample.read.one.id = 99; | 203 | sample.read.one.id = 99; |
202 | } | 204 | } |
203 | 205 | ||
204 | sz = perf_event__sample_event_size(&sample, sample_type, | 206 | sz = perf_event__sample_event_size(&sample, sample_type, read_format); |
205 | sample_regs_user, read_format); | ||
206 | bufsz = sz + 4096; /* Add a bit for overrun checking */ | 207 | bufsz = sz + 4096; /* Add a bit for overrun checking */ |
207 | event = malloc(bufsz); | 208 | event = malloc(bufsz); |
208 | if (!event) { | 209 | if (!event) { |
@@ -215,8 +216,7 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format) | |||
215 | event->header.misc = 0; | 216 | event->header.misc = 0; |
216 | event->header.size = sz; | 217 | event->header.size = sz; |
217 | 218 | ||
218 | err = perf_event__synthesize_sample(event, sample_type, | 219 | err = perf_event__synthesize_sample(event, sample_type, read_format, |
219 | sample_regs_user, read_format, | ||
220 | &sample, false); | 220 | &sample, false); |
221 | if (err) { | 221 | if (err) { |
222 | pr_debug("%s failed for sample_type %#"PRIx64", error %d\n", | 222 | pr_debug("%s failed for sample_type %#"PRIx64", error %d\n", |
@@ -244,8 +244,7 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format) | |||
244 | goto out_free; | 244 | goto out_free; |
245 | } | 245 | } |
246 | 246 | ||
247 | if (!samples_same(&sample, &sample_out, sample_type, | 247 | if (!samples_same(&sample, &sample_out, sample_type, read_format)) { |
248 | sample_regs_user, read_format)) { | ||
249 | pr_debug("parsing failed for sample_type %#"PRIx64"\n", | 248 | pr_debug("parsing failed for sample_type %#"PRIx64"\n", |
250 | sample_type); | 249 | sample_type); |
251 | goto out_free; | 250 | goto out_free; |
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 851fa06f4a42..38457d447a13 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
@@ -85,6 +85,7 @@ struct sample_event { | |||
85 | 85 | ||
86 | struct regs_dump { | 86 | struct regs_dump { |
87 | u64 abi; | 87 | u64 abi; |
88 | u64 mask; | ||
88 | u64 *regs; | 89 | u64 *regs; |
89 | }; | 90 | }; |
90 | 91 | ||
@@ -259,9 +260,9 @@ int perf_event__preprocess_sample(const union perf_event *event, | |||
259 | const char *perf_event__name(unsigned int id); | 260 | const char *perf_event__name(unsigned int id); |
260 | 261 | ||
261 | size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, | 262 | size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, |
262 | u64 sample_regs_user, u64 read_format); | 263 | u64 read_format); |
263 | int perf_event__synthesize_sample(union perf_event *event, u64 type, | 264 | int perf_event__synthesize_sample(union perf_event *event, u64 type, |
264 | u64 sample_regs_user, u64 read_format, | 265 | u64 read_format, |
265 | const struct perf_sample *sample, | 266 | const struct perf_sample *sample, |
266 | bool swapped); | 267 | bool swapped); |
267 | 268 | ||
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 8201abe0925e..adc94dd1794d 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -1396,10 +1396,11 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, | |||
1396 | array++; | 1396 | array++; |
1397 | 1397 | ||
1398 | if (data->user_regs.abi) { | 1398 | if (data->user_regs.abi) { |
1399 | u64 regs_user = evsel->attr.sample_regs_user; | 1399 | u64 mask = evsel->attr.sample_regs_user; |
1400 | 1400 | ||
1401 | sz = hweight_long(regs_user) * sizeof(u64); | 1401 | sz = hweight_long(mask) * sizeof(u64); |
1402 | OVERFLOW_CHECK(array, sz, max_size); | 1402 | OVERFLOW_CHECK(array, sz, max_size); |
1403 | data->user_regs.mask = mask; | ||
1403 | data->user_regs.regs = (u64 *)array; | 1404 | data->user_regs.regs = (u64 *)array; |
1404 | array = (void *)array + sz; | 1405 | array = (void *)array + sz; |
1405 | } | 1406 | } |
@@ -1451,7 +1452,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, | |||
1451 | } | 1452 | } |
1452 | 1453 | ||
1453 | size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, | 1454 | size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, |
1454 | u64 sample_regs_user, u64 read_format) | 1455 | u64 read_format) |
1455 | { | 1456 | { |
1456 | size_t sz, result = sizeof(struct sample_event); | 1457 | size_t sz, result = sizeof(struct sample_event); |
1457 | 1458 | ||
@@ -1517,7 +1518,7 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, | |||
1517 | if (type & PERF_SAMPLE_REGS_USER) { | 1518 | if (type & PERF_SAMPLE_REGS_USER) { |
1518 | if (sample->user_regs.abi) { | 1519 | if (sample->user_regs.abi) { |
1519 | result += sizeof(u64); | 1520 | result += sizeof(u64); |
1520 | sz = hweight_long(sample_regs_user) * sizeof(u64); | 1521 | sz = hweight_long(sample->user_regs.mask) * sizeof(u64); |
1521 | result += sz; | 1522 | result += sz; |
1522 | } else { | 1523 | } else { |
1523 | result += sizeof(u64); | 1524 | result += sizeof(u64); |
@@ -1546,7 +1547,7 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, | |||
1546 | } | 1547 | } |
1547 | 1548 | ||
1548 | int perf_event__synthesize_sample(union perf_event *event, u64 type, | 1549 | int perf_event__synthesize_sample(union perf_event *event, u64 type, |
1549 | u64 sample_regs_user, u64 read_format, | 1550 | u64 read_format, |
1550 | const struct perf_sample *sample, | 1551 | const struct perf_sample *sample, |
1551 | bool swapped) | 1552 | bool swapped) |
1552 | { | 1553 | { |
@@ -1687,7 +1688,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, | |||
1687 | if (type & PERF_SAMPLE_REGS_USER) { | 1688 | if (type & PERF_SAMPLE_REGS_USER) { |
1688 | if (sample->user_regs.abi) { | 1689 | if (sample->user_regs.abi) { |
1689 | *array++ = sample->user_regs.abi; | 1690 | *array++ = sample->user_regs.abi; |
1690 | sz = hweight_long(sample_regs_user) * sizeof(u64); | 1691 | sz = hweight_long(sample->user_regs.mask) * sizeof(u64); |
1691 | memcpy(array, sample->user_regs.regs, sz); | 1692 | memcpy(array, sample->user_regs.regs, sz); |
1692 | array = (void *)array + sz; | 1693 | array = (void *)array + sz; |
1693 | } else { | 1694 | } else { |
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 6c08ab03a697..ac37d788b5cb 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -1383,8 +1383,7 @@ int machine__resolve_callchain(struct machine *machine, | |||
1383 | return 0; | 1383 | return 0; |
1384 | 1384 | ||
1385 | return unwind__get_entries(unwind_entry, &callchain_cursor, machine, | 1385 | return unwind__get_entries(unwind_entry, &callchain_cursor, machine, |
1386 | thread, evsel->attr.sample_regs_user, | 1386 | thread, sample, max_stack); |
1387 | sample, max_stack); | ||
1388 | 1387 | ||
1389 | } | 1388 | } |
1390 | 1389 | ||
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 5da6ce74c676..1d555d652f58 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -702,11 +702,12 @@ static void regs_dump__printf(u64 mask, u64 *regs) | |||
702 | } | 702 | } |
703 | } | 703 | } |
704 | 704 | ||
705 | static void regs_user__printf(struct perf_sample *sample, u64 mask) | 705 | static void regs_user__printf(struct perf_sample *sample) |
706 | { | 706 | { |
707 | struct regs_dump *user_regs = &sample->user_regs; | 707 | struct regs_dump *user_regs = &sample->user_regs; |
708 | 708 | ||
709 | if (user_regs->regs) { | 709 | if (user_regs->regs) { |
710 | u64 mask = user_regs->mask; | ||
710 | printf("... user regs: mask 0x%" PRIx64 "\n", mask); | 711 | printf("... user regs: mask 0x%" PRIx64 "\n", mask); |
711 | regs_dump__printf(mask, user_regs->regs); | 712 | regs_dump__printf(mask, user_regs->regs); |
712 | } | 713 | } |
@@ -806,7 +807,7 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event, | |||
806 | branch_stack__printf(sample); | 807 | branch_stack__printf(sample); |
807 | 808 | ||
808 | if (sample_type & PERF_SAMPLE_REGS_USER) | 809 | if (sample_type & PERF_SAMPLE_REGS_USER) |
809 | regs_user__printf(sample, evsel->attr.sample_regs_user); | 810 | regs_user__printf(sample); |
810 | 811 | ||
811 | if (sample_type & PERF_SAMPLE_STACK_USER) | 812 | if (sample_type & PERF_SAMPLE_STACK_USER) |
812 | stack_user__printf(&sample->user_stack); | 813 | stack_user__printf(&sample->user_stack); |
diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c index 3b7018102dfb..720a4cae6004 100644 --- a/tools/perf/util/unwind.c +++ b/tools/perf/util/unwind.c | |||
@@ -86,7 +86,6 @@ struct unwind_info { | |||
86 | struct perf_sample *sample; | 86 | struct perf_sample *sample; |
87 | struct machine *machine; | 87 | struct machine *machine; |
88 | struct thread *thread; | 88 | struct thread *thread; |
89 | u64 sample_uregs; | ||
90 | }; | 89 | }; |
91 | 90 | ||
92 | #define dw_read(ptr, type, end) ({ \ | 91 | #define dw_read(ptr, type, end) ({ \ |
@@ -391,16 +390,16 @@ static int access_dso_mem(struct unwind_info *ui, unw_word_t addr, | |||
391 | return !(size == sizeof(*data)); | 390 | return !(size == sizeof(*data)); |
392 | } | 391 | } |
393 | 392 | ||
394 | static int reg_value(unw_word_t *valp, struct regs_dump *regs, int id, | 393 | static int reg_value(unw_word_t *valp, struct regs_dump *regs, int id) |
395 | u64 sample_regs) | ||
396 | { | 394 | { |
397 | int i, idx = 0; | 395 | int i, idx = 0; |
396 | u64 mask = regs->mask; | ||
398 | 397 | ||
399 | if (!(sample_regs & (1 << id))) | 398 | if (!(mask & (1 << id))) |
400 | return -EINVAL; | 399 | return -EINVAL; |
401 | 400 | ||
402 | for (i = 0; i < id; i++) { | 401 | for (i = 0; i < id; i++) { |
403 | if (sample_regs & (1 << i)) | 402 | if (mask & (1 << i)) |
404 | idx++; | 403 | idx++; |
405 | } | 404 | } |
406 | 405 | ||
@@ -424,8 +423,7 @@ static int access_mem(unw_addr_space_t __maybe_unused as, | |||
424 | return 0; | 423 | return 0; |
425 | } | 424 | } |
426 | 425 | ||
427 | ret = reg_value(&start, &ui->sample->user_regs, PERF_REG_SP, | 426 | ret = reg_value(&start, &ui->sample->user_regs, PERF_REG_SP); |
428 | ui->sample_uregs); | ||
429 | if (ret) | 427 | if (ret) |
430 | return ret; | 428 | return ret; |
431 | 429 | ||
@@ -475,7 +473,7 @@ static int access_reg(unw_addr_space_t __maybe_unused as, | |||
475 | if (id < 0) | 473 | if (id < 0) |
476 | return -EINVAL; | 474 | return -EINVAL; |
477 | 475 | ||
478 | ret = reg_value(valp, &ui->sample->user_regs, id, ui->sample_uregs); | 476 | ret = reg_value(valp, &ui->sample->user_regs, id); |
479 | if (ret) { | 477 | if (ret) { |
480 | pr_err("unwind: can't read reg %d\n", regnum); | 478 | pr_err("unwind: can't read reg %d\n", regnum); |
481 | return ret; | 479 | return ret; |
@@ -572,13 +570,11 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, | |||
572 | 570 | ||
573 | int unwind__get_entries(unwind_entry_cb_t cb, void *arg, | 571 | int unwind__get_entries(unwind_entry_cb_t cb, void *arg, |
574 | struct machine *machine, struct thread *thread, | 572 | struct machine *machine, struct thread *thread, |
575 | u64 sample_uregs, struct perf_sample *data, | 573 | struct perf_sample *data, int max_stack) |
576 | int max_stack) | ||
577 | { | 574 | { |
578 | unw_word_t ip; | 575 | unw_word_t ip; |
579 | struct unwind_info ui = { | 576 | struct unwind_info ui = { |
580 | .sample = data, | 577 | .sample = data, |
581 | .sample_uregs = sample_uregs, | ||
582 | .thread = thread, | 578 | .thread = thread, |
583 | .machine = machine, | 579 | .machine = machine, |
584 | }; | 580 | }; |
@@ -587,7 +583,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, | |||
587 | if (!data->user_regs.regs) | 583 | if (!data->user_regs.regs) |
588 | return -EINVAL; | 584 | return -EINVAL; |
589 | 585 | ||
590 | ret = reg_value(&ip, &data->user_regs, PERF_REG_IP, sample_uregs); | 586 | ret = reg_value(&ip, &data->user_regs, PERF_REG_IP); |
591 | if (ret) | 587 | if (ret) |
592 | return ret; | 588 | return ret; |
593 | 589 | ||
diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h index d5966f49e22c..356e1d642f9d 100644 --- a/tools/perf/util/unwind.h +++ b/tools/perf/util/unwind.h | |||
@@ -17,7 +17,6 @@ typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg); | |||
17 | int unwind__get_entries(unwind_entry_cb_t cb, void *arg, | 17 | int unwind__get_entries(unwind_entry_cb_t cb, void *arg, |
18 | struct machine *machine, | 18 | struct machine *machine, |
19 | struct thread *thread, | 19 | struct thread *thread, |
20 | u64 sample_uregs, | ||
21 | struct perf_sample *data, int max_stack); | 20 | struct perf_sample *data, int max_stack); |
22 | int unwind__arch_reg_id(int regnum); | 21 | int unwind__arch_reg_id(int regnum); |
23 | #else | 22 | #else |
@@ -26,7 +25,6 @@ unwind__get_entries(unwind_entry_cb_t cb __maybe_unused, | |||
26 | void *arg __maybe_unused, | 25 | void *arg __maybe_unused, |
27 | struct machine *machine __maybe_unused, | 26 | struct machine *machine __maybe_unused, |
28 | struct thread *thread __maybe_unused, | 27 | struct thread *thread __maybe_unused, |
29 | u64 sample_uregs __maybe_unused, | ||
30 | struct perf_sample *data __maybe_unused, | 28 | struct perf_sample *data __maybe_unused, |
31 | int max_stack __maybe_unused) | 29 | int max_stack __maybe_unused) |
32 | { | 30 | { |