Received: by 10.192.165.156 with SMTP id m28csp230163imm; Tue, 17 Apr 2018 09:11:04 -0700 (PDT) X-Google-Smtp-Source: AIpwx495bJIVYsqMDUBlTfu1TLUAN19w92GUWfBZVjpLdkPbgQi/U0xDckvFlCrxmvSp7V4M4yjR X-Received: by 10.99.124.15 with SMTP id x15mr2337057pgc.308.1523981464449; Tue, 17 Apr 2018 09:11:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1523981464; cv=none; d=google.com; s=arc-20160816; b=0eIM2kUhH/Y+WvaytsTfaA7/DASCqVbPmwEFkwkqoWrqVZLWLGK9cl5vw1TGJx/nBU 7NcQlaJl8qq0OeGw/YeDlDhq2vqUqqmuHST24YrAgOJkfe+1I8KI8mD9oBb1ys+q276s HrKvkzimD1NDg9PpQn/lBXCMCehsXyg7Q08HBiAwSLl9bRqexmAx8+rsYtbC26zUAIBJ Z+HVU4gp5Rj+ewH5YUJj/JtJ5BbSmy5+PlPfgZBgfhbKFQcTBqtRlU/KqZaz6JLgmr/c A71JKsXKVTRFmZCY8UfRWF3I2yl82AlMVOVnAJQmQ8J/BERcECAl001TQNKK3QdFPmzq N1Lg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=liDdafrFPXKtJHxf9R1IIYC6ksjW5vbqMgQ1efem6Hk=; b=rlBCqoqTMjdQ9kYAVQ/nF8lZtqUVryJmTQw563NVVvhkT8KVfF15MHampVGUUJoMf0 2mMf5ffoEyVau96WIFlhobFRjUdaKwvSIZxWsoAC7AXB6ggNW2PjNjy7TyEjQPiyhd8A qbRbrzqz/mBfJogVBJcwPgFalvlXw3GqvoKbUDrvjCx4tTQ67NXeEPRirRLT5DctNn/L lc/tSlSSxsNyVdH1KJBcF3USPrL/sfO4CTfo1Ln7kcvhS9TLqoLiXoXKhawRQFcDAdkm RMF4RxvlH1uVrIrOEoKbBtT10ZQOeENJJg15Mi5MW9v+6fDKV45Gs5abMjDuKS+1FSzv Sj3Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r63-v6si2107196plb.366.2018.04.17.09.10.50; Tue, 17 Apr 2018 09:11:04 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932088AbeDQQJM (ORCPT + 99 others); Tue, 17 Apr 2018 12:09:12 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:35672 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755594AbeDQQJJ (ORCPT ); Tue, 17 Apr 2018 12:09:09 -0400 Received: from localhost (unknown [46.44.180.42]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id B60A5F13; Tue, 17 Apr 2018 16:09:08 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Adrian Hunter , Jiri Olsa , Arnaldo Carvalho de Melo Subject: [PATCH 4.9 04/66] perf intel-pt: Fix overlap detection to identify consecutive buffers correctly Date: Tue, 17 Apr 2018 17:58:37 +0200 Message-Id: <20180417155646.044775793@linuxfoundation.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180417155645.868055442@linuxfoundation.org> References: <20180417155645.868055442@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.9-stable review patch. If anyone has any objections, please let me know. ------------------ From: Adrian Hunter commit 117db4b27bf08dba412faf3924ba55fe970c57b8 upstream. Overlap detection was not not updating the buffer's 'consecutive' flag. Marking buffers consecutive has the advantage that decoding begins from the start of the buffer instead of the first PSB. Fix overlap detection to identify consecutive buffers correctly. Signed-off-by: Adrian Hunter Cc: Jiri Olsa Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/1520431349-30689-2-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Greg Kroah-Hartman --- tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | 62 +++++++++----------- tools/perf/util/intel-pt-decoder/intel-pt-decoder.h | 2 tools/perf/util/intel-pt.c | 5 + 3 files changed, 34 insertions(+), 35 deletions(-) --- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c @@ -2182,14 +2182,6 @@ const struct intel_pt_state *intel_pt_de return &decoder->state; } -static bool intel_pt_at_psb(unsigned char *buf, size_t len) -{ - if (len < INTEL_PT_PSB_LEN) - return false; - return memmem(buf, INTEL_PT_PSB_LEN, INTEL_PT_PSB_STR, - INTEL_PT_PSB_LEN); -} - /** * intel_pt_next_psb - move buffer pointer to the start of the next PSB packet. * @buf: pointer to buffer pointer @@ -2278,6 +2270,7 @@ static unsigned char *intel_pt_last_psb( * @buf: buffer * @len: size of buffer * @tsc: TSC value returned + * @rem: returns remaining size when TSC is found * * Find a TSC packet in @buf and return the TSC value. This function assumes * that @buf starts at a PSB and that PSB+ will contain TSC and so stops if a @@ -2285,7 +2278,8 @@ static unsigned char *intel_pt_last_psb( * * Return: %true if TSC is found, false otherwise. */ -static bool intel_pt_next_tsc(unsigned char *buf, size_t len, uint64_t *tsc) +static bool intel_pt_next_tsc(unsigned char *buf, size_t len, uint64_t *tsc, + size_t *rem) { struct intel_pt_pkt packet; int ret; @@ -2296,6 +2290,7 @@ static bool intel_pt_next_tsc(unsigned c return false; if (packet.type == INTEL_PT_TSC) { *tsc = packet.payload; + *rem = len; return true; } if (packet.type == INTEL_PT_PSBEND) @@ -2346,6 +2341,8 @@ static int intel_pt_tsc_cmp(uint64_t tsc * @len_a: size of first buffer * @buf_b: second buffer * @len_b: size of second buffer + * @consecutive: returns true if there is data in buf_b that is consecutive + * to buf_a * * If the trace contains TSC we can look at the last TSC of @buf_a and the * first TSC of @buf_b in order to determine if the buffers overlap, and then @@ -2358,33 +2355,41 @@ static int intel_pt_tsc_cmp(uint64_t tsc static unsigned char *intel_pt_find_overlap_tsc(unsigned char *buf_a, size_t len_a, unsigned char *buf_b, - size_t len_b) + size_t len_b, bool *consecutive) { uint64_t tsc_a, tsc_b; unsigned char *p; - size_t len; + size_t len, rem_a, rem_b; p = intel_pt_last_psb(buf_a, len_a); if (!p) return buf_b; /* No PSB in buf_a => no overlap */ len = len_a - (p - buf_a); - if (!intel_pt_next_tsc(p, len, &tsc_a)) { + if (!intel_pt_next_tsc(p, len, &tsc_a, &rem_a)) { /* The last PSB+ in buf_a is incomplete, so go back one more */ len_a -= len; p = intel_pt_last_psb(buf_a, len_a); if (!p) return buf_b; /* No full PSB+ => assume no overlap */ len = len_a - (p - buf_a); - if (!intel_pt_next_tsc(p, len, &tsc_a)) + if (!intel_pt_next_tsc(p, len, &tsc_a, &rem_a)) return buf_b; /* No TSC in buf_a => assume no overlap */ } while (1) { /* Ignore PSB+ with no TSC */ - if (intel_pt_next_tsc(buf_b, len_b, &tsc_b) && - intel_pt_tsc_cmp(tsc_a, tsc_b) < 0) - return buf_b; /* tsc_a < tsc_b => no overlap */ + if (intel_pt_next_tsc(buf_b, len_b, &tsc_b, &rem_b)) { + int cmp = intel_pt_tsc_cmp(tsc_a, tsc_b); + + /* Same TSC, so buffers are consecutive */ + if (!cmp && rem_b >= rem_a) { + *consecutive = true; + return buf_b + len_b - (rem_b - rem_a); + } + if (cmp < 0) + return buf_b; /* tsc_a < tsc_b => no overlap */ + } if (!intel_pt_step_psb(&buf_b, &len_b)) return buf_b + len_b; /* No PSB in buf_b => no data */ @@ -2398,6 +2403,8 @@ static unsigned char *intel_pt_find_over * @buf_b: second buffer * @len_b: size of second buffer * @have_tsc: can use TSC packets to detect overlap + * @consecutive: returns true if there is data in buf_b that is consecutive + * to buf_a * * When trace samples or snapshots are recorded there is the possibility that * the data overlaps. Note that, for the purposes of decoding, data is only @@ -2408,7 +2415,7 @@ static unsigned char *intel_pt_find_over */ unsigned char *intel_pt_find_overlap(unsigned char *buf_a, size_t len_a, unsigned char *buf_b, size_t len_b, - bool have_tsc) + bool have_tsc, bool *consecutive) { unsigned char *found; @@ -2420,7 +2427,8 @@ unsigned char *intel_pt_find_overlap(uns return buf_b; /* No overlap */ if (have_tsc) { - found = intel_pt_find_overlap_tsc(buf_a, len_a, buf_b, len_b); + found = intel_pt_find_overlap_tsc(buf_a, len_a, buf_b, len_b, + consecutive); if (found) return found; } @@ -2435,28 +2443,16 @@ unsigned char *intel_pt_find_overlap(uns } /* Now len_b >= len_a */ - if (len_b > len_a) { - /* The leftover buffer 'b' must start at a PSB */ - while (!intel_pt_at_psb(buf_b + len_a, len_b - len_a)) { - if (!intel_pt_step_psb(&buf_a, &len_a)) - return buf_b; /* No overlap */ - } - } - while (1) { /* Potential overlap so check the bytes */ found = memmem(buf_a, len_a, buf_b, len_a); - if (found) + if (found) { + *consecutive = true; return buf_b + len_a; + } /* Try again at next PSB in buffer 'a' */ if (!intel_pt_step_psb(&buf_a, &len_a)) return buf_b; /* No overlap */ - - /* The leftover buffer 'b' must start at a PSB */ - while (!intel_pt_at_psb(buf_b + len_a, len_b - len_a)) { - if (!intel_pt_step_psb(&buf_a, &len_a)) - return buf_b; /* No overlap */ - } } } --- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h +++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h @@ -103,7 +103,7 @@ const struct intel_pt_state *intel_pt_de unsigned char *intel_pt_find_overlap(unsigned char *buf_a, size_t len_a, unsigned char *buf_b, size_t len_b, - bool have_tsc); + bool have_tsc, bool *consecutive); int intel_pt__strerror(int code, char *buf, size_t buflen); --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -194,14 +194,17 @@ static void intel_pt_dump_event(struct i static int intel_pt_do_fix_overlap(struct intel_pt *pt, struct auxtrace_buffer *a, struct auxtrace_buffer *b) { + bool consecutive = false; void *start; start = intel_pt_find_overlap(a->data, a->size, b->data, b->size, - pt->have_tsc); + pt->have_tsc, &consecutive); if (!start) return -EINVAL; b->use_size = b->data + b->size - start; b->use_data = start; + if (b->use_size && consecutive) + b->consecutive = true; return 0; }