From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933582AbeAXLv6 (ORCPT ); Wed, 24 Jan 2018 06:51:58 -0500 Received: from mx1.redhat.com ([209.132.183.28]:50962 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933554AbeAXLv4 (ORCPT ); Wed, 24 Jan 2018 06:51:56 -0500 From: Jiri Olsa To: Peter Zijlstra , Ingo Molnar Cc: lkml , Namhyung Kim , David Ahern , Andi Kleen , Alexander Shishkin , Andy Lutomirski , Arnaldo Carvalho de Melo Subject: [PATCH 04/21] perf tools: Add perf_sample__copy|free functions Date: Wed, 24 Jan 2018 12:51:26 +0100 Message-Id: <20180124115143.14322-5-jolsa@kernel.org> In-Reply-To: <20180124115143.14322-1-jolsa@kernel.org> References: <20180124115143.14322-1-jolsa@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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