aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@redhat.com>2014-01-07 07:47:25 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-02-18 07:34:48 -0500
commit352ea45a7229df8f5ae83c0757f6d426ba0f41b5 (patch)
tree594983cc1b5917b4e7b116cc51d388f81cd190b9 /tools
parent1cf0382af98f6365b01b59453fe18dffe3c73d2f (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.c1
-rw-r--r--tools/perf/builtin-inject.c1
-rw-r--r--tools/perf/tests/dwarf-unwind.c2
-rw-r--r--tools/perf/tests/sample-parsing.c17
-rw-r--r--tools/perf/util/event.h5
-rw-r--r--tools/perf/util/evsel.c13
-rw-r--r--tools/perf/util/machine.c3
-rw-r--r--tools/perf/util/session.c5
-rw-r--r--tools/perf/util/unwind.c20
-rw-r--r--tools/perf/util/unwind.h2
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
24static bool samples_same(const struct perf_sample *s1, 24static 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
86struct regs_dump { 86struct 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,
259const char *perf_event__name(unsigned int id); 260const char *perf_event__name(unsigned int id);
260 261
261size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, 262size_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);
263int perf_event__synthesize_sample(union perf_event *event, u64 type, 264int 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
1453size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, 1454size_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
1548int perf_event__synthesize_sample(union perf_event *event, u64 type, 1549int 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
705static void regs_user__printf(struct perf_sample *sample, u64 mask) 705static 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
394static int reg_value(unw_word_t *valp, struct regs_dump *regs, int id, 393static 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
573int unwind__get_entries(unwind_entry_cb_t cb, void *arg, 571int 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);
17int unwind__get_entries(unwind_entry_cb_t cb, void *arg, 17int 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);
22int unwind__arch_reg_id(int regnum); 21int 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{