perf callchain: Add mask into struct regs_dump
authorJiri Olsa <jolsa@redhat.com>
Tue, 7 Jan 2014 12:47:25 +0000 (13:47 +0100)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 18 Feb 2014 12:34:48 +0000 (09:34 -0300)
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>
tools/perf/arch/x86/tests/dwarf-unwind.c
tools/perf/builtin-inject.c
tools/perf/tests/dwarf-unwind.c
tools/perf/tests/sample-parsing.c
tools/perf/util/event.h
tools/perf/util/evsel.c
tools/perf/util/machine.c
tools/perf/util/session.c
tools/perf/util/unwind.c
tools/perf/util/unwind.h

index 371f8493dcfdec6928d995b3dc36b8c2edcacaab..b602ad93ce630ae3f611ee74f0bb6277c367a09b 100644 (file)
@@ -53,6 +53,7 @@ int test__arch_unwind_sample(struct perf_sample *sample,
        perf_regs_load(buf);
        regs->abi  = PERF_SAMPLE_REGS_ABI;
        regs->regs = buf;
+       regs->mask = PERF_REGS_MASK;
 
        return sample_ustack(sample, thread, buf);
 }
index b3466018bbd7b514811dd6a5e2bad10ed275eb5b..3a7387551369c97ab38b249ced193cc386c2cabe 100644 (file)
@@ -312,7 +312,6 @@ found:
        sample_sw.period = sample->period;
        sample_sw.time   = sample->time;
        perf_event__synthesize_sample(event_sw, evsel->attr.sample_type,
-                                     evsel->attr.sample_regs_user,
                                      evsel->attr.read_format, &sample_sw,
                                      false);
        build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine);
