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@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
Jan Beulich committed 2020-03-16 17:31:35 +01:00
1 parent 6b7860b5d0
commit a60bb68219
3 files changed
+9 -4

No files matched your search

+3 -1
View File
@@ -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 */
+2 -2
View File
@@ -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)
+4 -1
View File
@@ -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;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.