]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 27 Sep 2013 19:36:56 +0000 (12:36 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 27 Sep 2013 19:36:56 +0000 (12:36 -0700)
added patches:
timekeeping-fix-hrtick-related-deadlock-from-ntp-lock-changes.patch

queue-3.10/series
queue-3.10/timekeeping-fix-hrtick-related-deadlock-from-ntp-lock-changes.patch [new file with mode: 0644]

index dcaf871fc213ce1c1b4036c9fc7652a0b2ec804c..48f59f69d5ee7f8da6c9b2564444d3d09062d46b 100644 (file)
@@ -3,3 +3,4 @@ net-usb-cdc_ether-use-wwan-interface-for-telit-modules.patch
 cifs-fix-filp-leak-in-cifs_atomic_open.patch
 bgmac-fix-internal-switch-initialization.patch
 rt2800-fix-wrong-tx-power-compensation.patch
+timekeeping-fix-hrtick-related-deadlock-from-ntp-lock-changes.patch
diff --git a/queue-3.10/timekeeping-fix-hrtick-related-deadlock-from-ntp-lock-changes.patch b/queue-3.10/timekeeping-fix-hrtick-related-deadlock-from-ntp-lock-changes.patch
new file mode 100644 (file)
index 0000000..931fdac
--- /dev/null
@@ -0,0 +1,107 @@
+From 7bd36014460f793c19e7d6c94dab67b0afcfcb7f Mon Sep 17 00:00:00 2001
+From: John Stultz <john.stultz@linaro.org>
+Date: Wed, 11 Sep 2013 16:50:56 -0700
+Subject: timekeeping: Fix HRTICK related deadlock from ntp lock changes
+
+From: John Stultz <john.stultz@linaro.org>
+
+commit 7bd36014460f793c19e7d6c94dab67b0afcfcb7f upstream.
+
+Gerlando Falauto reported that when HRTICK is enabled, it is
+possible to trigger system deadlocks. These were hard to
+reproduce, as HRTICK has been broken in the past, but seemed
+to be connected to the timekeeping_seq lock.
+
+Since seqlock/seqcount's aren't supported w/ lockdep, I added
+some extra spinlock based locking and triggered the following
+lockdep output:
+
+[   15.849182] ntpd/4062 is trying to acquire lock:
+[   15.849765]  (&(&pool->lock)->rlock){..-...}, at: [<ffffffff810aa9b5>] __queue_work+0x145/0x480
+[   15.850051]
+[   15.850051] but task is already holding lock:
+[   15.850051]  (timekeeper_lock){-.-.-.}, at: [<ffffffff810df6df>] do_adjtimex+0x7f/0x100
+
+<snip>
+
+[   15.850051] Chain exists of: &(&pool->lock)->rlock --> &p->pi_lock --> timekeeper_lock
+[   15.850051]  Possible unsafe locking scenario:
+[   15.850051]
+[   15.850051]        CPU0                    CPU1
+[   15.850051]        ----                    ----
+[   15.850051]   lock(timekeeper_lock);
+[   15.850051]                                lock(&p->pi_lock);
+[   15.850051] lock(timekeeper_lock);
+[   15.850051] lock(&(&pool->lock)->rlock);
+[   15.850051]
+[   15.850051]  *** DEADLOCK ***
+
+The deadlock was introduced by 06c017fdd4dc48451a ("timekeeping:
+Hold timekeepering locks in do_adjtimex and hardpps") in 3.10
+
+This patch avoids this deadlock, by moving the call to
+schedule_delayed_work() outside of the timekeeper lock
+critical section.
+
+Reported-by: Gerlando Falauto <gerlando.falauto@keymile.com>
+Tested-by: Lin Ming <minggr@gmail.com>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Link: http://lkml.kernel.org/r/1378943457-27314-1-git-send-email-john.stultz@linaro.org
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/timex.h     |    1 +
+ kernel/time/ntp.c         |    6 ++----
+ kernel/time/timekeeping.c |    2 ++
+ 3 files changed, 5 insertions(+), 4 deletions(-)
+
+--- a/include/linux/timex.h
++++ b/include/linux/timex.h
+@@ -141,6 +141,7 @@ extern int do_adjtimex(struct timex *);
+ extern void hardpps(const struct timespec *, const struct timespec *);
+ int read_current_timer(unsigned long *timer_val);
++void ntp_notify_cmos_timer(void);
+ /* The clock frequency of the i8253/i8254 PIT */
+ #define PIT_TICK_RATE 1193182ul
+--- a/kernel/time/ntp.c
++++ b/kernel/time/ntp.c
+@@ -516,13 +516,13 @@ static void sync_cmos_clock(struct work_
+       schedule_delayed_work(&sync_cmos_work, timespec_to_jiffies(&next));
+ }
+-static void notify_cmos_timer(void)
++void ntp_notify_cmos_timer(void)
+ {
+       schedule_delayed_work(&sync_cmos_work, 0);
+ }
+ #else
+-static inline void notify_cmos_timer(void) { }
++void ntp_notify_cmos_timer(void) { }
+ #endif
+@@ -687,8 +687,6 @@ int __do_adjtimex(struct timex *txc, str
+       if (!(time_status & STA_NANO))
+               txc->time.tv_usec /= NSEC_PER_USEC;
+-      notify_cmos_timer();
+-
+       return result;
+ }
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -1682,6 +1682,8 @@ int do_adjtimex(struct timex *txc)
+       write_seqcount_end(&timekeeper_seq);
+       raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
++      ntp_notify_cmos_timer();
++
+       return ret;
+ }