From: Greg Kroah-Hartman Date: Tue, 11 Feb 2014 17:53:10 +0000 (-0800) Subject: 3.13-stable patches X-Git-Tag: v3.4.80~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7188332f94d3fd3e30e25da66407275a5448d6d2;p=thirdparty%2Fkernel%2Fstable-queue.git 3.13-stable patches added patches: timekeeping-fix-lost-updates-to-tai-adjustment.patch timekeeping-fix-potential-lost-pv-notification-of-time-change.patch --- diff --git a/queue-3.13/series b/queue-3.13/series index 6c060650e04..cf266a19e69 100644 --- a/queue-3.13/series +++ b/queue-3.13/series @@ -109,3 +109,5 @@ ftrace-fix-synchronization-location-disabling-and-freeing-ftrace_ops.patch ftrace-have-function-graph-only-trace-based-on-global_ops-filters.patch powerpc-thp-fix-crash-on-mremap.patch powerpc-mm-fix-compile-error-of-pgtable-ppc64.h.patch +timekeeping-fix-lost-updates-to-tai-adjustment.patch +timekeeping-fix-potential-lost-pv-notification-of-time-change.patch diff --git a/queue-3.13/timekeeping-fix-lost-updates-to-tai-adjustment.patch b/queue-3.13/timekeeping-fix-lost-updates-to-tai-adjustment.patch new file mode 100644 index 00000000000..625b7f024a8 --- /dev/null +++ b/queue-3.13/timekeeping-fix-lost-updates-to-tai-adjustment.patch @@ -0,0 +1,53 @@ +From f55c07607a38f84b5c7e6066ee1cfe433fa5643c Mon Sep 17 00:00:00 2001 +From: John Stultz +Date: Wed, 11 Dec 2013 18:50:25 -0800 +Subject: timekeeping: Fix lost updates to tai adjustment + +From: John Stultz + +commit f55c07607a38f84b5c7e6066ee1cfe433fa5643c upstream. + +Since 48cdc135d4840 (Implement a shadow timekeeper), we have to +call timekeeping_update() after any adjustment to the timekeeping +structure in order to make sure that any adjustments to the structure +persist. + +Unfortunately, the updates to the tai offset via adjtimex do not +trigger this update, causing adjustments to the tai offset to be +made and then over-written by the previous value at the next +update_wall_time() call. + +This patch resovles the issue by calling timekeeping_update() +right after setting the tai offset. + +Cc: Sasha Levin +Cc: Thomas Gleixner +Cc: Prarit Bhargava +Cc: Richard Cochran +Cc: Ingo Molnar +Signed-off-by: John Stultz +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/timekeeping.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -610,6 +610,7 @@ void timekeeping_set_tai_offset(s32 tai_ + raw_spin_lock_irqsave(&timekeeper_lock, flags); + write_seqcount_begin(&timekeeper_seq); + __timekeeping_set_tai_offset(tk, tai_offset); ++ timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET); + write_seqcount_end(&timekeeper_seq); + raw_spin_unlock_irqrestore(&timekeeper_lock, flags); + clock_was_set(); +@@ -1698,7 +1699,7 @@ int do_adjtimex(struct timex *txc) + + if (tai != orig_tai) { + __timekeeping_set_tai_offset(tk, tai); +- update_pvclock_gtod(tk, true); ++ timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET); + clock_was_set_delayed(); + } + write_seqcount_end(&timekeeper_seq); diff --git a/queue-3.13/timekeeping-fix-potential-lost-pv-notification-of-time-change.patch b/queue-3.13/timekeeping-fix-potential-lost-pv-notification-of-time-change.patch new file mode 100644 index 00000000000..77234fa7f50 --- /dev/null +++ b/queue-3.13/timekeeping-fix-potential-lost-pv-notification-of-time-change.patch @@ -0,0 +1,123 @@ +From 5258d3f25c76f6ab86e9333abf97a55a877d3870 Mon Sep 17 00:00:00 2001 +From: John Stultz +Date: Wed, 11 Dec 2013 20:07:49 -0800 +Subject: timekeeping: Fix potential lost pv notification of time change + +From: John Stultz + +commit 5258d3f25c76f6ab86e9333abf97a55a877d3870 upstream. + +In 780427f0e11 (Indicate that clock was set in the pvclock +gtod notifier), logic was added to pass a CLOCK_WAS_SET +notification to the pvclock notifier chain. + +While that patch added a action flag returned from +accumulate_nsecs_to_secs(), it only uses the returned value +in one location, and not in the logarithmic accumulation. + +This means if a leap second triggered during the logarithmic +accumulation (which is most likely where it would happen), +the notification that the clock was set would not make it to +the pv notifiers. + +This patch extends the logarithmic_accumulation pass down +that action flag so proper notification will occur. + +This patch also changes the varialbe action -> clock_set +per Ingo's suggestion. + +Cc: Sasha Levin +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: David Vrabel +Cc: Konrad Rzeszutek Wilk +Cc: Prarit Bhargava +Cc: Richard Cochran +Cc: +Signed-off-by: John Stultz +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/timekeeping.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -1256,7 +1256,7 @@ out_adjust: + static inline unsigned int accumulate_nsecs_to_secs(struct timekeeper *tk) + { + u64 nsecps = (u64)NSEC_PER_SEC << tk->shift; +- unsigned int action = 0; ++ unsigned int clock_set = 0; + + while (tk->xtime_nsec >= nsecps) { + int leap; +@@ -1279,10 +1279,10 @@ static inline unsigned int accumulate_ns + __timekeeping_set_tai_offset(tk, tk->tai_offset - leap); + + clock_was_set_delayed(); +- action = TK_CLOCK_WAS_SET; ++ clock_set = TK_CLOCK_WAS_SET; + } + } +- return action; ++ return clock_set; + } + + /** +@@ -1295,7 +1295,8 @@ static inline unsigned int accumulate_ns + * Returns the unconsumed cycles. + */ + static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset, +- u32 shift) ++ u32 shift, ++ unsigned int *clock_set) + { + cycle_t interval = tk->cycle_interval << shift; + u64 raw_nsecs; +@@ -1309,7 +1310,7 @@ static cycle_t logarithmic_accumulation( + tk->cycle_last += interval; + + tk->xtime_nsec += tk->xtime_interval << shift; +- accumulate_nsecs_to_secs(tk); ++ *clock_set |= accumulate_nsecs_to_secs(tk); + + /* Accumulate raw time */ + raw_nsecs = (u64)tk->raw_interval << shift; +@@ -1367,7 +1368,7 @@ static void update_wall_time(void) + struct timekeeper *tk = &shadow_timekeeper; + cycle_t offset; + int shift = 0, maxshift; +- unsigned int action; ++ unsigned int clock_set = 0; + unsigned long flags; + + raw_spin_lock_irqsave(&timekeeper_lock, flags); +@@ -1402,7 +1403,8 @@ static void update_wall_time(void) + maxshift = (64 - (ilog2(ntp_tick_length())+1)) - 1; + shift = min(shift, maxshift); + while (offset >= tk->cycle_interval) { +- offset = logarithmic_accumulation(tk, offset, shift); ++ offset = logarithmic_accumulation(tk, offset, shift, ++ &clock_set); + if (offset < tk->cycle_interval<cycle_last with the new value */ +@@ -1436,7 +1438,7 @@ static void update_wall_time(void) + * updating. + */ + memcpy(real_tk, tk, sizeof(*tk)); +- timekeeping_update(real_tk, action); ++ timekeeping_update(real_tk, clock_set); + write_seqcount_end(&timekeeper_seq); + out: + raw_spin_unlock_irqrestore(&timekeeper_lock, flags);