| From 796b28aa62cf1656da5cb984d8d483761d9bf7fc Mon Sep 17 00:00:00 2001 |
| From: John Stultz <johnstul@us.ibm.com> |
| Date: Tue, 17 Jul 2012 17:49:26 -0400 |
| Subject: [PATCH] timekeeping: Fix leapsecond triggered load spike issue |
| |
| commit 4873fa070ae84a4115f0b3c9dfabc224f1bc7c51 upstream. |
| |
| The timekeeping code misses an update of the hrtimer subsystem after a |
| leap second happened. Due to that timers based on CLOCK_REALTIME are |
| either expiring a second early or late depending on whether a leap |
| second has been inserted or deleted until an operation is initiated |
| which causes that update. Unless the update happens by some other |
| means this discrepancy between the timekeeping and the hrtimer data |
| stays forever and timers are expired either early or late. |
| |
| The reported immediate workaround - $ data -s "`date`" - is causing a |
| call to clock_was_set() which updates the hrtimer data structures. |
| See: http://www.sheeri.com/content/mysql-and-leap-second-high-cpu-and-fix |
| |
| Add the missing clock_was_set() call to update_wall_time() in case of |
| a leap second event. The actual update is deferred to softirq context |
| as the necessary smp function call cannot be invoked from hard |
| interrupt context. |
| |
| Signed-off-by: John Stultz <johnstul@us.ibm.com> |
| Reported-by: Jan Engelhardt <jengelh@inai.de> |
| Reviewed-by: Ingo Molnar <mingo@kernel.org> |
| Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> |
| Acked-by: Prarit Bhargava <prarit@redhat.com> |
| Link: http://lkml.kernel.org/r/1341960205-56738-3-git-send-email-johnstul@us.ibm.com |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Cc: Prarit Bhargava <prarit@redhat.com> |
| Cc: Thomas Gleixner <tglx@linutronix.de> |
| Cc: Linux Kernel <linux-kernel@vger.kernel.org> |
| Signed-off-by: John Stultz <johnstul@us.ibm.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| --- |
| kernel/time/timekeeping.c | 2 ++ |
| 1 file changed, 2 insertions(+) |
| |
| diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c |
| index adfa89d..634c9ee 100644 |
| --- a/kernel/time/timekeeping.c |
| +++ b/kernel/time/timekeeping.c |
| @@ -769,6 +769,8 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift) |
| leap = second_overflow(xtime.tv_sec); |
| xtime.tv_sec += leap; |
| wall_to_monotonic.tv_sec -= leap; |
| + if (leap) |
| + clock_was_set_delayed(); |
| } |
| |
| /* Accumulate into raw time */ |
| -- |
| 1.7.12.rc1.1.gbce1580 |
| |