LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Daniel Walker <dwalker@mvista.com>
To: Ingo Molnar <mingo@elte.hu>
Cc: tglx@linutronix.de, Andrew Morton <akpm@osdl.org>,
	LKML <linux-kernel@vger.kernel.org>,
	John Stultz <johnstul@us.ibm.com>,
	Arjan van de Veen <arjan@infradead.org>,
	Roman Zippel <zippel@linux-m68k.org>
Subject: Re: [patch 00/46] High resolution timer / dynamic tick update
Date: Wed, 24 Jan 2007 09:21:37 -0800	[thread overview]
Message-ID: <1169659297.19471.247.camel@imap.mvista.com> (raw)
In-Reply-To: <20070124160046.GA24798@elte.hu>

On Wed, 2007-01-24 at 17:00 +0100, Ingo Molnar wrote:
> you are also misunderstand the change. While the TSC is the only 
> unstable clocksource right now, the previous code tied the TSC to the
> >pm-timer< clocksource. This change makes it generic, hence the TSC can
> be verified by a hpet-only system (no pm-timer) as well. Systems without 
> a pm-timer and with a TSC are quite common. So it solves a real problem.

Here is an example of what I was talking about in my last email . This
is a TSC specific clock verify ontop of -mm + my patches. It will use
and acpi_pm or and hpet (or pit or whatever) . Clearly the
implementation details could be worked on but the clock access would
remain largely the same.

Signed-Off-By: Daniel Walker <dwalker@mvista.com>

---
 arch/i386/kernel/tsc.c      |   93 ++++++++++++++++++++------------------------
 include/linux/clocksource.h |    5 ++
 2 files changed, 49 insertions(+), 49 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,7 +343,7 @@ static struct clocksource clocksource_ts
 	.mask			= CLOCKSOURCE_MASK(64),
 	.mult			= 0, /* to be set */
 	.shift			= 22,
-	.flags			= CLOCKSOURCE_64BITS,
+	.flags			= CLOCKSOURCE_64BITS | CLOCKSOURCE_PM_AFFECTED,
 	.list			= LIST_HEAD_INIT(clocksource_tsc.list),
 };
 
@@ -382,55 +382,54 @@ static struct dmi_system_id __initdata b
 	 {}
 };
 
-#define TSC_FREQ_CHECK_INTERVAL MSEC_PER_SEC
+#define WATCHDOG_TRESHOLD (NSEC_PER_SEC >> 4)
+#define TSC_FREQ_CHECK_INTERVAL (MSEC_PER_SEC/2)
 static struct timer_list verify_tsc_freq_timer;
 static unsigned long pm_multiplier;
+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, last_pm;
+	static unsigned long last_jiffies;
+	static cycle_t last_tsc, last_verify;
 
-	u64 now_tsc, interval_tsc, tmp;
-	unsigned long now_jiffies, interval_jiffies, pm, pm_delta;
+	cycle_t now_tsc, interval_tsc, verify_clock_now, interval_verify;
+	unsigned long now_jiffies, interval_jiffies;
+	s64 ns_tsc, ns_verify, clock_diff;
 
 	if (check_tsc_unstable())
 		return;
 
-	rdtscll(now_tsc);
 	now_jiffies = jiffies;
-	pm = acpi_pm_read_early();
+
+	now_tsc = clocksource_read(&clocksource_tsc);
+	verify_clock_now = clocksource_read(verify_clock);
 
 	if (!last_jiffies)
 		goto out;
 
-	interval_tsc = now_tsc - last_tsc;
-	interval_tsc *= HZ;
-	do_div(interval_tsc, cpu_khz*1000);
-
-	if (pm == last_pm) {
-		interval_jiffies = now_jiffies - last_jiffies;
-	} else {
-		if (pm < last_pm)
-			pm_delta = (pm + ACPI_PM_OVRRUN) - last_pm;
-		else
-			pm_delta = pm - last_pm;
-		tmp = (((u64) pm_delta) * pm_multiplier) >> 22;
-		do_div(tmp, (NSEC_PER_SEC/HZ));
-		interval_jiffies = (unsigned long) tmp;
-	}
 
