From: Daniel Walker <dwalker@mvista.com>
To: akpm@osdl.org
Cc: linux-kernel@vger.kernel.org, johnstul@us.ibm.com,
tglx@linutronix.de, mingo@elte.hu
Subject: [PATCH 23/23] clocksource tsc: add verify routine
Date: Tue, 30 Jan 2007 19:37:33 -0800 [thread overview]
Message-ID: <20070131033810.319576375@mvista.com> (raw)
In-Reply-To: 20070131033710.420168478@mvista.com
[-- Attachment #1: generic-tsc-verifiy-clock.patch --]
[-- Type: text/plain, Size: 4242 bytes --]
I've included this as another user of the clocksource interface. I don't see a
usage for this across all achitectures. So a fully generic version isn't needed.
I modified this from the pre 2.6.20-rc6-mm2 release to make the routine smaller
and to make it select a clocksource inside the timer. It should work with an HPET.
Signed-Off-By: Daniel Walker <dwalker@mvista.com>
---
arch/i386/kernel/tsc.c | 55 ++++++++++++++++++++++++++++----------------
include/linux/clocksource.h | 16 ++++++++++++
2 files changed, 51 insertions(+), 20 deletions(-)
Index: linux-2.6.19/arch/i386/kernel/tsc.c
===================================================================
--- linux-2.6.19.orig/arch/i386/kernel/tsc.c
+++ linux-2.6.19/arch/i386/kernel/tsc.c
@@ -343,47 +343,59 @@ static struct dmi_system_id __initdata b
{}
};
-#define TSC_FREQ_CHECK_INTERVAL (10*MSEC_PER_SEC) /* 10sec in MS */
+#define WATCHDOG_TRESHOLD (NSEC_PER_SEC >> 4)
+#define TSC_FREQ_CHECK_INTERVAL (MSEC_PER_SEC/2)
static struct timer_list verify_tsc_freq_timer;
+struct clocksource *verify_clock;
/* XXX - Probably should add locking */
static void verify_tsc_freq(unsigned long unused)
{
- static u64 last_tsc;
- static unsigned long last_jiffies;
-
- u64 now_tsc, interval_tsc;
- unsigned long now_jiffies, interval_jiffies;
+ static cycle_t last_tsc, last_verify;
+ cycle_t now_tsc, verify_clock_now, interval;
+ s64 nsecs;
if (check_tsc_unstable())
return;
- rdtscll(now_tsc);
- now_jiffies = jiffies;
+ if (unlikely(system_state != SYSTEM_RUNNING))
+ goto out_timer;
- if (!last_jiffies) {
- goto out;
+ if (unlikely(!verify_clock)) {
+ verify_clock =
+ clocksource_get_masked_clock(CLOCKSOURCE_PM_AFFECTED);
+ printk("TSC: selected %s clocksource for TSC verification.\n",
+ verify_clock->name);
}
- interval_jiffies = now_jiffies - last_jiffies;
- interval_tsc = now_tsc - last_tsc;
- interval_tsc *= HZ;
- do_div(interval_tsc, cpu_khz*1000);
+ now_tsc = clocksource_read(&clocksource_tsc);
+ verify_clock_now = clocksource_read(verify_clock);
+
+ if (!last_tsc)
+ goto out;
- if (interval_tsc < (interval_jiffies * 3 / 4)) {
+ interval = clocksource_subtract(verify_clock, verify_clock_now,
+ last_verify);
+ nsecs = cyc2ns(verify_clock, interval);
+
+ interval = clocksource_subtract(&clocksource_tsc, now_tsc, last_tsc);
+ nsecs -= cyc2ns(&clocksource_tsc, interval);
+
+ if (nsecs > WATCHDOG_TRESHOLD) {
printk("TSC appears to be running slowly. "
- "Marking it as unstable\n");
+ "Marking it as unstable");
mark_tsc_unstable();
return;
}
out:
- last_tsc = now_tsc;
- last_jiffies = now_jiffies;
+ last_tsc = now_tsc;
+ last_verify = verify_clock_now;
+out_timer:
/* set us up to go off on the next interval: */
mod_timer(&verify_tsc_freq_timer,
- jiffies + msecs_to_jiffies(TSC_FREQ_CHECK_INTERVAL));
+ jiffies + msecs_to_jiffies(TSC_FREQ_CHECK_INTERVAL));
}
/*
@@ -444,7 +456,10 @@ static int __init init_tsc_clocksource(v
if (check_tsc_unstable())
clocksource_tsc.flags |= CLOCKSOURCE_UNSTABLE |
CLOCKSOURCE_NOT_CONTINUOUS;
-
+ /*
+ * The verify routine will select the right clock after the
+ * system boots fully.
+ */
init_timer(&verify_tsc_freq_timer);
verify_tsc_freq_timer.function = verify_tsc_freq;
verify_tsc_freq_timer.expires =
Index: linux-2.6.19/include/linux/clocksource.h
===================================================================
--- linux-2.6.19.orig/include/linux/clocksource.h
+++ linux-2.6.19/include/linux/clocksource.h
@@ -207,6 +207,22 @@ static inline s64 cyc2ns(struct clocksou
}
/**
+ * clocksource_subtract - Subtract two cycle_t timestamps
+ * @cs: Clocksource the timestamp came from
+ * @stop: Stop timestamp
+ * @start: Start timestamp
+ *
+ * This subtract accounts for rollover by using the clocksource mask.
+ * The clock can roll over only once, after that this subtract will not
+ * work properly.
+ */
+static inline s64 clocksource_subtract(struct clocksource* cs, cycle_t stop,
+ cycle_t start)
+{
+ return ((stop - start) & cs->mask);
+}
+
+/**
* clocksource_calculate_interval - Calculates a clocksource interval struct
*
* @c: Pointer to clocksource.
--
next prev parent reply other threads:[~2007-01-31 3:57 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-01-31 3:37 [PATCH 00/23] clocksource update v12 Daniel Walker
2007-01-31 3:37 ` [PATCH 01/23] clocksource: drop clocksource-add-verification-watchdog-helper-fix.patch Daniel Walker
2007-01-31 12:47 ` Ingo Molnar
2007-01-31 3:37 ` [PATCH 02/23] clocksource: drop clocksource-add-verification-watchdog-helper.patch Daniel Walker
2007-01-31 3:37 ` [PATCH 03/23] clocksource: drop clocksource-remove-the-update-callback.patch Daniel Walker
2007-01-31 3:37 ` [PATCH 04/23] clocksource: drop time-x86_64-tsc-fixup-clocksource-changes.patch Daniel Walker
2007-01-31 3:37 ` [PATCH 05/23] clocksource: drop simplify-the-registration-of-clocksources.patch Daniel Walker
2007-01-31 3:37 ` [PATCH 06/23] timekeeping: create kernel/time/timekeeping.c Daniel Walker
2007-01-31 8:59 ` Ingo Molnar
2007-01-31 15:05 ` Daniel Walker
2007-01-31 3:37 ` [PATCH 07/23] clocksource: rating sorted list Daniel Walker
2007-01-31 9:34 ` Ingo Molnar
2007-01-31 15:07 ` Daniel Walker
2007-01-31 3:37 ` [PATCH 08/23] clocksource: drop duplicate register checking Daniel Walker
2007-01-31 9:59 ` Ingo Molnar
2007-01-31 15:13 ` Daniel Walker
2007-01-31 17:19 ` Ingo Molnar
2007-01-31 3:37 ` [PATCH 09/23] clocksource: add block notifier Daniel Walker
2007-01-31 10:17 ` Ingo Molnar
2007-01-31 15:25 ` Daniel Walker
2007-01-31 17:22 ` Ingo Molnar
2007-01-31 3:37 ` [PATCH 10/23] clocksource: remove update_callback Daniel Walker
2007-01-31 10:46 ` Ingo Molnar
2007-01-31 15:42 ` Daniel Walker
2007-01-31 17:18 ` Ingo Molnar
2007-01-31 3:37 ` [PATCH 11/23] clocksource: atomic signals Daniel Walker
2007-01-31 11:07 ` Ingo Molnar
2007-01-31 15:59 ` Daniel Walker
2007-01-31 17:15 ` Ingo Molnar
2007-01-31 3:37 ` [PATCH 12/23] clocksource: add clocksource_get_clock() Daniel Walker
2007-01-31 11:46 ` Ingo Molnar
2007-01-31 16:40 ` Daniel Walker
2007-01-31 3:37 ` [PATCH 13/23] timekeeping: move sysfs layer/drop API calls Daniel Walker
2007-01-31 11:49 ` Ingo Molnar
2007-01-31 3:37 ` [PATCH 14/23] clocksource: increase initcall priority Daniel Walker
2007-01-31 11:50 ` Ingo Molnar
2007-01-31 16:42 ` Daniel Walker
2007-01-31 17:10 ` Ingo Molnar
2007-01-31 17:20 ` Daniel Walker
2007-01-31 17:29 ` Thomas Gleixner
2007-01-31 3:37 ` [PATCH 15/23] clocksource: add new flags Daniel Walker
2007-01-31 3:37 ` [PATCH 16/23] clocksource: arm update for " Daniel Walker
2007-01-31 12:27 ` Ingo Molnar
2007-01-31 3:37 ` [PATCH 17/23] clocksource: avr32 " Daniel Walker
2007-01-31 3:37 ` [PATCH 18/23] clocksource: i386 " Daniel Walker
2007-01-31 3:37 ` [PATCH 19/23] clocksource: mips " Daniel Walker
2007-01-31 3:37 ` [PATCH 20/23] clocksource: x86_64 " Daniel Walker
2007-01-31 3:37 ` [PATCH 21/23] clocksource: drivers/ " Daniel Walker
2007-01-31 3:37 ` [PATCH 22/23] clocksource: new clock lookup method Daniel Walker
[not found] ` <20070131122215.GE1847@elte.hu>
[not found] ` <1170261439.9781.96.camel@imap.mvista.com>
[not found] ` <20070131164918.GA4468@elte.hu>
[not found] ` <1170265169.9781.145.camel@imap.mvista.com>
2007-01-31 17:55 ` Thomas Gleixner
2007-01-31 18:07 ` Daniel Walker
2007-01-31 21:09 ` Thomas Gleixner
2007-01-31 3:37 ` Daniel Walker [this message]
2007-01-31 12:43 ` [PATCH 23/23] clocksource tsc: add verify routine Ingo Molnar
2007-01-31 17:02 ` Daniel Walker
2007-01-31 17:22 ` Thomas Gleixner
2007-01-31 17:33 ` Ingo Molnar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070131033810.319576375@mvista.com \
--to=dwalker@mvista.com \
--cc=akpm@osdl.org \
--cc=johnstul@us.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.