diff options
author | Tony Luck <tony.luck@intel.com> | 2006-02-07 18:25:57 -0500 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2006-02-07 18:25:57 -0500 |
commit | d6e56a2a088935f3c1feee5ff5a06c67f2ec6002 (patch) | |
tree | ab9fd17a56f81a7662aab8f135be7ed0f3c707c5 /arch | |
parent | 9d78f43d1fd3e028bfd37510ce847d0896f71f78 (diff) |
[IA64] Fix CONFIG_PRINTK_TIME
There were two problems with enabling the PRINTK_TIME config
option:
1) The first calls to printk() occur before per-cpu data virtual
address is pinned into the TLB, so sched_clock() can fault.
2) sched_clock() is based on ar.itc, which may not be synchronized
across cpus.
Ken Chen started this patch, Tony Luck tinkered with it, and Jes
Sorensen perfected it.
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/ia64/kernel/head.S | 1 | ||||
-rw-r--r-- | arch/ia64/kernel/setup.c | 4 | ||||
-rw-r--r-- | arch/ia64/kernel/time.c | 27 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/setup.c | 40 |
4 files changed, 59 insertions, 13 deletions
diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index fbc7ea35dd57..f1778a84ea61 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S | |||
@@ -352,6 +352,7 @@ start_ap: | |||
352 | mov ar.rsc=0 // place RSE in enforced lazy mode | 352 | mov ar.rsc=0 // place RSE in enforced lazy mode |
353 | ;; | 353 | ;; |
354 | loadrs // clear the dirty partition | 354 | loadrs // clear the dirty partition |
355 | mov IA64_KR(PER_CPU_DATA)=r0 // clear physical per-CPU base | ||
355 | ;; | 356 | ;; |
356 | mov ar.bspstore=r2 // establish the new RSE stack | 357 | mov ar.bspstore=r2 // establish the new RSE stack |
357 | ;; | 358 | ;; |
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index c0766575a3a2..35f7835294a3 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c | |||
@@ -71,6 +71,8 @@ unsigned long __per_cpu_offset[NR_CPUS]; | |||
71 | EXPORT_SYMBOL(__per_cpu_offset); | 71 | EXPORT_SYMBOL(__per_cpu_offset); |
72 | #endif | 72 | #endif |
73 | 73 | ||
74 | extern void ia64_setup_printk_clock(void); | ||
75 | |||
74 | DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info); | 76 | DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info); |
75 | DEFINE_PER_CPU(unsigned long, local_per_cpu_offset); | 77 | DEFINE_PER_CPU(unsigned long, local_per_cpu_offset); |
76 | DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8); | 78 | DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8); |
@@ -445,6 +447,8 @@ setup_arch (char **cmdline_p) | |||
445 | /* process SAL system table: */ | 447 | /* process SAL system table: */ |
446 | ia64_sal_init(efi.sal_systab); | 448 | ia64_sal_init(efi.sal_systab); |
447 | 449 | ||
450 | ia64_setup_printk_clock(); | ||
451 | |||
448 | #ifdef CONFIG_SMP | 452 | #ifdef CONFIG_SMP |
449 | cpu_physical_id(0) = hard_smp_processor_id(); | 453 | cpu_physical_id(0) = hard_smp_processor_id(); |
450 | 454 | ||
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 028a2b95936c..a094ec49ccfa 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c | |||
@@ -278,3 +278,30 @@ udelay (unsigned long usecs) | |||
278 | } | 278 | } |
279 | } | 279 | } |
280 | EXPORT_SYMBOL(udelay); | 280 | EXPORT_SYMBOL(udelay); |
281 | |||
282 | static unsigned long long ia64_itc_printk_clock(void) | ||
283 | { | ||
284 | if (ia64_get_kr(IA64_KR_PER_CPU_DATA)) | ||
285 | return sched_clock(); | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static unsigned long long ia64_default_printk_clock(void) | ||
290 | { | ||
291 | return (unsigned long long)(jiffies_64 - INITIAL_JIFFIES) * | ||
292 | (1000000000/HZ); | ||
293 | } | ||
294 | |||
295 | unsigned long long (*ia64_printk_clock)(void) = &ia64_default_printk_clock; | ||
296 | |||
297 | unsigned long long printk_clock(void) | ||
298 | { | ||
299 | return ia64_printk_clock(); | ||
300 | } | ||
301 | |||
302 | void __init | ||
303 | ia64_setup_printk_clock(void) | ||
304 | { | ||
305 | if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) | ||
306 | ia64_printk_clock = ia64_itc_printk_clock; | ||
307 | } | ||
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index ee36bff93c30..6ea5b8a37c01 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c | |||
@@ -67,6 +67,7 @@ extern unsigned long last_time_offset; | |||
67 | extern void (*ia64_mark_idle) (int); | 67 | extern void (*ia64_mark_idle) (int); |
68 | extern void snidle(int); | 68 | extern void snidle(int); |
69 | extern unsigned char acpi_kbd_controller_present; | 69 | extern unsigned char acpi_kbd_controller_present; |
70 | extern unsigned long long (*ia64_printk_clock)(void); | ||
70 | 71 | ||
71 | unsigned long sn_rtc_cycles_per_second; | 72 | unsigned long sn_rtc_cycles_per_second; |
72 | EXPORT_SYMBOL(sn_rtc_cycles_per_second); | 73 | EXPORT_SYMBOL(sn_rtc_cycles_per_second); |
@@ -372,6 +373,16 @@ sn_scan_pcdp(void) | |||
372 | } | 373 | } |
373 | } | 374 | } |
374 | 375 | ||
376 | static unsigned long sn2_rtc_initial; | ||
377 | |||
378 | static unsigned long long ia64_sn2_printk_clock(void) | ||
379 | { | ||
380 | unsigned long rtc_now = rtc_time(); | ||
381 | |||
382 | return (rtc_now - sn2_rtc_initial) * | ||
383 | (1000000000 / sn_rtc_cycles_per_second); | ||
384 | } | ||
385 | |||
375 | /** | 386 | /** |
376 | * sn_setup - SN platform setup routine | 387 | * sn_setup - SN platform setup routine |
377 | * @cmdline_p: kernel command line | 388 | * @cmdline_p: kernel command line |
@@ -386,6 +397,7 @@ void __init sn_setup(char **cmdline_p) | |||
386 | u32 version = sn_sal_rev(); | 397 | u32 version = sn_sal_rev(); |
387 | extern void sn_cpu_init(void); | 398 | extern void sn_cpu_init(void); |
388 | 399 | ||
400 | sn2_rtc_initial = rtc_time(); | ||
389 | ia64_sn_plat_set_error_handling_features(); // obsolete | 401 | ia64_sn_plat_set_error_handling_features(); // obsolete |
390 | ia64_sn_set_os_feature(OSF_MCA_SLV_TO_OS_INIT_SLV); | 402 | ia64_sn_set_os_feature(OSF_MCA_SLV_TO_OS_INIT_SLV); |
391 | ia64_sn_set_os_feature(OSF_FEAT_LOG_SBES); | 403 | ia64_sn_set_os_feature(OSF_FEAT_LOG_SBES); |
@@ -437,19 +449,6 @@ void __init sn_setup(char **cmdline_p) | |||
437 | */ | 449 | */ |
438 | build_cnode_tables(); | 450 | build_cnode_tables(); |
439 | 451 | ||
440 | /* | ||
441 | * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard | ||
442 | * support here so we don't have to listen to failed keyboard probe | ||
443 | * messages. | ||
444 | */ | ||
445 | if (version <= 0x0209 && acpi_kbd_controller_present) { | ||
446 | printk(KERN_INFO "Disabling legacy keyboard support as prom " | ||
447 | "is too old and doesn't provide FADT\n"); | ||
448 | acpi_kbd_controller_present = 0; | ||
449 | } | ||
450 | |||
451 | printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF); | ||
452 | |||
453 | status = | 452 | status = |
454 | ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec, | 453 | ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec, |
455 | &drift); | 454 | &drift); |
@@ -463,6 +462,21 @@ void __init sn_setup(char **cmdline_p) | |||
463 | 462 | ||
464 | platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR; | 463 | platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR; |
465 | 464 | ||
465 | ia64_printk_clock = ia64_sn2_printk_clock; | ||
466 | |||
467 | /* | ||
468 | * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard | ||
469 | * support here so we don't have to listen to failed keyboard probe | ||
470 | * messages. | ||
471 | */ | ||
472 | if (version <= 0x0209 && acpi_kbd_controller_present) { | ||
473 | printk(KERN_INFO "Disabling legacy keyboard support as prom " | ||
474 | "is too old and doesn't provide FADT\n"); | ||
475 | acpi_kbd_controller_present = 0; | ||
476 | } | ||
477 | |||
478 | printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF); | ||
479 | |||
466 | /* | 480 | /* |
467 | * we set the default root device to /dev/hda | 481 | * we set the default root device to /dev/hda |
468 | * to make simulation easy | 482 | * to make simulation easy |