[PATCH] x86_64: Move the SMP time selection earlier

SMP time selection originally ran after all CPUs were brought up because
it needed to know the number of CPUs to decide if it needs an MP safe
timer or not.

This is not needed anymore because we know present CPUs early.

This fixes a couple of problems:
 - apicmaintimer didn't always work because it relied on state that was
   set up time_init_gtod too late.
 - The output for the used timer in early kernel log was misleading
   because time_init_gtod could actually change it later.  Now always
   print the final timer choice

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Andi Kleen 2006-02-26 04:18:49 +01:00 committed by Linus Torvalds
parent e2c0388866
commit e8b917775b
3 changed files with 11 additions and 14 deletions

View File

@ -1152,8 +1152,6 @@ void __init smp_cpus_done(unsigned int max_cpus)
setup_ioapic_dest(); setup_ioapic_dest();
#endif #endif
time_init_gtod();
check_nmi_watchdog(); check_nmi_watchdog();
} }

View File

@ -48,6 +48,8 @@ static void cpufreq_delayed_get(void);
extern void i8254_timer_resume(void); extern void i8254_timer_resume(void);
extern int using_apic_timer; extern int using_apic_timer;
static char *time_init_gtod(void);
DEFINE_SPINLOCK(rtc_lock); DEFINE_SPINLOCK(rtc_lock);
DEFINE_SPINLOCK(i8253_lock); DEFINE_SPINLOCK(i8253_lock);
@ -901,6 +903,7 @@ static struct irqaction irq0 = {
void __init time_init(void) void __init time_init(void)
{ {
char *timename; char *timename;
char *gtod;
#ifdef HPET_HACK_ENABLE_DANGEROUS #ifdef HPET_HACK_ENABLE_DANGEROUS
if (!vxtime.hpet_address) { if (!vxtime.hpet_address) {
@ -945,21 +948,19 @@ void __init time_init(void)
timename = "PIT"; timename = "PIT";
} }
printk(KERN_INFO "time.c: Using %ld.%06ld MHz %s timer.\n", vxtime.mode = VXTIME_TSC;
vxtime_hz / 1000000, vxtime_hz % 1000000, timename); gtod = time_init_gtod();
printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n",
vxtime_hz / 1000000, vxtime_hz % 1000000, timename, gtod);
printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
cpu_khz / 1000, cpu_khz % 1000); cpu_khz / 1000, cpu_khz % 1000);
vxtime.mode = VXTIME_TSC;
vxtime.quot = (1000000L << 32) / vxtime_hz; vxtime.quot = (1000000L << 32) / vxtime_hz;
vxtime.tsc_quot = (1000L << 32) / cpu_khz; vxtime.tsc_quot = (1000L << 32) / cpu_khz;
vxtime.last_tsc = get_cycles_sync(); vxtime.last_tsc = get_cycles_sync();
setup_irq(0, &irq0); setup_irq(0, &irq0);
set_cyc2ns_scale(cpu_khz); set_cyc2ns_scale(cpu_khz);
#ifndef CONFIG_SMP
time_init_gtod();
#endif
} }
/* /*
@ -981,9 +982,9 @@ __cpuinit int unsynchronized_tsc(void)
} }
/* /*
* Decide after all CPUs are booted what mode gettimeofday should use. * Decide what mode gettimeofday should use.
*/ */
void __init time_init_gtod(void) __init static char *time_init_gtod(void)
{ {
char *timetype; char *timetype;
@ -1011,8 +1012,7 @@ void __init time_init_gtod(void)
timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC"; timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC";
vxtime.mode = VXTIME_TSC; vxtime.mode = VXTIME_TSC;
} }
return timetype;
printk(KERN_INFO "time.c: Using %s based timekeeping.\n", timetype);
} }
__setup("report_lost_ticks", time_setup); __setup("report_lost_ticks", time_setup);

View File

@ -39,7 +39,6 @@ extern void config_acpi_tables(void);
extern void ia32_syscall(void); extern void ia32_syscall(void);
extern void iommu_hole_init(void); extern void iommu_hole_init(void);
extern void time_init_gtod(void);
extern int pmtimer_mark_offset(void); extern int pmtimer_mark_offset(void);
extern void pmtimer_resume(void); extern void pmtimer_resume(void);
extern void pmtimer_wait(unsigned); extern void pmtimer_wait(unsigned);