Linux 3.8.13.13-rt26-rc1
Subsystems (6)
cover Linux 3.8.13.13-rt26-rc1
Dear RT Folks,
This is the RT stable review cycle of patch 3.8.13.13-rt26-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 12/13/2013.
Enjoy,
-- Steve
To build 3.8.13.13-rt26-rc1 directly, the following patches should be applied:
http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.8.tar.xz
http://www.kernel.org/pub/linux/kernel/v3.x/patch-3.8.13.13.xz
http://www.kernel.org/pub/linux/kernel/projects/rt/3.8/patch-3.8.13.13-rt26-rc1.patch.xz
You can also build from 3.8.13.13-rt25 by applying the incremental patch:
http://www.kernel.org/pub/linux/kernel/projects/rt/3.8/incr/patch-3.8.13.13-rt25-rt26-rc1.patch.xz
Changes from 3.8.13.13-rt25:
---
Peter Zijlstra (1):
lockdep: Correctly annotate hardirq context in irq_exit()
Sebastian Andrzej Siewior (2):
a few open coded completions
rtmutex: use a trylock for waiter lock in trylock
Steven Rostedt (Red Hat) (1):
Linux 3.8.13.13-rt26-rc1
Tiejun Chen (1):
cpu_down: move migrate_enable() back
----
drivers/net/wireless/orinoco/orinoco_usb.c | 2 +- drivers/usb/gadget/f_fs.c | 2 +- drivers/usb/gadget/inode.c | 4 +-- include/linux/netdevice.h | 2 +- include/linux/spinlock_rt.h | 1 + kernel/cpu.c | 2 +- kernel/rtmutex.c | 31 +++++++++++++++++--- kernel/softirq.c | 45 ++++++++++++++++++++++++++++-- kernel/timer.c | 2 +- localversion-rt | 2 +- 10 files changed, 78 insertions(+), 15 deletions(-)
PATCH 1/5 cpu_down: move migrate_enable() back
3.8.13.13-rt26-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Tiejun Chen <[email protected]>
Commit 08c1ab68, "hotplug-use-migrate-disable.patch", intends to use migrate_enable()/migrate_disable() to replace that combination of preempt_enable() and preempt_disable(), but actually in !CONFIG_PREEMPT_RT_FULL case, migrate_enable()/migrate_disable() are still equal to preempt_enable()/preempt_disable(). So that followed cpu_hotplug_begin()/cpu_unplug_begin(cpu) would go schedule() to trigger schedule_debug() like this:
_cpu_down()
| + migrate_disable() = preempt_disable() | + cpu_hotplug_begin() or cpu_unplug_begin() | + schedule() | + __schedule() | + preempt_disable(); | + __schedule_bug() is true!
So we should move migrate_enable() as the original scheme.
--- kernel/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/cpu.c +1 -1
@@ -594,6 +594,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) err = -EBUSY ; goto restore_cpus; } +migrate_enable ();cpu_hotplug_begin (); err =cpu_unplug_begin (cpu);
@@ -647,7 +648,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) out_release:cpu_unplug_done (cpu); out_cancel: -migrate_enable ();cpu_hotplug_done ();if (!err)cpu_notify_nofail (CPU_POST_DEAD | mod, hcpu);
Signature · 1 line
1.8.4.3
PATCH 2/5 a few open coded completions
In reply to Steven Rostedt3.8.13.13-rt26-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
--- drivers/net/wireless/orinoco/orinoco_usb.c | 2 +- drivers/usb/gadget/f_fs.c | 2 +- drivers/usb/gadget/inode.c | 4 ++-- include/linux/netdevice.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-)
drivers/net/wireless/orinoco/orinoco_usb.c +1 -1
@@ -714,7 +714,7 @@ static void ezusb_req_ctx_wait(struct ezusb_priv *upriv,while (!ctx->done.done && msecs--)udelay (1000 ); }else { -wait_event_interruptible (ctx->done.wait, +swait_event_interruptible (ctx->done.wait, ctx->done.done); }break ;
drivers/usb/gadget/f_fs.c +1 -1
@@ -1284,7 +1284,7 @@ static void ffs_data_put(struct ffs_data *ffs)pr_info ("%s(): freeing\n" , __func__);ffs_data_clear (ffs);BUG_ON (waitqueue_active (&ffs->ev.waitq) || -waitqueue_active (&ffs->ep0req_completion.wait)); +swaitqueue_active (&ffs->ep0req_completion.wait));kfree (ffs->dev_name);kfree (ffs); }
drivers/usb/gadget/inode.c +2 -2
@@ -338,7 +338,7 @@ ep_io (struct ep_data *epdata, void *buf, unsigned len)spin_unlock_irq (&epdata->dev->lock);if (likely (value ==0 )) { - value =wait_event_interruptible (done.wait, done.done); + value =swait_event_interruptible (done.wait, done.done);if (value !=0 ) {spin_lock_irq (&epdata->dev->lock);if (likely (epdata->ep !=NULL )) {
@@ -347,7 +347,7 @@ ep_io (struct ep_data *epdata, void *buf, unsigned len)usb_ep_dequeue (epdata->ep, epdata->req);spin_unlock_irq (&epdata->dev->lock); -wait_event (done.wait, done.done); +swait_event (done.wait, done.done);if (epdata->status == -ECONNRESET ) epdata->status = -EINTR ; }else {
include/linux/netdevice.h +1 -1
@@ -1123,7 +1123,7 @@ struct net_device {unsigned char perm_addr[MAX_ADDR_LEN ];/* permanent hw address */ unsigned char addr_assign_type;/* hw address assignment type */ unsigned char addr_len;/* hardware address length */ -unsigned char neigh_priv_len; +unsigned short neigh_priv_len;unsigned short dev_id;/* for shared network cards */ spinlock_t addr_list_lock;
Signature · 1 line
1.8.4.3
Re: [PATCH RT 2/5] a few open coded completions
Here's the new patch for 3.8-rt.
-- Steve
From: Sebastian Andrzej Siewior <[email protected]>
Date: Mon, 28 Oct 2013 11:50:06 +0100
Subject: [PATCH] swait: Add a few more users
The wait-simple queue is lighter weight and more efficient than the full wait queue, and may be used in atomic context on PREEMPT_RT.
Fix up some places that needed to call the swait_*() functions instead of the wait_*() functions.
--- drivers/net/wireless/orinoco/orinoco_usb.c | 2 +- drivers/usb/gadget/f_fs.c | 2 +- drivers/usb/gadget/inode.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-)
drivers/net/wireless/orinoco/orinoco_usb.c +1 -1
@@ -714,7 +714,7 @@ static void ezusb_req_ctx_wait(struct ezusb_priv *upriv,while (!ctx->done.done && msecs--)udelay (1000 ); }else { -wait_event_interruptible (ctx->done.wait, +swait_event_interruptible (ctx->done.wait, ctx->done.done); }break ;
drivers/usb/gadget/f_fs.c +1 -1
@@ -1284,7 +1284,7 @@ static void ffs_data_put(struct ffs_data *ffs)pr_info ("%s(): freeing\n" , __func__);ffs_data_clear (ffs);BUG_ON (waitqueue_active (&ffs->ev.waitq) || -waitqueue_active (&ffs->ep0req_completion.wait)); +swaitqueue_active (&ffs->ep0req_completion.wait));kfree (ffs->dev_name);kfree (ffs); }
drivers/usb/gadget/inode.c +2 -2
@@ -338,7 +338,7 @@ ep_io (struct ep_data *epdata, void *buf, unsigned len)spin_unlock_irq (&epdata->dev->lock);if (likely (value ==0 )) { - value =wait_event_interruptible (done.wait, done.done); + value =swait_event_interruptible (done.wait, done.done);if (value !=0 ) {spin_lock_irq (&epdata->dev->lock);if (likely (epdata->ep !=NULL )) {
@@ -347,7 +347,7 @@ ep_io (struct ep_data *epdata, void *buf, unsigned len)usb_ep_dequeue (epdata->ep, epdata->req);spin_unlock_irq (&epdata->dev->lock); -wait_event (done.wait, done.done); +swait_event (done.wait, done.done);if (epdata->status == -ECONNRESET ) epdata->status = -EINTR ; }else {
Signature · 1 line
1.8.4.3
PATCH 3/5 lockdep: Correctly annotate hardirq context in irq_exit()
In reply to Steven Rostedt3.8.13.13-rt26-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
There was a reported deadlock on -rt which lockdep didn't report.
It turns out that in irq_exit() we tell lockdep that the hardirq context ends and then do all kinds of locking afterwards.
To fix it, move trace_hardirq_exit() to the very end of irq_exit(), this ensures all locking in tick_irq_exit() and rcu_irq_exit() are properly recorded as happening from hardirq context.
This however leads to the 'fun' little problem of running softirqs while in hardirq context. To cure this make the softirq code a little more complex (in the CONFIG_TRACE_IRQFLAGS case).
Due to stack swizzling arch dependent trickery we cannot pass an argument to __do_softirq() to tell it if it was done from hardirq context or not; so use a side-band argument.
When we do __do_softirq() from hardirq context, 'atomically' flip to softirq context and back, so that no locking goes without being in either hard- or soft-irq context.
I didn't find any new problems in mainline using this patch, but it did show the -rt problem.
--- kernel/softirq.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-)
kernel/softirq.c +42 -3
@@ -350,6 +350,44 @@ EXPORT_SYMBOL(local_bh_enable_ip);*/ #define MAX_SOFTIRQ_RESTART 10 +#ifdef CONFIG_TRACE_IRQFLAGS +/* +* Convoluted means of passing __do_softirq() a message through the various +* architecture execute_on_stack() bits. +* +* When we run softirqs from irq_exit() and thus on the hardirq stack we need +* to keep the lockdep irq context tracking as tight as possible in order to +* not miss-qualify lock contexts and miss possible deadlocks. +*/ +static DEFINE_PER_CPU(int, softirq_from_hardirq); + +static inline void lockdep_softirq_from_hardirq (void ) +{ +this_cpu_write (softirq_from_hardirq,1 ); +} + +static inline void lockdep_softirq_start (void ) +{ +if (this_cpu_read (softirq_from_hardirq)) +trace_hardirq_exit (); +lockdep_softirq_enter (); +} + +static inline void lockdep_softirq_end (void ) +{ +lockdep_softirq_exit (); +if (this_cpu_read (softirq_from_hardirq)) { +this_cpu_write (softirq_from_hardirq,0 ); +trace_hardirq_enter (); + } +} + +#else +static inline void lockdep_softirq_from_hardirq (void ) { } +static inline void lockdep_softirq_start (void ) { } +static inline void lockdep_softirq_end (void ) { } +#endif + asmlinkage void __do_softirq(void) {__u32 pending;
@@ -369,7 +407,7 @@ asmlinkage void __do_softirq(void)__local_bh_disable ((unsigned long )__builtin_return_address (0 ),SOFTIRQ_OFFSET ); -lockdep_softirq_enter (); +lockdep_softirq_start (); cpu =smp_processor_id (); restart:
@@ -385,7 +423,7 @@ restart:if (pending)wakeup_softirqd (); -lockdep_softirq_exit (); +lockdep_softirq_end ();vtime_account_irq_exit (current);__local_bh_enable (SOFTIRQ_OFFSET );
@@ -692,6 +730,7 @@ static inline void invoke_softirq(void) {#ifndef CONFIG_PREEMPT_RT_FULL if (!force_irqthreads) { +lockdep_softirq_from_hardirq ();#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED__do_softirq ();#else
@@ -720,7 +759,6 @@ static inline void invoke_softirq(void)void irq_exit (void ) {vtime_account_irq_exit (current); -trace_hardirq_exit ();sub_preempt_count (IRQ_EXIT_OFFSET );if (!in_interrupt () &&local_softirq_pending ())invoke_softirq ();
@@ -731,6 +769,7 @@ void irq_exit(void)tick_nohz_irq_exit ();#endif rcu_irq_exit (); +trace_hardirq_exit ();/* must be last! */ sched_preempt_enable_no_resched (); }
Signature · 1 line
1.8.4.3
PATCH 4/5 rtmutex: use a trylock for waiter lock in trylock
In reply to Steven Rostedt3.8.13.13-rt26-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
Mike Galbraith captered the following:
| >#11 [ffff88017b243e90] _raw_spin_lock at ffffffff815d2596 | >#12 [ffff88017b243e90] rt_mutex_trylock at ffffffff815d15be | >#13 [ffff88017b243eb0] get_next_timer_interrupt at ffffffff81063b42 | >#14 [ffff88017b243f00] tick_nohz_stop_sched_tick at ffffffff810bd1fd | >#15 [ffff88017b243f70] tick_nohz_irq_exit at ffffffff810bd7d2 | >#16 [ffff88017b243f90] irq_exit at ffffffff8105b02d | >#17 [ffff88017b243fb0] reschedule_interrupt at ffffffff815db3dd | >--- <IRQ stack> --- | >#18 [ffff88017a2a9bc8] reschedule_interrupt at ffffffff815db3dd | > [exception RIP: task_blocks_on_rt_mutex+51] | >#19 [ffff88017a2a9ce0] rt_spin_lock_slowlock at ffffffff815d183c | >#20 [ffff88017a2a9da0] lock_timer_base.isra.35 at ffffffff81061cbf | >#21 [ffff88017a2a9dd0] schedule_timeout at ffffffff815cf1ce | >#22 [ffff88017a2a9e50] rcu_gp_kthread at ffffffff810f9bbb | >#23 [ffff88017a2a9ed0] kthread at ffffffff810796d5 | >#24 [ffff88017a2a9f50] ret_from_fork at ffffffff815da04c
lock_timer_base() does a try_lock() which deadlocks on the waiter lock not the lock itself.
This patch takes the waiter_lock with trylock so it should work from interrupt context as well. If the fastpath doesn't work and the waiter_lock itself is taken then it seems that the lock itself taken.
This patch also adds a "rt_spin_try_unlock" to keep lockdep happy. If we managed to take the wait_lock in the first place we should also be able to take it in the unlock path.
--- include/linux/spinlock_rt.h | 1 + kernel/rtmutex.c | 31 +++++++++++++++++++++++++++---- kernel/timer.c | 2 +- 3 files changed, 29 insertions(+), 5 deletions(-)
include/linux/spinlock_rt.h +1 -0
@@ -22,6 +22,7 @@ extern void __lockfunc rt_spin_lock(spinlock_t *lock);extern unsigned long __lockfunc rt_spin_lock_trace_flags (spinlock_t *lock); extern void __lockfunc rt_spin_lock_nested(spinlock_t *lock, int subclass); extern void __lockfunc rt_spin_unlock(spinlock_t *lock); +extern void __lockfunc rt_spin_unlock_after_trylock_in_irq(spinlock_t *lock); extern void __lockfunc rt_spin_unlock_wait(spinlock_t *lock); extern int __lockfunc rt_spin_trylock_irqsave(spinlock_t *lock, unsigned long *flags); extern int __lockfunc rt_spin_trylock_bh(spinlock_t *lock);
kernel/rtmutex.c +27 -4
@@ -801,10 +801,8 @@ static void noinline __sched rt_spin_lock_slowlock(struct rt_mutex *lock)/* * Slow path to release a rt_mutex spin_lock style */ -static void noinline __sched rt_spin_lock_slowunlock(struct rt_mutex *lock) +static void __sched __rt_spin_lock_slowunlock(struct rt_mutex *lock) { -raw_spin_lock (&lock->wait_lock); -debug_rt_mutex_unlock (lock);rt_mutex_deadlock_account_unlock (current);
@@ -823,6 +821,23 @@ static void noinline __sched rt_spin_lock_slowunlock(struct rt_mutex *lock)rt_mutex_adjust_prio (current); } +static void noinline __sched rt_spin_lock_slowunlock(struct rt_mutex *lock) +{ +raw_spin_lock (&lock->wait_lock); +__rt_spin_lock_slowunlock (lock); +} + +static void noinline __sched rt_spin_lock_slowunlock_hirq(struct rt_mutex *lock) +{ +int ret; + +do { + ret =raw_spin_trylock (&lock->wait_lock); + }while (!ret); + +__rt_spin_lock_slowunlock (lock); +} + void __lockfunc rt_spin_lock(spinlock_t *lock) {rt_spin_lock_fastlock (&lock->lock, rt_spin_lock_slowlock);
@@ -853,6 +868,13 @@ void __lockfunc rt_spin_unlock(spinlock_t *lock) }EXPORT_SYMBOL (rt_spin_unlock); +void __lockfunc rt_spin_unlock_after_trylock_in_irq(spinlock_t *lock) +{ +/* NOTE: we always pass in '1' for nested, for simplicity */ +spin_release (&lock->dep_map,1 , _RET_IP_); +rt_spin_lock_fastunlock (&lock->lock, rt_spin_lock_slowunlock_hirq); +} + void __lockfunc __rt_spin_unlock(struct rt_mutex *lock) {rt_spin_lock_fastunlock (lock, rt_spin_lock_slowunlock);
@@ -1056,7 +1078,8 @@ rt_mutex_slowtrylock(struct rt_mutex *lock) {int ret =0 ; -raw_spin_lock (&lock->wait_lock); +if (!raw_spin_trylock (&lock->wait_lock)) +return ret;init_lists (lock);if (likely (rt_mutex_owner (lock) != current)) {
kernel/timer.c +1 -1
@@ -1398,7 +1398,7 @@ unsigned long get_next_timer_interrupt(unsigned long now) expires = base->next_timer; }#ifdef CONFIG_PREEMPT_RT_FULL -rt_spin_unlock (&base->lock); +rt_spin_unlock_after_trylock_in_irq (&base->lock);#else spin_unlock (&base->lock);#endif
Signature · 1 line
1.8.4.3
PATCH 5/5 Linux 3.8.13.13-rt26-rc1
In reply to Steven Rostedt3.8.13.13-rt26-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 @@ --rt25 +-rt26-rc1
Signature · 1 line
1.8.4.3