From patchwork Wed Jan 11 21:13:02 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris J Arges X-Patchwork-Id: 135501 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id 2717DB6EFE for ; Thu, 12 Jan 2012 08:13:22 +1100 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1Rl5Tm-0003DB-Mp; Wed, 11 Jan 2012 21:13:06 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1Rl5Tk-0003D6-Ar for kernel-team@lists.ubuntu.com; Wed, 11 Jan 2012 21:13:04 +0000 Received: from user-387o921.cable.mindspring.com ([208.124.36.65] helo=[192.168.11.40]) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1Rl5Tk-0004pI-5H for kernel-team@lists.ubuntu.com; Wed, 11 Jan 2012 21:13:04 +0000 Message-ID: <4F0DFB5E.7030007@canonical.com> Date: Wed, 11 Jan 2012 15:13:02 -0600 From: Chris J Arges User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:8.0) Gecko/20111124 Thunderbird/8.0 MIME-Version: 1.0 To: kernel-team@lists.ubuntu.com Subject: [natty/maverick] [PATCH] SRU: sched, x86: Avoid unnecessary overflow in sched_clock X-Enigmail-Version: 1.3.4 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: kernel-team-bounces@lists.ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com SRU Justification: BugLink: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/805341 Impact: Machines with uptimes of 200+ days will sometimes have soft lockups. Fix: This was fixed in upstream. It has already been backported to Lucid. Testcase: Run your computer for 200+ days and verify it doesn't lockup. Acked-by: Seth Forshee From a9747c4dc863ab62553dd65c4159b4b8e749042f Mon Sep 17 00:00:00 2001 From: Salman Qazi Date: Wed, 11 Jan 2012 12:29:48 -0600 Subject: [PATCH] sched, x86: Avoid unnecessary overflow in sched_clock (Added the missing signed-off-by line) In hundreds of days, the __cycles_2_ns calculation in sched_clock has an overflow. cyc * per_cpu(cyc2ns, cpu) exceeds 64 bits, causing the final value to become zero. We can solve this without losing any precision. We can decompose TSC into quotient and remainder of division by the scale factor, and then use this to convert TSC into nanoseconds. Signed-off-by: Salman Qazi Acked-by: John Stultz Reviewed-by: Paul Turner Cc: stable@kernel.org Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20111115221121.7262.88871.stgit@dungbeetle.mtv.corp.google.com Signed-off-by: Ingo Molnar (cherry picked from commit 4cecf6d401a01d054afc1e5f605bcbfe553cb9b9) Signed-off-by: Chris J Arges BugLink: http://bugs.launchpad.net/bugs/805341 --- arch/x86/include/asm/timer.h | 23 ++++++++++++++++++++++- 1 files changed, 22 insertions(+), 1 deletions(-) diff --git a/arch/x86/include/asm/timer.h b/arch/x86/include/asm/timer.h index fa7b917..431793e 100644 --- a/arch/x86/include/asm/timer.h +++ b/arch/x86/include/asm/timer.h @@ -32,6 +32,22 @@ extern int no_timer_check; * (mathieu.desnoyers@polymtl.ca) * * -johnstul@us.ibm.com "math is hard, lets go shopping!" + * + * In: + * + * ns = cycles * cyc2ns_scale / SC + * + * Although we may still have enough bits to store the value of ns, + * in some cases, we may not have enough bits to store cycles * cyc2ns_scale, + * leading to an incorrect result. + * + * To avoid this, we can decompose 'cycles' into quotient and remainder + * of division by SC. Then, + * + * ns = (quot * SC + rem) * cyc2ns_scale / SC + * = quot * cyc2ns_scale + (rem * cyc2ns_scale) / SC + * + * - sqazi@google.com */ DECLARE_PER_CPU(unsigned long, cyc2ns); @@ -41,9 +57,14 @@ DECLARE_PER_CPU(unsigned long long, cyc2ns_offset); static inline unsigned long long __cycles_2_ns(unsigned long long cyc) { + unsigned long long quot; + unsigned long long rem; int cpu = smp_processor_id(); unsigned long long ns = per_cpu(cyc2ns_offset, cpu); - ns += cyc * per_cpu(cyc2ns, cpu) >> CYC2NS_SCALE_FACTOR; + quot = (cyc >> CYC2NS_SCALE_FACTOR); + rem = cyc & ((1ULL << CYC2NS_SCALE_FACTOR) - 1); + ns += quot * per_cpu(cyc2ns, cpu) + + ((rem * per_cpu(cyc2ns, cpu)) >> CYC2NS_SCALE_FACTOR); return ns; } -- 1.7.5.4