summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2016-12-23 16:21:17 +0100
committerSebastian Andrzej Siewior <bigeasy@linutronix.de>2016-12-23 16:21:17 +0100
commite498b1662ce9fc156cd2391b06bda9356d5977a3 (patch)
tree4f42e74aeed48a03052fef4d08316ab9015b6eef
parentaf8baa079eec1bda7e7d9df85acc65a7bcec28c6 (diff)
download4.9-rt-patches-linux-4.8.y-rt-patches.tar.gz
Dear RT folks! I'm pleased to announce the v4.8.15-rt10 patch set. You can get this release via the git tree at: git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git v4.8.15-rt10 The RT patch against v4.8.15 can be found here: https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.8/patch-4.8.15-rt10.patch.xz The split quilt queue is available at: https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.8/patches-4.8.15-rt10.tar.xz Sebastian Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-rw-r--r--patches/futex-requeue-pi-fix.patch2
-rw-r--r--patches/hotplug-light-get-online-cpus.patch6
-rw-r--r--patches/introduce_migrate_disable_cpu_light.patch2
-rw-r--r--patches/localversion.patch2
-rw-r--r--patches/rt-add-rt-locks.patch4
-rw-r--r--patches/rtmutex--Handle-non-enqueued-waiters-gracefully.patch2
-rw-r--r--patches/rtmutex-Prevent-dequeue-vs.-unlock-race.patch167
-rw-r--r--patches/rtmutex-futex-prepare-rt.patch2
-rw-r--r--patches/series1
9 files changed, 10 insertions, 178 deletions
diff --git a/patches/futex-requeue-pi-fix.patch b/patches/futex-requeue-pi-fix.patch
index 8948a2e700b40c..2719fd7e8926ff 100644
--- a/patches/futex-requeue-pi-fix.patch
+++ b/patches/futex-requeue-pi-fix.patch
@@ -103,7 +103,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
RT_MUTEX_FULL_CHAINWALK);
--- a/kernel/locking/rtmutex_common.h
+++ b/kernel/locking/rtmutex_common.h
-@@ -98,6 +98,7 @@ enum rtmutex_chainwalk {
+@@ -99,6 +99,7 @@ enum rtmutex_chainwalk {
* PI-futex support (proxy locking functions, etc.):
*/
#define PI_WAKEUP_INPROGRESS ((struct rt_mutex_waiter *) 1)
diff --git a/patches/hotplug-light-get-online-cpus.patch b/patches/hotplug-light-get-online-cpus.patch
index 44ee873498420a..0297231bc0ddfb 100644
--- a/patches/hotplug-light-get-online-cpus.patch
+++ b/patches/hotplug-light-get-online-cpus.patch
@@ -18,7 +18,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
-@@ -192,9 +192,6 @@ static inline void cpu_notifier_register
+@@ -185,9 +185,6 @@ static inline void cpu_notifier_register
#endif /* CONFIG_SMP */
extern struct bus_type cpu_subsys;
@@ -28,7 +28,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
#ifdef CONFIG_HOTPLUG_CPU
/* Stop CPUs going up and down. */
-@@ -204,6 +201,8 @@ extern void get_online_cpus(void);
+@@ -197,6 +194,8 @@ extern void get_online_cpus(void);
extern void put_online_cpus(void);
extern void cpu_hotplug_disable(void);
extern void cpu_hotplug_enable(void);
@@ -37,7 +37,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
#define hotcpu_notifier(fn, pri) cpu_notifier(fn, pri)
#define __hotcpu_notifier(fn, pri) __cpu_notifier(fn, pri)
#define register_hotcpu_notifier(nb) register_cpu_notifier(nb)
-@@ -221,6 +220,8 @@ static inline void cpu_hotplug_done(void
+@@ -214,6 +213,8 @@ static inline void cpu_hotplug_done(void
#define put_online_cpus() do { } while (0)
#define cpu_hotplug_disable() do { } while (0)
#define cpu_hotplug_enable() do { } while (0)
diff --git a/patches/introduce_migrate_disable_cpu_light.patch b/patches/introduce_migrate_disable_cpu_light.patch
index cdefe6d736d4ed..6a913cd8719ec6 100644
--- a/patches/introduce_migrate_disable_cpu_light.patch
+++ b/patches/introduce_migrate_disable_cpu_light.patch
@@ -41,7 +41,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
-@@ -192,6 +192,9 @@ static inline void cpu_notifier_register
+@@ -185,6 +185,9 @@ static inline void cpu_notifier_register
#endif /* CONFIG_SMP */
extern struct bus_type cpu_subsys;
diff --git a/patches/localversion.patch b/patches/localversion.patch
index 02952cda4bfa23..e16fb07c0a7d6f 100644
--- a/patches/localversion.patch
+++ b/patches/localversion.patch
@@ -10,4 +10,4 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
--- /dev/null
+++ b/localversion-rt
@@ -0,0 +1 @@
-+-rt9
++-rt10
diff --git a/patches/rt-add-rt-locks.patch b/patches/rt-add-rt-locks.patch
index 44ef1f077daab1..fe0c62a0708106 100644
--- a/patches/rt-add-rt-locks.patch
+++ b/patches/rt-add-rt-locks.patch
@@ -2120,7 +2120,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
#ifdef CONFIG_DEBUG_RT_MUTEXES
unsigned long ip;
struct pid *deadlock_task_pid;
-@@ -113,7 +114,8 @@ extern int rt_mutex_finish_proxy_lock(st
+@@ -114,7 +115,8 @@ extern int rt_mutex_finish_proxy_lock(st
struct rt_mutex_waiter *waiter);
extern int rt_mutex_timed_futex_lock(struct rt_mutex *l, struct hrtimer_sleeper *to);
extern bool rt_mutex_futex_unlock(struct rt_mutex *lock,
@@ -2130,7 +2130,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
extern void rt_mutex_adjust_prio(struct task_struct *task);
#ifdef CONFIG_DEBUG_RT_MUTEXES
-@@ -122,4 +124,14 @@ extern void rt_mutex_adjust_prio(struct
+@@ -123,4 +125,14 @@ extern void rt_mutex_adjust_prio(struct
# include "rtmutex.h"
#endif
diff --git a/patches/rtmutex--Handle-non-enqueued-waiters-gracefully.patch b/patches/rtmutex--Handle-non-enqueued-waiters-gracefully.patch
index 7223153e73cff7..b05524f25aeb58 100644
--- a/patches/rtmutex--Handle-non-enqueued-waiters-gracefully.patch
+++ b/patches/rtmutex--Handle-non-enqueued-waiters-gracefully.patch
@@ -21,7 +21,7 @@ Cc: stable-rt@vger.kernel.org
--- a/kernel/locking/rtmutex.c
+++ b/kernel/locking/rtmutex.c
-@@ -1626,7 +1626,7 @@ int rt_mutex_start_proxy_lock(struct rt_
+@@ -1690,7 +1690,7 @@ int rt_mutex_start_proxy_lock(struct rt_
ret = 0;
}
diff --git a/patches/rtmutex-Prevent-dequeue-vs.-unlock-race.patch b/patches/rtmutex-Prevent-dequeue-vs.-unlock-race.patch
deleted file mode 100644
index 3e3631820c9ed1..00000000000000
--- a/patches/rtmutex-Prevent-dequeue-vs.-unlock-race.patch
+++ /dev/null
@@ -1,167 +0,0 @@
-From: Thomas Gleixner <tglx@linutronix.de>
-Date: Thu, 1 Dec 2016 16:47:21 +0100
-Subject: [PATCH] rtmutex: Prevent dequeue vs. unlock race
-
-David reported a futex/rtmutex state corruption. It's caused by the
-following problem:
-
-CPU0 CPU1 CPU2
-
-l->owner=T1
- rt_mutex_lock(l)
- lock(l->wait_lock)
- l->owner = T1 | HAS_WAITERS;
- enqueue(T2)
- boost()
- unlock(l->wait_lock)
- schedule()
-
- rt_mutex_lock(l)
- lock(l->wait_lock)
- l->owner = T1 | HAS_WAITERS;
- enqueue(T3)
- boost()
- unlock(l->wait_lock)
- schedule()
- signal(->T2) signal(->T3)
- lock(l->wait_lock)
- dequeue(T2)
- deboost()
- unlock(l->wait_lock)
- lock(l->wait_lock)
- dequeue(T3)
- ===> wait list is now empty
- deboost()
- unlock(l->wait_lock)
- lock(l->wait_lock)
- fixup_rt_mutex_waiters()
- if (wait_list_empty(l)) {
- owner = l->owner & ~HAS_WAITERS;
- l->owner = owner
- ==> l->owner = T1
- }
-
- lock(l->wait_lock)
-rt_mutex_unlock(l) fixup_rt_mutex_waiters()
- if (wait_list_empty(l)) {
- owner = l->owner & ~HAS_WAITERS;
-cmpxchg(l->owner, T1, NULL)
- ===> Success (l->owner = NULL)
- l->owner = owner
- ==> l->owner = T1
- }
-
-That means the problem is caused by fixup_rt_mutex_waiters() which does the
-RMW to clear the waiters bit unconditionally when there are no waiters in
-the rtmutexes rbtree.
-
-This can be fatal: A concurrent unlock can release the rtmutex in the
-fastpath because the waiters bit is not set. If the cmpxchg() gets in the
-middle of the RMW operation then the previous owner, which just unlocked
-the rtmutex is set as the owner again when the write takes place after the
-successfull cmpxchg().
-
-The solution is rather trivial: Verify that the owner member of the rtmutex
-has the waiters bit set before clearing it. This does not require a
-cmpxchg() or other atomic operations because the waiters bit can only be
-set and cleared with the rtmutex wait_lock held. It's also safe against the
-fast path unlock attempt. The unlock attempt via cmpxchg() will either see
-the bit set and take the slowpath or see the bit cleared and release it
-atomically in the fastpath.
-
-It's remarkable that the test program provided by David triggers on ARM64
-and MIPS64 really quick, but it refuses to reproduce on x8664, while the
-problem exists there as well. That refusal might explain that this got not
-discovered earlier despite the bug existing from day one of the rtmutex
-implementation more than 10 years ago.
-
-Thanks to David for meticulously instrumenting the code and providing the
-information which allowed to decode this subtle problem.
-
-Fixes: 23f78d4a03c5 ("[PATCH] pi-futex: rt mutex core")
-Cc: stable@vger.kernel.org
-Cc: stable-rt@vger.kernel.org
-Reported-by: David Daney <ddaney@caviumnetworks.com>
-Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
----
- kernel/locking/rtmutex.c | 68 +++++++++++++++++++++++++++++++++++++++++++++--
- 1 file changed, 66 insertions(+), 2 deletions(-)
-
---- a/kernel/locking/rtmutex.c
-+++ b/kernel/locking/rtmutex.c
-@@ -65,8 +65,72 @@ static inline void clear_rt_mutex_waiter
-
- static void fixup_rt_mutex_waiters(struct rt_mutex *lock)
- {
-- if (!rt_mutex_has_waiters(lock))
-- clear_rt_mutex_waiters(lock);
-+ unsigned long owner, *p = (unsigned long *) &lock->owner;
-+
-+ if (rt_mutex_has_waiters(lock))
-+ return;
-+
-+ /*
-+ * The rbtree has no waiters enqueued, now make sure that the
-+ * lock->owner still has the waiters bit set, otherwise the
-+ * following can happen:
-+ *
-+ * CPU 0 CPU 1 CPU2
-+ * l->owner=T1
-+ * rt_mutex_lock(l)
-+ * lock(l->lock)
-+ * l->owner = T1 | HAS_WAITERS;
-+ * enqueue(T2)
-+ * boost()
-+ * unlock(l->lock)
-+ * block()
-+ *
-+ * rt_mutex_lock(l)
-+ * lock(l->lock)
-+ * l->owner = T1 | HAS_WAITERS;
-+ * enqueue(T3)
-+ * boost()
-+ * unlock(l->lock)
-+ * block()
-+ * signal(->T2) signal(->T3)
-+ * lock(l->lock)
-+ * dequeue(T2)
-+ * deboost()
-+ * unlock(l->lock)
-+ * lock(l->lock)
-+ * dequeue(T3)
-+ * ==> wait list is empty
-+ * deboost()
-+ * unlock(l->lock)
-+ * lock(l->lock)
-+ * fixup_rt_mutex_waiters()
-+ * if (wait_list_empty(l) {
-+ * l->owner = owner
-+ * owner = l->owner & ~HAS_WAITERS;
-+ * ==> l->owner = T1
-+ * }
-+ * lock(l->lock)
-+ * rt_mutex_unlock(l) fixup_rt_mutex_waiters()
-+ * if (wait_list_empty(l) {
-+ * owner = l->owner & ~HAS_WAITERS;
-+ * cmpxchg(l->owner, T1, NULL)
-+ * ===> Success (l->owner = NULL)
-+ *
-+ * l->owner = owner
-+ * ==> l->owner = T1
-+ * }
-+ *
-+ * With the check for the waiter bit in place T3 on CPU2 will not
-+ * overwrite. All tasks fiddling with the waiters bit are
-+ * serialized by l->lock, so nothing else can modify the waiters
-+ * bit. If the bit is set then nothing can change l->owner either
-+ * so the simple RMW is safe. The cmpxchg() will simply fail if it
-+ * happens in the middle of the RMW because the waiters bit is
-+ * still set.
-+ */
-+ owner = READ_ONCE(*p);
-+ if (owner & RT_MUTEX_HAS_WAITERS)
-+ WRITE_ONCE(*p, owner & ~RT_MUTEX_HAS_WAITERS);
- }
-
- /*
diff --git a/patches/rtmutex-futex-prepare-rt.patch b/patches/rtmutex-futex-prepare-rt.patch
index c4ccea1577768b..e2887fa2adadf1 100644
--- a/patches/rtmutex-futex-prepare-rt.patch
+++ b/patches/rtmutex-futex-prepare-rt.patch
@@ -232,7 +232,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
return;
--- a/kernel/locking/rtmutex_common.h
+++ b/kernel/locking/rtmutex_common.h
-@@ -97,6 +97,8 @@ enum rtmutex_chainwalk {
+@@ -98,6 +98,8 @@ enum rtmutex_chainwalk {
/*
* PI-futex support (proxy locking functions, etc.):
*/
diff --git a/patches/series b/patches/series
index bdc4e512a4184a..a09de6cf9135cf 100644
--- a/patches/series
+++ b/patches/series
@@ -45,7 +45,6 @@ NFSv4-replace-seqcount_t-with-a-seqlock_t.patch
############################################################
# Submitted on LKML
############################################################
-rtmutex-Prevent-dequeue-vs.-unlock-race.patch
# SPARC part of erly printk consolidation
sparc64-use-generic-rwsem-spinlocks-rt.patch