Messages in this thread Patch in this message | | | From | Jiri Olsa <> | Subject | [PATCH 04/21] perf tools: Add perf_sample__copy|free functions | Date | Wed, 24 Jan 2018 12:51:26 +0100 |
| |
Later in the patchset we are going to queue some samples for later processing. To be able to do that I'm adding perf_sample__copy|free functions that duplicate|free perf_sample data.
Link: http://lkml.kernel.org/n/tip-lcwyac9i125cq89m9msvgu9f@git.kernel.org Signed-off-by: Jiri Olsa <jolsa@kernel.org> --- tools/perf/builtin-report.c | 75 +++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/event.h | 1 + 2 files changed, 76 insertions(+)
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 9bae7f11691c..a08e2c88070a 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -193,6 +193,81 @@ static int hist_iter__branch_callback(struct hist_entry_iter *iter, return err; } +static void perf_sample__free(struct perf_sample *sample) +{ + if (sample->copy) { + free(sample->callchain); + free(sample->raw_data); + free(sample->branch_stack); + free(sample->user_regs.regs); + free(sample->intr_regs.regs); + free(sample->user_stack.data); + } +} + +static __maybe_unused int +perf_sample__copy(struct perf_sample *dst, struct perf_sample *src) +{ + int ret = -1; + u64 size; + + *dst = *src; + + dst->callchain = NULL; + dst->raw_data = NULL; + dst->branch_stack = NULL; + dst->user_regs.regs = NULL; + dst->intr_regs.regs = NULL; + dst->user_stack.data = NULL; + +#define DUP(__field, __size) \ + do { \ + dst->__field = memdup(src->__field, __size); \ + if (!dst->__field) \ + goto error; \ + } while (0) + + if (src->callchain) { + size = (src->callchain->nr + 1) * sizeof(u64); + DUP(callchain, size); + } + + if (src->raw_data) + DUP(raw_data, src->raw_size); + + if (src->branch_stack) { + size = sizeof(u64); + size += src->branch_stack->nr * sizeof(struct branch_entry); + DUP(branch_stack, size); + } + + if (src->user_regs.regs) { + u64 mask = src->user_regs.mask; + + size = hweight_long(mask) * sizeof(u64); + DUP(user_regs.regs, size); + } + + if (src->intr_regs.regs) { + u64 mask = src->intr_regs.mask; + + size = hweight_long(mask) * sizeof(u64); + DUP(intr_regs.regs, size); + } + + if (src->user_stack.data) + DUP(user_stack.data, src->user_stack.size); + +#undef DUP + dst->copy = true; + ret = 0; + +error: + if (ret) + perf_sample__free(dst); + return ret; +} + static int perf_sample__process(struct perf_sample *sample, struct addr_location *al, struct perf_evsel *evsel, struct report *rep) diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 0f794744919c..546539da1592 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -189,6 +189,7 @@ enum { #define MAX_INSN 16 struct perf_sample { + bool copy; u64 ip; u32 pid, tid; u64 time; -- 2.13.6
| |