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

[Xen-changelog] [xen staging] x86/time: reduce rounding errors in calculations



commit a60bb682190f8c0147584fa58de47528cd866be3
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Mon Mar 16 17:31:35 2020 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Mon Mar 16 17:31:35 2020 +0100

    x86/time: reduce rounding errors in calculations
    
    Plain (unsigned) integer division simply truncates the results. The
    overall errors are smaller though if we use proper rounding. (Extend
    this to the purely cosmetic aspect of time.c's freq_string(), which
    before this change I've frequently observed to report e.g. NN.999MHz
    HPET clock speeds.)
    
    While adding the rounding logic, also switch to using an unsigned
    constant for the other, original half of bus_cycle's calculation.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 xen/arch/x86/apic.c | 4 +++-
 xen/arch/x86/hpet.c | 4 ++--
 xen/arch/x86/time.c | 5 ++++-
 3 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c
index dbea826d48..ab30de939c 100644
--- a/xen/arch/x86/apic.c
+++ b/xen/arch/x86/apic.c
@@ -1260,8 +1260,10 @@ static int __init calibrate_APIC_clock(void)
 
     /* set up multipliers for accurate timer code */
     bus_freq   = result*HZ;
-    bus_cycle  = (u32) (1000000000000LL/bus_freq); /* in pico seconds */
+    bus_cycle  = 1000000000000UL / bus_freq; /* in pico seconds */
+    bus_cycle += (1000000000000UL % bus_freq) * 2 > bus_freq;
     bus_scale  = (1000*262144)/bus_cycle;
+    bus_scale += ((1000 * 262144) % bus_cycle) * 2 > bus_cycle;
 
     apic_printk(APIC_VERBOSE, "..... bus_scale = %#x\n", bus_scale);
     /* reset APIC to zero timeout value */
diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c
index ae99993d90..86929b9ba1 100644
--- a/xen/arch/x86/hpet.c
+++ b/xen/arch/x86/hpet.c
@@ -799,9 +799,9 @@ u64 __init hpet_setup(void)
     hpet_resume(hpet_boot_cfg);
 
     hpet_rate = 1000000000000000ULL; /* 10^15 */
-    (void)do_div(hpet_rate, hpet_period);
+    last = do_div(hpet_rate, hpet_period);
 
-    return hpet_rate;
+    return hpet_rate + (last * 2 > hpet_period);
 }
 
 void hpet_resume(u32 *boot_cfg)
diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
index bb1b97787f..2d4430b283 100644
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -275,7 +275,10 @@ static char *freq_string(u64 freq)
 {
     static char s[20];
     unsigned int x, y;
-    y = (unsigned int)do_div(freq, 1000000) / 1000;
+
+    if ( do_div(freq, 1000) > 500 )
+        ++freq;
+    y = (unsigned int)do_div(freq, 1000);
     x = (unsigned int)freq;
     snprintf(s, sizeof(s), "%u.%03uMHz", x, y);
     return s;
--
generated by git-patchbot for /home/xen/git/xen.git#staging

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

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