diff options
Diffstat (limited to 'arch/x86/kernel/tsc.c')
-rw-r--r-- | arch/x86/kernel/tsc.c | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 46bcda4cb1c2..4f7a9833d8e5 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
@@ -327,9 +327,16 @@ unsigned long long sched_clock(void) | |||
327 | { | 327 | { |
328 | return paravirt_sched_clock(); | 328 | return paravirt_sched_clock(); |
329 | } | 329 | } |
330 | |||
331 | static inline bool using_native_sched_clock(void) | ||
332 | { | ||
333 | return pv_time_ops.sched_clock == native_sched_clock; | ||
334 | } | ||
330 | #else | 335 | #else |
331 | unsigned long long | 336 | unsigned long long |
332 | sched_clock(void) __attribute__((alias("native_sched_clock"))); | 337 | sched_clock(void) __attribute__((alias("native_sched_clock"))); |
338 | |||
339 | static inline bool using_native_sched_clock(void) { return true; } | ||
333 | #endif | 340 | #endif |
334 | 341 | ||
335 | int check_tsc_unstable(void) | 342 | int check_tsc_unstable(void) |
@@ -1112,8 +1119,10 @@ static void tsc_cs_mark_unstable(struct clocksource *cs) | |||
1112 | { | 1119 | { |
1113 | if (tsc_unstable) | 1120 | if (tsc_unstable) |
1114 | return; | 1121 | return; |
1122 | |||
1115 | tsc_unstable = 1; | 1123 | tsc_unstable = 1; |
1116 | clear_sched_clock_stable(); | 1124 | if (using_native_sched_clock()) |
1125 | clear_sched_clock_stable(); | ||
1117 | disable_sched_clock_irqtime(); | 1126 | disable_sched_clock_irqtime(); |
1118 | pr_info("Marking TSC unstable due to clocksource watchdog\n"); | 1127 | pr_info("Marking TSC unstable due to clocksource watchdog\n"); |
1119 | } | 1128 | } |
@@ -1135,18 +1144,20 @@ static struct clocksource clocksource_tsc = { | |||
1135 | 1144 | ||
1136 | void mark_tsc_unstable(char *reason) | 1145 | void mark_tsc_unstable(char *reason) |
1137 | { | 1146 | { |
1138 | if (!tsc_unstable) { | 1147 | if (tsc_unstable) |
1139 | tsc_unstable = 1; | 1148 | return; |
1149 | |||
1150 | tsc_unstable = 1; | ||
1151 | if (using_native_sched_clock()) | ||
1140 | clear_sched_clock_stable(); | 1152 | clear_sched_clock_stable(); |
1141 | disable_sched_clock_irqtime(); | 1153 | disable_sched_clock_irqtime(); |
1142 | pr_info("Marking TSC unstable due to %s\n", reason); | 1154 | pr_info("Marking TSC unstable due to %s\n", reason); |
1143 | /* Change only the rating, when not registered */ | 1155 | /* Change only the rating, when not registered */ |
1144 | if (clocksource_tsc.mult) | 1156 | if (clocksource_tsc.mult) { |
1145 | clocksource_mark_unstable(&clocksource_tsc); | 1157 | clocksource_mark_unstable(&clocksource_tsc); |
1146 | else { | 1158 | } else { |
1147 | clocksource_tsc.flags |= CLOCK_SOURCE_UNSTABLE; | 1159 | clocksource_tsc.flags |= CLOCK_SOURCE_UNSTABLE; |
1148 | clocksource_tsc.rating = 0; | 1160 | clocksource_tsc.rating = 0; |
1149 | } | ||
1150 | } | 1161 | } |
1151 | } | 1162 | } |
1152 | 1163 | ||