[PATCH] synchronize_tsc() fixes
- Move the tsc synchronisation variables into a struct, mark it __initdata - local `realdelta' wants to be 64-bit - Print the skew for negative skews, as well as for positive ones - remove dead code Cc: john stultz <johnstul@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
851f8a6906
commit
c35a7261ea
|
@ -212,14 +212,20 @@ valid_k7:
|
||||||
* then we print a warning if not, and always resync.
|
* then we print a warning if not, and always resync.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static atomic_t tsc_start_flag = ATOMIC_INIT(0);
|
static struct {
|
||||||
static atomic_t tsc_count_start = ATOMIC_INIT(0);
|
atomic_t start_flag;
|
||||||
static atomic_t tsc_count_stop = ATOMIC_INIT(0);
|
atomic_t count_start;
|
||||||
static unsigned long long tsc_values[NR_CPUS];
|
atomic_t count_stop;
|
||||||
|
unsigned long long values[NR_CPUS];
|
||||||
|
} tsc __initdata = {
|
||||||
|
.start_flag = ATOMIC_INIT(0),
|
||||||
|
.count_start = ATOMIC_INIT(0),
|
||||||
|
.count_stop = ATOMIC_INIT(0),
|
||||||
|
};
|
||||||
|
|
||||||
#define NR_LOOPS 5
|
#define NR_LOOPS 5
|
||||||
|
|
||||||
static void __init synchronize_tsc_bp (void)
|
static void __init synchronize_tsc_bp(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned long long t0;
|
unsigned long long t0;
|
||||||
|
@ -233,7 +239,7 @@ static void __init synchronize_tsc_bp (void)
|
||||||
/* convert from kcyc/sec to cyc/usec */
|
/* convert from kcyc/sec to cyc/usec */
|
||||||
one_usec = cpu_khz / 1000;
|
one_usec = cpu_khz / 1000;
|
||||||
|
|
||||||
atomic_set(&tsc_start_flag, 1);
|
atomic_set(&tsc.start_flag, 1);
|
||||||
wmb();
|
wmb();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -250,16 +256,16 @@ static void __init synchronize_tsc_bp (void)
|
||||||
/*
|
/*
|
||||||
* all APs synchronize but they loop on '== num_cpus'
|
* all APs synchronize but they loop on '== num_cpus'
|
||||||
*/
|
*/
|
||||||
while (atomic_read(&tsc_count_start) != num_booting_cpus()-1)
|
while (atomic_read(&tsc.count_start) != num_booting_cpus()-1)
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
atomic_set(&tsc_count_stop, 0);
|
atomic_set(&tsc.count_stop, 0);
|
||||||
wmb();
|
wmb();
|
||||||
/*
|
/*
|
||||||
* this lets the APs save their current TSC:
|
* this lets the APs save their current TSC:
|
||||||
*/
|
*/
|
||||||
atomic_inc(&tsc_count_start);
|
atomic_inc(&tsc.count_start);
|
||||||
|
|
||||||
rdtscll(tsc_values[smp_processor_id()]);
|
rdtscll(tsc.values[smp_processor_id()]);
|
||||||
/*
|
/*
|
||||||
* We clear the TSC in the last loop:
|
* We clear the TSC in the last loop:
|
||||||
*/
|
*/
|
||||||
|
@ -269,56 +275,54 @@ static void __init synchronize_tsc_bp (void)
|
||||||
/*
|
/*
|
||||||
* Wait for all APs to leave the synchronization point:
|
* Wait for all APs to leave the synchronization point:
|
||||||
*/
|
*/
|
||||||
while (atomic_read(&tsc_count_stop) != num_booting_cpus()-1)
|
while (atomic_read(&tsc.count_stop) != num_booting_cpus()-1)
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
atomic_set(&tsc_count_start, 0);
|
atomic_set(&tsc.count_start, 0);
|
||||||
wmb();
|
wmb();
|
||||||
atomic_inc(&tsc_count_stop);
|
atomic_inc(&tsc.count_stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
sum = 0;
|
sum = 0;
|
||||||
for (i = 0; i < NR_CPUS; i++) {
|
for (i = 0; i < NR_CPUS; i++) {
|
||||||
if (cpu_isset(i, cpu_callout_map)) {
|
if (cpu_isset(i, cpu_callout_map)) {
|
||||||
t0 = tsc_values[i];
|
t0 = tsc.values[i];
|
||||||
sum += t0;
|
sum += t0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
avg = sum;
|
avg = sum;
|
||||||
do_div(avg, num_booting_cpus());
|
do_div(avg, num_booting_cpus());
|
||||||
|
|
||||||
sum = 0;
|
|
||||||
for (i = 0; i < NR_CPUS; i++) {
|
for (i = 0; i < NR_CPUS; i++) {
|
||||||
if (!cpu_isset(i, cpu_callout_map))
|
if (!cpu_isset(i, cpu_callout_map))
|
||||||
continue;
|
continue;
|
||||||
delta = tsc_values[i] - avg;
|
delta = tsc.values[i] - avg;
|
||||||
if (delta < 0)
|
if (delta < 0)
|
||||||
delta = -delta;
|
delta = -delta;
|
||||||
/*
|
/*
|
||||||
* We report bigger than 2 microseconds clock differences.
|
* We report bigger than 2 microseconds clock differences.
|
||||||
*/
|
*/
|
||||||
if (delta > 2*one_usec) {
|
if (delta > 2*one_usec) {
|
||||||
long realdelta;
|
long long realdelta;
|
||||||
|
|
||||||
if (!buggy) {
|
if (!buggy) {
|
||||||
buggy = 1;
|
buggy = 1;
|
||||||
printk("\n");
|
printk("\n");
|
||||||
}
|
}
|
||||||
realdelta = delta;
|
realdelta = delta;
|
||||||
do_div(realdelta, one_usec);
|
do_div(realdelta, one_usec);
|
||||||
if (tsc_values[i] < avg)
|
if (tsc.values[i] < avg)
|
||||||
realdelta = -realdelta;
|
realdelta = -realdelta;
|
||||||
|
|
||||||
if (realdelta > 0)
|
if (realdelta)
|
||||||
printk(KERN_INFO "CPU#%d had %ld usecs TSC "
|
printk(KERN_INFO "CPU#%d had %Ld usecs TSC "
|
||||||
"skew, fixed it up.\n", i, realdelta);
|
"skew, fixed it up.\n", i, realdelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
sum += delta;
|
|
||||||
}
|
}
|
||||||
if (!buggy)
|
if (!buggy)
|
||||||
printk("passed.\n");
|
printk("passed.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init synchronize_tsc_ap (void)
|
static void __init synchronize_tsc_ap(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -327,20 +331,20 @@ static void __init synchronize_tsc_ap (void)
|
||||||
* this gets called, so we first wait for the BP to
|
* this gets called, so we first wait for the BP to
|
||||||
* finish SMP initialization:
|
* finish SMP initialization:
|
||||||
*/
|
*/
|
||||||
while (!atomic_read(&tsc_start_flag))
|
while (!atomic_read(&tsc.start_flag))
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
|
|
||||||
for (i = 0; i < NR_LOOPS; i++) {
|
for (i = 0; i < NR_LOOPS; i++) {
|
||||||
atomic_inc(&tsc_count_start);
|
atomic_inc(&tsc.count_start);
|
||||||
while (atomic_read(&tsc_count_start) != num_booting_cpus())
|
while (atomic_read(&tsc.count_start) != num_booting_cpus())
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
|
|
||||||
rdtscll(tsc_values[smp_processor_id()]);
|
rdtscll(tsc.values[smp_processor_id()]);
|
||||||
if (i == NR_LOOPS-1)
|
if (i == NR_LOOPS-1)
|
||||||
write_tsc(0, 0);
|
write_tsc(0, 0);
|
||||||
|
|
||||||
atomic_inc(&tsc_count_stop);
|
atomic_inc(&tsc.count_stop);
|
||||||
while (atomic_read(&tsc_count_stop) != num_booting_cpus())
|
while (atomic_read(&tsc.count_stop) != num_booting_cpus())
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue