aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjohn stultz <johnstul@us.ibm.com>2007-05-02 13:27:08 -0400
committerAndi Kleen <andi@basil.nowhere.org>2007-05-02 13:27:08 -0400
commit5a90cf205c922707ffed2d8f87cefd942e96b0ba (patch)
tree5e9c9c1be3d149bff7620db89e1ede2317ba7362
parent2714221985ce6388ec2fa78d7d52e2a5bef78eec (diff)
[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: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Andi Kleen <ak@suse.de>
-rw-r--r--arch/i386/kernel/cpu/cyrix.c2
-rw-r--r--arch/i386/kernel/tsc.c5
-rw-r--r--arch/x86_64/kernel/time.c2
-rw-r--r--arch/x86_64/kernel/tsc.c5
-rw-r--r--arch/x86_64/kernel/tsc_sync.c2
-rw-r--r--drivers/acpi/processor_idle.c4
-rw-r--r--include/asm-i386/mach-summit/mach_mpparse.h4
-rw-r--r--include/asm-i386/tsc.h2
-rw-r--r--include/asm-x86_64/timex.h2
9 files changed, 15 insertions, 13 deletions
diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c
index f0badfdd4e45..e77f8e1cf7aa 100644
--- a/arch/i386/kernel/cpu/cyrix.c
+++ b/arch/i386/kernel/cpu/cyrix.c
@@ -279,7 +279,7 @@ static void __cpuinit init_cyrix(struct cpuinfo_x86 *c)
279 */ 279 */
280 if (vendor == PCI_VENDOR_ID_CYRIX && 280 if (vendor == PCI_VENDOR_ID_CYRIX &&
281 (device == PCI_DEVICE_ID_CYRIX_5510 || device == PCI_DEVICE_ID_CYRIX_5520)) 281 (device == PCI_DEVICE_ID_CYRIX_5510 || device == PCI_DEVICE_ID_CYRIX_5520))
282 mark_tsc_unstable(); 282 mark_tsc_unstable("cyrix 5510/5520 detected");
283 } 283 }
284#endif 284#endif
285 c->x86_cache_size=16; /* Yep 16K integrated cache thats it */ 285 c->x86_cache_size=16; /* Yep 16K integrated cache thats it */
diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c
index 6cb8f5336732..755209dc93e1 100644
--- a/arch/i386/kernel/tsc.c
+++ b/arch/i386/kernel/tsc.c
@@ -233,7 +233,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
233 * TSC based sched_clock turns 233 * TSC based sched_clock turns
234 * to junk w/ cpufreq 234 * to junk w/ cpufreq
235 */ 235 */
236 mark_tsc_unstable(); 236 mark_tsc_unstable("cpufreq changes");
237 } 237 }
238 } 238 }
239 } 239 }
@@ -281,11 +281,12 @@ static struct clocksource clocksource_tsc = {
281 CLOCK_SOURCE_MUST_VERIFY, 281 CLOCK_SOURCE_MUST_VERIFY,
282}; 282};
283 283
284void mark_tsc_unstable(void) 284void mark_tsc_unstable(char *reason)
285{ 285{
286 if (!tsc_unstable) { 286 if (!tsc_unstable) {
287 tsc_unstable = 1; 287 tsc_unstable = 1;
288 tsc_enabled = 0; 288 tsc_enabled = 0;
289 printk("Marking TSC unstable due to: %s.\n", reason);
289 /* Can be called before registration */ 290 /* Can be called before registration */
290 if (clocksource_tsc.mult) 291 if (clocksource_tsc.mult)
291 clocksource_change_rating(&clocksource_tsc, 0); 292 clocksource_change_rating(&clocksource_tsc, 0);
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 5f862e216a42..91c9066a380d 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -397,7 +397,7 @@ void __init time_init(void)
397 cpu_khz = tsc_calibrate_cpu_khz(); 397 cpu_khz = tsc_calibrate_cpu_khz();
398 398
399 if (unsynchronized_tsc()) 399 if (unsynchronized_tsc())
400 mark_tsc_unstable(); 400 mark_tsc_unstable("TSCs unsynchronized");
401 401
402 if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP)) 402 if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP))
403 vgetcpu_mode = VGETCPU_RDTSCP; 403 vgetcpu_mode = VGETCPU_RDTSCP;
diff --git a/arch/x86_64/kernel/tsc.c b/arch/x86_64/kernel/tsc.c
index 5c84992c676d..48f9a8e6aa91 100644
--- a/arch/x86_64/kernel/tsc.c
+++ b/arch/x86_64/kernel/tsc.c
@@ -111,7 +111,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
111 111
112 tsc_khz = cpufreq_scale(tsc_khz_ref, ref_freq, freq->new); 112 tsc_khz = cpufreq_scale(tsc_khz_ref, ref_freq, freq->new);
113 if (!(freq->flags & CPUFREQ_CONST_LOOPS)) 113 if (!(freq->flags & CPUFREQ_CONST_LOOPS))
114 mark_tsc_unstable(); 114 mark_tsc_unstable("cpufreq changes");
115 } 115 }
116 116
117 set_cyc2ns_scale(tsc_khz_ref); 117 set_cyc2ns_scale(tsc_khz_ref);
@@ -199,10 +199,11 @@ static struct clocksource clocksource_tsc = {
199 .vread = vread_tsc, 199 .vread = vread_tsc,
200}; 200};
201 201
202void mark_tsc_unstable(void) 202void mark_tsc_unstable(char *reason)
203{ 203{
204 if (!tsc_unstable) { 204 if (!tsc_unstable) {
205 tsc_unstable = 1; 205 tsc_unstable = 1;
206 printk("Marking TSC unstable due to %s\n", reason);
206 /* Change only the rating, when not registered */ 207 /* Change only the rating, when not registered */
207 if (clocksource_tsc.mult) 208 if (clocksource_tsc.mult)
208 clocksource_change_rating(&clocksource_tsc, 0); 209 clocksource_change_rating(&clocksource_tsc, 0);
diff --git a/arch/x86_64/kernel/tsc_sync.c b/arch/x86_64/kernel/tsc_sync.c
index 72d444dede9b..355f5f506c81 100644
--- a/arch/x86_64/kernel/tsc_sync.c
+++ b/arch/x86_64/kernel/tsc_sync.c
@@ -138,7 +138,7 @@ void __cpuinit check_tsc_sync_source(int cpu)
138 printk("\n"); 138 printk("\n");
139 printk(KERN_WARNING "Measured %Ld cycles TSC warp between CPUs," 139 printk(KERN_WARNING "Measured %Ld cycles TSC warp between CPUs,"
140 " turning off TSC clock.\n", max_warp); 140 " turning off TSC clock.\n", max_warp);
141 mark_tsc_unstable(); 141 mark_tsc_unstable("check_tsc_sync_source failed");
142 nr_warps = 0; 142 nr_warps = 0;
143 max_warp = 0; 143 max_warp = 0;
144 last_tsc = 0; 144 last_tsc = 0;
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index ae0654cd11ea..ee5759bef945 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -475,7 +475,7 @@ static void acpi_processor_idle(void)
475 475
476#ifdef CONFIG_GENERIC_TIME 476#ifdef CONFIG_GENERIC_TIME
477 /* TSC halts in C2, so notify users */ 477 /* TSC halts in C2, so notify users */
478 mark_tsc_unstable(); 478 mark_tsc_unstable("possible TSC halt in C2");
479#endif 479#endif
480 /* Re-enable interrupts */ 480 /* Re-enable interrupts */
481 local_irq_enable(); 481 local_irq_enable();
@@ -517,7 +517,7 @@ static void acpi_processor_idle(void)
517 517
518#ifdef CONFIG_GENERIC_TIME 518#ifdef CONFIG_GENERIC_TIME
519 /* TSC halts in C3, so notify users */ 519 /* TSC halts in C3, so notify users */
520 mark_tsc_unstable(); 520 mark_tsc_unstable("TSC halts in C3");
521#endif 521#endif
522 /* Re-enable interrupts */ 522 /* Re-enable interrupts */
523 local_irq_enable(); 523 local_irq_enable();
diff --git a/include/asm-i386/mach-summit/mach_mpparse.h b/include/asm-i386/mach-summit/mach_mpparse.h
index 94268399170d..c2520539d934 100644
--- a/include/asm-i386/mach-summit/mach_mpparse.h
+++ b/include/asm-i386/mach-summit/mach_mpparse.h
@@ -30,7 +30,7 @@ static inline int mps_oem_check(struct mp_config_table *mpc, char *oem,
30 (!strncmp(productid, "VIGIL SMP", 9) 30 (!strncmp(productid, "VIGIL SMP", 9)
31 || !strncmp(productid, "EXA", 3) 31 || !strncmp(productid, "EXA", 3)
32 || !strncmp(productid, "RUTHLESS SMP", 12))){ 32 || !strncmp(productid, "RUTHLESS SMP", 12))){
33 mark_tsc_unstable(); 33 mark_tsc_unstable("Summit based system");
34 use_cyclone = 1; /*enable cyclone-timer*/ 34 use_cyclone = 1; /*enable cyclone-timer*/
35 setup_summit(); 35 setup_summit();
36 return 1; 36 return 1;
@@ -44,7 +44,7 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
44 if (!strncmp(oem_id, "IBM", 3) && 44 if (!strncmp(oem_id, "IBM", 3) &&
45 (!strncmp(oem_table_id, "SERVIGIL", 8) 45 (!strncmp(oem_table_id, "SERVIGIL", 8)
46 || !strncmp(oem_table_id, "EXA", 3))){ 46 || !strncmp(oem_table_id, "EXA", 3))){
47 mark_tsc_unstable(); 47 mark_tsc_unstable("Summit based system");
48 use_cyclone = 1; /*enable cyclone-timer*/ 48 use_cyclone = 1; /*enable cyclone-timer*/
49 setup_summit(); 49 setup_summit();
50 return 1; 50 return 1;
diff --git a/include/asm-i386/tsc.h b/include/asm-i386/tsc.h
index 84016ff481b9..346976632e15 100644
--- a/include/asm-i386/tsc.h
+++ b/include/asm-i386/tsc.h
@@ -53,7 +53,7 @@ static __always_inline cycles_t get_cycles_sync(void)
53} 53}
54 54
55extern void tsc_init(void); 55extern void tsc_init(void);
56extern void mark_tsc_unstable(void); 56extern void mark_tsc_unstable(char *reason);
57extern int unsynchronized_tsc(void); 57extern int unsynchronized_tsc(void);
58extern void init_tsc_clocksource(void); 58extern void init_tsc_clocksource(void);
59 59
diff --git a/include/asm-x86_64/timex.h b/include/asm-x86_64/timex.h
index 8c6808a3fba4..f6527e1b6c1c 100644
--- a/include/asm-x86_64/timex.h
+++ b/include/asm-x86_64/timex.h
@@ -27,6 +27,6 @@ extern int read_current_timer(unsigned long *timer_value);
27#define NS_SCALE 10 /* 2^10, carefully chosen */ 27#define NS_SCALE 10 /* 2^10, carefully chosen */
28#define US_SCALE 32 /* 2^32, arbitralrily chosen */ 28#define US_SCALE 32 /* 2^32, arbitralrily chosen */
29 29
30extern void mark_tsc_unstable(void); 30extern void mark_tsc_unstable(char *msg);
31extern void set_cyc2ns_scale(unsigned long khz); 31extern void set_cyc2ns_scale(unsigned long khz);
32#endif 32#endif