[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/2] x86/time: use relative counts in calibration loops


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Wed, 12 Jan 2022 09:55:17 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=suse.com; dmarc=pass action=none header.from=suse.com; dkim=pass header.d=suse.com; arc=none
  • 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=wxh9IDBUC18qTBjUbBaFY6EpgeSBeQZi1rjPikAJ6H0=; b=NVi5BzrFbF0CenDYt7fvIi7aYfWkMLe52X826PC0kMYcRxEA0ZQ1upDUzRhJkcu8n8XFp586xmF2y9UGMQ2X0iauvQipwIotlf8BmkgKa5Mpi5i9sq6dxjvYItqBXB4D5m59bdaND8WYerbktO/txhqt+Bt4LcrX8T0oq6cycqsCuGE9N6fX4hapzRb+q+8uQIFm/W3NIx10UiK7NItSmHtBeYZ5MbTZegICC/16o3HU3nb7I6iztIznjbk4xC1WZw7/Jb1ThWYyJgNHOjL/LtWYzXa6vXhGBPxMouv12OP8FmBSrRX3cWHgZ/X/gQyECJXxWF/O2ONXnheMcMIqeA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=lMsmSVviw7eC0ArQ1pfS5UaY7FtzzUCD3PM4HCIojZ8oc85dllixiF1WKvRsHIxeKJK9ghZPIOMxMAxA1i3pmAO6+aNIljhqzLgxI5hzyMbGp5jaMfZpZ4Ln8fn8qM+2NzhYgbe4fQvO0roxWtJaqqZepWNeeF56LCBLe9U2GAv7cO18lKEE8K5HIfAdVmIPKV5ve1A7YDKuXOK7Z5WHM72W11BjAuIgmg0RrQOyycgZQDYvZsdJcDyPjJECs52T4CUdwSpyTjOGPIX2FFf4nu9TWOWW6WHHMUqkmNQov2HaKaFNbb61yWGIDxLEY3nf0ROyBNhdQ4PvqMUWyS+fqQ==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=suse.com;
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Delivery-date: Wed, 12 Jan 2022 08:55:29 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Looping until reaching/exceeding a certain value is error prone: If the
target value is close enough to the wrapping point, the loop may not
terminate at all. Switch to using delta values, which then allows to
fold the two loops each into just one.

Fixes: 93340297802b ("x86/time: calibrate TSC against platform timer")
Reported-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>

--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -378,7 +378,7 @@ static u64 read_hpet_count(void)
 static int64_t __init init_hpet(struct platform_timesource *pts)
 {
     uint64_t hpet_rate, start;
-    uint32_t count, target;
+    uint32_t count, target, elapsed;
     /*
      * Allow HPET to be setup, but report a frequency of 0 so it's not selected
      * as a timer source. This is required so it can be used in legacy
@@ -451,11 +451,8 @@ static int64_t __init init_hpet(struct p
 
     count = hpet_read32(HPET_COUNTER);
     start = rdtsc_ordered();
-    target = count + CALIBRATE_VALUE(hpet_rate);
-    if ( target < count )
-        while ( hpet_read32(HPET_COUNTER) >= count )
-            continue;
-    while ( hpet_read32(HPET_COUNTER) < target )
+    target = CALIBRATE_VALUE(hpet_rate);
+    while ( (elapsed = hpet_read32(HPET_COUNTER) - count) < target )
         continue;
 
     return (rdtsc_ordered() - start) * CALIBRATE_FRAC;
@@ -493,8 +490,8 @@ static u64 read_pmtimer_count(void)
 
 static s64 __init init_pmtimer(struct platform_timesource *pts)
 {
-    u64 start;
-    u32 count, target, mask;
+    uint64_t start;
+    uint32_t count, target, mask, elapsed;
 
     if ( !pmtmr_ioport || (pmtmr_width != 24 && pmtmr_width != 32) )
         return 0;
@@ -504,11 +501,8 @@ static s64 __init init_pmtimer(struct pl
 
     count = inl(pmtmr_ioport) & mask;
     start = rdtsc_ordered();
-    target = count + CALIBRATE_VALUE(ACPI_PM_FREQUENCY);
-    if ( target < count )
-        while ( (inl(pmtmr_ioport) & mask) >= count )
-            continue;
-    while ( (inl(pmtmr_ioport) & mask) < target )
+    target = CALIBRATE_VALUE(ACPI_PM_FREQUENCY);
+    while ( (elapsed = (inl(pmtmr_ioport) & mask) - count) < target )
         continue;
 
     return (rdtsc_ordered() - start) * CALIBRATE_FRAC;




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.