aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/tsc.c8
-rw-r--r--include/linux/clocksource.h1
-rw-r--r--kernel/time/clocksource.c33
3 files changed, 36 insertions, 6 deletions
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 968425422c46..fc3672a303d6 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -767,12 +767,14 @@ void mark_tsc_unstable(char *reason)
767{ 767{
768 if (!tsc_unstable) { 768 if (!tsc_unstable) {
769 tsc_unstable = 1; 769 tsc_unstable = 1;
770 printk("Marking TSC unstable due to %s\n", reason); 770 printk(KERN_INFO "Marking TSC unstable due to %s\n", reason);
771 /* Change only the rating, when not registered */ 771 /* Change only the rating, when not registered */
772 if (clocksource_tsc.mult) 772 if (clocksource_tsc.mult)
773 clocksource_change_rating(&clocksource_tsc, 0); 773 clocksource_mark_unstable(&clocksource_tsc);
774 else 774 else {
775 clocksource_tsc.flags |= CLOCK_SOURCE_UNSTABLE;
775 clocksource_tsc.rating = 0; 776 clocksource_tsc.rating = 0;
777 }
776 } 778 }
777} 779}
778 780
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 9ea40ff26f0e..83d2fbd81b93 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -277,6 +277,7 @@ extern struct clocksource* clocksource_get_next(void);
277extern void clocksource_change_rating(struct clocksource *cs, int rating); 277extern void clocksource_change_rating(struct clocksource *cs, int rating);
278extern void clocksource_resume(void); 278extern void clocksource_resume(void);
279extern struct clocksource * __init __weak clocksource_default_clock(void); 279extern struct clocksource * __init __weak clocksource_default_clock(void);
280extern void clocksource_mark_unstable(struct clocksource *cs);
280 281
281#ifdef CONFIG_GENERIC_TIME_VSYSCALL 282#ifdef CONFIG_GENERIC_TIME_VSYSCALL
282extern void update_vsyscall(struct timespec *ts, struct clocksource *c); 283extern void update_vsyscall(struct timespec *ts, struct clocksource *c);
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index e0c86ad6e9fb..a0af4ffcb6e5 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -149,15 +149,42 @@ static void clocksource_watchdog_work(struct work_struct *work)
149 kthread_run(clocksource_watchdog_kthread, NULL, "kwatchdog"); 149 kthread_run(clocksource_watchdog_kthread, NULL, "kwatchdog");
150} 150}
151 151
152static void clocksource_unstable(struct clocksource *cs, int64_t delta) 152static void __clocksource_unstable(struct clocksource *cs)
153{ 153{
154 printk(KERN_WARNING "Clocksource %s unstable (delta = %Ld ns)\n",
155 cs->name, delta);
156 cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG); 154 cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG);
157 cs->flags |= CLOCK_SOURCE_UNSTABLE; 155 cs->flags |= CLOCK_SOURCE_UNSTABLE;
158 schedule_work(&watchdog_work); 156 schedule_work(&watchdog_work);
159} 157}
160 158
159static void clocksource_unstable(struct clocksource *cs, int64_t delta)
160{
161 printk(KERN_WARNING "Clocksource %s unstable (delta = %Ld ns)\n",
162 cs->name, delta);
163 __clocksource_unstable(cs);
164}
165
166/**
167 * clocksource_mark_unstable - mark clocksource unstable via watchdog
168 * @cs: clocksource to be marked unstable
169 *
170 * This function is called instead of clocksource_change_rating from
171 * cpu hotplug code to avoid a deadlock between the clocksource mutex
172 * and the cpu hotplug mutex. It defers the update of the clocksource
173 * to the watchdog thread.
174 */
175void clocksource_mark_unstable(struct clocksource *cs)
176{
177 unsigned long flags;
178
179 spin_lock_irqsave(&watchdog_lock, flags);
180 if (!(cs->flags & CLOCK_SOURCE_UNSTABLE)) {
181 if (list_empty(&cs->wd_list))
182 list_add(&cs->wd_list, &watchdog_list);
183 __clocksource_unstable(cs);
184 }
185 spin_unlock_irqrestore(&watchdog_lock, flags);
186}
187
161static void clocksource_watchdog(unsigned long data) 188static void clocksource_watchdog(unsigned long data)
162{ 189{
163 struct clocksource *cs; 190 struct clocksource *cs;