Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753140AbcKPQ6F (ORCPT ); Wed, 16 Nov 2016 11:58:05 -0500 Received: from mail-il-dmz.mellanox.com ([193.47.165.129]:38643 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752446AbcKPQ6D (ORCPT ); Wed, 16 Nov 2016 11:58:03 -0500 From: Chris Metcalf To: John Stultz , Thomas Gleixner , Salman Qazi , Paul Turner , Tony Lindgren , Steven Miao , linux-kernel@vger.kernel.org Cc: Chris Metcalf Subject: [PATCH] clocksource_cyc2ns: avoid overflowing 64 bits Date: Wed, 16 Nov 2016 11:57:52 -0500 Message-Id: <1479315472-5245-1-git-send-email-cmetcalf@mellanox.com> X-Mailer: git-send-email 2.7.2 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1302 Lines: 35 For large values of "mult" and long uptimes, the intermediate result of "cycles * mult" can overflow 64 bits. For example, the tile platform uses this helper function; for a 1.2 GHz clock, we have mult = 853, and after 208.5 days, we overflow 64 bits. The fix is basically the same as the fix for arch/x86 __cycles_2_ns() in commit 4cecf6d401a0 ("sched, x86: Avoid unnecessary overflow in sched_clock"), using the new mult_frac() helper. In addition to tile, arm/plat-omap and blackfin also use this helper function, so will presumably hit similar issues. Signed-off-by: Chris Metcalf --- By the way, this is the bug that I was looking for when I tripped over the missing bugfix for timekeeping_delta_to_ns() a couple of days ago :-) include/linux/clocksource.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 08398182f56e..b2a022acf232 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -175,7 +175,7 @@ static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant) */ static inline s64 clocksource_cyc2ns(cycle_t cycles, u32 mult, u32 shift) { - return ((u64) cycles * mult) >> shift; + return mult_frac(cycles, mult, 1ULL << shift); } -- 2.7.2