]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Alok Kataria <akataria@vmware.com> |
2 | Subject: x86: Skip verification by the watchdog for TSC clocksource. | |
3 | Patch-mainline: | |
4 | References: bnc#441338 | |
5 | ||
6 | Impact: Changes timekeeping on Vmware (or with tsc=reliable). | |
7 | ||
8 | This is achieved by resetting the CLOCKSOURCE_MUST_VERIFY flag. | |
9 | ||
10 | We add a tsc=reliable commandline option to enable this. | |
11 | This enables legacy hardware without HPET, LAPIC, or ACPI timers | |
12 | to enter high-resolution timer mode. | |
13 | ||
14 | Along with that have extended this to be used in virtualization environement | |
15 | too. Now we also set this flag if the X86_FEATURE_TSC_RELIABLE bit is set. | |
16 | This is important since there is a wrap-around problem with the acpi_pm timer. | |
17 | The acpi_pm counter is just 24bits and this can overflow in ~4 seconds. With | |
18 | the NO_HZ kernels in virtualized environment, there can be situations when | |
19 | the guest is descheduled for longer duration, as a result we may miss the wrap | |
20 | of the acpi counter. When TSC is used as a clocksource and acpi_pm timer is | |
21 | being used as the watchdog clocksource this error in acpi_pm results in TSC | |
22 | being marked as unstable, and essentially results in time dropping in chunks | |
23 | of 4 seconds whenever this wrap is missed. Since the virtualized TSC is | |
24 | reliable on VMware, we should always use the TSCs clocksource on VMware, so | |
25 | we skip the verfication at runtime, by checking for the feature bit. | |
26 | ||
27 | Since we reset the flag for mgeode systems too, i have combined | |
28 | the mgeode case with the feature bit check. | |
29 | ||
30 | Signed-off-by: Jeff Hansen <jhansen@cardaccess-inc.com> | |
31 | Signed-off-by: Alok N Kataria <akataria@vmware.com> | |
32 | Signed-off-by: Dan Hecht <dhecht@vmware.com> | |
33 | Signed-off-by: H. Peter Anvin <hpa@zytor.com> | |
34 | Signed-off-by: Takashi Iwai <tiwai@suse.de> | |
35 | ||
36 | --- | |
37 | ||
38 | Documentation/kernel-parameters.txt | 7 +++++++ | |
39 | arch/x86/kernel/tsc.c | 33 +++++++++++++++++++++------------ | |
40 | 2 files changed, 28 insertions(+), 12 deletions(-) | |
41 | ||
42 | ||
43 | --- a/arch/x86/kernel/tsc.c | |
44 | +++ b/arch/x86/kernel/tsc.c | |
45 | @@ -32,6 +32,7 @@ static int tsc_unstable; | |
46 | erroneous rdtsc usage on !cpu_has_tsc processors */ | |
47 | static int tsc_disabled = -1; | |
48 | ||
49 | +static int tsc_clocksource_reliable; | |
50 | /* | |
51 | * Scheduler clock - returns current time in nanosec units. | |
52 | */ | |
53 | @@ -99,6 +100,15 @@ int __init notsc_setup(char *str) | |
54 | ||
55 | __setup("notsc", notsc_setup); | |
56 | ||
57 | +static int __init tsc_setup(char *str) | |
58 | +{ | |
59 | + if (!strcmp(str, "reliable")) | |
60 | + tsc_clocksource_reliable = 1; | |
61 | + return 1; | |
62 | +} | |
63 | + | |
64 | +__setup("tsc=", tsc_setup); | |
65 | + | |
66 | #define MAX_RETRIES 5 | |
67 | #define SMI_TRESHOLD 50000 | |
68 | ||
69 | @@ -564,24 +574,21 @@ static struct dmi_system_id __initdata b | |
70 | {} | |
71 | }; | |
72 | ||
73 | -/* | |
74 | - * Geode_LX - the OLPC CPU has a possibly a very reliable TSC | |
75 | - */ | |
76 | +static void __init check_system_tsc_reliable(void) | |
77 | +{ | |
78 | #ifdef CONFIG_MGEODE_LX | |
79 | -/* RTSC counts during suspend */ | |
80 | + /* RTSC counts during suspend */ | |
81 | #define RTSC_SUSP 0x100 | |
82 | - | |
83 | -static void __init check_geode_tsc_reliable(void) | |
84 | -{ | |
85 | unsigned long res_low, res_high; | |
86 | ||
87 | rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high); | |
88 | + /* Geode_LX - the OLPC CPU has a possibly a very reliable TSC */ | |
89 | if (res_low & RTSC_SUSP) | |
90 | - clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; | |
91 | -} | |
92 | -#else | |
93 | -static inline void check_geode_tsc_reliable(void) { } | |
94 | + tsc_clocksource_reliable = 1; | |
95 | #endif | |
96 | + if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) | |
97 | + tsc_clocksource_reliable = 1; | |
98 | +} | |
99 | ||
100 | /* | |
101 | * Make an educated guess if the TSC is trustworthy and synchronized | |
102 | @@ -616,6 +623,8 @@ static void __init init_tsc_clocksource( | |
103 | { | |
104 | clocksource_tsc.mult = clocksource_khz2mult(tsc_khz, | |
105 | clocksource_tsc.shift); | |
106 | + if (tsc_clocksource_reliable) | |
107 | + clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; | |
108 | /* lower the rating if we already know its unstable: */ | |
109 | if (check_tsc_unstable()) { | |
110 | clocksource_tsc.rating = 0; | |
111 | @@ -676,7 +685,7 @@ void __init tsc_init(void) | |
112 | if (unsynchronized_tsc()) | |
113 | mark_tsc_unstable("TSCs unsynchronized"); | |
114 | ||
115 | - check_geode_tsc_reliable(); | |
116 | + check_system_tsc_reliable(); | |
117 | init_tsc_clocksource(); | |
118 | } | |
119 | ||
120 | --- a/Documentation/kernel-parameters.txt | |
121 | +++ b/Documentation/kernel-parameters.txt | |
122 | @@ -2200,6 +2200,13 @@ and is between 256 and 4096 characters. | |
123 | Format: | |
124 | <io>,<irq>,<dma>,<dma2>,<sb_io>,<sb_irq>,<sb_dma>,<mpu_io>,<mpu_irq> | |
125 | ||
126 | + tsc= Disable clocksource-must-verify flag for TSC. | |
127 | + Format: <string> | |
128 | + [x86] reliable: mark tsc clocksource as reliable, this | |
129 | + disables clocksource verification at runtime. | |
130 | + Used to enable high-resolution timer mode on older | |
131 | + hardware, and in virtualized environment. | |
132 | + | |
133 | turbografx.map[2|3]= [HW,JOY] | |
134 | TurboGraFX parallel port interface | |
135 | Format: |