linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] Fix for leapsecond caused hrtimer/futex issue (updated)
@ 2012-07-10 22:43 John Stultz
  2012-07-10 22:43 ` [PATCH 1/6] hrtimer: Provide clock_was_set_delayed() John Stultz
                   ` (11 more replies)
  0 siblings, 12 replies; 37+ messages in thread
From: John Stultz @ 2012-07-10 22:43 UTC (permalink / raw)
  To: Linux Kernel
  Cc: John Stultz, Ingo Molnar, Peter Zijlstra, Prarit Bhargava,
	Thomas Gleixner, stable

Over the weekend, Thomas got a chance to review the leap second fix
in more detail and had a few additional changes he wanted to make
to improve performance as well as style.

So this iteration includes his modifications.

Once merged, I'll be working to get the backports finished as quickly
as I can and sent to -stable.

thanks
-john

CC: Ingo Molnar <mingo@kernel.org>
CC: Peter Zijlstra <a.p.zijlstra@chello.nl>
CC: Prarit Bhargava <prarit@redhat.com>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: stable@vger.kernel.org


John Stultz (3):
  hrtimer: Provide clock_was_set_delayed()
  timekeeping: Fix leapsecond triggered load spike issue
  hrtimer: Update hrtimer base offsets each hrtimer_interrupt

