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

[xen stable-4.15] x86/time: use relative counts in calibration loops



commit 793d5ca89fdd9e2cdcb05e88c6cd8446e475b15a
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Tue Jan 25 13:44:42 2022 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Jan 25 13:44:42 2022 +0100

    x86/time: use relative counts in calibration loops
    
    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>
    Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
    master commit: 467191641d2a2fd2e43b3ae7b80399f89d339980
    master date: 2022-01-13 14:30:18 +0100
---
 xen/arch/x86/time.c | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
index 6bc1fd11d6..719dc38c7b 100644
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -376,7 +376,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;
 
     if ( hpet_address && strcmp(opt_clocksource, pts->id) &&
          cpuidle_using_deep_cstate() )
@@ -414,11 +414,8 @@ static int64_t __init init_hpet(struct platform_timesource 
*pts)
 
     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;
@@ -456,8 +453,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;
@@ -465,13 +462,10 @@ static s64 __init init_pmtimer(struct platform_timesource 
*pts)
     pts->counter_bits = pmtmr_width;
     mask = 0xffffffff >> (32 - pmtmr_width);
 
-    count = inl(pmtmr_ioport) & mask;
+    count = inl(pmtmr_ioport);
     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) - count) & mask) < target )
         continue;
 
     return (rdtsc_ordered() - start) * CALIBRATE_FRAC;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.15



 


Rackspace

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