Received: from milmhbs1.lsil.com (147.145.21.209) by coscas01.lsi.com
 (172.21.36.60) with Microsoft SMTP Server id 8.1.393.1; Fri, 8 Jan 2010
 15:48:48 -0700
Received: from mail1.lsil.com (mail1.lsil.com [147.145.40.21])	by
 milmhbs1.lsil.com (8.12.11/8.12.11) with ESMTP id o08Mmfmm007240	for
 <andy.sharp@lsi.com>; Fri, 8 Jan 2010 14:48:44 -0800
Received: from psmtp.com (na3sys009amx201.postini.com [74.125.149.41])	by
 mail1.lsil.com (8.12.11/8.12.11) with SMTP id o08MmZL4022923	for
 <andy.sharp@lsi.com>; Fri, 8 Jan 2010 14:48:40 -0800 (PST)
Received: from source ([78.24.191.182]) by na3sys009amx201.postini.com
 ([74.125.148.14]) with SMTP;	Fri, 08 Jan 2010 14:48:40 PST
Received: from localhost.localdomain ([127.0.0.1]:60055 "EHLO
        eddie.linux-mips.org" rhost-flags-OK-OK-OK-FAIL)        by
 eddie.linux-mips.org with ESMTP id S1492891Ab0AHWsR (ORCPT
        <rfc822;andy.sharp@lsi.com>); Fri, 8 Jan 2010 23:48:17 +0100
Received: with ECARTIS (v1.0.0; list linux-mips); Fri, 08 Jan 2010 23:47:59
 +0100 (CET)
Received: from mail3.caviumnetworks.com ([12.108.191.235]:18222 "EHLO
        mail3.caviumnetworks.com" rhost-flags-OK-OK-OK-OK)        by
 eddie.linux-mips.org with ESMTP id S1492890Ab0AHWrz (ORCPT
        <rfc822;linux-mips@linux-mips.org>); Fri, 8 Jan 2010 23:47:55 +0100
Received: from caexch01.caveonetworks.com (Not Verified[192.168.16.9]) by
 mail3.caviumnetworks.com with MailMarshal (v6,5,4,7535)        id
 <B4b47b6110000>; Fri, 08 Jan 2010 14:47:45 -0800
Received: from caexch01.caveonetworks.com ([192.168.16.9]) by
 caexch01.caveonetworks.com with Microsoft SMTPSVC(6.0.3790.3959);
         Fri, 8 Jan 2010 14:47:42 -0800
Received: from dd1.caveonetworks.com ([12.108.191.236]) by
 caexch01.caveonetworks.com over TLS secured channel with Microsoft
 SMTPSVC(6.0.3790.3959);         Fri, 8 Jan 2010 14:47:41 -0800
Received: from dd1.caveonetworks.com (localhost.localdomain [127.0.0.1])
        by dd1.caveonetworks.com (8.14.2/8.14.2) with ESMTP id o08Mlb2F008326;
        Fri, 8 Jan 2010 14:47:37 -0800
Received: (from ddaney@localhost)        by dd1.caveonetworks.com
 (8.14.2/8.14.2/Submit) id o08MlaJY008324;        Fri, 8 Jan 2010 14:47:36
 -0800
From: David Daney <ddaney@caviumnetworks.com>
To: "linux-mips@linux-mips.org" <linux-mips@linux-mips.org>,
	"ralf@linux-mips.org" <ralf@linux-mips.org>
CC: David Daney <ddaney@caviumnetworks.com>
Sender: "linux-mips-bounce@linux-mips.org" <linux-mips-bounce@linux-mips.org>
Date: Fri, 8 Jan 2010 15:47:36 -0700
Subject: [PATCH] MIPS: Octeon: Use non-overflowing arithmetic in sched_clock
Thread-Topic: [PATCH] MIPS: Octeon: Use non-overflowing arithmetic in
 sched_clock
Thread-Index: AcqQtL4nkcjs5OTQQ+KpZePLmojmFw==
Message-ID: <1262990856-8300-1-git-send-email-ddaney@caviumnetworks.com>
Accept-Language: en-US
Content-Language: en-US
X-MS-Exchange-Organization-AuthAs: Anonymous
X-MS-Exchange-Organization-AuthSource: coscas01.lsi.com
X-MS-Has-Attach:
X-Auto-Response-Suppress: All
X-MS-TNEF-Correlator:
x-scanned-by: MIMEDefang 2.39
errors-to: linux-mips-bounce@linux-mips.org
x-originalarrivaltime: 08 Jan 2010 22:47:42.0028 (UTC)
 FILETIME=[961A00C0:01CA90B4]
x-pstn-levels: (S:99.51456/99.90000 CV:99.9000 FC:95.5390 LC:95.5390
 R:95.9108 P:95.9108 M:97.0282 C:98.6951 )
x-pstn-settings: 3 (1.0000:1.0000) s cv gt3 gt2 gt1 r p m c 
x-pstn-addresses: from <ddaney@caviumnetworks.com> [22/1] 
x-pstn-neptune: 1/1/1.00/85
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0

With typical mult and shift values, the calculation for Octeon's
sched_clock overflows when using 64-bit arithmetic.  Use 128-bit
calculations instead.

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
---
 arch/mips/cavium-octeon/csrc-octeon.c |   31 ++++++++++++++++++++++++++++-=
--
 1 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/arch/mips/cavium-octeon/csrc-octeon.c b/arch/mips/cavium-octeo=
n/csrc-octeon.c
index 96df821..0bf4bbe 100644
--- a/arch/mips/cavium-octeon/csrc-octeon.c
+++ b/arch/mips/cavium-octeon/csrc-octeon.c
@@ -52,9 +52,34 @@ static struct clocksource clocksource_mips =3D {
=20
 unsigned long long notrace sched_clock(void)
 {
-	return clocksource_cyc2ns(read_c0_cvmcount(),
-				  clocksource_mips.mult,
-				  clocksource_mips.shift);
+	/* 64-bit arithmatic can overflow, so use 128-bit.  */
+#if (__GNUC__ < 4) || ((__GNUC__ =3D=3D 4) && (__GNUC_MINOR__ <=3D 3))
+	u64 t1, t2, t3;
+	unsigned long long rv;
+	u64 mult =3D clocksource_mips.mult;
+	u64 shift =3D clocksource_mips.shift;
+	u64 cnt =3D read_c0_cvmcount();
+
+	asm (
+		"dmultu\t%[cnt],%[mult]\n\t"
+		"nor\t%[t1],$0,%[shift]\n\t"
+		"mfhi\t%[t2]\n\t"
+		"mflo\t%[t3]\n\t"
+		"dsll\t%[t2],%[t2],1\n\t"
+		"dsrlv\t%[rv],%[t3],%[shift]\n\t"
+		"dsllv\t%[t1],%[t2],%[t1]\n\t"
+		"or\t%[rv],%[t1],%[rv]\n\t"
+		: [rv] "=3D&r" (rv), [t1] "=3D&r" (t1), [t2] "=3D&r" (t2), [t3] "=3D&r" =
(t3)
+		: [cnt] "r" (cnt), [mult] "r" (mult), [shift] "r" (shift)
+		: "hi", "lo");
+	return rv;
+#else
+	/* GCC > 4.3 do it the easy way.  */
+	unsigned int __attribute__((mode(TI))) t;
+	t =3D read_c0_cvmcount();
+	t =3D t * clocksource_mips.mult;
+	return (unsigned long long)(t >> clocksource_mips.shift);
+#endif
 }
=20
 void __init plat_time_init(void)
--=20
1.6.0.6