Thomas Gleixner (3):
  timekeeping: Maintain ktime_t based offsets for hrtimers
  hrtimer: Move lock held region in hrtimer_interrupt()
  timekeeping: Provide hrtimer update function

 include/linux/hrtimer.h   |    6 ++++-
 kernel/hrtimer.c          |   53 ++++++++++++++++++++++++++------------
 kernel/time/timekeeping.c |   63 +++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 103 insertions(+), 19 deletions(-)

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 37+ messages in thread
* [PATCH 3/3] hrtimer: Update hrtimer base offsets each hrtimer_interrupt
@ 2012-07-05 19:12 John Stultz
  2012-07-09  9:44 ` [tip:timers/urgent] " tip-bot for John Stultz
  0 siblings, 1 reply; 37+ messages in thread
From: John Stultz @ 2012-07-05 19:12 UTC (permalink / raw)
  To: Linux Kernel; +Cc: John Stultz, Prarit Bhargava, stable, Thomas Gleixner

This patch introduces a new funciton which captures the
CLOCK_MONOTONIC time, along with the CLOCK_REALTIME and
CLOCK_BOOTTIME offsets at the same moment. This new function
is then used in place of ktime_get() when hrtimer_interrupt()
is expiring timers.

This ensures that any changes to realtime or boottime offsets
are noticed and stored into the per-cpu hrtimer base structures,
prior to doing any hrtimer expiration. This should ensure that
timers are not expired early if the offsets changes under us.

This is useful in the case where clock_was_set() is called from
atomic context and have to schedule the hrtimer base offset update
via a timer, as it provides extra robustness in the face of any
possible timer delay.

CC: Prarit Bhargava <prarit@redhat.com>
CC: stable@vger.kernel.org
CC: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Prarit Bhargava <prarit@redhat.com>
Signed-off-by: John Stultz <johnstul@us.ibm.com>
---
 include/linux/hrtimer.h   |    3 +++
 kernel/hrtimer.c          |   14 +++++++++++---
 kernel/time/timekeeping.c |   34 ++++++++++++++++++++++++++++++++++
 3 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index fd0dc30..f6b2a74 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -320,6 +320,9 @@ extern ktime_t ktime_get(void);
 extern ktime_t ktime_get_real(void);
 extern ktime_t ktime_get_boottime(void);
 extern ktime_t ktime_get_monotonic_offset(void);
+extern void ktime_get_and_real_and_sleep_offset(ktime_t *monotonic,
+						ktime_t *real_offset,
+						ktime_t *sleep_offset);
 
 DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
 
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index d730678..56600c4 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -1258,18 +1258,26 @@ static void __run_hrtimer(struct hrtimer *timer, ktime_t *now)
 void hrtimer_interrupt(struct clock_event_device *dev)
 {
 	struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
-	ktime_t expires_next, now, entry_time, delta;
+	ktime_t expires_next, now, entry_time, delta, real_offset, sleep_offset;
 	int i, retries = 0;
 
 	BUG_ON(!cpu_base->hres_active);
 	cpu_base->nr_events++;
 	dev->next_event.tv64 = KTIME_MAX;
 
-	entry_time = now = ktime_get();
+
+	ktime_get_and_real_and_sleep_offset(&now, &real_offset, &sleep_offset);
+
+	entry_time = now;
 retry:
 	expires_next.tv64 = KTIME_MAX;
 
 	raw_spin_lock(&cpu_base->lock);
+
+	/* Update base offsets, to avoid early wakeups */
+	cpu_base->clock_base[HRTIMER_BASE_REALTIME].offset = real_offset;
+	cpu_base->clock_base[HRTIMER_BASE_BOOTTIME].offset = sleep_offset;
+
 	/*
 	 * We set expires_next to KTIME_MAX here with cpu_base->lock
 	 * held to prevent that a timer is enqueued in our queue via
@@ -1346,7 +1354,7 @@ retry:
 	 * interrupt routine. We give it 3 attempts to avoid
 	 * overreacting on some spurious event.
 	 */
-	now = ktime_get();
+	ktime_get_and_real_and_sleep_offset(&now, &real_offset, &sleep_offset);
 	cpu_base->nr_retries++;
 	if (++retries < 3)
 		goto retry;
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index cc2991d..b3404cf 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1251,6 +1251,40 @@ void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim,
 }
 
 /**
+ * ktime_get_and_real_and_sleep_offset() - hrtimer helper, gets monotonic ktime,
+ *	realtime offset, and sleep offsets.
+ */
+void ktime_get_and_real_and_sleep_offset(ktime_t *monotonic,
+						ktime_t *real_offset,
+						ktime_t *sleep_offset)
+{
+	unsigned long seq;
+	struct timespec wtom, sleep;
+	u64 secs, nsecs;
+
+	do {
+		seq = read_seqbegin(&timekeeper.lock);
+
+		secs = timekeeper.xtime.tv_sec +
+				timekeeper.wall_to_monotonic.tv_sec;
+		nsecs = timekeeper.xtime.tv_nsec +
+				timekeeper.wall_to_monotonic.tv_nsec;
+		nsecs += timekeeping_get_ns();
+		/* If arch requires, add in gettimeoffset() */
+		nsecs += arch_gettimeoffset();
+
+		wtom = timekeeper.wall_to_monotonic;
+		sleep = timekeeper.total_sleep_time;
+	} while (read_seqretry(&timekeeper.lock, seq));
+
+	*monotonic = ktime_add_ns(ktime_set(secs, 0), nsecs);
+	set_normalized_timespec(&wtom, -wtom.tv_sec, -wtom.tv_nsec);
+	*real_offset =	timespec_to_ktime(wtom);
+	*sleep_offset = timespec_to_ktime(sleep);
+}
+
+
+/**
  * ktime_get_monotonic_offset() - get wall_to_monotonic in ktime_t format
  */
 ktime_t ktime_get_monotonic_offset(void)
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2012-07-15 20:23 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-10 22:43 [PATCH 0/6] Fix for leapsecond caused hrtimer/futex issue (updated) John Stultz
2012-07-10 22:43 ` [PATCH 1/6] hrtimer: Provide clock_was_set_delayed() John Stultz
2012-07-11 12:15   ` Prarit Bhargava
2012-07-11 12:45     ` Thomas Gleixner
2012-07-11 13:05       ` Peter Zijlstra
2012-07-11 15:18         ` Thomas Gleixner
2012-07-11 15:56           ` Peter Zijlstra
2012-07-11 16:47           ` John Stultz
2012-07-12  7:44             ` Jan Ceuleers
2012-07-12 12:29               ` Prarit Bhargava
2012-07-11 13:05       ` Prarit Bhargava
2012-07-11 13:38         ` Peter Zijlstra
2012-07-11 21:40   ` [tip:timers/urgent] " tip-bot for John Stultz
2012-07-10 22:43 ` [PATCH 2/6] timekeeping: Fix leapsecond triggered load spike issue John Stultz
2012-07-11 21:41   ` [tip:timers/urgent] " tip-bot for John Stultz
2012-07-10 22:43 ` [PATCH 3/6] timekeeping: Maintain ktime_t based offsets for hrtimers John Stultz
2012-07-11 21:42   ` [tip:timers/urgent] " tip-bot for Thomas Gleixner
2012-07-10 22:43 ` [PATCH 4/6] hrtimer: Move lock held region in hrtimer_interrupt() John Stultz
2012-07-10 22:43 ` [PATCH 4/6] hrtimers: " John Stultz
2012-07-11 21:43   ` [tip:timers/urgent] " tip-bot for Thomas Gleixner
2012-07-10 22:43 ` [PATCH 5/6] timekeeping: Provide hrtimer update function John Stultz
2012-07-11 21:44   ` [tip:timers/urgent] " tip-bot for Thomas Gleixner
2012-07-10 22:43 ` [PATCH 6/6] hrtimer: Update hrtimer base offsets each hrtimer_interrupt John Stultz
2012-07-11 21:45   ` [tip:timers/urgent] " tip-bot for John Stultz
2012-07-15 15:22   ` [PATCH 6/6] " Andreas Schwab
2012-07-15 20:28     ` Rafael J. Wysocki
     [not found]   ` <m2y5mlnj5z.fsf__49536.0585897744$1342365803$gmane$org@igel.home>
2012-07-15 16:02     ` Andreas Schwab
2012-07-10 22:53 ` [PATCH 0/6] Fix for leapsecond caused hrtimer/futex issue (updated) John Stultz
2012-07-12 22:43   ` Jiri Bohac
2012-07-12 23:58     ` John Stultz
2012-07-10 23:00 ` John Stultz
2012-07-13  0:43   ` John Stultz
2012-07-11 10:59 ` Peter Zijlstra
2012-07-11 11:17 ` Ingo Molnar
2012-07-12 12:32   ` Prarit Bhargava
2012-07-11 12:16 ` Prarit Bhargava
  -- strict thread matches above, loose matches on Subject: below --
2012-07-05 19:12 [PATCH 3/3] hrtimer: Update hrtimer base offsets each hrtimer_interrupt John Stultz
2012-07-09  9:44 ` [tip:timers/urgent] " tip-bot for John Stultz

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).