-	if (interval_tsc < (interval_jiffies * 3 / 4)) {
+	interval_tsc = clocksource_subtract(&clocksource_tsc, last_tsc, now_tsc);
+	interval_verify = clocksource_subtract(verify_clock, last_verify,
+					       verify_clock_now);
+
+	ns_tsc = cyc2ns(&clocksource_tsc, interval_tsc);
+	ns_verify = cyc2ns(verify_clock, interval_verify);
+
+	clock_diff = ns_tsc - ns_verify;
+	if (abs(clock_diff) > 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_pm = pm;
+	last_verify = verify_clock_now;
+
 	/* set us up to go off on the next interval: */
 	mod_timer(&verify_tsc_freq_timer,
 		jiffies + msecs_to_jiffies(TSC_FREQ_CHECK_INTERVAL));
@@ -471,29 +470,6 @@ static int __init init_tsc_clocksource(v
 		if (check_tsc_unstable())
 			clocksource_tsc.flags |= CLOCKSOURCE_UNSTABLE;
 
-		/*
-		 * Mark TSC unsuitable for high resolution timers, when
-		 * pm_timer is not available as a fallback. TSC has so many
-		 * pitfalls: frequency changes, stop in idle ...  When we
-		 * switch to high resolution mode we can not longer detect a
-		 * firmware caused frequency change, as the emulated tick uses
-		 * TSC as reference. This results in a circular dependency.
-		 * Switch only to high resolution mode, if pm_timer or such is
-		 * available.
-		 */
-		if (!pmtmr_ioport) {
-			mark_tsc_unstable();
-			clocksource_tsc.flags &= CLOCKSOURCE_UNSTABLE;
-		}
-
-		pm_multiplier = clocksource_hz2mult(PMTMR_TICKS_PER_SEC, 22);
-
-		init_timer(&verify_tsc_freq_timer);
-		verify_tsc_freq_timer.function = verify_tsc_freq;
-		verify_tsc_freq_timer.expires =
-			jiffies + msecs_to_jiffies(TSC_FREQ_CHECK_INTERVAL);
-		add_timer(&verify_tsc_freq_timer);
-
 		return clocksource_register(&clocksource_tsc);
 	}
 
@@ -501,3 +477,22 @@ static int __init init_tsc_clocksource(v
 }
 
 fs_initcall(init_tsc_clocksource);
+
+void tsc_verify_init(void)
+{
+	verify_clock = clocksource_get_clock(NULL, CLOCKSOURCE_PM_AFFECTED);
+	if (!verify_clock) {
+		printk("TSC: Verify clock not found!\n");
+		return;
+	}
+
+	printk("TSC: selected %s for TSC verification\n", verify_clock->name);
+
+	init_timer(&verify_tsc_freq_timer);
+	verify_tsc_freq_timer.function = verify_tsc_freq;
+	verify_tsc_freq_timer.expires =
+		jiffies + msecs_to_jiffies(TSC_FREQ_CHECK_INTERVAL);
+	add_timer(&verify_tsc_freq_timer);
+
+}
+device_initcall(tsc_verify_init);
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,11 @@ static inline s64 cyc2ns(struct clocksou
 	return ret;
 }
 
+static inline s64 clocksource_subtract(struct clocksource* cs, s64 start, s64 stop)
+{
+	return ((stop - start) & cs->mask);
+}
+
 /**
  * clocksource_calculate_interval - Calculates a clocksource interval struct
  *



  parent reply	other threads:[~2007-01-24 17:22 UTC|newest]

Thread overview: 78+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-23 22:00 Thomas Gleixner
2007-01-23 22:00 ` [patch 01/46] Add irq flag to disable balancing for an interrupt Thomas Gleixner
2007-01-23 22:00 ` [patch 02/46] Add a functions to handle interrupt affinity setting Thomas Gleixner
2007-01-23 22:00 ` [patch 03/46] [RFC] HZ free ntp Thomas Gleixner
2007-01-23 22:00 ` [patch 04/46] Uninline jiffies.h functions Thomas Gleixner
2007-01-23 22:01 ` [patch 05/46] Thomas Gleixner
2007-01-23 22:01 ` [patch 06/46] Fix timeout overflow with jiffies Thomas Gleixner
2007-01-23 22:01 ` [patch 07/46] GTOD: persistent clock support Thomas Gleixner
2007-01-23 22:01 ` [patch 08/46] i386: use GTOD " Thomas Gleixner
2007-01-23 22:01 ` [patch 09/46] i386 Remove useless code in tsc.c Thomas Gleixner
2007-01-23 22:01 ` [patch 10/46] Simplify the registration of clocksources Thomas Gleixner
2007-01-23 22:01 ` [patch 11/46] x86: rewrite SMP TSC sync code Thomas Gleixner
2007-01-23 22:01 ` [patch 12/46] clocksource: replace is_continuous by a flag field Thomas Gleixner
2007-01-24 11:23   ` [patch] clocksource: fixup is_continous changes in vmitime.c Ingo Molnar
2007-01-24 11:53     ` Thomas Gleixner
2007-01-23 22:01 ` [patch 13/46] clocksource: fixup is_continous changes on ARM Thomas Gleixner
2007-01-23 22:01 ` [patch 14/46] clocksource: fixup is_continous changes on AVR32 Thomas Gleixner
2007-01-23 22:01 ` [patch 15/46] clocksource: fixup is_continous changes on S390 Thomas Gleixner
2007-01-23 22:01 ` [patch 16/46] clocksource: fixup is_continous changes on MIPS Thomas Gleixner
2007-01-23 22:01 ` [patch 17/46] clocksource: Remove the update callback Thomas Gleixner
2007-01-23 22:01 ` [patch 18/46] clocksource: Add verification (watchdog) helper Thomas Gleixner
2007-01-24 15:42   ` [patch] clocksource: add verification (watchdog) helper, fix Ingo Molnar
2007-01-23 22:01 ` [patch 19/46] Mark TSC on GeodeLX reliable Thomas Gleixner
2007-01-23 22:01 ` [patch 20/46] uninline irq_enter() Thomas Gleixner
2007-01-23 22:01 ` [patch 21/46] Fix cascade lookup of next_timer_interrupt Thomas Gleixner
2007-01-23 22:01 ` [patch 22/46] Extend next_timer_interrupt() to use a reference jiffie Thomas Gleixner
2007-01-23 22:01 ` [patch 23/46] hrtimers: namespace and enum cleanup Thomas Gleixner
2007-01-23 22:01 ` [patch 24/46] hrtimers: namespace and enum cleanup vs. git-input Thomas Gleixner
2007-01-23 22:01 ` [patch 25/46] hrtimers: cleanup locking Thomas Gleixner
2007-01-23 22:01 ` [patch 26/46] hrtimers; add state tracking Thomas Gleixner
2007-01-23 22:01 ` [patch 27/46] hrtimers: clean up callback tracking Thomas Gleixner
2007-01-23 22:01 ` [patch 28/46] hrtimers: move and add documentation Thomas Gleixner
2007-01-23 22:01 ` [patch 29/46] ACPI: fix missing include for UP Thomas Gleixner
2007-01-23 22:01 ` [patch 30/46] ACPI keep track of timer broadcasting Thomas Gleixner
2007-01-23 22:01 ` [patch 31/46] Allow early access to the power management timer Thomas Gleixner
2007-01-23 22:01 ` [patch 32/46] i386, apic: clean up the APIC code Thomas Gleixner
2007-01-23 22:01 ` [patch 33/46] clockevents: add core functionality Thomas Gleixner
2007-01-23 22:01 ` [patch 34/46] tick-management: " Thomas Gleixner
2007-01-23 22:01 ` [patch 35/46] tick-management: broadcast functionality Thomas Gleixner
2007-01-23 22:01 ` [patch 36/46] tick-management: dyntick / highres functionality Thomas Gleixner
2007-01-28  2:03   ` [PATCH] high_res_timers: precisely update_process_times; " Karsten Wiese
2007-01-23 22:01 ` [patch 37/46] clockevents: i383 drivers Thomas Gleixner
2007-01-23 22:01 ` [patch 38/46] i386 rework local apic timer calibration Thomas Gleixner
2007-01-23 22:01 ` [patch 39/46] i386 prepare for dyntick Thomas Gleixner
2007-01-23 22:01 ` [patch 40/46] i386 prepare nmi watchdog for dynticks Thomas Gleixner
2007-01-23 22:01 ` [patch 41/46] i386: enable dynticks in kconfig Thomas Gleixner
2007-01-23 22:01 ` [patch 42/46] hrtimers: add high resolution timer support Thomas Gleixner
2007-01-23 22:01 ` [patch 43/46] hrtimers: prevent possible itimer DoS Thomas Gleixner
2007-01-23 22:01 ` [patch 44/46] Add debugging feature /proc/timer_stat Thomas Gleixner
2007-01-23 22:01 ` [patch 45/46] Add debugging feature /proc/timer_list Thomas Gleixner
2007-01-23 22:01 ` [patch 46/46] Add SysRq-Q to print timer_list debug info Thomas Gleixner
2007-01-24  2:16 ` [patch 00/46] High resolution timer / dynamic tick update Daniel Walker
2007-01-24  2:23   ` Andrew Morton
2007-01-24  3:25     ` Daniel Walker
2007-01-24  7:07   ` Ingo Molnar
2007-01-24  9:30     ` Daniel Walker
2007-01-24  9:51       ` Ingo Molnar
2007-01-24 10:23         ` Daniel Walker
2007-01-24 10:29           ` Ingo Molnar
2007-01-24 10:53             ` Daniel Walker
2007-01-24 11:04               ` Ingo Molnar
2007-01-24 11:13           ` Thomas Gleixner
2007-01-24 15:53             ` Daniel Walker
     [not found]               ` <20070124160046.GA24798@elte.hu>
2007-01-24 17:21                 ` Daniel Walker [this message]
     [not found]                 ` <1169655076.19471.241.camel@imap.mvista.com>
2007-01-24 19:38                   ` Ingo Molnar
2007-01-24 20:09                     ` Daniel Walker
2007-01-24 20:13                       ` Ingo Molnar
2007-01-24 19:57       ` john stultz
2007-01-24 20:51         ` Daniel Walker
2007-01-24 21:23           ` john stultz
2007-01-24 21:37             ` Daniel Walker
2007-01-25  6:10           ` Ingo Molnar
2007-01-25  6:37           ` Ingo Molnar
2007-01-25  6:32         ` Ingo Molnar
2007-01-25 16:38           ` Daniel Walker
2007-01-28  2:17 ` Andrew Morton
2007-01-29 21:31   ` john stultz
2007-01-29 21:45     ` john stultz

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=1169659297.19471.247.camel@imap.mvista.com \
    --to=dwalker@mvista.com \
    --cc=akpm@osdl.org \
    --cc=arjan@infradead.org \
    --cc=johnstul@us.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=tglx@linutronix.de \
    --cc=zippel@linux-m68k.org \
    --subject='Re: [patch 00/46] High resolution timer / dynamic tick update' \
    /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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).