diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2017-09-01 10:35:59 +0200 |
---|---|---|
committer | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2017-09-01 10:35:59 +0200 |
commit | a43794cd01154b6778fb82eec344ffdf776cea08 (patch) | |
tree | ae47fb31de07a74e318a91a9b6e2e215ac72bdaf | |
parent | 5a4f22d5ee59f1e83f70b870afcf7f78b3f7ac6c (diff) | |
download | linux-rt-a43794cd01154b6778fb82eec344ffdf776cea08.tar.gz |
[ANNOUNCE] v4.11.12-rt11v4.11.12-rt11-patches
Dear RT folks!
I'm pleased to announce the v4.11.12-rt11 patch set.
Changes since v4.11.12-rt10:
- Jacek Konieczny reported a lockdep splat of tcp_sk_lock vs softirq.
- Mike Galbraith fixed a lockdep splat in the zcomp driver.
- Mike Galbraith reported a locking problem in hrtimer during CPU
hotplug.
Known issues
- There was a report regarding a deadlock within the rtmutex code.
The delta patch against v4.11.12-rt10 is appended below and can be found here:
https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.11/incr/patch-4.11.12-rt10-rt11.patch.xz
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.11.12-rt11
The RT patch against v4.11.12 can be found here:
https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.11/older/patch-4.11.12-rt11.patch.xz
The split quilt queue is available at:
https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.11/older/patches-4.11.12-rt11.tar.xz
Sebastian
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -120,7 +120,7 @@ struct zcomp_strm *zcomp_stream_get(struct zcomp *comp)
{
struct zcomp_strm *zstrm;
- zstrm = *this_cpu_ptr(comp->stream);
+ zstrm = *get_local_ptr(comp->stream);
spin_lock(&zstrm->zcomp_lock);
return zstrm;
}
@@ -131,6 +131,7 @@ void zcomp_stream_put(struct zcomp *comp)
zstrm = *this_cpu_ptr(comp->stream);
spin_unlock(&zstrm->zcomp_lock);
+ put_local_ptr(zstrm);
}
int zcomp_compress(struct zcomp_strm *zstrm,
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1391,7 +1391,7 @@ static inline int hrtimer_rt_defer(struct hrtimer *timer) { return 0; }
#endif
-static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now)
+static int __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now)
{
struct hrtimer_clock_base *base = cpu_base->clock_base;
unsigned int active = cpu_base->active_bases;
@@ -1432,8 +1432,7 @@ static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now)
raise = 1;
}
}
- if (raise)
- raise_softirq_irqoff(HRTIMER_SOFTIRQ);
+ return raise;
}
#ifdef CONFIG_HIGH_RES_TIMERS
@@ -1447,6 +1446,7 @@ void hrtimer_interrupt(struct clock_event_device *dev)
struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases);
ktime_t expires_next, now, entry_time, delta;
int retries = 0;
+ int raise;
BUG_ON(!cpu_base->hres_active);
cpu_base->nr_events++;
@@ -1465,7 +1465,7 @@ void hrtimer_interrupt(struct clock_event_device *dev)
*/
cpu_base->expires_next = KTIME_MAX;
- __hrtimer_run_queues(cpu_base, now);
+ raise = __hrtimer_run_queues(cpu_base, now);
/* Reevaluate the clock bases for the next expiry */
expires_next = __hrtimer_get_next_event(cpu_base);
@@ -1476,6 +1476,8 @@ void hrtimer_interrupt(struct clock_event_device *dev)
cpu_base->expires_next = expires_next;
cpu_base->in_hrtirq = 0;
raw_spin_unlock(&cpu_base->lock);
+ if (raise)
+ raise_softirq_irqoff(HRTIMER_SOFTIRQ);
/* Reprogramming necessary ? */
if (!tick_program_event(expires_next, 0)) {
@@ -1555,6 +1557,7 @@ void hrtimer_run_queues(void)
{
struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases);
ktime_t now;
+ int raise;
if (__hrtimer_hres_active(cpu_base))
return;
@@ -1573,8 +1576,10 @@ void hrtimer_run_queues(void)
raw_spin_lock(&cpu_base->lock);
now = hrtimer_update_base(cpu_base);
- __hrtimer_run_queues(cpu_base, now);
+ raise = __hrtimer_run_queues(cpu_base, now);
raw_spin_unlock(&cpu_base->lock);
+ if (raise)
+ raise_softirq_irqoff(HRTIMER_SOFTIRQ);
}
/*
diff --git a/localversion-rt b/localversion-rt
--- a/localversion-rt
+++ b/localversion-rt
@@ -1 +1 @@
--rt10
+-rt11
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -713,8 +713,8 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb)
arg.tos = ip_hdr(skb)->tos;
arg.uid = sock_net_uid(net, sk && sk_fullsock(sk) ? sk : NULL);
- local_lock(tcp_sk_lock);
local_bh_disable();
+ local_lock(tcp_sk_lock);
ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk),
skb, &TCP_SKB_CB(skb)->header.h4.opt,
ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
@@ -722,8 +722,8 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb)
__TCP_INC_STATS(net, TCP_MIB_OUTSEGS);
__TCP_INC_STATS(net, TCP_MIB_OUTRSTS);
- local_bh_enable();
local_unlock(tcp_sk_lock);
+ local_bh_enable();
#ifdef CONFIG_TCP_MD5SIG
out:
@@ -801,16 +801,16 @@ static void tcp_v4_send_ack(const struct sock *sk,
arg.bound_dev_if = oif;
arg.tos = tos;
arg.uid = sock_net_uid(net, sk_fullsock(sk) ? sk : NULL);
- local_lock(tcp_sk_lock);
local_bh_disable();
+ local_lock(tcp_sk_lock);
ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk),
skb, &TCP_SKB_CB(skb)->header.h4.opt,
ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
&arg, arg.iov[0].iov_len);
__TCP_INC_STATS(net, TCP_MIB_OUTSEGS);
- local_bh_enable();
local_unlock(tcp_sk_lock);
+ local_bh_enable();
}
static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
8 files changed, 202 insertions, 9 deletions
diff --git a/patches/cpu_chill-Add-a-UNINTERRUPTIBLE-hrtimer_nanosleep.patch b/patches/cpu_chill-Add-a-UNINTERRUPTIBLE-hrtimer_nanosleep.patch index 6604d0695ae8..95494c5e7a19 100644 --- a/patches/cpu_chill-Add-a-UNINTERRUPTIBLE-hrtimer_nanosleep.patch +++ b/patches/cpu_chill-Add-a-UNINTERRUPTIBLE-hrtimer_nanosleep.patch @@ -33,7 +33,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -1601,12 +1601,13 @@ void hrtimer_init_sleeper(struct hrtimer +@@ -1606,12 +1606,13 @@ void hrtimer_init_sleeper(struct hrtimer } EXPORT_SYMBOL_GPL(hrtimer_init_sleeper); @@ -49,7 +49,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> hrtimer_start_expires(&t->timer, mode); if (likely(t->task)) -@@ -1648,7 +1649,8 @@ long __sched hrtimer_nanosleep_restart(s +@@ -1653,7 +1654,8 @@ long __sched hrtimer_nanosleep_restart(s HRTIMER_MODE_ABS); hrtimer_set_expires_tv64(&t.timer, restart->nanosleep.expires); @@ -59,7 +59,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> goto out; rmtp = restart->nanosleep.rmtp; -@@ -1665,8 +1667,10 @@ long __sched hrtimer_nanosleep_restart(s +@@ -1670,8 +1672,10 @@ long __sched hrtimer_nanosleep_restart(s return ret; } @@ -72,7 +72,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> { struct restart_block *restart; struct hrtimer_sleeper t; -@@ -1679,7 +1683,7 @@ long hrtimer_nanosleep(struct timespec * +@@ -1684,7 +1688,7 @@ long hrtimer_nanosleep(struct timespec * hrtimer_init_on_stack(&t.timer, clockid, mode); hrtimer_set_expires_range_ns(&t.timer, timespec_to_ktime(*rqtp), slack); @@ -81,7 +81,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> goto out; /* Absolute timers do not update the rmtp value and restart: */ -@@ -1706,6 +1710,12 @@ long hrtimer_nanosleep(struct timespec * +@@ -1711,6 +1715,12 @@ long hrtimer_nanosleep(struct timespec * return ret; } @@ -94,7 +94,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp, struct timespec __user *, rmtp) { -@@ -1732,7 +1742,8 @@ void cpu_chill(void) +@@ -1737,7 +1747,8 @@ void cpu_chill(void) unsigned int freeze_flag = current->flags & PF_NOFREEZE; current->flags |= PF_NOFREEZE; diff --git a/patches/drivers-zram-fix-zcomp_stream_get-smp_processor_id-u.patch b/patches/drivers-zram-fix-zcomp_stream_get-smp_processor_id-u.patch new file mode 100644 index 000000000000..40ece686ab02 --- /dev/null +++ b/patches/drivers-zram-fix-zcomp_stream_get-smp_processor_id-u.patch @@ -0,0 +1,38 @@ +From 8b91f086c2492145698727d3d9c1918d97a0e41c Mon Sep 17 00:00:00 2001 +From: Mike Galbraith <efault@gmx.de> +Date: Wed, 23 Aug 2017 11:57:29 +0200 +Subject: [PATCH] drivers/zram: fix zcomp_stream_get() smp_processor_id() use + in preemptible code + +Use get_local_ptr() instead this_cpu_ptr() to avoid a warning regarding +smp_processor_id() in preemptible code. +raw_cpu_ptr() would be fine, too because the per-CPU data structure is +protected with a spin lock so it does not matter much if we take the +other one. + +Cc: stable-rt@vger.kernel.org +Signed-off-by: Mike Galbraith <efault@gmx.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/block/zram/zcomp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/block/zram/zcomp.c ++++ b/drivers/block/zram/zcomp.c +@@ -120,7 +120,7 @@ struct zcomp_strm *zcomp_stream_get(stru + { + struct zcomp_strm *zstrm; + +- zstrm = *this_cpu_ptr(comp->stream); ++ zstrm = *get_local_ptr(comp->stream); + spin_lock(&zstrm->zcomp_lock); + return zstrm; + } +@@ -131,6 +131,7 @@ void zcomp_stream_put(struct zcomp *comp + + zstrm = *this_cpu_ptr(comp->stream); + spin_unlock(&zstrm->zcomp_lock); ++ put_local_ptr(zstrm); + } + + int zcomp_compress(struct zcomp_strm *zstrm, diff --git a/patches/kernel-hrtimer-don-t-wakeup-a-process-while-holding-.patch b/patches/kernel-hrtimer-don-t-wakeup-a-process-while-holding-.patch new file mode 100644 index 000000000000..e97b1ad0558a --- /dev/null +++ b/patches/kernel-hrtimer-don-t-wakeup-a-process-while-holding-.patch @@ -0,0 +1,86 @@ +From 9e5116d50ea95f2a2e420216bc5a01bd1bdd7e86 Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Thu, 31 Aug 2017 18:19:06 +0200 +Subject: [PATCH] kernel/hrtimer: don't wakeup a process while holding the + hrtimer base lock + +We must not wake any process (and thus acquire the pi->lock) while +holding the hrtimer's base lock. This does not happen usually because +the hrtimer-callback is invoked in IRQ-context and so +raise_softirq_irqoff() does not wakeup a process. +However during CPU-hotplug it might get called from hrtimers_dead_cpu() +which would wakeup the thread immediately. + +Reported-by: Mike Galbraith <efault@gmx.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + kernel/time/hrtimer.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/kernel/time/hrtimer.c ++++ b/kernel/time/hrtimer.c +@@ -1367,7 +1367,7 @@ static inline int hrtimer_rt_defer(struc + + #endif + +-static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now) ++static int __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now) + { + struct hrtimer_clock_base *base = cpu_base->clock_base; + unsigned int active = cpu_base->active_bases; +@@ -1408,8 +1408,7 @@ static void __hrtimer_run_queues(struct + raise = 1; + } + } +- if (raise) +- raise_softirq_irqoff(HRTIMER_SOFTIRQ); ++ return raise; + } + + #ifdef CONFIG_HIGH_RES_TIMERS +@@ -1423,6 +1422,7 @@ void hrtimer_interrupt(struct clock_even + struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases); + ktime_t expires_next, now, entry_time, delta; + int retries = 0; ++ int raise; + + BUG_ON(!cpu_base->hres_active); + cpu_base->nr_events++; +@@ -1441,7 +1441,7 @@ void hrtimer_interrupt(struct clock_even + */ + cpu_base->expires_next = KTIME_MAX; + +- __hrtimer_run_queues(cpu_base, now); ++ raise = __hrtimer_run_queues(cpu_base, now); + + /* Reevaluate the clock bases for the next expiry */ + expires_next = __hrtimer_get_next_event(cpu_base); +@@ -1452,6 +1452,8 @@ void hrtimer_interrupt(struct clock_even + cpu_base->expires_next = expires_next; + cpu_base->in_hrtirq = 0; + raw_spin_unlock(&cpu_base->lock); ++ if (raise) ++ raise_softirq_irqoff(HRTIMER_SOFTIRQ); + + /* Reprogramming necessary ? */ + if (!tick_program_event(expires_next, 0)) { +@@ -1531,6 +1533,7 @@ void hrtimer_run_queues(void) + { + struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases); + ktime_t now; ++ int raise; + + if (__hrtimer_hres_active(cpu_base)) + return; +@@ -1549,8 +1552,10 @@ void hrtimer_run_queues(void) + + raw_spin_lock(&cpu_base->lock); + now = hrtimer_update_base(cpu_base); +- __hrtimer_run_queues(cpu_base, now); ++ raise = __hrtimer_run_queues(cpu_base, now); + raw_spin_unlock(&cpu_base->lock); ++ if (raise) ++ raise_softirq_irqoff(HRTIMER_SOFTIRQ); + } + + /* diff --git a/patches/localversion.patch b/patches/localversion.patch index e16fb07c0a7d..58842b503a27 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 @@ -+-rt10 ++-rt11 diff --git a/patches/locking-don-t-check-for-__LINUX_SPINLOCK_TYPES_H-on-.patch b/patches/locking-don-t-check-for-__LINUX_SPINLOCK_TYPES_H-on-.patch index 970eddfb4a8a..3c31a911a93d 100644 --- a/patches/locking-don-t-check-for-__LINUX_SPINLOCK_TYPES_H-on-.patch +++ b/patches/locking-don-t-check-for-__LINUX_SPINLOCK_TYPES_H-on-.patch @@ -1,4 +1,3 @@ -From 6d0b801a75aab6ba80af0ba99c8c04d0feeffcbd Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Fri, 4 Aug 2017 17:40:42 +0200 Subject: [PATCH 1/2] locking: don't check for __LINUX_SPINLOCK_TYPES_H on -RT diff --git a/patches/net-take-the-tcp_sk_lock-lock-with-BH-disabled.patch b/patches/net-take-the-tcp_sk_lock-lock-with-BH-disabled.patch new file mode 100644 index 000000000000..75af4f5f788b --- /dev/null +++ b/patches/net-take-the-tcp_sk_lock-lock-with-BH-disabled.patch @@ -0,0 +1,67 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Mon, 21 Aug 2017 15:09:13 +0200 +Subject: [PATCH] net: take the tcp_sk_lock lock with BH disabled + +Lockdep may complain about an unsafe locking scenario: +| CPU0 CPU1 +| ---- ---- +| lock((tcp_sk_lock).lock); +| lock(&per_cpu(local_softirq_locks[i], __cpu).lock); +| lock((tcp_sk_lock).lock); +| lock(&per_cpu(local_softirq_locks[i], __cpu).lock); + +in the call paths: + do_current_softirqs -> tcp_v4_send_ack() +vs + tcp_v4_send_reset -> do_current_softirqs(). + +This should not happen since local_softirq_locks is per CPU. Reversing +the order makes lockdep happy. + +Reported-by: Jacek Konieczny <jajcus@jajcus.net> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + net/ipv4/tcp_ipv4.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -713,8 +713,8 @@ static void tcp_v4_send_reset(const stru + + arg.tos = ip_hdr(skb)->tos; + arg.uid = sock_net_uid(net, sk && sk_fullsock(sk) ? sk : NULL); +- local_lock(tcp_sk_lock); + local_bh_disable(); ++ local_lock(tcp_sk_lock); + ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), + skb, &TCP_SKB_CB(skb)->header.h4.opt, + ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, +@@ -722,8 +722,8 @@ static void tcp_v4_send_reset(const stru + + __TCP_INC_STATS(net, TCP_MIB_OUTSEGS); + __TCP_INC_STATS(net, TCP_MIB_OUTRSTS); +- local_bh_enable(); + local_unlock(tcp_sk_lock); ++ local_bh_enable(); + + #ifdef CONFIG_TCP_MD5SIG + out: +@@ -801,16 +801,16 @@ static void tcp_v4_send_ack(const struct + arg.bound_dev_if = oif; + arg.tos = tos; + arg.uid = sock_net_uid(net, sk_fullsock(sk) ? sk : NULL); +- local_lock(tcp_sk_lock); + local_bh_disable(); ++ local_lock(tcp_sk_lock); + ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), + skb, &TCP_SKB_CB(skb)->header.h4.opt, + ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, + &arg, arg.iov[0].iov_len); + + __TCP_INC_STATS(net, TCP_MIB_OUTSEGS); +- local_bh_enable(); + local_unlock(tcp_sk_lock); ++ local_bh_enable(); + } + + static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) diff --git a/patches/rt-introduce-cpu-chill.patch b/patches/rt-introduce-cpu-chill.patch index 43831e64f37e..8e049dc59335 100644 --- a/patches/rt-introduce-cpu-chill.patch +++ b/patches/rt-introduce-cpu-chill.patch @@ -100,7 +100,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #endif /* defined(_LINUX_DELAY_H) */ --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -1720,6 +1720,25 @@ SYSCALL_DEFINE2(nanosleep, struct timesp +@@ -1725,6 +1725,25 @@ SYSCALL_DEFINE2(nanosleep, struct timesp return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC); } diff --git a/patches/series b/patches/series index 813e43113cff..8dac6fa0f250 100644 --- a/patches/series +++ b/patches/series @@ -396,6 +396,7 @@ timer-fd-avoid-live-lock.patch tick-broadcast--Make-hrtimer-irqsafe.patch timer-hrtimer-check-properly-for-a-running-timer.patch kernel-hrtimer-migrate-deferred-timer-on-CPU-down.patch +kernel-hrtimer-don-t-wakeup-a-process-while-holding-.patch # POSIX-CPU-TIMERS posix-timers-thread-posix-cpu-timers-on-rt.patch @@ -568,6 +569,7 @@ net-provide-a-way-to-delegate-processing-a-softirq-t.patch net-dev-always-take-qdisc-s-busylock-in-__dev_xmit_s.patch net-Qdisc-use-a-seqlock-instead-seqcount.patch net-add-back-the-missing-serialization-in-ip_send_un.patch +net-take-the-tcp_sk_lock-lock-with-BH-disabled.patch net-add-a-lock-around-icmp_sk.patch net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch @@ -692,6 +694,7 @@ cpufreq-drop-K8-s-driver-from-beeing-selected.patch connector-cn_proc-Protect-send_msg-with-a-local-lock.patch drivers-block-zram-Replace-bit-spinlocks-with-rtmute.patch drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch +drivers-zram-fix-zcomp_stream_get-smp_processor_id-u.patch # I915 drm-i915-drop-trace_i915_gem_ring_dispatch-onrt.patch |