Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 269198
b: refs/heads/master
c: 9fb6033
h: refs/heads/master
v: v3
  • Loading branch information
Thomas Gleixner committed Sep 13, 2011
1 parent e3228d7 commit 590c235
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e8abccb719377af63cb0f1fed289db405e3def16
refs/heads/master: 9fb60336253edf73dedc527b2aa2bf32eae0d6da
38 changes: 18 additions & 20 deletions trunk/kernel/time/clocksource.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ static struct timer_list watchdog_timer;
static DECLARE_WORK(watchdog_work, clocksource_watchdog_work);
static DEFINE_SPINLOCK(watchdog_lock);
static int watchdog_running;
static atomic_t watchdog_reset_pending;

static int clocksource_watchdog_kthread(void *data);
static void __clocksource_change_rating(struct clocksource *cs, int rating);
Expand Down Expand Up @@ -247,12 +248,14 @@ static void clocksource_watchdog(unsigned long data)
struct clocksource *cs;
cycle_t csnow, wdnow;
int64_t wd_nsec, cs_nsec;
int next_cpu;
int next_cpu, reset_pending;

spin_lock(&watchdog_lock);
if (!watchdog_running)
goto out;

reset_pending = atomic_read(&watchdog_reset_pending);

list_for_each_entry(cs, &watchdog_list, wd_list) {

/* Clocksource already marked unstable? */
Expand All @@ -268,7 +271,8 @@ static void clocksource_watchdog(unsigned long data)
local_irq_enable();

/* Clocksource initialized ? */
if (!(cs->flags & CLOCK_SOURCE_WATCHDOG)) {
if (!(cs->flags & CLOCK_SOURCE_WATCHDOG) ||
atomic_read(&watchdog_reset_pending)) {
cs->flags |= CLOCK_SOURCE_WATCHDOG;
cs->wd_last = wdnow;
cs->cs_last = csnow;
Expand All @@ -283,8 +287,11 @@ static void clocksource_watchdog(unsigned long data)
cs->cs_last = csnow;
cs->wd_last = wdnow;

if (atomic_read(&watchdog_reset_pending))
continue;

/* Check the deviation from the watchdog clocksource. */
if (abs(cs_nsec - wd_nsec) > WATCHDOG_THRESHOLD) {
if ((abs(cs_nsec - wd_nsec) > WATCHDOG_THRESHOLD)) {
clocksource_unstable(cs, cs_nsec - wd_nsec);
continue;
}
Expand All @@ -302,6 +309,13 @@ static void clocksource_watchdog(unsigned long data)
}
}

/*
* We only clear the watchdog_reset_pending, when we did a
* full cycle through all clocksources.
*/
if (reset_pending)
atomic_dec(&watchdog_reset_pending);

/*
* Cycle through CPUs to check if the CPUs stay synchronized
* to each other.
Expand Down Expand Up @@ -344,23 +358,7 @@ static inline void clocksource_reset_watchdog(void)

static void clocksource_resume_watchdog(void)
{
unsigned long flags;

/*
* We use trylock here to avoid a potential dead lock when
* kgdb calls this code after the kernel has been stopped with
* watchdog_lock held. When watchdog_lock is held we just
* return and accept, that the watchdog might trigger and mark
* the monitored clock source (usually TSC) unstable.
*
* This does not affect the other caller clocksource_resume()
* because at this point the kernel is UP, interrupts are
* disabled and nothing can hold watchdog_lock.
*/
if (!spin_trylock_irqsave(&watchdog_lock, flags))
return;
clocksource_reset_watchdog();
spin_unlock_irqrestore(&watchdog_lock, flags);
atomic_inc(&watchdog_reset_pending);
}

static void clocksource_enqueue_watchdog(struct clocksource *cs)
Expand Down

0 comments on commit 590c235

Please sign in to comment.