Commit 5a90cf20 authored by john stultz's avatar john stultz Committed by Andi Kleen

[PATCH] x86: Log reason why TSC was marked unstable

Change mark_tsc_unstable() so it takes a string argument, which holds the
reason the TSC was marked unstable.

This is then displayed the first time mark_tsc_unstable is called.

This should help us better debug why the TSC was marked unstable on certain
systems and allow us to make sure we're not being overly paranoid when
throwing out this troublesome clocksource.

Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
parent 27142219
...@@ -279,7 +279,7 @@ static void __cpuinit init_cyrix(struct cpuinfo_x86 *c) ...@@ -279,7 +279,7 @@ static void __cpuinit init_cyrix(struct cpuinfo_x86 *c)
*/ */
if (vendor == PCI_VENDOR_ID_CYRIX && if (vendor == PCI_VENDOR_ID_CYRIX &&
(device == PCI_DEVICE_ID_CYRIX_5510 || device == PCI_DEVICE_ID_CYRIX_5520)) (device == PCI_DEVICE_ID_CYRIX_5510 || device == PCI_DEVICE_ID_CYRIX_5520))
mark_tsc_unstable(); mark_tsc_unstable("cyrix 5510/5520 detected");
} }
#endif #endif
c->x86_cache_size=16; /* Yep 16K integrated cache thats it */ c->x86_cache_size=16; /* Yep 16K integrated cache thats it */
......
...@@ -233,7 +233,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) ...@@ -233,7 +233,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
* TSC based sched_clock turns * TSC based sched_clock turns
* to junk w/ cpufreq * to junk w/ cpufreq
*/ */
mark_tsc_unstable(); mark_tsc_unstable("cpufreq changes");
} }
} }
} }
...@@ -281,11 +281,12 @@ static struct clocksource clocksource_tsc = { ...@@ -281,11 +281,12 @@ static struct clocksource clocksource_tsc = {
CLOCK_SOURCE_MUST_VERIFY, CLOCK_SOURCE_MUST_VERIFY,
}; };
void mark_tsc_unstable(void) void mark_tsc_unstable(char *reason)
{ {
if (!tsc_unstable) { if (!tsc_unstable) {
tsc_unstable = 1; tsc_unstable = 1;
tsc_enabled = 0; tsc_enabled = 0;
printk("Marking TSC unstable due to: %s.\n", reason);
/* Can be called before registration */ /* Can be called before registration */
if (clocksource_tsc.mult) if (clocksource_tsc.mult)
clocksource_change_rating(&clocksource_tsc, 0); clocksource_change_rating(&clocksource_tsc, 0);
......
...@@ -397,7 +397,7 @@ void __init time_init(void) ...@@ -397,7 +397,7 @@ void __init time_init(void)
cpu_khz = tsc_calibrate_cpu_khz(); cpu_khz = tsc_calibrate_cpu_khz();
if (unsynchronized_tsc()) if (unsynchronized_tsc())
mark_tsc_unstable(); mark_tsc_unstable("TSCs unsynchronized");
if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP)) if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP))
vgetcpu_mode = VGETCPU_RDTSCP; vgetcpu_mode = VGETCPU_RDTSCP;
......
...@@ -111,7 +111,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, ...@@ -111,7 +111,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
tsc_khz = cpufreq_scale(tsc_khz_ref, ref_freq, freq->new); tsc_khz = cpufreq_scale(tsc_khz_ref, ref_freq, freq->new);
if (!(freq->flags & CPUFREQ_CONST_LOOPS)) if (!(freq->flags & CPUFREQ_CONST_LOOPS))
mark_tsc_unstable(); mark_tsc_unstable("cpufreq changes");
} }
set_cyc2ns_scale(tsc_khz_ref); set_cyc2ns_scale(tsc_khz_ref);
...@@ -199,10 +199,11 @@ static struct clocksource clocksource_tsc = { ...@@ -199,10 +199,11 @@ static struct clocksource clocksource_tsc = {
.vread = vread_tsc, .vread = vread_tsc,
}; };
void mark_tsc_unstable(void) void mark_tsc_unstable(char *reason)
{ {
if (!tsc_unstable) { if (!tsc_unstable) {
tsc_unstable = 1; tsc_unstable = 1;
printk("Marking TSC unstable due to %s\n", reason);
/* Change only the rating, when not registered */ /* Change only the rating, when not registered */
if (clocksource_tsc.mult) if (clocksource_tsc.mult)
clocksource_change_rating(&clocksource_tsc, 0); clocksource_change_rating(&clocksource_tsc, 0);
......
...@@ -138,7 +138,7 @@ void __cpuinit check_tsc_sync_source(int cpu) ...@@ -138,7 +138,7 @@ void __cpuinit check_tsc_sync_source(int cpu)
printk("\n"); printk("\n");
printk(KERN_WARNING "Measured %Ld cycles TSC warp between CPUs," printk(KERN_WARNING "Measured %Ld cycles TSC warp between CPUs,"
" turning off TSC clock.\n", max_warp); " turning off TSC clock.\n", max_warp);
mark_tsc_unstable(); mark_tsc_unstable("check_tsc_sync_source failed");
nr_warps = 0; nr_warps = 0;
max_warp = 0; max_warp = 0;
last_tsc = 0; last_tsc = 0;
......
...@@ -475,7 +475,7 @@ static void acpi_processor_idle(void) ...@@ -475,7 +475,7 @@ static void acpi_processor_idle(void)
#ifdef CONFIG_GENERIC_TIME #ifdef CONFIG_GENERIC_TIME
/* TSC halts in C2, so notify users */ /* TSC halts in C2, so notify users */
mark_tsc_unstable(); mark_tsc_unstable("possible TSC halt in C2");
#endif #endif
/* Re-enable interrupts */ /* Re-enable interrupts */
local_irq_enable(); local_irq_enable();
...@@ -517,7 +517,7 @@ static void acpi_processor_idle(void) ...@@ -517,7 +517,7 @@ static void acpi_processor_idle(void)
#ifdef CONFIG_GENERIC_TIME #ifdef CONFIG_GENERIC_TIME
/* TSC halts in C3, so notify users */ /* TSC halts in C3, so notify users */
mark_tsc_unstable(); mark_tsc_unstable("TSC halts in C3");
#endif #endif
/* Re-enable interrupts */ /* Re-enable interrupts */
local_irq_enable(); local_irq_enable();
......
...@@ -30,7 +30,7 @@ static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, ...@@ -30,7 +30,7 @@ static inline int mps_oem_check(struct mp_config_table *mpc, char *oem,
(!strncmp(productid, "VIGIL SMP", 9) (!strncmp(productid, "VIGIL SMP", 9)
|| !strncmp(productid, "EXA", 3) || !strncmp(productid, "EXA", 3)
|| !strncmp(productid, "RUTHLESS SMP", 12))){ || !strncmp(productid, "RUTHLESS SMP", 12))){
mark_tsc_unstable(); mark_tsc_unstable("Summit based system");
use_cyclone = 1; /*enable cyclone-timer*/ use_cyclone = 1; /*enable cyclone-timer*/
setup_summit(); setup_summit();
return 1; return 1;
...@@ -44,7 +44,7 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) ...@@ -44,7 +44,7 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
if (!strncmp(oem_id, "IBM", 3) && if (!strncmp(oem_id, "IBM", 3) &&
(!strncmp(oem_table_id, "SERVIGIL", 8) (!strncmp(oem_table_id, "SERVIGIL", 8)
|| !strncmp(oem_table_id, "EXA", 3))){ || !strncmp(oem_table_id, "EXA", 3))){
mark_tsc_unstable(); mark_tsc_unstable("Summit based system");
use_cyclone = 1; /*enable cyclone-timer*/ use_cyclone = 1; /*enable cyclone-timer*/
setup_summit(); setup_summit();
return 1; return 1;
......
...@@ -53,7 +53,7 @@ static __always_inline cycles_t get_cycles_sync(void) ...@@ -53,7 +53,7 @@ static __always_inline cycles_t get_cycles_sync(void)
} }
extern void tsc_init(void); extern void tsc_init(void);
extern void mark_tsc_unstable(void); extern void mark_tsc_unstable(char *reason);
extern int unsynchronized_tsc(void); extern int unsynchronized_tsc(void);
extern void init_tsc_clocksource(void); extern void init_tsc_clocksource(void);
......
...@@ -27,6 +27,6 @@ extern int read_current_timer(unsigned long *timer_value); ...@@ -27,6 +27,6 @@ extern int read_current_timer(unsigned long *timer_value);
#define NS_SCALE 10 /* 2^10, carefully chosen */ #define NS_SCALE 10 /* 2^10, carefully chosen */
#define US_SCALE 32 /* 2^32, arbitralrily chosen */ #define US_SCALE 32 /* 2^32, arbitralrily chosen */
extern void mark_tsc_unstable(void); extern void mark_tsc_unstable(char *msg);
extern void set_cyc2ns_scale(unsigned long khz); extern void set_cyc2ns_scale(unsigned long khz);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment