[ANNOUNCE] 3.12.8-rt11
From: Sebastian Andrzej Siewior
Date: Sat Jan 25 2014 - 08:45:37 EST
Dear RT folks!
I'm pleased to announce the v3.12.8-rt11 patch set.
Changes since v3.12.8-rt10
- The "do not to raise the timer softirq unconditionally" resulted a few
boot lockups on a few boxes. Steven found the problem and sent a fix.
Thank you Steven.
- A compile fix to "do not to raise the timer softirq unconditionally"
patch to compile without RT enabled.
- Brian Silverman reported a BUG (Debian #723180) where gdb's
record command does something nasty and causes a double fault on
x86-64 kernel with 32bit userland (the debugged application).
The problem was a RT specific patch which has been reverted
- Sami PietikÃinen reported a crash in __ip_make_skb(). Nicholas
Mc Guire posted a patch for it, thank you Nicholas.
- A patch from Steven to document why we need a spinlock in struct
hotplug_pcp
- Don't unwind on ARM if called from irq_disabled() regions. This may
cause a lockup with debug object enabled while loading a module.
There is also a patch in the queue from Paul E. McKenney to move RCU
processing from softirq into its own thread. After Mike Galbraith
reported a few RCU stalls I decided to keep it disabled for now.
Steven's fix may have fixed the problem. If nothing else comes up I will
try to enable it in the next release.
Known issues:
- bcache is disabled.
The delta patch against v3.12.8-rt11 is appended below and can be found
here:
https://www.kernel.org/pub/linux/kernel/projects/rt/3.12/incr/patch-3.12.8-rt10-rt11.patch.xz
The RT patch against 3.12.8 can be found here:
https://www.kernel.org/pub/linux/kernel/projects/rt/3.12/patch-3.12.8-rt11.patch.xz
The split quilt queue is available at:
https://www.kernel.org/pub/linux/kernel/projects/rt/3.12/patches-3.12.8-rt11.tar.xz
Sebastian
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index 00df012..2af232d 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -195,6 +195,11 @@ static const struct unwind_idx *unwind_find_idx(unsigned long addr)
/* module unwind tables */
struct unwind_table *table;
+#ifdef CONFIG_PREEMPT_RT_FULL
+ if (irqs_disabled())
+ goto out;
+#endif
+
spin_lock_irqsave(&unwind_lock, flags);
list_for_each_entry(table, &unwind_tables, list) {
if (addr >= table->begin_addr &&
@@ -211,6 +216,7 @@ static const struct unwind_idx *unwind_find_idx(unsigned long addr)
}
pr_debug("%s: idx = %p\n", __func__, idx);
+out:
return idx;
}
@@ -345,7 +351,9 @@ int unwind_frame(struct stackframe *frame)
idx = unwind_find_idx(frame->pc);
if (!idx) {
+#ifndef CONFIG_PREEMPT_RT_FULL
pr_warning("unwind: Index not found %08lx\n", frame->pc);
+#endif
return -URC_FAILURE;
}
diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h
index 695e04d..43dcd80 100644
--- a/arch/x86/include/asm/page_64_types.h
+++ b/arch/x86/include/asm/page_64_types.h
@@ -14,21 +14,12 @@
#define IRQ_STACK_ORDER 2
#define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER)
-#ifdef CONFIG_PREEMPT_RT_FULL
-# define STACKFAULT_STACK 0
-# define DOUBLEFAULT_STACK 1
-# define NMI_STACK 2
-# define DEBUG_STACK 0
-# define MCE_STACK 3
-# define N_EXCEPTION_STACKS 3 /* hw limit: 7 */
-#else
-# define STACKFAULT_STACK 1
-# define DOUBLEFAULT_STACK 2
-# define NMI_STACK 3
-# define DEBUG_STACK 4
-# define MCE_STACK 5
-# define N_EXCEPTION_STACKS 5 /* hw limit: 7 */
-#endif
+#define STACKFAULT_STACK 1
+#define DOUBLEFAULT_STACK 2
+#define NMI_STACK 3
+#define DEBUG_STACK 4
+#define MCE_STACK 5
+#define N_EXCEPTION_STACKS 5 /* hw limit: 7 */
#define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT)
#define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1))
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index c0dcf06..2793d1f 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1105,9 +1105,7 @@ DEFINE_PER_CPU(struct task_struct *, fpu_owner_task);
*/
static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = {
[0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ,
-#if DEBUG_STACK > 0
[DEBUG_STACK - 1] = DEBUG_STKSZ
-#endif
};
static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
index 52b4bcd..addb207 100644
--- a/arch/x86/kernel/dumpstack_64.c
+++ b/arch/x86/kernel/dumpstack_64.c
@@ -21,14 +21,10 @@
(N_EXCEPTION_STACKS + DEBUG_STKSZ/EXCEPTION_STKSZ - 2)
static char x86_stack_ids[][8] = {
-#if DEBUG_STACK > 0
[ DEBUG_STACK-1 ] = "#DB",
-#endif
[ NMI_STACK-1 ] = "NMI",
[ DOUBLEFAULT_STACK-1 ] = "#DF",
-#if STACKFAULT_STACK > 0
[ STACKFAULT_STACK-1 ] = "#SS",
-#endif
[ MCE_STACK-1 ] = "#MC",
#if DEBUG_STKSZ > EXCEPTION_STKSZ
[ N_EXCEPTION_STACKS ...
diff --git a/kernel/cpu.c b/kernel/cpu.c
index c36b075..ba7416b 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -85,6 +85,14 @@ struct hotplug_pcp {
struct completion synced;
struct completion unplug_wait;
#ifdef CONFIG_PREEMPT_RT_FULL
+ /*
+ * Note, on PREEMPT_RT, the hotplug lock must save the state of
+ * the task, otherwise the mutex will cause the task to fail
+ * to sleep when required. (Because it's called from migrate_disable())
+ *
+ * The spinlock_t on PREEMPT_RT is a mutex that saves the task's
+ * state.
+ */
spinlock_t lock;
#else
struct mutex mutex;
diff --git a/kernel/timer.c b/kernel/timer.c
index 46467be..106968f 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1460,19 +1460,29 @@ void run_local_timers(void)
* interrupt. If there are no timers queued, nothing to do in
* the timer softirq.
*/
+#ifdef CONFIG_PREEMPT_RT_FULL
if (!spin_do_trylock(&base->lock)) {
raise_softirq(TIMER_SOFTIRQ);
return;
}
- if (!base->active_timers)
- goto out;
+#endif
+ if (!base->active_timers) {
+#ifdef CONFIG_PREEMPT_RT_FULL
+ /* On RT, irq work runs from softirq */
+ if (!irq_work_needs_cpu())
+#endif
+ goto out;
+ }
/* Check whether the next pending timer has expired */
if (time_before_eq(base->next_timer, jiffies))
raise_softirq(TIMER_SOFTIRQ);
out:
+#ifdef CONFIG_PREEMPT_RT_FULL
rt_spin_unlock_after_trylock_in_irq(&base->lock);
-
+#endif
+ /* The ; ensures that gcc won't complain in the !RT case */
+ ;
}
#ifdef __ARCH_WANT_SYS_ALARM
diff --git a/localversion-rt b/localversion-rt
index d79dde6..05c35cb 100644
--- a/localversion-rt
+++ b/localversion-rt
@@ -1 +1 @@
--rt10
+-rt11
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index e9fa68c..8bb3b4a 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -79,6 +79,7 @@
#include <linux/mroute.h>
#include <linux/netlink.h>
#include <linux/tcp.h>
+#include <linux/locallock.h>
int sysctl_ip_default_ttl __read_mostly = IPDEFTTL;
EXPORT_SYMBOL(sysctl_ip_default_ttl);
@@ -1468,6 +1469,9 @@ static DEFINE_PER_CPU(struct inet_sock, unicast_sock) = {
.uc_ttl = -1,
};
+/* serialize concurrent calls on the same CPU to ip_send_unicast_reply */
+static DEFINE_LOCAL_IRQ_LOCK(unicast_lock);
+
void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
__be32 saddr, const struct ip_reply_arg *arg,
unsigned int len)
@@ -1505,8 +1509,7 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
if (IS_ERR(rt))
return;
- get_cpu_light();
- inet = &__get_cpu_var(unicast_sock);
+ inet = &get_locked_var(unicast_lock, unicast_sock);
inet->tos = arg->tos;
sk = &inet->sk;
@@ -1530,7 +1533,7 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
ip_push_pending_frames(sk, &fl4);
}
- put_cpu_light();
+ put_locked_var(unicast_lock, unicast_sock);
ip_rt_put(rt);
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/