x86/time: avoid reading the platform timer in rendezvous functions

Reading the platform timer isn't cheap, so we'd better avoid it when the
resulting value is of no interest to anyone.

The consumer of master_stime, obtained by
time_calibration_{std,tsc}_rendezvous() and propagated through
this_cpu(cpu_calibration), is local_time_calibration(). With
CONSTANT_TSC the latter function uses an early exit path, which doesn't
explicitly use the field. While this_cpu(cpu_calibration) (including the
master_stime field) gets propagated to this_cpu(cpu_time).stamp on that
path, both structures' fields get consumed only by the !CONSTANT_TSC
logic of the function.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Roger Pau Monné <roger.pau@citrix.com>
This commit is contained in:
Jan Beulich committed 2021-05-04 10:49:59 +02:00
1 parent 075926410e
commit 48bb237fca
1 file changed
+7 -3
+7 -3
View File
@@ -52,6 +52,7 @@ unsigned long pit0_ticks;
struct cpu_time_stamp {
u64 local_tsc;
s_time_t local_stime;
/* Next field unconditionally valid only when !CONSTANT_TSC. */
s_time_t master_stime;
};
@@ -1702,7 +1703,7 @@ static void time_calibration_tsc_rendezvous(void *_r)
* iteration.
*/
r->master_tsc_stamp = r->max_tsc_stamp;
else if ( i == 0 )
else if ( !boot_cpu_has(X86_FEATURE_CONSTANT_TSC) && i == 0 )
r->master_stime = read_platform_stime(NULL);
atomic_inc(&r->semaphore);
@@ -1776,8 +1777,11 @@ static void time_calibration_std_rendezvous(void *_r)
{
while ( atomic_read(&r->semaphore) != (total_cpus - 1) )
cpu_relax();
r->master_stime = read_platform_stime(NULL);
smp_wmb(); /* write r->master_stime /then/ signal */
if ( !boot_cpu_has(X86_FEATURE_CONSTANT_TSC) )
{
r->master_stime = read_platform_stime(NULL);
smp_wmb(); /* write r->master_stime /then/ signal */
}
atomic_inc(&r->semaphore);
}
else
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.