From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753857AbbJTJgN (ORCPT ); Tue, 20 Oct 2015 05:36:13 -0400 Received: from terminus.zytor.com ([198.137.202.10]:49859 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752985AbbJTJgI (ORCPT ); Tue, 20 Oct 2015 05:36:08 -0400 Date: Tue, 20 Oct 2015 02:35:25 -0700 From: tip-bot for Adrian Hunter Message-ID: Cc: jolsa@redhat.com, dsahern@gmail.com, peterz@infradead.org, acme@redhat.com, mingo@kernel.org, torvalds@linux-foundation.org, eranian@google.com, namhyung@kernel.org, tglx@linutronix.de, acme@kernel.org, adrian.hunter@intel.com, linux-kernel@vger.kernel.org, vincent.weaver@maine.edu, luto@amacapital.net, hpa@zytor.com Reply-To: hpa@zytor.com, luto@amacapital.net, vincent.weaver@maine.edu, adrian.hunter@intel.com, linux-kernel@vger.kernel.org, tglx@linutronix.de, namhyung@kernel.org, acme@kernel.org, torvalds@linux-foundation.org, eranian@google.com, mingo@kernel.org, peterz@infradead.org, dsahern@gmail.com, jolsa@redhat.com, acme@redhat.com In-Reply-To: <1445001845-13688-2-git-send-email-adrian.hunter@intel.com> References: <1445001845-13688-2-git-send-email-adrian.hunter@intel.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:perf/core] perf/x86: Fix time_shift in perf_event_mmap_page Git-Commit-ID: b9511cd761faafca7a1acc059e792c1399f9d7c6 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: b9511cd761faafca7a1acc059e792c1399f9d7c6 Gitweb: http://git.kernel.org/tip/b9511cd761faafca7a1acc059e792c1399f9d7c6 Author: Adrian Hunter AuthorDate: Fri, 16 Oct 2015 16:24:05 +0300 Committer: Ingo Molnar CommitDate: Tue, 20 Oct 2015 10:30:52 +0200 perf/x86: Fix time_shift in perf_event_mmap_page Commit: b20112edeadf ("perf/x86: Improve accuracy of perf/sched clock") allowed the time_shift value in perf_event_mmap_page to be as much as 32. Unfortunately the documented algorithms for using time_shift have it shifting an integer, whereas to work correctly with the value 32, the type must be u64. In the case of perf tools, Intel PT decodes correctly but the timestamps that are output (for example by perf script) have lost 32-bits of granularity so they look like they are not changing at all. Fix by limiting the shift to 31 and adjusting the multiplier accordingly. Also update the documentation of perf_event_mmap_page so that new code based on it will be more future-proof. Signed-off-by: Adrian Hunter Signed-off-by: Peter Zijlstra (Intel) Cc: Andy Lutomirski Cc: Arnaldo Carvalho de Melo Cc: Arnaldo Carvalho de Melo Cc: David Ahern Cc: Jiri Olsa Cc: Linus Torvalds Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Fixes: b20112edeadf ("perf/x86: Improve accuracy of perf/sched clock") Link: http://lkml.kernel.org/r/1445001845-13688-2-git-send-email-adrian.hunter@intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/tsc.c | 11 +++++++++++ include/uapi/linux/perf_event.h | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 69b84a2..c7c4d9c 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -259,6 +259,17 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) clocks_calc_mult_shift(&data->cyc2ns_mul, &data->cyc2ns_shift, cpu_khz, NSEC_PER_MSEC, 0); + /* + * cyc2ns_shift is exported via arch_perf_update_userpage() where it is + * not expected to be greater than 31 due to the original published + * conversion algorithm shifting a 32-bit value (now specifies a 64-bit + * value) - refer perf_event_mmap_page documentation in perf_event.h. + */ + if (data->cyc2ns_shift == 32) { + data->cyc2ns_shift = 31; + data->cyc2ns_mul >>= 1; + } + data->cyc2ns_offset = ns_now - mul_u64_u32_shr(tsc_now, data->cyc2ns_mul, data->cyc2ns_shift); diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h index 2881145..6c72e72 100644 --- a/include/uapi/linux/perf_event.h +++ b/include/uapi/linux/perf_event.h @@ -476,7 +476,7 @@ struct perf_event_mmap_page { * u64 delta; * * quot = (cyc >> time_shift); - * rem = cyc & ((1 << time_shift) - 1); + * rem = cyc & (((u64)1 << time_shift) - 1); * delta = time_offset + quot * time_mult + * ((rem * time_mult) >> time_shift); * @@ -507,7 +507,7 @@ struct perf_event_mmap_page { * And vice versa: * * quot = cyc >> time_shift; - * rem = cyc & ((1 << time_shift) - 1); + * rem = cyc & (((u64)1 << time_shift) - 1); * timestamp = time_zero + quot * time_mult + * ((rem * time_mult) >> time_shift); */