diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2016-12-23 16:21:17 +0100 |
---|---|---|
committer | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2016-12-23 16:21:17 +0100 |
commit | e498b1662ce9fc156cd2391b06bda9356d5977a3 (patch) | |
tree | 4f42e74aeed48a03052fef4d08316ab9015b6eef | |
parent | af8baa079eec1bda7e7d9df85acc65a7bcec28c6 (diff) | |
download | linux-rt-e498b1662ce9fc156cd2391b06bda9356d5977a3.tar.gz |
[ANNOUNCE] v4.8.15-rt10v4.8.15-rt10-patches
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.patch | 2 | ||||
-rw-r--r-- | patches/hotplug-light-get-online-cpus.patch | 6 | ||||
-rw-r--r-- | patches/introduce_migrate_disable_cpu_light.patch | 2 | ||||
-rw-r--r-- | patches/localversion.patch | 2 | ||||
-rw-r--r-- | patches/rt-add-rt-locks.patch | 4 | ||||
-rw-r--r-- | patches/rtmutex--Handle-non-enqueued-waiters-gracefully.patch | 2 | ||||
-rw-r--r-- | patches/rtmutex-Prevent-dequeue-vs.-unlock-race.patch | 167 | ||||
-rw-r--r-- | patches/rtmutex-futex-prepare-rt.patch | 2 | ||||
-rw-r--r-- | patches/series | 1 |
9 files changed, 10 insertions, 178 deletions
diff --git a/patches/futex-requeue-pi-fix.patch b/patches/futex-requeue-pi-fix.patch index 8948a2e700b4..2719fd7e8926 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 44ee87349842..0297231bc0dd 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 cdefe6d736d4..6a913cd8719e 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 02952cda4bfa..e16fb07c0a7d 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 44ef1f077daa..fe0c62a07081 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 7223153e73cf..b05524f25aeb 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 3e3631820c9e..000000000000 --- 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 c4ccea157776..e2887fa2adad 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 bdc4e512a418..a09de6cf9135 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 |