From patchwork Mon Jan 24 08:26:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 12721655 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 43491C433F5 for ; Mon, 24 Jan 2022 08:26:59 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.259735.448235 (Exim 4.92) (envelope-from ) id 1nBugZ-0001Mu-IO; Mon, 24 Jan 2022 08:26:47 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 259735.448235; Mon, 24 Jan 2022 08:26:47 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nBugZ-0001Mn-FC; Mon, 24 Jan 2022 08:26:47 +0000 Received: by outflank-mailman (input) for mailman id 259735; Mon, 24 Jan 2022 08:26:45 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nBugX-0001Me-NV for xen-devel@lists.xenproject.org; Mon, 24 Jan 2022 08:26:45 +0000 Received: from de-smtp-delivery-102.mimecast.com (de-smtp-delivery-102.mimecast.com [194.104.109.102]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 5d1f0baa-7cef-11ec-8fa7-f31e035a9116; Mon, 24 Jan 2022 09:26:44 +0100 (CET) Received: from EUR03-AM5-obe.outbound.protection.outlook.com (mail-am5eur03lp2057.outbound.protection.outlook.com [104.47.8.57]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id de-mta-25-I5i16AvjNoCmc-t5nOJ-EA-1; Mon, 24 Jan 2022 09:26:43 +0100 Received: from VI1PR04MB5600.eurprd04.prod.outlook.com (2603:10a6:803:e7::16) by DBBPR04MB7883.eurprd04.prod.outlook.com (2603:10a6:10:1e9::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4909.17; Mon, 24 Jan 2022 08:26:42 +0000 Received: from VI1PR04MB5600.eurprd04.prod.outlook.com ([fe80::5951:a489:1cf0:19fe]) by VI1PR04MB5600.eurprd04.prod.outlook.com ([fe80::5951:a489:1cf0:19fe%6]) with mapi id 15.20.4909.017; Mon, 24 Jan 2022 08:26:42 +0000 X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 5d1f0baa-7cef-11ec-8fa7-f31e035a9116 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=mimecast20200619; t=1643012804; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=jCxscIvq6zLulNKcY3/NWbd2vQ3CrupkD38ZmXXmcn4=; b=HN0hRmA14MVo2DTQzISJTY0T3R+bQOPbGZZosJtfYUgzyOXC3IHfail6D6j+d19eRwL8CH OhBIhOmacAqSpkOWctgbcZ74Qkgawr/BHWcytUoYxsCWvRON7IWJu6oBzaQ0lXYli9je2x m5wtvRZqz5rBOJF5CFNE7lSBHuNh+kc= X-MC-Unique: I5i16AvjNoCmc-t5nOJ-EA-1 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=UdaXG49nSwNhZQ6t0hhqLxCiBJtHlTE+FrlM2zvz69qhhnNTZ1kEfC5wWEJFDdzAgZUkBIkFOWubI5FlI2wHiAkCyGEvL1lzXor6zYI9gKDiXlJUYbe7wC7Tv1ZoJA48l08rrK6ugDLbRU11MPLHCqe0qKtB1I8PzfuDPpLV1q8sh5DE318ny7j7mli21G1VFHRaPdf6EOzxc8RXd1GLqBP3EIRI0ehqlD5wMvoxngKSe09OwCK18Y7H0+Xraafqo7PD7OtRlR2F5a9UPPkPZzOirCvJykPkIuXJ2bKr7ybbg09Pl90XEX3OHZfjtcN+wraQYc5LS3oYEJga1ZgeCg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=jCxscIvq6zLulNKcY3/NWbd2vQ3CrupkD38ZmXXmcn4=; b=MdZpHVMhraP5u85KQC3ijSjnCOgIAXTEfWvBB4yW5cAqxOMxV2panTgSHYwjeSCh8UZApVYec0MPGqFSKqJ6ef0gMlZw1jK4zzlUEWeb0xLaBA0Xpn/27YNjhUJz8Oi2vXhMbnfnoeMCM14/nJzXehr8vqDahE766cDHJ1wnouA8uND46FhofSkB6zAtYbeL/Zj/KHgBwljjAdFPl2ZJlSL/cRwYMtuSgTHYC+3oZW2SMNXAkLX8afLTEojEAtqm1cxrPsc6h2q305Q1F+KY45En0dL5xJUYUVS6nYT/9kAxqQ/nJKPXT0++yadreIci5+MvpYH0fWrQuwRdaPbmzQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=suse.com; Message-ID: <0ab22edc-bc06-4c52-8cd4-c7dd57746779@suse.com> Date: Mon, 24 Jan 2022 09:26:43 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.5.0 Subject: [PATCH v2 2/4] x86/APIC: calibrate against platform timer when possible Content-Language: en-US From: Jan Beulich To: "xen-devel@lists.xenproject.org" Cc: Andrew Cooper , Wei Liu , =?utf-8?q?Roger_Pau_Monn=C3=A9?= References: <879e5b70-bffd-b240-b2c8-c755b09d41a9@suse.com> In-Reply-To: <879e5b70-bffd-b240-b2c8-c755b09d41a9@suse.com> X-ClientProxiedBy: AM6P191CA0077.EURP191.PROD.OUTLOOK.COM (2603:10a6:209:8a::18) To VI1PR04MB5600.eurprd04.prod.outlook.com (2603:10a6:803:e7::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: c3c46a5c-72fb-4004-e411-08d9df133ff8 X-MS-TrafficTypeDiagnostic: DBBPR04MB7883:EE_ X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:5797; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: kIR1S95DfiauCMPUtHG/XBUnwyx9R0Y2EwnNkaEifUTV5cZ7e7t4gSI5sxwDlO5hKRzAVtE153LvTsn3JlT5EdEZyg1mprOwADyaBoa2dxuuKmeIXcx49W4iXdJI5Svcs/VGApetzPfN2juCamZb3IGp3/sPdFIuu2Ynn6nwCA3TIkDaDI++TWX6aYIx/bgYymsSNrBP10XXUEYRDKNrIrPg+InKKJ/Yj3KjSdSsBosVB8t3Adqom9ZYJtkZVyAXNyj2C9JYaOa3BU4r1nmu5Q8plBtnfRNjRKa208OhE9WKJZjzpldvUvi4nYkyklmoYO3JoWyqYOeR/K5D23cbyJuiuPq2zb8KZbT4hDILBXqbta1fzNQVIpQxCMS3eGuWGxaldvb920yKbwYPrNobT09FcTA2I9+XfKmz+IYrDefri0lzZkmbcbMZqdtINCqyX/PC60gmSaYCZu7NC3lLPLE0xJkUkGzkqwGLWjMz+9tUqhEWnxRlVjhhMRf8MP/6dq3LTSjlpv//15fUEiiN4J49AhnjeYuAwnWXudy/USYG2ORKZMfXaZi6OlK524DhKNyx5ZDo7qZUr9Hr5BRQNnGnUIE2IB7jMyu3VHn2oyjtoOjjXsVccxumd+Mc1HTfP2670wN7kl5lStvtb9p+667CPGOd+Lt+O3lVYLjQZQBbWtlai0et8VtV++WjNFrmfADdJ2DNhGa5Kmy9nikIyMBTq50DZKYkquSzUlEMYGM= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:VI1PR04MB5600.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(366004)(2616005)(36756003)(38100700002)(54906003)(4326008)(83380400001)(86362001)(66946007)(6916009)(8676002)(31686004)(316002)(31696002)(5660300002)(6512007)(26005)(508600001)(66476007)(2906002)(66556008)(6486002)(186003)(6506007)(8936002)(43740500002)(45980500001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?65ymQNsbcKOo/BZ5DOaD9C/vmUKt?= =?utf-8?q?9Ztex6T8NsvYbuygpPqgkq2lODOHM87kIZW4wPYNxSx6fWs1wNN7Lgel6cEsVrxKY?= =?utf-8?q?NlfBkmikG2ksAVErh7xPh+enUO8fniKAeWn93aJC+siWwQxdRZI/oM5EiURkVkIEz?= =?utf-8?q?kzE0NusNugizAmGjJDVOJesuOxd36kU/MKT7UgipvJ9PmeZ5ZWkxERLhxP1t/QGnE?= =?utf-8?q?5Q84ZHbNDwAq6YdJ8FTIyHM3fyEbGi1c+0r+KrFvb/elgPNz1ga1E4o1+tYEFr3mH?= =?utf-8?q?ry1rxBEwHiQp67V04nrC6UovdiTuBQhgKJcPijsm4LitxUvCtid9F68xF3JKJmfmk?= =?utf-8?q?GvncpBBdPCxCysfdPmNABt3p4kLsx6tOHo/CSMLjd6R5KzqEwUHMF5DR+ql+9btNM?= =?utf-8?q?Wh5MZSiwIq/ALePq7rw6QnAnu33La6Bi6PRXHii5whu0BVRH/mELD11myfcY1hA2Z?= =?utf-8?q?58aOVutFRF4vVx/9E2lhZ18v8M1SHM4hsM1q9VFYrNCbHtKV+BuaiuF1AwkAcnG/C?= =?utf-8?q?qxBkFFGt0q+iBuDnCAVVqahMw85hJxqwvoix6VIdgeqqXaBWVwfeUZbjZTD4dxBeK?= =?utf-8?q?4NHP3+QedrHFtsVKBWtbFycwxy+25f4WoK8ohKdOMl8rGeBRg9q6CH1Yv3JHDuaxc?= =?utf-8?q?92lfJEP1N8XzQ+vdR8yAxg0hv7l+OvkW1e7UH9nFYxy5iRuRUFRO/e2PtqkhIKQwy?= =?utf-8?q?w444UbxBX2xaSpt6+iq0go7x3hmtaPpQaO6cKdGnSHqLZvj23ro/sgO9BU9diYdVp?= =?utf-8?q?7T0a9K3Re7J0svOI3tN6w8feDBVI9G8XQaJjVlhqR960co+mSABGG3584d2DrNS+H?= =?utf-8?q?dyyDeLx36ILOOW+mlhzoXAqVZ1gK53fS207JWhRKcq5VRvoYGqm3IyYa4ADdCjG4R?= =?utf-8?q?l9znNa0RmYc9ZHzGQjKLtmnINgy74BupDnbxYAm+5M+/3A5dtGsNqzBACCGQAiWLg?= =?utf-8?q?/h+ksOkUqNtnvU36gNUu9YWuvSDmTvVBRrXMzU7ZGT/uAxxEhF1jG/9ip1CI5UDaV?= =?utf-8?q?13ckxgt2JZV0k9oqLZOjRkgf/Ub6v1aID5pGnc/gCkAn7q6WkYJwQfDGhyCTE5xzD?= =?utf-8?q?I0Z+NFRUf+8cempmDRdUkZDQCLTGBDhKifUpyHV5SuefBZUDSut+JuanDRxRUkFrB?= =?utf-8?q?z1t4z3P9nr7tXBMyK2kYO1g0+uhsnqxB1l2TQa9dH+ogd1zjTLqnIFMifxOrQlsmD?= =?utf-8?q?ocMzw9N78UxHNRIlng2CuQPJK9johWfLr+E6ry7pxs/y/7RqNaoPiA2fLEyq4GoxZ?= =?utf-8?q?ndiqRfyzMUpmi1h+IwPLF67NA9KxRmOcr/wV5eYTLXBSYdQ639bRdkT28t+XS0ZzL?= =?utf-8?q?sqU5qP8OvTMo5QAbPkrIWmfD5HIE1rLkyul8sZqvq0YkvKI8yFT9Ll1l1u9q6VXaE?= =?utf-8?q?RxfpIcGt2HsQfbKxM9Jq1UWWecdOk8AryjsFdVKOiAr5LfKVH8m6IZNhqKodocIzQ?= =?utf-8?q?avmpm06Vca79LjmcdQi8VI27IdT7btGUfu1iJUZdAvr5n1etotEbYUugfa8TM1l8n?= =?utf-8?q?4ji0THDtCwEHDF6VSCxT3odTd7U4fhtEVu53VnRM+qUUkZd/UwrtaX0=3D?= X-OriginatorOrg: suse.com X-MS-Exchange-CrossTenant-Network-Message-Id: c3c46a5c-72fb-4004-e411-08d9df133ff8 X-MS-Exchange-CrossTenant-AuthSource: VI1PR04MB5600.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Jan 2022 08:26:42.1463 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f7a17af6-1c5c-4a36-aa8b-f5be247aa4ba X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: wiiV6bjMJvu4qdgLAcW2h85PTwqjNvUzCHICSQOgFUlhg7Xz2to3PMzecEE6C7HAHKY/SdEETslr35gKUie6WA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBBPR04MB7883 Use the original calibration against PIT only when the platform timer is PIT. This implicitly excludes the "xen_guest" case from using the PIT logic (init_pit() fails there, and as of 5e73b2594c54 ["x86/time: minor adjustments to init_pit()"] using_pit also isn't being set too early anymore), so the respective hack there can be dropped at the same time. This also reduces calibration time from 100ms to 50ms, albeit this step is being skipped as of 0731a56c7c72 ("x86/APIC: no need for timer calibration when using TDT") anyway. While re-indenting the PIT logic in calibrate_APIC_clock(), besides adjusting style also switch around the 2nd TSC/TMCCT read pair, to match the order of the 1st one, yielding more consistent deltas. Signed-off-by: Jan Beulich --- Open-coding apic_read() in read_tmcct() isn't overly nice, but I wanted to avoid x2apic_enabled being evaluated twice in close succession. (The barrier is there just in case only anyway: While this RDMSR isn't serializing, I'm unaware of any statement whether it can also be executed speculatively, like RDTSC can.) An option might be to move the function to apic.c such that it would also be used by calibrate_APIC_clock(). Unlike the CPU frequencies enumerated in CPUID leaf 0x16 (which aren't precise), using CPUID[0x15].ECX - if populated - may be an option to skip calibration altogether. Iirc the value there is precise, but using the systems I have easy access to I cannot verify this: In the sample of three I have, none have ECX populated. I wonder whether the secondary CPU freq measurement (used for display purposes only) wouldn't better be dropped at this occasion. --- v2: New. --- a/xen/arch/x86/apic.c +++ b/xen/arch/x86/apic.c @@ -1182,20 +1182,6 @@ static void __init check_deadline_errata "please update microcode to version %#x (or later)\n", rev); } -static void __init wait_tick_pvh(void) -{ - u64 lapse_ns = 1000000000ULL / HZ; - s_time_t start, curr_time; - - start = NOW(); - - /* Won't wrap around */ - do { - cpu_relax(); - curr_time = NOW(); - } while ( curr_time - start < lapse_ns ); -} - /* * In this function we calibrate APIC bus clocks to the external * timer. Unfortunately we cannot use jiffies and the timer irq @@ -1211,9 +1197,6 @@ static void __init wait_tick_pvh(void) static void __init calibrate_APIC_clock(void) { - unsigned long long t1, t2; - unsigned long tt1, tt2; - unsigned int i; unsigned long bus_freq; /* KAF: pointer-size avoids compile warns. */ unsigned int bus_cycle; /* length of one bus cycle in pico-seconds */ #define LOOPS_FRAC 10U /* measure for one tenth of a second */ @@ -1226,39 +1209,38 @@ static void __init calibrate_APIC_clock( */ __setup_APIC_LVTT(0xffffffff); - if ( !xen_guest ) + bus_freq = calibrate_apic_timer(); + if ( !bus_freq ) + { + unsigned int i, tt1, tt2; + unsigned long t1, t2; + + ASSERT(!xen_guest); + /* - * The timer chip counts down to zero. Let's wait - * for a wraparound to start exact measurement: - * (the current tick might have been already half done) + * The timer chip counts down to zero. Let's wait for a wraparound to + * start exact measurement (the current tick might have been already + * half done): */ wait_8254_wraparound(); - else - wait_tick_pvh(); - /* - * We wrapped around just now. Let's start: - */ - t1 = rdtsc_ordered(); - tt1 = apic_read(APIC_TMCCT); + /* We wrapped around just now. Let's start: */ + t1 = rdtsc_ordered(); + tt1 = apic_read(APIC_TMCCT); - /* - * Let's wait HZ / LOOPS_FRAC ticks: - */ - for (i = 0; i < HZ / LOOPS_FRAC; i++) - if ( !xen_guest ) + /* Let's wait HZ / LOOPS_FRAC ticks: */ + for ( i = 0; i < HZ / LOOPS_FRAC; ++i ) wait_8254_wraparound(); - else - wait_tick_pvh(); - tt2 = apic_read(APIC_TMCCT); - t2 = rdtsc_ordered(); + t2 = rdtsc_ordered(); + tt2 = apic_read(APIC_TMCCT); - bus_freq = (tt1 - tt2) * APIC_DIVISOR * LOOPS_FRAC; + bus_freq = (tt1 - tt2) * APIC_DIVISOR * LOOPS_FRAC; - apic_printk(APIC_VERBOSE, "..... CPU clock speed is %lu.%04lu MHz.\n", - ((unsigned long)(t2 - t1) * LOOPS_FRAC) / 1000000, - (((unsigned long)(t2 - t1) * LOOPS_FRAC) / 100) % 10000); + apic_printk(APIC_VERBOSE, "..... CPU clock speed is %lu.%04lu MHz.\n", + ((t2 - t1) * LOOPS_FRAC) / 1000000, + (((t2 - t1) * LOOPS_FRAC) / 100) % 10000); + } apic_printk(APIC_VERBOSE, "..... host bus clock speed is %ld.%04ld MHz.\n", bus_freq / 1000000, (bus_freq / 100) % 10000); --- a/xen/arch/x86/include/asm/apic.h +++ b/xen/arch/x86/include/asm/apic.h @@ -192,6 +192,8 @@ extern void record_boot_APIC_mode(void); extern enum apic_mode current_local_apic_mode(void); extern void check_for_unexpected_msi(unsigned int vector); +uint64_t calibrate_apic_timer(void); + extern void check_nmi_watchdog(void); extern unsigned int nmi_watchdog; --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -1004,6 +1005,78 @@ static u64 __init init_platform_timer(vo return rc; } +static uint32_t __init read_tmcct(void) +{ + if ( x2apic_enabled ) + { + alternative("lfence", "mfence", X86_FEATURE_MFENCE_RDTSC); + return apic_rdmsr(APIC_TMCCT); + } + + return apic_mem_read(APIC_TMCCT); +} + +static uint64_t __init read_pt_and_tmcct(uint32_t *tmcct) +{ + uint32_t tmcct_prev = *tmcct = read_tmcct(), tmcct_min = ~0; + uint64_t best = best; + unsigned int i; + + for ( i = 0; ; ++i ) + { + uint64_t pt = plt_src.read_counter(); + uint32_t tmcct_cur = read_tmcct(); + uint32_t tmcct_delta = tmcct_prev - tmcct_cur; + + if ( tmcct_delta < tmcct_min ) + { + tmcct_min = tmcct_delta; + *tmcct = tmcct_cur; + best = pt; + } + else if ( i > 2 ) + break; + + tmcct_prev = tmcct_cur; + } + + return best; +} + +uint64_t __init calibrate_apic_timer(void) +{ + uint32_t start, end; + uint64_t count = read_pt_and_tmcct(&start), elapsed; + uint64_t target = CALIBRATE_VALUE(plt_src.frequency), actual; + uint64_t mask = (uint64_t)~0 >> (64 - plt_src.counter_bits); + + /* + * PIT cannot be used here as it requires the timer interrupt to maintain + * its 32-bit software counter, yet here we run with IRQs disabled. + */ + if ( using_pit ) + return 0; + + while ( ((plt_src.read_counter() - count) & mask) < target ) + continue; + + actual = read_pt_and_tmcct(&end) - count; + elapsed = start - end; + + if ( likely(actual > target) ) + { + /* See the comment in calibrate_tsc(). */ + while ( unlikely(actual > (uint32_t)actual) ) + { + actual >>= 1; + target >>= 1; + } + elapsed = muldiv64(elapsed, target, actual); + } + + return elapsed * CALIBRATE_FRAC; +} + u64 stime2tsc(s_time_t stime) { struct cpu_time *t;