From: Steven Rostedt <rostedt@goodmis.org>
To: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>, john stultz <johnstul@us.ibm.com>,
LKML <linux-kernel@vger.kernel.org>,
rostedt@goodmis.org
Subject: [PATCH 02/02 -rt] Include an interval timer for timeofday_periodic_hook
Date: Mon, 03 Apr 2006 11:27:13 -0400 [thread overview]
Message-ID: <1144078033.21444.13.camel@localhost.localdomain> (raw)
This patch uses an interval timer that can be updated in interrupt
context without too much latency, so that the timeofday_periodic_hook
doesn't wrap if is is prevented from executing because of a high
priority task.
-- Steve
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Index: linux-2.6.16-rt12/kernel/time/timeofday.c
===================================================================
--- linux-2.6.16-rt12.orig/kernel/time/timeofday.c 2006-04-03 11:14:29.000000000 -0400
+++ linux-2.6.16-rt12/kernel/time/timeofday.c 2006-04-03 11:18:44.000000000 -0400
@@ -69,8 +69,19 @@ static struct timespec monotonic_time_of
* cycle_last:
* Value of the clocksource at the last timeofday_periodic_hook()
* (adjusted only minorly to account for rounded off cycles)
+ * cycle_last_interval:
+ * A value called at small intervals to prevent the cycle_last
+ * from wrapping. The difference is added to cycle_last_index
+ * to keep a running value of the time from the last call to
+ * timeofday_periodic_hook.
+ * cycle_last_index:
+ * The time called by the cycle update between calls
+ * to timeofday_periodic_hook. The cycle update can be done in
+ * interrupt context, where as the periodic hook is too heavy.
*/
static cycle_t cycle_last;
+static cycle_t cycle_last_interval;
+static cycle_t cycle_last_index;
/* [clocksource_interval variables]
* ts_interval:
@@ -271,7 +282,8 @@ static inline s64 __get_nsec_offset(void
cycle_now = read_clocksource(clock);
/* calculate the delta since the last timeofday_periodic_hook: */
- cycle_delta = (cycle_now - cycle_last) & clock->mask;
+ cycle_delta = (cycle_now - cycle_last_interval) & clock->mask;
+ cycle_delta += cycle_last_index;
/* convert to nanoseconds: */
ns_offset = cyc2ns(clock, ntp_adj, cycle_delta);
@@ -575,7 +587,8 @@ static int timeofday_resume_hook(struct
* time drift.
*/
suspend_end = read_persistent_clock();
- cycle_last = read_clocksource(clock);
+ cycle_last = cycle_last_interval = read_clocksource(clock);
+ cycle_last_index = 0;
/* calculate suspend time and add it to system time: */
suspend_time = suspend_end - suspend_start;
@@ -619,6 +632,48 @@ static int timeofday_init_device(void)
device_initcall(timeofday_init_device);
+static int timeofday_update_cycles(struct hrtimer *timer)
+{
+ unsigned long flags;
+
+ cycle_t cycle_now, cycle_delta;
+
+ write_seqlock_irqsave(&system_time_lock, flags);
+
+ /* read time source & calc time since last call: */
+ cycle_now = read_clocksource(clock);
+ cycle_delta = (cycle_now - cycle_last_interval) & clock->mask;
+ cycle_last_interval = cycle_now;
+
+ cycle_last_index += cycle_delta;
+
+ write_sequnlock_irqrestore(&system_time_lock, flags);
+
+ timer->expires.tv64 += TICK_NSEC;
+
+ return HRTIMER_RESTART;
+}
+
+static struct hrtimer cycle_update_timer;
+
+static void timeofday_init_update_cycles(void)
+{
+ ktime_t now;
+
+ hrtimer_init(&cycle_update_timer, CLOCK_MONOTONIC,
+ HRTIMER_ABS);
+
+ cycle_update_timer.function = timeofday_update_cycles;
+
+#ifdef CONFIG_HIGH_RES_TIMERS
+ cycle_update_timer.mode = HRTIMER_CB_IRQSAFE;
+#endif
+ now = ktime_get();
+ now.tv64 += TICK_NSEC;
+
+ hrtimer_start(&cycle_update_timer, now, HRTIMER_ABS);
+}
+
/**
* timeofday_periodic_hook - Does periodic update of timekeeping values.
* @unused: unused value
@@ -652,10 +707,12 @@ static void timeofday_periodic_hook(unsi
/* read time source & calc time since last call: */
cycle_now = read_clocksource(clock);
check_periodic_interval(cycle_now);
- cycle_delta = (cycle_now - cycle_last) & clock->mask;
+ cycle_delta = (cycle_now - cycle_last_interval) & clock->mask;
+ cycle_delta += cycle_last_index;
+ cycle_last = cycle_last_interval = cycle_now;
+ cycle_last_index = 0;
delta_nsec = cyc2ns_fixed_rem(ts_interval, &cycle_delta, &remainder);
- cycle_last = (cycle_now - cycle_delta)&clock->mask;
/* update system_time: */
__increment_system_time(delta_nsec);
@@ -681,7 +738,8 @@ static void timeofday_periodic_hook(unsi
next = get_next_clocksource();
if (next != clock) {
/* immediately set new cycle_last: */
- cycle_last = read_clocksource(next);
+ cycle_last = cycle_last_interval = read_clocksource(next);
+ cycle_last_index = 0;
/* update cycle_now to avoid problems in accumulation later: */
cycle_now = cycle_last;
/* swap clocksources: */
@@ -728,7 +786,8 @@ static void timeofday_periodic_hook(unsi
if (cycle_delta) {
delta_nsec = cyc2ns_rem(&old_clock, ntp_adj,
cycle_delta, &remainder);
- cycle_last = cycle_now;
+ cycle_last = cycle_last_interval = cycle_now;
+ cycle_last_index = 0;
__increment_system_time(delta_nsec);
ntp_advance(delta_nsec);
}
@@ -810,7 +869,7 @@ void __init timeofday_init(void)
clock = get_next_clocksource();
/* initialize cycle_last offset base: */
- cycle_last = read_clocksource(clock);
+ cycle_last = cycle_last_interval = read_clocksource(clock);
/* initialize wall_time_offset to now: */
/* XXX - this should be something like ns_to_ktime() */
@@ -828,6 +887,8 @@ void __init timeofday_init(void)
write_sequnlock_irqrestore(&system_time_lock, flags);
+ timeofday_init_update_cycles();
+
/* install timeofday_periodic_hook timer: */
init_timer(&timeofday_timer);
timeofday_timer.function = timeofday_periodic_hook;
reply other threads:[~2006-04-03 15:27 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=1144078033.21444.13.camel@localhost.localdomain \
--to=rostedt@goodmis.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.