Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 32922
b: refs/heads/master
c: c35a726
h: refs/heads/master
v: v3
  • Loading branch information
Andrew Morton authored and Linus Torvalds committed Jul 31, 2006
1 parent bf4c194 commit 81e125a
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 30 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: 851f8a6906b71f7a19043d4d722dd4ffab7aeafc
refs/heads/master: c35a7261eaf0e57924e2c56c6d72dc44ee9f3634
62 changes: 33 additions & 29 deletions trunk/arch/i386/kernel/smpboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,14 +212,20 @@ static void __devinit smp_store_cpu_info(int id)
* then we print a warning if not, and always resync.
*/

static atomic_t tsc_start_flag = ATOMIC_INIT(0);
static atomic_t tsc_count_start = ATOMIC_INIT(0);
static atomic_t tsc_count_stop = ATOMIC_INIT(0);
static unsigned long long tsc_values[NR_CPUS];
static struct {
atomic_t start_flag;
atomic_t count_start;
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

static void __init synchronize_tsc_bp (void)
static void __init synchronize_tsc_bp(void)
{
int i;
unsigned long long t0;
Expand All @@ -233,7 +239,7 @@ static void __init synchronize_tsc_bp (void)
/* convert from kcyc/sec to cyc/usec */
one_usec = cpu_khz / 1000;

atomic_set(&tsc_start_flag, 1);
atomic_set(&tsc.start_flag, 1);
wmb();

/*
Expand All @@ -250,16 +256,16 @@ static void __init synchronize_tsc_bp (void)
/*
* 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();
atomic_set(&tsc_count_stop, 0);
atomic_set(&tsc.count_stop, 0);
wmb();
/*
* 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:
*/
Expand All @@ -269,56 +275,54 @@ static void __init synchronize_tsc_bp (void)
/*
* 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();
atomic_set(&tsc_count_start, 0);
atomic_set(&tsc.count_start, 0);
wmb();
atomic_inc(&tsc_count_stop);
atomic_inc(&tsc.count_stop);
}

sum = 0;
for (i = 0; i < NR_CPUS; i++) {
if (cpu_isset(i, cpu_callout_map)) {
t0 = tsc_values[i];
t0 = tsc.values[i];
sum += t0;
}
}
avg = sum;
do_div(avg, num_booting_cpus());

sum = 0;
for (i = 0; i < NR_CPUS; i++) {
if (!cpu_isset(i, cpu_callout_map))
continue;
delta = tsc_values[i] - avg;
delta = tsc.values[i] - avg;
if (delta < 0)
delta = -delta;
/*
* We report bigger than 2 microseconds clock differences.
*/
if (delta > 2*one_usec) {
long realdelta;
long long realdelta;

if (!buggy) {
buggy = 1;
printk("\n");
}
realdelta = delta;
do_div(realdelta, one_usec);
if (tsc_values[i] < avg)
if (tsc.values[i] < avg)
realdelta = -realdelta;

if (realdelta > 0)
printk(KERN_INFO "CPU#%d had %ld usecs TSC "
if (realdelta)
printk(KERN_INFO "CPU#%d had %Ld usecs TSC "
"skew, fixed it up.\n", i, realdelta);
}

sum += delta;
}
if (!buggy)
printk("passed.\n");
}

static void __init synchronize_tsc_ap (void)
static void __init synchronize_tsc_ap(void)
{
int i;

Expand All @@ -327,20 +331,20 @@ static void __init synchronize_tsc_ap (void)
* this gets called, so we first wait for the BP to
* finish SMP initialization:
*/
while (!atomic_read(&tsc_start_flag))
while (!atomic_read(&tsc.start_flag))
cpu_relax();

for (i = 0; i < NR_LOOPS; i++) {
atomic_inc(&tsc_count_start);
while (atomic_read(&tsc_count_start) != num_booting_cpus())
atomic_inc(&tsc.count_start);
while (atomic_read(&tsc.count_start) != num_booting_cpus())
cpu_relax();

rdtscll(tsc_values[smp_processor_id()]);
rdtscll(tsc.values[smp_processor_id()]);
if (i == NR_LOOPS-1)
write_tsc(0, 0);

atomic_inc(&tsc_count_stop);
while (atomic_read(&tsc_count_stop) != num_booting_cpus())
atomic_inc(&tsc.count_stop);
while (atomic_read(&tsc.count_stop) != num_booting_cpus())
cpu_relax();
}
}
Expand Down

0 comments on commit 81e125a

Please sign in to comment.