Linux 3.10.102-rt113-rc1
Subsystems (6)
Steven Rostedt
maintainercover Linux 3.10.102-rt113-rc1
Dear RT Folks,
This is the RT stable review cycle of patch 3.10.102-rt113-rc1.
Please scream at me if I messed something up. Please test the patches too.
The -rc release will be uploaded to kernel.org and will be deleted when the final release is out. This is just a review release (or release candidate).
The pre-releases will not be pushed to the git repository, only the final release is.
If all goes well, this patch will be converted to the next main release on 7/14/2016.
Enjoy,
-- Steve
To build 3.10.102-rt113-rc1 directly, the following patches should be applied:
http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.10.tar.xz
http://www.kernel.org/pub/linux/kernel/v3.x/patch-3.10.102.xz
http://www.kernel.org/pub/linux/kernel/projects/rt/3.10/patch-3.10.102-rt113-rc1.patch.xz
You can also build from 3.10.102-rt112 by applying the incremental patch:
http://www.kernel.org/pub/linux/kernel/projects/rt/3.10/incr/patch-3.10.102-rt112-rt113-rc1.patch.xz
Changes from 3.10.102-rt112:
---
Corey Minyard (1):
x86: Fix an RT MCE crash
Josh Cartwright (1):
list_bl: fixup bogus lockdep warning
Rik van Riel (1):
kvm, rt: change async pagefault code locking for PREEMPT_RT
Sebastian Andrzej Siewior (4):
net: dev: always take qdisc's busylock in __dev_xmit_skb() kernel/printk: Don't try to print from IRQ/NMI region
arm: lazy preempt: correct resched condition
trace: correct off by one while recording the trace-event
Steven Rostedt (Red Hat) (1):
Linux 3.10.102-rt113-rc1
----
arch/arm/kernel/entry-armv.S | 6 +++++- arch/x86/kernel/cpu/mcheck/mce.c | 3 ++- arch/x86/kernel/kvm.c | 37 +++++++++++++++++++------------------ include/linux/list_bl.h | 12 +++++++----- include/trace/ftrace.h | 3 +++ kernel/printk.c | 10 ++++++++++ localversion-rt | 2 +- net/core/dev.c | 4 ++++ 8 files changed, 51 insertions(+), 26 deletions(-)
Steven Rostedt
maintainerPATCH 1/8 kvm, rt: change async pagefault code locking for PREEMPT_RT
3.10.102-rt113-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Rik van Riel <[email protected]>
The async pagefault wake code can run from the idle task in exception context, so everything here needs to be made non-preemptible.
Conversion to a simple wait queue and raw spinlock does the trick.
--- arch/x86/kernel/kvm.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-)
arch/x86/kernel/kvm.c +19 -18
@@ -34,6 +34,7 @@#include <linux/sched.h> #include <linux/slab.h> #include <linux/kprobes.h> +#include <linux/wait-simple.h> #include <asm/timer.h> #include <asm/cpu.h> #include <asm/traps.h>
@@ -89,14 +90,14 @@ static void kvm_io_delay(void)struct kvm_task_sleep_node {struct hlist_node link; -wait_queue_head_t wq; +struct swait_head wq;u32 token;int cpu;bool halted; };static struct kvm_task_sleep_head { -spinlock_t lock; +raw_spinlock_t lock;struct hlist_head list; } async_pf_sleepers[KVM_TASK_SLEEP_HASHSIZE ];
@@ -120,17 +121,17 @@ void kvm_async_pf_task_wait(u32 token)u32 key =hash_32 (token,KVM_TASK_SLEEP_HASHBITS );struct kvm_task_sleep_head *b = &async_pf_sleepers[key];struct kvm_task_sleep_node n, *e; -DEFINE_WAIT (wait); +DEFINE_SWAITER (wait);rcu_irq_enter (); -spin_lock (&b->lock); +raw_spin_lock (&b->lock); e =_find_apf_task (b, token);if (e) {/* dummy entry exist -> wake up was delivered ahead of PF */ hlist_del (&e->link);kfree (e); -spin_unlock (&b->lock); +raw_spin_unlock (&b->lock);rcu_irq_exit ();return ;
@@ -139,13 +140,13 @@ void kvm_async_pf_task_wait(u32 token) n.token = token; n.cpu =smp_processor_id (); n.halted =is_idle_task (current) ||preempt_count () >1 ; -init_waitqueue_head (&n.wq); +init_swait_head (&n.wq);hlist_add_head (&n.link, &b->list); -spin_unlock (&b->lock); +raw_spin_unlock (&b->lock);for (;;) {if (!n.halted) -prepare_to_wait (&n.wq, &wait,TASK_UNINTERRUPTIBLE ); +swait_prepare (&n.wq, &wait,TASK_UNINTERRUPTIBLE );if (hlist_unhashed (&n.link))break ;
@@ -164,7 +165,7 @@ void kvm_async_pf_task_wait(u32 token) } }if (!n.halted) -finish_wait (&n.wq, &wait); +swait_finish (&n.wq, &wait);rcu_irq_exit ();return ;
@@ -176,8 +177,8 @@ static void apf_task_wake_one(struct kvm_task_sleep_node *n)hlist_del_init (&n->link);if (n->halted)smp_send_reschedule (n->cpu); -else if (waitqueue_active (&n->wq)) -wake_up (&n->wq); +else if (swaitqueue_active (&n->wq)) +swait_wake (&n->wq); }static void apf_task_wake_all (void )
@@ -187,14 +188,14 @@ static void apf_task_wake_all(void)for (i =0 ; i <KVM_TASK_SLEEP_HASHSIZE ; i++) {struct hlist_node *p, *next;struct kvm_task_sleep_head *b = &async_pf_sleepers[i]; -spin_lock (&b->lock); +raw_spin_lock (&b->lock);hlist_for_each_safe (p, next, &b->list) {struct kvm_task_sleep_node *n =hlist_entry (p,typeof (*n), link);if (n->cpu ==smp_processor_id ())apf_task_wake_one (n); } -spin_unlock (&b->lock); +raw_spin_unlock (&b->lock); } }
@@ -210,7 +211,7 @@ void kvm_async_pf_task_wake(u32 token) } again: -spin_lock (&b->lock); +raw_spin_lock (&b->lock); n =_find_apf_task (b, token);if (!n) {/*
@@ -223,17 +224,17 @@ again:* Allocation failed! Busy wait while other cpu * handles async PF. */ -spin_unlock (&b->lock); +raw_spin_unlock (&b->lock);cpu_relax (); goto again; } n->token = token; n->cpu =smp_processor_id (); -init_waitqueue_head (&n->wq); +init_swait_head (&n->wq);hlist_add_head (&n->link, &b->list); }else apf_task_wake_one (n); -spin_unlock (&b->lock); +raw_spin_unlock (&b->lock);return ; }EXPORT_SYMBOL_GPL (kvm_async_pf_task_wake);
@@ -482,7 +483,7 @@ void __init kvm_guest_init(void)paravirt_ops_setup ();register_reboot_notifier (&kvm_pv_reboot_nb);for (i =0 ; i <KVM_TASK_SLEEP_HASHSIZE ; i++) -spin_lock_init (&async_pf_sleepers[i].lock); +raw_spin_lock_init (&async_pf_sleepers[i].lock);if (kvm_para_has_feature (KVM_FEATURE_ASYNC_PF )) x86_init.irqs.trap_init = kvm_apf_trap_init;
Signature · 1 line
2.8.1
Steven Rostedt
maintainerPATCH 2/8 net: dev: always take qdiscs busylock in __dev_xmit_skb()
In reply to Steven Rostedt3.10.102-rt113-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
The root-lock is dropped before dev_hard_start_xmit() is invoked and after setting the __QDISC___STATE_RUNNING bit. If this task is now pushed away by a task with a higher priority then the task with the higher priority won't be able to submit packets to the NIC directly instead they will be enqueued into the Qdisc. The NIC will remain idle until the task(s) with higher priority leave the CPU and the task with lower priority gets back and finishes the job.
If we take always the busylock we ensure that the RT task can boost the low-prio task and submit the packet.
--- net/core/dev.c | 4 ++++ 1 file changed, 4 insertions(+)
net/core/dev.c +4 -0
@@ -2680,7 +2680,11 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,* This permits __QDISC_STATE_RUNNING owner to get the lock more often * and dequeue packets faster. */ +#ifdef CONFIG_PREEMPT_RT_FULL + contended = true; +#else contended =qdisc_is_running (q); +#endif if (unlikely (contended))spin_lock (&q->busylock);
Signature · 1 line
2.8.1
Steven Rostedt
maintainerPATCH 3/8 list_bl: fixup bogus lockdep warning
In reply to Steven Rostedt3.10.102-rt113-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Josh Cartwright <[email protected]>
At first glance, the use of 'static inline' seems appropriate for INIT_HLIST_BL_HEAD().
However, when a 'static inline' function invocation is inlined by gcc, all callers share any static local data declared within that inline function.
This presents a problem for how lockdep classes are setup. raw_spinlocks, for example, when CONFIG_DEBUG_SPINLOCK,
# define raw_spin_lock_init(lock) \
do { \
static struct lock_class_key __key; \
\
__raw_spin_lock_init((lock), #lock, &__key); \
} while (0)When this macro is expanded into a 'static inline' caller, like INIT_HLIST_BL_HEAD():
static inline INIT_HLIST_BL_HEAD(struct hlist_bl_head *h)
{
h->first = NULL;
raw_spin_lock_init(&h->lock);
}...the static local lock_class_key object is made a function static.
For compilation units which initialize invoke INIT_HLIST_BL_HEAD() more than once, then, all of the invocations share this same static local object.
This can lead to some very confusing lockdep splats (example below). Solve this problem by forcing the INIT_HLIST_BL_HEAD() to be a macro, which prevents the lockdep class object sharing.
=============================================
[ INFO: possible recursive locking detected ]
4.4.4-rt11 #4 Not tainted
---------------------------------------------
kswapd0/59 is trying to acquire lock:
(&h->lock#2){+.+.-.}, at: mb_cache_shrink_scan
but task is already holding lock:
(&h->lock#2){+.+.-.}, at: mb_cache_shrink_scan
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
---- lock(&h->lock#2);
lock(&h->lock#2);
*** DEADLOCK ***
May be due to missing lock nesting notation
2 locks held by kswapd0/59:
#0: (shrinker_rwsem){+.+...}, at: rt_down_read_trylock #1: (&h->lock#2){+.+.-.}, at: mb_cache_shrink_scan
--- include/linux/list_bl.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
include/linux/list_bl.h +7 -5
@@ -42,13 +42,15 @@ struct hlist_bl_node {struct hlist_bl_node *next, **pprev; }; -static inline void INIT_HLIST_BL_HEAD (struct hlist_bl_head *h) -{ - h->first =NULL ;#ifdef CONFIG_PREEMPT_RT_BASE -raw_spin_lock_init (&h->lock); +#define INIT_HLIST_BL_HEAD (h) \ +do { \ + (h)->first = NULL; \ + raw_spin_lock_init(&(h)->lock); \ +} while (0) +#else +#define INIT_HLIST_BL_HEAD (h) (h)->first = NULL#endif -}static inline void INIT_HLIST_BL_NODE (struct hlist_bl_node *h) {
Signature · 1 line
2.8.1
Steven Rostedt
maintainerPATCH 4/8 kernel/printk: Dont try to print from IRQ/NMI region
In reply to Steven Rostedt3.10.102-rt113-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
On -RT we try to acquire sleeping locks which might lead to warnings from lockdep or a warn_on() from spin_try_lock() (which is a rtmutex on RT).
We don't print in general from a IRQ off region so we should not try this via console_unblank() / bust_spinlocks() as well.
--- kernel/printk.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
kernel/printk.c +10 -0
@@ -1302,6 +1302,11 @@ static void call_console_drivers(int level, const char *text, size_t len)if (!console_drivers)return ; +if (IS_ENABLED (CONFIG_PREEMPT_RT_BASE )) { +if (in_irq () ||in_nmi ()) +return ; + } +migrate_disable ();for_each_console (con) {if (exclusive_console && con != exclusive_console)
@@ -2236,6 +2241,11 @@ void console_unblank(void) {struct console *c; +if (IS_ENABLED (CONFIG_PREEMPT_RT_BASE )) { +if (in_irq () ||in_nmi ()) +return ; + } +/* * console_unblank can no longer be called in interrupt context unless * oops_in_progress is set to 1..
Signature · 1 line
2.8.1
Steven Rostedt
maintainerPATCH 5/8 arm: lazy preempt: correct resched condition
In reply to Steven Rostedt3.10.102-rt113-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
If we get out of preempt_schedule_irq() then we check for NEED_RESCHED and call the former function again if set because the preemption counter has be zero at this point.
However the counter for lazy-preempt might not be zero therefore we have to check the counter before looking at the need_resched_lazy flag.
--- arch/arm/kernel/entry-armv.S | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm/kernel/entry-armv.S +5 -1
@@ -234,7 +234,11 @@ svc_preempt: bne 1b tst r0, #_TIF_NEED_RESCHED_LAZY moveq pc, r8 @ go again - b 1b + ldr r0, [tsk, #TI_PREEMPT_LAZY] @ get preempt lazy count + teq r0, #0 @ if preempt lazy count != 0 + beq 1b + mov pc, r8 @ go again + #endif __und_fault:
Signature · 1 line
2.8.1
Steven Rostedt
maintainerPATCH 6/8 trace: correct off by one while recording the trace-event
In reply to Steven Rostedt3.10.102-rt113-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
Trace events like raw_syscalls show always a preempt code of one. The reason is that on PREEMPT kernels rcu_read_lock_sched_notrace() increases the preemption counter and the function recording the counter is caller within the RCU section.
--- include/trace/ftrace.h | 3 +++ 1 file changed, 3 insertions(+)
include/trace/ftrace.h +3 -0
@@ -526,6 +526,9 @@ ftrace_raw_event_##call(void *__data, proto) \ \local_save_flags (irq_flags); \ pc =preempt_count (); \ +/* Account for tracepoint preempt disable */ \ +if (IS_ENABLED (CONFIG_PREEMPT )) \ + pc--; \ \ __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ \
Signature · 1 line
2.8.1
Steven Rostedt
maintainerPATCH 7/8 x86: Fix an RT MCE crash
In reply to Steven Rostedt3.10.102-rt113-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Corey Minyard <[email protected]>
On some x86 systems an MCE interrupt would come in before the kernel was ready for it. Looking at the latest RT code, it has similar (but not quite the same) code, except it adds a bool that tells if MCE handling is initialized. That was required because they had switched to use swork instead of a kernel thread. Here, just checking to see if the thread is NULL is good enough to see if MCE handling is initialized.
--- arch/x86/kernel/cpu/mcheck/mce.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/kernel/cpu/mcheck/mce.c +2 -1
@@ -1391,7 +1391,8 @@ static int mce_notify_work_init(void)static void mce_notify_work (void ) { -wake_up_process (mce_notify_helper); +if (mce_notify_helper) +wake_up_process (mce_notify_helper); }#else static void mce_notify_work (void )
Signature · 1 line
2.8.1
Steven Rostedt
maintainerPATCH 8/8 Linux 3.10.102-rt113-rc1
In reply to Steven Rostedt3.10.102-rt113-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: "Steven Rostedt (Red Hat)" <[email protected]>
--- localversion-rt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
localversion-rt +1 -1
@@ -1 +1 @@ --rt112 +-rt113-rc1
Signature · 1 line
2.8.1