index a203c0caaf8aac246bca0354428afa02c1c4ce46..f16ea2808a7500d18fdaa1aa6cb76993f7ef868c 100644 (file)
@@ -72,7 +72,7 @@ static int unwind_thread(struct thread *thread, struct machine *machine)
        }
 
        err = unwind__get_entries(unwind_entry, &cnt, machine, thread,
-                                 PERF_REGS_MASK, &sample, MAX_STACK);
+                                 &sample, MAX_STACK);
        if (err)
                pr_debug("unwind failed\n");
        else if (cnt != MAX_STACK) {
index 1b677202638d087b94903f3f395d9fab8ae15bc7..0014d3c8c21cd47d2868cac66bc65253913e888e 100644 (file)
@@ -22,8 +22,8 @@
 } while (0)
 
 static bool samples_same(const struct perf_sample *s1,
-                        const struct perf_sample *s2, u64 type, u64 regs_user,
-                        u64 read_format)
+                        const struct perf_sample *s2,
+                        u64 type, u64 read_format)
 {
        size_t i;
 
@@ -95,8 +95,9 @@ static bool samples_same(const struct perf_sample *s1,
        }
 
        if (type & PERF_SAMPLE_REGS_USER) {
-               size_t sz = hweight_long(regs_user) * sizeof(u64);
+               size_t sz = hweight_long(s1->user_regs.mask) * sizeof(u64);
 
+               COMP(user_regs.mask);
                COMP(user_regs.abi);
                if (s1->user_regs.abi &&
                    (!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)
                .branch_stack   = &branch_stack.branch_stack,
                .user_regs      = {
                        .abi    = PERF_SAMPLE_REGS_ABI_64,
+                       .mask   = sample_regs_user,
                        .regs   = user_regs,
                },
                .user_stack     = {
@@ -201,8 +203,7 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format)
                sample.read.one.id    = 99;
        }
 
-       sz = perf_event__sample_event_size(&sample, sample_type,
-                                          sample_regs_user, read_format);
+       sz = perf_event__sample_event_size(&sample, sample_type, read_format);
        bufsz = sz + 4096; /* Add a bit for overrun checking */
        event = malloc(bufsz);
        if (!event) {
@@ -215,8 +216,7 @@ static int do_test(u64 sample_type, u64 sample_regs_user, u64 read_format)
        event->header.misc = 0;
        event->header.size = sz;
 
-       err = perf_event__synthesize_sample(event, sample_type,
-                                           sample_regs_user, read_format,
+       err = perf_event__synthesize_sample(event, sample_type, read_format,
                                            &sample, false);
        if (err) {
                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)
                goto out_free;
        }
 
-       if (!samples_same(&sample, &sample_out, sample_type,
-                         sample_regs_user, read_format)) {
+       if (!samples_same(&sample, &sample_out, sample_type, read_format)) {
                pr_debug("parsing failed for sample_type %#"PRIx64"\n",
                         sample_type);
                goto out_free;
index 851fa06f4a427d47b2c2af5ee70e345fda643978..38457d447a13106360fb60d7b93dd3eab5217f50 100644 (file)
@@ -85,6 +85,7 @@ struct sample_event {
 
 struct regs_dump {
        u64 abi;
+       u64 mask;
        u64 *regs;
 };
 
@@ -259,9 +260,9 @@ int perf_event__preprocess_sample(const union perf_event *event,
 const char *perf_event__name(unsigned int id);
 
 size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
-                                    u64 sample_regs_user, u64 read_format);
+                                    u64 read_format);
 int perf_event__synthesize_sample(union perf_event *event, u64 type,
-                                 u64 sample_regs_user, u64 read_format,
+                                 u64 read_format,
                                  const struct perf_sample *sample,
                                  bool swapped);
 
index 8201abe0925e7238b98a5ff22732109ea85ce5be..adc94dd1794dde47acb45d25eee728861ed620fd 100644 (file)
@@ -1396,10 +1396,11 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
                array++;
 
                if (data->user_regs.abi) {
-                       u64 regs_user = evsel->attr.sample_regs_user;
+                       u64 mask = evsel->attr.sample_regs_user;
 
-                       sz = hweight_long(regs_user) * sizeof(u64);
+                       sz = hweight_long(mask) * sizeof(u64);
                        OVERFLOW_CHECK(array, sz, max_size);
+                       data->user_regs.mask = mask;
                        data->user_regs.regs = (u64 *)array;
                        array = (void *)array + sz;
                }
@@ -1451,7 +1452,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
 }
 
 size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
-                                    u64 sample_regs_user, u64 read_format)
+                                    u64 read_format)
 {
        size_t sz, result = sizeof(struct sample_event);
 
@@ -1517,7 +1518,7 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
        if (type & PERF_SAMPLE_REGS_USER) {
                if (sample->user_regs.abi) {
                        result += sizeof(u64);
-                       sz = hweight_long(sample_regs_user) * sizeof(u64);
+                       sz = hweight_long(sample->user_regs.mask) * sizeof(u64);
                        result += sz;
                } else {
                        result += sizeof(u64);
@@ -1546,7 +1547,7 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
 }
 
 int perf_event__synthesize_sample(union perf_event *event, u64 type,
-                                 u64 sample_regs_user, u64 read_format,
+                                 u64 read_format,
                                  const struct perf_sample *sample,
                                  bool swapped)
 {
@@ -1687,7 +1688,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type,
        if (type & PERF_SAMPLE_REGS_USER) {
                if (sample->user_regs.abi) {
                        *array++ = sample->user_regs.abi;
-                       sz = hweight_long(sample_regs_user) * sizeof(u64);
+                       sz = hweight_long(sample->user_regs.mask) * sizeof(u64);
                        memcpy(array, sample->user_regs.regs, sz);
                        array = (void *)array + sz;
                } else {
index 6c08ab03a6979dfcbc4fe8101fd46e9c42c836cf..ac37d788b5cbcdd2f2848b67f727642ada6e871d 100644 (file)
@@ -1383,8 +1383,7 @@ int machine__resolve_callchain(struct machine *machine,
                return 0;
 
        return unwind__get_entries(unwind_entry, &callchain_cursor, machine,
-                                  thread, evsel->attr.sample_regs_user,
-                                  sample, max_stack);
+                                  thread, sample, max_stack);
 
 }
 
index 5da6ce74c676722ff13ae858c1bb579ba353edbf..1d555d652f58ea0636f1ec433e9e7fe9cb265d99 100644 (file)
@@ -702,11 +702,12 @@ static void regs_dump__printf(u64 mask, u64 *regs)
        }
 }
 
-static void regs_user__printf(struct perf_sample *sample, u64 mask)
+static void regs_user__printf(struct perf_sample *sample)
 {
        struct regs_dump *user_regs = &sample->user_regs;
 
        if (user_regs->regs) {
+               u64 mask = user_regs->mask;
                printf("... user regs: mask 0x%" PRIx64 "\n", mask);
                regs_dump__printf(mask, user_regs->regs);
        }
@@ -806,7 +807,7 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event,
                branch_stack__printf(sample);
 
        if (sample_type & PERF_SAMPLE_REGS_USER)
-               regs_user__printf(sample, evsel->attr.sample_regs_user);
+               regs_user__printf(sample);
 
        if (sample_type & PERF_SAMPLE_STACK_USER)
                stack_user__printf(&sample->user_stack);
index 3b7018102dfb7ab690cbbd1087e8b2b3d039f340..720a4cae60047d30ca3af4b89f88f6e0ab482e30 100644 (file)
@@ -86,7 +86,6 @@ struct unwind_info {
        struct perf_sample      *sample;
        struct machine          *machine;
        struct thread           *thread;
-       u64                     sample_uregs;
 };
 
 #define dw_read(ptr, type, end) ({     \
@@ -391,16 +390,16 @@ static int access_dso_mem(struct unwind_info *ui, unw_word_t addr,
        return !(size == sizeof(*data));
 }
 
-static int reg_value(unw_word_t *valp, struct regs_dump *regs, int id,
-                    u64 sample_regs)
+static int reg_value(unw_word_t *valp, struct regs_dump *regs, int id)
 {
        int i, idx = 0;
+       u64 mask = regs->mask;
 
-       if (!(sample_regs & (1 << id)))
+       if (!(mask & (1 << id)))
                return -EINVAL;
 
        for (i = 0; i < id; i++) {
-               if (sample_regs & (1 << i))
+               if (mask & (1 << i))
                        idx++;
        }
 
@@ -424,8 +423,7 @@ static int access_mem(unw_addr_space_t __maybe_unused as,
                return 0;
        }
 
-       ret = reg_value(&start, &ui->sample->user_regs, PERF_REG_SP,
-                       ui->sample_uregs);
+       ret = reg_value(&start, &ui->sample->user_regs, PERF_REG_SP);
        if (ret)
                return ret;
 
@@ -475,7 +473,7 @@ static int access_reg(unw_addr_space_t __maybe_unused as,
        if (id < 0)
                return -EINVAL;
 
-       ret = reg_value(valp, &ui->sample->user_regs, id, ui->sample_uregs);
+       ret = reg_value(valp, &ui->sample->user_regs, id);
        if (ret) {
                pr_err("unwind: can't read reg %d\n", regnum);
                return ret;
@@ -572,13 +570,11 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
 
 int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
                        struct machine *machine, struct thread *thread,
-                       u64 sample_uregs, struct perf_sample *data,
-                       int max_stack)
+                       struct perf_sample *data, int max_stack)
 {
        unw_word_t ip;
        struct unwind_info ui = {
                .sample       = data,
-               .sample_uregs = sample_uregs,
                .thread       = thread,
                .machine      = machine,
        };
@@ -587,7 +583,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
        if (!data->user_regs.regs)
                return -EINVAL;
 
-       ret = reg_value(&ip, &data->user_regs, PERF_REG_IP, sample_uregs);
+       ret = reg_value(&ip, &data->user_regs, PERF_REG_IP);
        if (ret)
                return ret;
 
index d5966f49e22cc24fb91e8f53307504cfed7e290d..356e1d642f9def9b7244e5cee0230ce5e8a2a44a 100644 (file)
@@ -17,7 +17,6 @@ typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg);
 int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
                        struct machine *machine,
                        struct thread *thread,
-                       u64 sample_uregs,
                        struct perf_sample *data, int max_stack);
 int unwind__arch_reg_id(int regnum);
 #else
@@ -26,7 +25,6 @@ unwind__get_entries(unwind_entry_cb_t cb __maybe_unused,
                    void *arg __maybe_unused,
                    struct machine *machine __maybe_unused,
                    struct thread *thread __maybe_unused,
-                   u64 sample_uregs __maybe_unused,
                    struct perf_sample *data __maybe_unused,
                    int max_stack __maybe_unused)
 {