From patchwork Mon Dec 28 16:59:41 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joao Martins X-Patchwork-Id: 7926831 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 9BFEE9F350 for ; Mon, 28 Dec 2015 17:03:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B7D7F20254 for ; Mon, 28 Dec 2015 17:03:08 +0000 (UTC) Received: from lists.xen.org (lists.xenproject.org [50.57.142.19]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B520F20251 for ; Mon, 28 Dec 2015 17:03:07 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aDb9d-0008Da-VF; Mon, 28 Dec 2015 17:00:17 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aDb9c-0008DH-OF for xen-devel@lists.xen.org; Mon, 28 Dec 2015 17:00:16 +0000 Received: from [85.158.137.68] by server-5.bemta-3.messagelabs.com id EF/34-07651-F9A61865; Mon, 28 Dec 2015 17:00:15 +0000 X-Env-Sender: joao.m.martins@oracle.com X-Msg-Ref: server-11.tower-31.messagelabs.com!1451322013!12426496!1 X-Originating-IP: [156.151.31.81] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogMTU2LjE1MS4zMS44MSA9PiAyODgzMzk=\n X-StarScan-Received: X-StarScan-Version: 7.35.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 65527 invoked from network); 28 Dec 2015 17:00:15 -0000 Received: from userp1040.oracle.com (HELO userp1040.oracle.com) (156.151.31.81) by server-11.tower-31.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 28 Dec 2015 17:00:15 -0000 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tBSH0B4O020862 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Mon, 28 Dec 2015 17:00:11 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tBSH0ADl019227 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Mon, 28 Dec 2015 17:00:11 GMT Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tBSH0AwE005893; Mon, 28 Dec 2015 17:00:10 GMT Received: from paddy.lan (/85.245.89.156) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 28 Dec 2015 09:00:10 -0800 From: Joao Martins To: xen-devel@lists.xen.org Date: Mon, 28 Dec 2015 16:59:41 +0000 Message-Id: <1451321985-13728-3-git-send-email-joao.m.martins@oracle.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1451321985-13728-1-git-send-email-joao.m.martins@oracle.com> References: <1451321985-13728-1-git-send-email-joao.m.martins@oracle.com> X-Source-IP: aserv0022.oracle.com [141.146.126.234] Cc: Andrew Cooper , Joao Martins , Keir Fraser , Jan Beulich Subject: [Xen-devel] [PATCH RFC 2/6] x86/time: implement tsc as clocksource X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Introduce support for using TSC as platform time which is the highest resolution time and most performant to get (~20 nsecs). Though there are also several problems associated with its usage, and there isn't a complete (and architecturally defined) guarantee that all machines will provide reliable and monotonic TSC across all CPUs, on different sockets and different P/C states. I believe Intel to be the only that can guarantee that. For this reason it's set with less priority when compared to HPET unless adminstrator changes "clocksource" boot option to "tsc". Upon initializing it, we also check for time warps and appropriate CPU features i.e. TSC_RELIABLE, CONSTANT_TSC and NONSTOP_TSC. And in case none of these conditions are met, we fail in order to fallback to the next available clocksource. It is also worth nothing that with clocksource=tsc there isn't no synchronization with another clocksource, and I could verify that great portion the time skew was eliminated and seeing much less time warps happening. With HPET I used to observe ~500 warps in the period of 1h of around 27 us, and with TSC down to 50 warps in the same period having each warp < 100 ns. The warps still exist though but are only related to cross CPU calibration (being how much it takes to rendezvous with master), in which a later patch in this series aims to solve. Signed-off-by: Joao Martins --- xen/arch/x86/time.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 30d52c4..c9e5c14 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -433,6 +433,64 @@ uint64_t ns_to_acpi_pm_tick(uint64_t ns) } /************************************************************ + * PLATFORM TIMER 4: TSC + */ +static bool_t clocksource_is_tsc = 0; +static u64 tsc_freq; +static unsigned long tsc_max_warp; +static void tsc_check_reliability(void); + +static int __init init_tsctimer(struct platform_timesource *pts) +{ + bool_t tsc_reliable = 0; + + tsc_check_reliability(); + + if ( tsc_max_warp > 0 ) + { + tsc_reliable = 0; + printk("TSC: didn't passed warp test\n"); + } + else if ( boot_cpu_has(X86_FEATURE_TSC_RELIABLE) || + ( boot_cpu_has(X86_FEATURE_CONSTANT_TSC) && + boot_cpu_has(X86_FEATURE_NONSTOP_TSC) ) ) + { + tsc_reliable = 1; + } + else if ( boot_cpu_has(X86_FEATURE_CONSTANT_TSC) ) + { + tsc_reliable = (max_cstate <= 2); + + if (tsc_reliable) + printk("TSC: no deep Cstates, deemed reliable\n"); + else + printk("TSC: deep Cstates possible, so not reliable\n"); + } + + pts->frequency = tsc_freq; + return ( clocksource_is_tsc = tsc_reliable ); +} + +static u64 read_tsc(void) +{ + return rdtsc(); +} + +static void resume_tsctimer(struct platform_timesource *pts) +{ +} + +static struct platform_timesource __initdata plt_tsc = +{ + .id = "tsc", + .name = "TSC", + .read_counter = read_tsc, + .counter_bits = 64, + .init = init_tsctimer, + .resume = resume_tsctimer, +}; + +/************************************************************ * GENERIC PLATFORM TIMER INFRASTRUCTURE */ @@ -537,7 +595,7 @@ static void resume_platform_timer(void) static void __init init_platform_timer(void) { static struct platform_timesource * __initdata plt_timers[] = { - &plt_hpet, &plt_pmtimer, &plt_pit + &plt_hpet, &plt_tsc, &plt_pmtimer, &plt_pit }; struct platform_timesource *pts = NULL; @@ -1174,7 +1232,7 @@ static void check_tsc_warp(unsigned long tsc_khz, unsigned long *max_warp) } } -static unsigned long tsc_max_warp, tsc_check_count; +static unsigned long tsc_check_count; static cpumask_t tsc_check_cpumask; static void tsc_check_slave(void *unused) @@ -1458,6 +1516,7 @@ void __init early_time_init(void) struct cpu_time *t = &this_cpu(cpu_time); u64 tmp = init_pit_and_calibrate_tsc(); + tsc_freq = tmp; set_time_scale(&t->tsc_scale, tmp); t->local_tsc_stamp = boot_tsc_stamp;