From patchwork Mon Jun 27 21:56:13 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Scott Wood X-Patchwork-Id: 102285 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from ozlabs.org (localhost [IPv6:::1]) by ozlabs.org (Postfix) with ESMTP id 07430B7270 for ; Tue, 28 Jun 2011 08:00:10 +1000 (EST) Received: from TX2EHSOBE006.bigfish.com (tx2ehsobe003.messaging.microsoft.com [65.55.88.13]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (Client CN "mail.global.frontbridge.com", Issuer "Cybertrust SureServer Standard Validation CA" (verified OK)) by ozlabs.org (Postfix) with ESMTPS id D6945B6F53 for ; Tue, 28 Jun 2011 07:59:32 +1000 (EST) Received: from mail68-tx2-R.bigfish.com (10.9.14.249) by TX2EHSOBE006.bigfish.com (10.9.40.26) with Microsoft SMTP Server id 14.1.225.22; Mon, 27 Jun 2011 21:59:16 +0000 Received: from mail68-tx2 (localhost.localdomain [127.0.0.1]) by mail68-tx2-R.bigfish.com (Postfix) with ESMTP id 70C3F12D02CA; Mon, 27 Jun 2011 21:59:16 +0000 (UTC) X-SpamScore: 0 X-BigFish: VS0(zzzz1202hzz8275bhz2dh2a8h668h839h61h) X-Spam-TCS-SCL: 0:0 X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPVD:NLI; H:mail.freescale.net; RD:none; EFVD:NLI Received: from mail68-tx2 (localhost.localdomain [127.0.0.1]) by mail68-tx2 (MessageSwitch) id 1309211775593104_28959; Mon, 27 Jun 2011 21:56:15 +0000 (UTC) Received: from TX2EHSMHS047.bigfish.com (unknown [10.9.14.254]) by mail68-tx2.bigfish.com (Postfix) with ESMTP id 88E6D73804C; Mon, 27 Jun 2011 21:56:15 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by TX2EHSMHS047.bigfish.com (10.9.99.147) with Microsoft SMTP Server (TLS) id 14.1.225.22; Mon, 27 Jun 2011 21:56:15 +0000 Received: from az33smr01.freescale.net (10.64.34.199) by 039-SN1MMR1-001.039d.mgd.msft.net (10.84.1.13) with Microsoft SMTP Server id 14.1.289.8; Mon, 27 Jun 2011 16:56:14 -0500 Received: from schlenkerla.am.freescale.net (schlenkerla.am.freescale.net [10.82.121.12]) by az33smr01.freescale.net (8.13.1/8.13.0) with ESMTP id p5RLuDW7013910; Mon, 27 Jun 2011 16:56:13 -0500 (CDT) Date: Mon, 27 Jun 2011 16:56:13 -0500 From: Scott Wood To: Subject: [PATCH] powerpc/timebase_read: don't return time older than cycle_last Message-ID: <20110627215613.GA13676@schlenkerla.am.freescale.net> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-OriginatorOrg: freescale.com Cc: linuxppc-dev@lists.ozlabs.org X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org As is done in read_tsc() on x86, make sure that we don't return a timebase value smaller than cycle_last, which can happen on SMP if the timebases are not perfectly synchronized. It is less expensive than total enforcement of monotonicity, since we don't need to add another variable and update it on each read, but it will prevent core timekeeping functions from translating a small timebase regression into a large jump forward. Based on commit d8bb6f4c1670c8324e4135c61ef07486f7f17379 for x86. Signed-off-by: Scott Wood --- arch/powerpc/kernel/time.c | 15 ++++++++++++++- 1 files changed, 14 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index f33acfd..b66ce41 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -806,9 +806,22 @@ static cycle_t rtc_read(struct clocksource *cs) return (cycle_t)get_rtc(); } +/* + * We compare the timebase to the cycle_last value in the clocksource + * structure to avoid a nasty time-warp. This can be observed in a very + * small window right after one CPU updated cycle_last under the xtime lock, + * and the other CPU reads a TSC value which is smaller than the cycle_last + * reference value due to a TSC which is slighty behind. This delta is + * nowhere else observable, but in that case it results in a large forward + * time jump due to the unsigned delta calculation of the time keeping core + * code, which is necessary to support wrapping clocksources like pm timer. + */ static cycle_t timebase_read(struct clocksource *cs) { - return (cycle_t)get_tb(); + cycle_t ret = (cycle_t)get_tb(); + + return ret >= clocksource_timebase.cycle_last ? + ret : clocksource_timebase.cycle_last; } void update_vsyscall(struct timespec *wall_time, struct timespec *wtm,