Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 288798
b: refs/heads/master
c: b0e5c77
h: refs/heads/master
v: v3
  • Loading branch information
Suresh Siddha authored and Ingo Molnar committed Feb 22, 2012
1 parent bc81d11 commit cf50dcc
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 97ac984d2feec885d10f900591431088eab42021
refs/heads/master: b0e5c77903fd717cc5eb02b7b8f5de3c869efc49
29 changes: 24 additions & 5 deletions trunk/arch/x86/kernel/tsc_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ static __cpuinitdata int nr_warps;
/*
* TSC-warp measurement loop running on both CPUs:
*/
static __cpuinit void check_tsc_warp(void)
static __cpuinit void check_tsc_warp(unsigned int timeout)
{
cycles_t start, now, prev, end;
int i;
Expand All @@ -51,9 +51,9 @@ static __cpuinit void check_tsc_warp(void)
start = get_cycles();
rdtsc_barrier();
/*
* The measurement runs for 20 msecs:
* The measurement runs for 'timeout' msecs:
*/
end = start + tsc_khz * 20ULL;
end = start + (cycles_t) tsc_khz * timeout;
now = start;

for (i = 0; ; i++) {
Expand Down Expand Up @@ -98,6 +98,25 @@ static __cpuinit void check_tsc_warp(void)
now-start, end-start);
}

/*
* If the target CPU coming online doesn't have any of its core-siblings
* online, a timeout of 20msec will be used for the TSC-warp measurement
* loop. Otherwise a smaller timeout of 2msec will be used, as we have some
* information about this socket already (and this information grows as we
* have more and more logical-siblings in that socket).
*
* Ideally we should be able to skip the TSC sync check on the other
* core-siblings, if the first logical CPU in a socket passed the sync test.
* But as the TSC is per-logical CPU and can potentially be modified wrongly
* by the bios, TSC sync test for smaller duration should be able
* to catch such errors. Also this will catch the condition where all the
* cores in the socket doesn't get reset at the same time.
*/
static inline unsigned int loop_timeout(int cpu)
{
return (cpumask_weight(cpu_core_mask(cpu)) > 1) ? 2 : 20;
}

/*
* Source CPU calls into this - it waits for the freshly booted
* target CPU to arrive and then starts the measurement:
Expand Down Expand Up @@ -135,7 +154,7 @@ void __cpuinit check_tsc_sync_source(int cpu)
*/
atomic_inc(&start_count);

check_tsc_warp();
check_tsc_warp(loop_timeout(cpu));

while (atomic_read(&stop_count) != cpus-1)
cpu_relax();
Expand Down Expand Up @@ -183,7 +202,7 @@ void __cpuinit check_tsc_sync_target(void)
while (atomic_read(&start_count) != cpus)
cpu_relax();

check_tsc_warp();
check_tsc_warp(loop_timeout(smp_processor_id()));

/*
* Ok, we are done:
Expand Down

0 comments on commit cf50dcc

Please sign in to comment.