Linux 3.2.53-rt76-rc1
Subsystems (6)
cover Linux 3.2.53-rt76-rc1
Dear RT Folks,
This is the RT stable review cycle of patch 3.2.53-rt76-rc1.
Note, the reason I did not release this earlier, was that I found that the v3.2-rt series was locking up with my cpu hotplug stress test. I finally got some time to debug this, and found that the problem was in the invalidate_bh_lrs() where it was stuck in the on_each_cpu() call where it was waiting for an offline CPU. Looking at what 3.4-rt does, which does not have this problem, there were three patches in mainline from Gilad Ben-Yossef that appears to fix the issue. At least it makes the symptom go away. I may look into this deeper to make sure that we did not just make a race window much harder to hit, and really did fix the problem. But as 3.2-rt is now as stable as 3.4-rt and later I can finally release this candidate.
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 1/17/2014.
Enjoy,
-- Steve
To build 3.2.53-rt76-rc1 directly, the following patches should be applied:
http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.2.tar.xz
http://www.kernel.org/pub/linux/kernel/v3.x/patch-3.2.53.xz
http://www.kernel.org/pub/linux/kernel/projects/rt/3.2/patch-3.2.53-rt76-rc1.patch.xz
You can also build from 3.2.53-rt75 by applying the incremental patch:
http://www.kernel.org/pub/linux/kernel/projects/rt/3.2/incr/patch-3.2.53-rt75-rt76-rc1.patch.xz
Changes from 3.2.53-rt75:
---
Gilad Ben-Yossef (3):
smp: introduce a generic on_each_cpu_mask() function
smp: add func to IPI cpus based on parameter func
fs: only send IPI to invalidate LRU BH when needed
Peter Zijlstra (1):
lockdep: Correctly annotate hardirq context in irq_exit()
Sebastian Andrzej Siewior (2):
swait: Add a few more users
rtmutex: use a trylock for waiter lock in trylock
Steven Rostedt (Red Hat) (1):
Linux 3.2.53-rt76-rc1
Tiejun Chen (1):
cpu_down: move migrate_enable() back
----
arch/arm/kernel/smp_tlb.c | 20 ++----- arch/tile/include/asm/smp.h | 7 --- arch/tile/kernel/smp.c | 19 ------- drivers/net/wireless/orinoco/orinoco_usb.c | 2 +- drivers/usb/gadget/f_fs.c | 2 +- drivers/usb/gadget/inode.c | 4 +- fs/buffer.c | 15 ++++- include/linux/smp.h | 46 +++++++++++++++ include/linux/spinlock_rt.h | 1 + kernel/cpu.c | 2 +- kernel/rtmutex.c | 31 ++++++++-- kernel/smp.c | 90 ++++++++++++++++++++++++++++++ kernel/softirq.c | 45 ++++++++++++++- kernel/timer.c | 2 +- localversion-rt | 2 +- 15 files changed, 232 insertions(+), 56 deletions(-)
PATCH 1/8 cpu_down: move migrate_enable() back
3.2.53-rt76-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
@@ -546,6 +546,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);
@@ -598,7 +599,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/8 swait: Add a few more users
In reply to Steven Rostedt3.2.53-rt76-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
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
@@ -1270,7 +1270,7 @@ static void ffs_data_put(struct ffs_data *ffs)BUG_ON (mutex_is_locked (&ffs->mutex) ||spin_is_locked (&ffs->ev.waitq.lock) ||waitqueue_active (&ffs->ev.waitq) || -waitqueue_active (&ffs->ep0req_completion.wait)); +swaitqueue_active (&ffs->ep0req_completion.wait));kfree (ffs); } }
drivers/usb/gadget/inode.c +2 -2
@@ -339,7 +339,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 )) {
@@ -348,7 +348,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/8 lockdep: Correctly annotate hardirq context in irq_exit()
In reply to Steven Rostedt3.2.53-rt76-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
@@ -297,6 +297,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;
@@ -308,7 +346,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:
@@ -324,7 +362,7 @@ restart:if (pending)wakeup_softirqd (); -lockdep_softirq_exit (); +lockdep_softirq_end ();account_system_vtime (current);__local_bh_enable (SOFTIRQ_OFFSET );
@@ -583,6 +621,7 @@ static inline void invoke_softirq(void) {#ifndef CONFIG_PREEMPT_RT_FULL if (!force_irqthreads) +lockdep_softirq_from_hardirq ();__do_softirq (); else { __local_bh_disable((unsigned long)__builtin_return_address(0),
@@ -618,7 +657,6 @@ static inline void invoke_softirq(void)void irq_exit (void ) {account_system_vtime (current); -trace_hardirq_exit ();sub_preempt_count (IRQ_EXIT_OFFSET );if (!in_interrupt () &&local_softirq_pending ())invoke_softirq ();
@@ -629,6 +667,7 @@ void irq_exit(void)if (idle_cpu (smp_processor_id ()) && !in_interrupt () && !need_resched ())tick_nohz_stop_sched_tick (0 );#endif +trace_hardirq_exit ();/* must be last! */ __preempt_enable_no_resched (); }
Signature · 1 line
1.8.4.3
PATCH 4/8 rtmutex: use a trylock for waiter lock in trylock
In reply to Steven Rostedt3.2.53-rt76-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
@@ -20,6 +20,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);
@@ -1064,7 +1086,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
@@ -1336,7 +1336,7 @@ unsigned long get_next_timer_interrupt(unsigned long now)if (time_before_eq (base->next_timer, base->timer_jiffies)) base->next_timer =__next_timer_interrupt (base); expires = base->next_timer; -rt_spin_unlock (&base->lock); +rt_spin_unlock_after_trylock_in_irq (&base->lock); }else { expires = now +1 ; }
Signature · 1 line
1.8.4.3
Re: [PATCH RT 4/8] rtmutex: use a trylock for waiter lock in trylock
Quoted 2 lines · Steven Rostedt
3.2.53-rt76-rc1 stable review patch.
If anyone has any objections, please let me know.
Not sure this is needed without the tglx don't unconditionally raise timer softirq patch, and with that patch applied in the form it exists in 3.12-rt9, as well as this one, you'll still eventually deadlock.
Quoted 129 lines
------------------
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 atry_lock()which deadlocks on the waiter lock not the lock itself.
This patch takes thewaiter_lockwith trylock so it should work from interrupt context as well. If the fastpath doesn't work and thewaiter_lockitself 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 thewait_lockin the first place we should also be able to take it in the unlock path.Reported-by Mike Galbraith <[email protected]>Signed-off-by Sebastian Andrzej Siewior <[email protected]>--- 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@@ -20,6 +20,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);@@ -1064,7 +1086,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@@ -1336,7 +1336,7 @@ unsigned long get_next_timer_interrupt(unsigned long now)if (time_before_eq (base->next_timer, base->timer_jiffies)) base->next_timer =__next_timer_interrupt (base); expires = base->next_timer; -rt_spin_unlock (&base->lock); +rt_spin_unlock_after_trylock_in_irq (&base->lock); }else { expires = now +1 ; }
Re: [PATCH RT 4/8] rtmutex: use a trylock for waiter lock in trylock
Quoted 9 lines · On Thu, 16 Jan 2014 04:08:57 +0100 Mike Galbraith <[email protected]> wrote:
Quoted 2 lines · Steven Rostedt
3.2.53-rt76-rc1 stable review patch.
If anyone has any objections, please let me know.Not sure this is needed without the tglx don't unconditionally raise timer softirq patch, and with that patch applied in the form it exists in 3.12-rt9, as well as this one, you'll still eventually deadlock.
Hmm, I'll have to take a look. This sounds to be missing from all the stable -rt kernels. I'll be pulling in the latest updates from 3.12-rt soon.
Thanks,
-- Steve
Re: [PATCH RT 4/8] rtmutex: use a trylock for waiter lock in trylock
Quoted 9 lines · Steven Rostedt
Quoted 6 lines · On Thu, 16 Jan 2014 04:08:57 +0100 Mike Galbraith <[email protected]> wrote:
Quoted 2 lines · Steven Rostedt
3.2.53-rt76-rc1 stable review patch.
If anyone has any objections, please let me know.
Quoted 7 lines
Quoted 3 lines
Not sure this is needed without the tglx don't unconditionally raise timer softirq patch, and with that patch applied in the form it exists in 3.12-rt9, as well as this one, you'll still eventually deadlock.
Hmm, I'll have to take a look. This sounds to be missing from all the stable -rt kernels. I'll be pulling in the latest updates from 3.12-rt soon.
Below are the two deadlocks I encountered with 3.12-rt9, which has both $subject and timers-do-not-raise-softirq-unconditionally.patch applied.
With bandaids applied, no others appeared.
nohz_full_all:
PID: 508 TASK: ffff8802739ba340 CPU: 16 COMMAND: "ksoftirqd/16"
#0 [ffff880276806a40] machine_kexec at ffffffff8103bc07 #1 [ffff880276806aa0] crash_kexec at ffffffff810d56b3
#2 [ffff880276806b70] panic at ffffffff815bf8b0
#3 [ffff880276806bf0] watchdog_overflow_callback at ffffffff810fed3d #4 [ffff880276806c10] __perf_event_overflow at ffffffff81131928 #5 [ffff880276806ca0] perf_event_overflow at ffffffff81132254 #6 [ffff880276806cb0] intel_pmu_handle_irq at ffffffff8102078f #7 [ffff880276806de0] perf_event_nmi_handler at ffffffff815c5825 #8 [ffff880276806e10] nmi_handle at ffffffff815c4ed3
#9 [ffff880276806ea0] default_do_nmi at ffffffff815c5063
#10 [ffff880276806ed0] do_nmi at ffffffff815c5388
#11 [ffff880276806ef0] end_repeat_nmi at ffffffff815c4371
[exception RIP: _raw_spin_trylock+48]
RIP: ffffffff815c3790 RSP: ffff880276803e28 RFLAGS: 00000002
RAX: 0000000000000010 RBX: 0000000000000010 RCX: 0000000000000002
RDX: ffff880276803e28 RSI: 0000000000000018 RDI: 0000000000000001
RBP: ffffffff815c3790 R8: ffffffff815c3790 R9: 0000000000000018
R10: ffff880276803e28 R11: 0000000000000002 R12: ffffffffffffffff
R13: ffff880273a0c000 R14: ffff8802739ba340 R15: ffff880273a03fd8
ORIG_RAX: ffff880273a03fd8 CS: 0010 SS: 0018--- <RT exception stack> ---
#12 [ffff880276803e28] _raw_spin_trylock at ffffffff815c3790
#13 [ffff880276803e30] rt_spin_lock_slowunlock_hirq at ffffffff815c2cc8 #14 [ffff880276803e50] rt_spin_unlock_after_trylock_in_irq at ffffffff815c3425 #15 [ffff880276803e60] get_next_timer_interrupt at ffffffff810684a7 #16 [ffff880276803ed0] tick_nohz_stop_sched_tick at ffffffff810c5f2e #17 [ffff880276803f50] tick_nohz_irq_exit at ffffffff810c6333
#18 [ffff880276803f70] irq_exit at ffffffff81060065
#19 [ffff880276803f90] smp_apic_timer_interrupt at ffffffff810358f5 #20 [ffff880276803fb0] apic_timer_interrupt at ffffffff815cbf9d --- <IRQ stack> ---
#21 [ffff880273a03b28] apic_timer_interrupt at ffffffff815cbf9d
[exception RIP: _raw_spin_lock+50]
RIP: ffffffff815c3642 RSP: ffff880273a03bd8 RFLAGS: 00000202
RAX: 0000000000008b49 RBX: ffff880272157290 RCX: ffff8802739ba340
RDX: 0000000000008b4a RSI: 0000000000000010 RDI: ffff880273a0c000
RBP: ffff880273a03bd8 R8: 0000000000000001 R9: 0000000000000000
R10: 0000000000000000 R11: 0000000000000001 R12: ffffffff810927b5
R13: ffff880273a03b68 R14: 0000000000000010 R15: 0000000000000010
ORIG_RAX: ffffffffffffff10 CS: 0010 SS: 0018#22 [ffff880273a03be0] rt_spin_lock_slowlock at ffffffff815c2591 #23 [ffff880273a03cc0] rt_spin_lock at ffffffff815c3362 #24 [ffff880273a03cd0] run_timer_softirq at ffffffff81069002 #25 [ffff880273a03d70] handle_softirq at ffffffff81060d0f #26 [ffff880273a03db0] do_current_softirqs at ffffffff81060f3c #27 [ffff880273a03e20] run_ksoftirqd at ffffffff81061045 #28 [ffff880273a03e40] smpboot_thread_fn at ffffffff81089c31 #29 [ffff880273a03ec0] kthread at ffffffff810807fe
#30 [ffff880273a03f50] ret_from_fork at ffffffff815cb28c
nohz_tick:
PID: 6948 TASK: ffff880272d1f1c0 CPU: 29 COMMAND: "tbench"
#0 [ffff8802769a6a40] machine_kexec at ffffffff8103bc07 #1 [ffff8802769a6aa0] crash_kexec at ffffffff810d3e93
#2 [ffff8802769a6b70] panic at ffffffff815bce70
#3 [ffff8802769a6bf0] watchdog_overflow_callback at ffffffff810fd51d #4 [ffff8802769a6c10] __perf_event_overflow at ffffffff8112f1f8 #5 [ffff8802769a6ca0] perf_event_overflow at ffffffff8112fb14 #6 [ffff8802769a6cb0] intel_pmu_handle_irq at ffffffff8102078f #7 [ffff8802769a6de0] perf_event_nmi_handler at ffffffff815c2de5 #8 [ffff8802769a6e10] nmi_handle at ffffffff815c2493
#9 [ffff8802769a6ea0] default_do_nmi at ffffffff815c2623
#10 [ffff8802769a6ed0] do_nmi at ffffffff815c2948
#11 [ffff8802769a6ef0] end_repeat_nmi at ffffffff815c1931
[exception RIP: preempt_schedule+36]
RIP: ffffffff815be944 RSP: ffff8802769a3d98 RFLAGS: 00000002
RAX: 0000000000000010 RBX: 0000000000000010 RCX: 0000000000000002
RDX: ffff8802769a3d98 RSI: 0000000000000018 RDI: 0000000000000001
RBP: ffffffff815be944 R8: ffffffff815be944 R9: 0000000000000018
R10: ffff8802769a3d98 R11: 0000000000000002 R12: ffffffffffffffff
R13: ffff880273f74000 R14: ffff880272d1f1c0 R15: ffff880269cedfd8
ORIG_RAX: ffff880269cedfd8 CS: 0010 SS: 0018--- <RT exception stack> ---
#12 [ffff8802769a3d98] preempt_schedule at ffffffff815be944
#13 [ffff8802769a3db0] _raw_spin_trylock at ffffffff815c0d6e
#14 [ffff8802769a3dc0] rt_spin_lock_slowunlock_hirq at ffffffff815c0288 #15 [ffff8802769a3de0] rt_spin_unlock_after_trylock_in_irq at ffffffff815c09e5 #16 [ffff8802769a3df0] run_local_timers at ffffffff81068025
#17 [ffff8802769a3e10] update_process_times at ffffffff810680ac #18 [ffff8802769a3e40] tick_sched_handle at ffffffff810c3a92
#19 [ffff8802769a3e60] tick_sched_timer at ffffffff810c3d2f
#20 [ffff8802769a3e90] __run_hrtimer at ffffffff8108471d
#21 [ffff8802769a3ed0] hrtimer_interrupt at ffffffff8108497a
#22 [ffff8802769a3f70] local_apic_timer_interrupt at ffffffff810349e6 #23 [ffff8802769a3f90] smp_apic_timer_interrupt at ffffffff810358ee #24 [ffff8802769a3fb0] apic_timer_interrupt at ffffffff815c955d --- <IRQ stack> ---
#25 [ffff880269ced848] apic_timer_interrupt at ffffffff815c955d
[exception RIP: _raw_spin_lock+53]
RIP: ffffffff815c0c05 RSP: ffff880269ced8f8 RFLAGS: 00000202
RAX: 0000000000000b7b RBX: 0000000000000282 RCX: ffff880272d1f1c0
RDX: 0000000000000b7d RSI: ffff880269ceda38 RDI: ffff880273f74000
RBP: ffff880269ced8f8 R8: 0000000000000001 R9: 00000000b54d13a4
R10: 0000000000000001 R11: 0000000000000001 R12: ffff880269ced910
R13: ffff880276d32170 R14: ffffffff810c9030 R15: ffff880269ced8b8
ORIG_RAX: ffffffffffffff10 CS: 0010 SS: 0018#26 [ffff880269ced900] rt_spin_lock_slowlock at ffffffff815bfb51 #27 [ffff880269ced9e0] rt_spin_lock at ffffffff815c0922 #28 [ffff880269ced9f0] lock_timer_base at ffffffff81067f92 #29 [ffff880269ceda20] mod_timer at ffffffff81069bcb
#30 [ffff880269ceda70] sk_reset_timer at ffffffff814d1e57 #31 [ffff880269ceda90] inet_csk_reset_xmit_timer at ffffffff8152d4a8 #32 [ffff880269cedac0] tcp_rearm_rto at ffffffff8152d583 #33 [ffff880269cedae0] tcp_ack at ffffffff81534085
#34 [ffff880269cedb60] tcp_rcv_established at ffffffff8153443d #35 [ffff880269cedbb0] tcp_v4_do_rcv at ffffffff8153f56a #36 [ffff880269cedbe0] __release_sock at ffffffff814d3891 #37 [ffff880269cedc10] release_sock at ffffffff814d3942 #38 [ffff880269cedc30] tcp_sendmsg at ffffffff8152b955
#39 [ffff880269cedd00] inet_sendmsg at ffffffff8155350e #40 [ffff880269cedd30] sock_sendmsg at ffffffff814cea87 #41 [ffff880269cede40] sys_sendto at ffffffff814cebdf
#42 [ffff880269cedf80] tracesys at ffffffff815c8b09 (via system_call)
RIP: 00007f0441a1fc35 RSP: 00007fffdea86130 RFLAGS: 00000246
RAX: ffffffffffffffda RBX: ffffffff815c8b09 RCX: ffffffffffffffff
RDX: 000000000000248d RSI: 0000000000607260 RDI: 0000000000000004
RBP: 000000000000248d R8: 0000000000000000 R9: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00007fffdea86a10
R13: 00007fffdea86414 R14: 0000000000000004 R15: 0000000000607260
ORIG_RAX: 000000000000002c CS: 0033 SS: 002bUnrelated to this, just FYI, hotplug is still racy in -rt, though I'm suspecting -rt isn't really to blame. I'm trying to finger it out now.
Your stress script makes virgin -rt9 explode in get_group() ala below. You can also end up accessing bad domain data in idle_balance().. 64 core box with no SMT enabled enters idle_balance(), and finds SIBLING domain with groups of 0 weight, and promptly do /0 in that case.
This is virgin source running on 64 core DL980.. well, virgin plus one trace_printk() to help asm-challenged self find stuff on the stack.
[ 4466.495899] CPU: 9 PID: 63150 Comm: stress-cpu-hotp Tainted: GF 3.12.7-rt9 #240 [ 4466.495900] Hardware name: Hewlett-Packard ProLiant DL980 G7, BIOS P66 07/07/2010 [ 4466.495901] task: ffff88026ddfbd40 ti: ffff880267486000 task.ti: ffff880267486000 [ 4466.495904] RIP: 0010:[<ffffffff8108c58f>] [<ffffffff8108c58f>] get_group+0x4f/0x80 [ 4466.495905] RSP: 0018:ffff880267487b88 EFLAGS: 00010282 [ 4466.495906] RAX: 0000000000017390 RBX: ffff8802703aba48 RCX: 0000000000000100 [ 4466.495906] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100 [ 4466.495907] RBP: ffff880267487b98 R08: 0000000000000100 R09: ffff880270215290 [ 4466.495908] R10: ffff880270215290 R11: 0000000000000007 R12: ffff880267487bc8 [ 4466.495909] R13: ffff880270215290 R14: ffff8802703aba48 R15: 0000000000000011 [ 4466.495910] FS: 00007fb8c9390700(0000) GS:ffff880276f20000(0000) knlGS:0000000000000000 [ 4466.495911] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 4466.495912] CR2: 0000000000017390 CR3: 0000000265033000 CR4: 00000000000007e0 [ 4466.495913] Stack: [ 4466.495917] 0000000000000012 00000000ffffffff ffff880267487bf8 ffffffff8108c6b0 [ 4466.495921] ffff8802703aba00 ffff8802682d1b40 ffff8802648b3380 ffffffff8108d2da [ 4466.495925] ffff8802648b3380 ffff880270215200 0000000000000000 0000000000000000 [ 4466.495925] Call Trace: [ 4466.495931] [<ffffffff8108c6b0>] build_sched_groups+0xf0/0x200 [ 4466.495934] [<ffffffff8108d2da>] ? build_sched_domain+0x5a/0xf0 [ 4466.495936] [<ffffffff8108f7ca>] build_sched_domains+0x22a/0x490 [ 4466.495939] [<ffffffff8108fbd1>] partition_sched_domains+0x1a1/0x3e0 [ 4466.495946] [<ffffffff810dfcb2>] cpuset_update_active_cpus+0x12/0x30 [ 4466.495948] [<ffffffff8108fe4c>] cpuset_cpu_active+0x3c/0x70 [ 4466.495954] [<ffffffff815c987f>] notifier_call_chain+0x3f/0x80 [ 4466.495960] [<ffffffff81085c09>] __raw_notifier_call_chain+0x9/0x10 [ 4466.495966] [<ffffffff8105a138>] _cpu_up+0x158/0x170 [ 4466.495968] [<ffffffff8105a3aa>] cpu_up+0xca/0x130 [ 4466.495974] [<ffffffff815bcc26>] cpu_subsys_online+0x56/0xb0 [ 4466.495978] [<ffffffff8141303d>] device_online+0x7d/0xa0 [ 4466.495982] [<ffffffff814149b8>] online_store+0x78/0x80 [ 4466.495989] [<ffffffff814124db>] dev_attr_store+0x1b/0x20 [ 4466.495996] [<ffffffff8121ba35>] sysfs_write_file+0xc5/0x140 [ 4466.496003] [<ffffffff811a0f27>] vfs_write+0xe7/0x190 [ 4466.496007] [<ffffffff811a187d>] SyS_write+0x5d/0xa0 [ 4466.496012] [<ffffffff815cd4b9>] system_call_fastpath+0x16/0x1b [ 4466.496026] Code: 85 c0 74 13 48 8d b8 90 00 00 00 be 00 01 00 00 e8 c7 9d 29 00 89 c7 4d 85 e4 74 39 48 63 cf 48 8b 43 08 48 8b 14 cd 40 27 ab 81 <48> 8b 34 10 49 89 34 24 48 8b 14 cd 40 27 ab 81 48 8b 43 10 48 [ 4466.496028] RIP [<ffffffff8108c58f>] get_group+0x4f/0x80 [ 4466.496028] RSP <ffff880267487b88> [ 4466.496029] CR2: 0000000000017390
crash> bt
PID: 63150 TASK: ffff88026ddfbd40 CPU: 9 COMMAND: "stress-cpu-hotp"
#0 [ffff880267487790] machine_kexec at ffffffff8103b9e7 #1 [ffff8802674877f0] crash_kexec at ffffffff810d3763 #2 [ffff8802674878c0] oops_end at ffffffff815c6f58
#3 [ffff8802674878f0] no_context at ffffffff81048529 #4 [ffff880267487930] __bad_area_nosemaphore at ffffffff8104873d #5 [ffff880267487980] bad_area at ffffffff8104888c
#6 [ffff8802674879b0] __do_page_fault at ffffffff815c97ac #7 [ffff880267487ac0] do_page_fault at ffffffff815c9839 #8 [ffff880267487ad0] page_fault at ffffffff815c6348
[exception RIP: get_group+79] core.c:5721 *sg = *per_cpu_ptr(sdd->sg, cpu)
RIP: ffffffff8108c58f RSP: ffff880267487b88 RFLAGS: 00010282
RAX: 0000000000017390 RBX: ffff8802703aba48 RCX: 0000000000000100
RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000100
RBP: ffff880267487b98 R8: 0000000000000100 R9: ffff880270215290
R10: ffff880270215290 R11: 0000000000000007 R12: ffff880267487bc8
R13: ffff880270215290 R14: ffff8802703aba48 R15: 0000000000000011
ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
#9 [ffff880267487ba0] build_sched_groups at ffffffff8108c6b0 core.c:5763 group = get_group(i, sdd, &sg);
#10 [ffff880267487c00] build_sched_domains at ffffffff8108f7ca core.c:6407 if (build_sched_groups(sd, i))
#11 [ffff880267487c50] partition_sched_domains at ffffffff8108fbd1 core.c:6608 build_sched_domains(doms_new[i], dattr_new ? dattr_new + i : NULL);
#12 [ffff880267487d00] cpuset_update_active_cpus at ffffffff810dfcb2 cpuset.c:2286 partition_sched_domains(1, NULL, NULL);
#13 [ffff880267487d10] cpuset_cpu_active at ffffffff8108fe4c core.c:6662 cpuset_update_active_cpus(true);#14 [ffff880267487d20] notifier_call_chain at ffffffff815c987f #15 [ffff880267487d60] __raw_notifier_call_chain at ffffffff81085c09 #16 [ffff880267487d70] _cpu_up at ffffffff8105a138
#17 [ffff880267487dc0] cpu_up at ffffffff8105a3aa
#18 [ffff880267487df0] cpu_subsys_online at ffffffff815bcc26 #19 [ffff880267487e30] device_online at ffffffff8141303d #20 [ffff880267487e60] online_store at ffffffff814149b8 #21 [ffff880267487e90] dev_attr_store at ffffffff814124db #22 [ffff880267487ea0] sysfs_write_file at ffffffff8121ba35 #23 [ffff880267487ef0] vfs_write at ffffffff811a0f27
#24 [ffff880267487f20] sys_write at ffffffff811a187d
#25 [ffff880267487f80] system_call_fastpath at ffffffff815cd4b9
RIP: 00007fb8c8ab31f0 RSP: 00007fff96a6f348 RFLAGS: 00000246
RAX: 0000000000000001 RBX: ffffffff815cd4b9 RCX: ffffffffffffffff
RDX: 0000000000000002 RSI: 00007fb8c93b9000 RDI: 0000000000000001
RBP: 00007fb8c93b9000 R8: 00007fb8c9390700 R9: 00007fb8c8d59e30
R10: 00007fb8c8d59e30 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fff96a6f470 R14: 0000000000000002 R15: 00007fb8c8d587a0
ORIG_RAX: 0000000000000001 CS: 0033 SS: 002bRe: [PATCH RT 4/8] rtmutex: use a trylock for waiter lock in trylock
Quoted 14 lines · * Mike Galbraith | 2014-01-17 06:17:12 [+0100]:
Quoted 13 lines · Steven Rostedt
Quoted 9 lines · On Thu, 16 Jan 2014 04:08:57 +0100 Mike Galbraith <[email protected]> wrote:
Quoted 2 lines · Steven Rostedt
3.2.53-rt76-rc1 stable review patch.
If anyone has any objections, please let me know.Not sure this is needed without the tglx don't unconditionally raise timer softirq patch, and with that patch applied in the form it exists in 3.12-rt9, as well as this one, you'll still eventually deadlock.
Quoted 6 lines
Quoted 3 lines
Hmm, I'll have to take a look. This sounds to be missing from all the stable -rt kernels. I'll be pulling in the latest updates from 3.12-rt soon.
Below are the two deadlocks I encountered with 3.12-rt9, which has both $subject and timers-do-not-raise-softirq-unconditionally.patch applied.
This patch was introduced because we had a deadlock in run_local_timers() which took a sleeping lock in hardirq context. This seem not to be the case in v3.2 therefore I would suggest not to take this patch here because it does not fix anything.
Mike, do you see these deadlocks with 3.12.*-rt11 as well?
Sebastian
Re: [PATCH RT 4/8] rtmutex: use a trylock for waiter lock in trylock
Quoted 23 lines · Sebastian Andrzej Siewior
Quoted 14 lines · * Mike Galbraith | 2014-01-17 06:17:12 [+0100]:
Quoted 13 lines · Steven Rostedt
Quoted 9 lines · On Thu, 16 Jan 2014 04:08:57 +0100 Mike Galbraith <[email protected]> wrote:
Quoted 2 lines · Steven Rostedt
3.2.53-rt76-rc1 stable review patch.
If anyone has any objections, please let me know.Not sure this is needed without the tglx don't unconditionally raise timer softirq patch, and with that patch applied in the form it exists in 3.12-rt9, as well as this one, you'll still eventually deadlock.
Quoted 6 lines
Quoted 3 lines
Hmm, I'll have to take a look. This sounds to be missing from all the stable -rt kernels. I'll be pulling in the latest updates from 3.12-rt soon.
Below are the two deadlocks I encountered with 3.12-rt9, which has both $subject and timers-do-not-raise-softirq-unconditionally.patch applied.
Quoted 6 lines
This patch was introduced because we had a deadlock in
run_local_timers()which took a sleeping lock in hardirq context. This seem not to be the case in v3.2 therefore I would suggest not to take this patch here because it does not fix anything.Mike, do you see these deadlocks with 3.12.*-rt11 as well?
No. I beat 64 core box hard configured both nohz_idle and nohz_full, the only thing that fell out was the nohz_full irqs enabled warning.
If Stevens patch didn't fix them, it did make them hide very well.
-Mike
Re: [PATCH RT 4/8] rtmutex: use a trylock for waiter lock in trylock
Quoted 29 lines · Mike Galbraith
Quoted 28 lines · Sebastian Andrzej Siewior
Quoted 14 lines · * Mike Galbraith | 2014-01-17 06:17:12 [+0100]:
Quoted 13 lines · Steven Rostedt
Quoted 9 lines · On Thu, 16 Jan 2014 04:08:57 +0100 Mike Galbraith <[email protected]> wrote:
Quoted 2 lines · Steven Rostedt
3.2.53-rt76-rc1 stable review patch.
If anyone has any objections, please let me know.Not sure this is needed without the tglx don't unconditionally raise timer softirq patch, and with that patch applied in the form it exists in 3.12-rt9, as well as this one, you'll still eventually deadlock.
Quoted 6 lines
Quoted 3 lines
Hmm, I'll have to take a look. This sounds to be missing from all the stable -rt kernels. I'll be pulling in the latest updates from 3.12-rt soon.
Below are the two deadlocks I encountered with 3.12-rt9, which has both $subject and timers-do-not-raise-softirq-unconditionally.patch applied.
This patch was introduced because we had a deadlock in
run_local_timers()which took a sleeping lock in hardirq context. This seem not to be the case in v3.2 therefore I would suggest not to take this patch here because it does not fix anything.
Quoted 4 lines
Quoted 1 line
Mike, do you see these deadlocks with 3.12.*-rt11 as well?
No. I beat 64 core box hard configured both
nohz_idleandnohz_full, the only thing that fell out was thenohz_fullirqs enabled warning.
Oh, and the softirq pending warnings appearing under heavy load. I hadn't gotten to chasing those, but I see they should be history.
I'll wedge the pending -rt11 fixes in, and let 64 core stress a bit while you're kneading -rt12 dough.
-Mike
PATCH 5/8 smp: introduce a generic on_each_cpu_mask() function
In reply to Steven Rostedt3.2.53-rt76-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Gilad Ben-Yossef <[email protected]>
[ Upstream commit 3fc498f165304dc913f1d13b5ac9ab4c758ee7ab ]
We have lots of infrastructure in place to partition multi-core systems such that we have a group of CPUs that are dedicated to specific task:
cgroups, scheduler and interrupt affinity, and cpuisol= boot parameter. Still, kernel code will at times interrupt all CPUs in the system via IPIs for various needs. These IPIs are useful and cannot be avoided altogether, but in certain cases it is possible to interrupt only specific CPUs that have useful work to do and not the entire system.
This patch set, inspired by discussions with Peter Zijlstra and Frederic Weisbecker when testing the nohz task patch set, is a first stab at trying to explore doing this by locating the places where such global IPI calls are being made and turning the global IPI into an IPI for a specific group of CPUs. The purpose of the patch set is to get feedback if this is the right way to go for dealing with this issue and indeed, if the issue is even worth dealing with at all. Based on the feedback from this patch set I plan to offer further patches that address similar issue in other code paths.
This patch creates an on_each_cpu_mask() and on_each_cpu_cond() infrastructure API (the former derived from existing arch specific versions in Tile and Arm) and uses them to turn several global IPI invocation to per CPU group invocations.
Core kernel:
on_each_cpu_mask() calls a function on processors specified by cpumask, which may or may not include the local processor.
You must not call this function with disabled interrupts or from a hardware interrupt handler or from a bottom half handler.
arch/arm:
Note that the generic version is a little different then the Arm one:
1. It has the mask as first parameter
2. It calls the function on the calling CPU with interrupts disabled, but this should be OK since the function is called on the other CPUs with interrupts disabled anyway.
arch/tile:
The API is the same as the tile private one, but the generic version also calls the function on the with interrupts disabled in UP case
This is OK since the function is called on the other CPUs with interrupts disabled.
--- arch/arm/kernel/smp_tlb.c | 20 +++++--------------- arch/tile/include/asm/smp.h | 7 ------- arch/tile/kernel/smp.c | 19 ------------------- include/linux/smp.h | 22 ++++++++++++++++++++++ kernel/smp.c | 29 +++++++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 41 deletions(-)
arch/arm/kernel/smp_tlb.c +5 -15
@@ -13,18 +13,6 @@#include <asm/smp_plat.h> #include <asm/tlbflush.h> -static void on_each_cpu_mask (void (*func)(void *),void *info,int wait, -const struct cpumask *mask) -{ -preempt_disable (); - -smp_call_function_many (mask, func, info, wait); -if (cpumask_test_cpu (smp_processor_id (), mask)) -func (info); - -preempt_enable (); -} -/**********************************************************************/ /*
@@ -87,7 +75,7 @@ void flush_tlb_all(void)void flush_tlb_mm (struct mm_struct *mm) {if (tlb_ops_need_broadcast ()) -on_each_cpu_mask (ipi_flush_tlb_mm, mm,1 ,mm_cpumask (mm)); +on_each_cpu_mask (mm_cpumask (mm), ipi_flush_tlb_mm, mm,1 );else local_flush_tlb_mm (mm); }
@@ -98,7 +86,8 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)struct tlb_args ta; ta.ta_vma = vma; ta.ta_start = uaddr; -on_each_cpu_mask (ipi_flush_tlb_page, &ta,1 ,mm_cpumask (vma->vm_mm)); +on_each_cpu_mask (mm_cpumask (vma->vm_mm), ipi_flush_tlb_page, + &ta,1 ); }else local_flush_tlb_page (vma, uaddr); }
@@ -121,7 +110,8 @@ void flush_tlb_range(struct vm_area_struct *vma, ta.ta_vma = vma; ta.ta_start = start; ta.ta_end = end; -on_each_cpu_mask (ipi_flush_tlb_range, &ta,1 ,mm_cpumask (vma->vm_mm)); +on_each_cpu_mask (mm_cpumask (vma->vm_mm), ipi_flush_tlb_range, + &ta,1 ); }else local_flush_tlb_range (vma, start, end); }
arch/tile/include/asm/smp.h +0 -7
@@ -43,10 +43,6 @@ void evaluate_message(int tag);/* Boot a secondary cpu */ void online_secondary (void ); -/* Call a function on a specified set of CPUs (may include this one). */ -extern void on_each_cpu_mask (const struct cpumask *mask, -void (*func)(void *),void *info,bool wait); -/* Topology of the supervisor tile grid, and coordinates of boot processor */ extern HV_Topology smp_topology;
@@ -91,9 +87,6 @@ void print_disabled_cpus(void);#else /* !CONFIG_SMP */ -#define on_each_cpu_mask (mask, func, info, wait) \ - do { if (cpumask_test_cpu(0, (mask))) func(info); } while (0) -#define smp_master_cpu 0#define smp_height 1#define smp_width 1
arch/tile/kernel/smp.c +0 -19
@@ -87,25 +87,6 @@ void send_IPI_allbutself(int tag)send_IPI_many (&mask, tag); } - -/* -* Provide smp_call_function_mask, but also run function locally -* if specified in the mask. -*/ -void on_each_cpu_mask (const struct cpumask *mask,void (*func)(void *), -void *info,bool wait) -{ -int cpu =get_cpu (); -smp_call_function_many (mask, func, info, wait); -if (cpumask_test_cpu (cpu, mask)) { -local_irq_disable (); -func (info); -local_irq_enable (); - } -put_cpu (); -} - -/* * Functions related to starting/stopping cpus. */
include/linux/smp.h +22 -0
@@ -101,6 +101,13 @@ static inline void call_function_init(void) { }int on_each_cpu (smp_call_func_t func,void *info,int wait);/* +* Call a function on processors specified by mask, which might include +* the local one. +*/ +void on_each_cpu_mask (const struct cpumask *mask,smp_call_func_t func, +void *info,bool wait); + +/* * Mark the boot cpu "online" so that it can call console drivers in * printk() and can access its per-cpu storage. */
@@ -131,6 +138,21 @@ static inline int up_smp_call_function(smp_call_func_t func, void *info)local_irq_enable (); \0 ; \ }) +/* +* Note we still need to test the mask even for UP +* because we actually can get an empty mask from +* code that on SMP might call us without the local +* CPU in the mask. +*/ +#define on_each_cpu_mask (mask, func, info, wait) \ + do { \ + if (cpumask_test_cpu(0, (mask))) { \ + local_irq_disable(); \ + (func)(info); \ + local_irq_enable(); \ + } \ + } while (0) +static inline void smp_send_reschedule (int cpu) { }#define num_booting_cpus () 1#define smp_prepare_boot_cpu () do {} while (0)
kernel/smp.c +29 -0
@@ -712,3 +712,32 @@ int on_each_cpu(void (*func) (void *info), void *info, int wait)return ret; }EXPORT_SYMBOL (on_each_cpu); + +/** +* on_each_cpu_mask(): Run a function on processors specified by +* cpumask, which may include the local processor. +* @mask: The set of cpus to run on (only runs on online subset). +* @func: The function to run. This must be fast and non-blocking. +* @info: An arbitrary pointer to pass to the function. +* @wait: If true, wait (atomically) until function has completed +* on other CPUs. +* +* If @wait is true, then returns once @func has returned. +* +* You must not call this function with disabled interrupts or +* from a hardware interrupt handler or from a bottom half handler. +*/ +void on_each_cpu_mask (const struct cpumask *mask,smp_call_func_t func, +void *info,bool wait) +{ +int cpu =get_cpu (); + +smp_call_function_many (mask, func, info, wait); +if (cpumask_test_cpu (cpu, mask)) { +local_irq_disable (); +func (info); +local_irq_enable (); + } +put_cpu (); +} +EXPORT_SYMBOL (on_each_cpu_mask);
Signature · 1 line
1.8.4.3
PATCH 6/8 smp: add func to IPI cpus based on parameter func
In reply to Steven Rostedt3.2.53-rt76-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Gilad Ben-Yossef <[email protected]>
[ Upstream commit b3a7e98e024ffa9f7e4554dd720c508015c4a831 ]
Add the on_each_cpu_cond() function that wraps on_each_cpu_mask() and calculates the cpumask of cpus to IPI by calling a function supplied as a parameter in order to determine whether to IPI each specific cpu.
The function works around allocation failure of cpumask variable in CONFIG_CPUMASK_OFFSTACK=y by itereating over cpus sending an IPI a time via smp_call_function_single().
The function is useful since it allows to seperate the specific code that decided in each case whether to IPI a specific cpu for a specific request from the common boilerplate code of handling creating the mask, handling failures etc.
--- include/linux/smp.h | 24 +++++++++++++++++++++ kernel/smp.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+)
include/linux/smp.h +24 -0
@@ -108,6 +108,15 @@ void on_each_cpu_mask(const struct cpumask *mask, smp_call_func_t func, void *info, bool wait);/* +* Call a function on each processor for which the supplied function +* cond_func returns a positive value. This may include the local +* processor. +*/ +void on_each_cpu_cond (bool (*cond_func)(int cpu,void *info), +smp_call_func_t func,void *info,bool wait, +gfp_t gfp_flags); + +/* * Mark the boot cpu "online" so that it can call console drivers in * printk() and can access its per-cpu storage. */
@@ -152,6 +161,21 @@ static inline int up_smp_call_function(smp_call_func_t func, void *info)local_irq_enable (); \ } \ }while (0 ) +/* +* Preemption is disabled here to make sure the cond_func is called under the +* same condtions in UP and SMP. + */ +#define on_each_cpu_cond (cond_func, func, info, wait, gfp_flags)\ + do { \ + void *__info = (info); \ + preempt_disable(); \ + if ((cond_func)(0, __info)) { \ + local_irq_disable(); \ + (func)(__info); \ + local_irq_enable(); \ + } \ + preempt_enable(); \ + } while (0)static inline void smp_send_reschedule (int cpu) { }#define num_booting_cpus () 1
kernel/smp.c +61 -0
64 lines not on this page · raw message
Signature · 1 line
1.8.4.3
PATCH 7/8 fs: only send IPI to invalidate LRU BH when needed
In reply to Steven Rostedt3.2.53-rt76-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Gilad Ben-Yossef <[email protected]>
[ Upstream commit 42be35d0390b966253136a285f507f5ad00fd9e8 ]
In several code paths, such as when unmounting a file system (but not only) we send an IPI to ask each cpu to invalidate its local LRU BHs.
For multi-cores systems that have many cpus that may not have any LRU BH because they are idle or because they have not performed any file system accesses since last invalidation (e.g. CPU crunching on high perfomance computing nodes that write results to shared memory or only using filesystems that do not use the bh layer.) This can lead to loss of performance each time someone switches the KVM (the virtual keyboard and screen type, not the hypervisor) if it has a USB storage stuck in.
This patch attempts to only send an IPI to cpus that have LRU BH.
--- fs/buffer.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
fs/buffer.c +14 -1
@@ -1425,10 +1425,23 @@ static void invalidate_bh_lru(void *arg) }put_cpu_var (bh_lrus); } + +static bool has_bh_in_lru (int cpu,void *dummy) +{ +struct bh_lru *b =per_cpu_ptr (&bh_lrus, cpu); +int i; +for (i =0 ; i <BH_LRU_SIZE ; i++) { +if (b->bhs[i]) +return 1 ; + } + +return 0 ; +} +void invalidate_bh_lrus (void ) { -on_each_cpu (invalidate_bh_lru,NULL ,1 ); +on_each_cpu_cond (has_bh_in_lru, invalidate_bh_lru,NULL ,1 ,GFP_KERNEL ); }EXPORT_SYMBOL_GPL (invalidate_bh_lrus);
Signature · 1 line
1.8.4.3
PATCH 8/8 Linux 3.2.53-rt76-rc1
In reply to Steven Rostedt3.2.53-rt76-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 @@ --rt75 +-rt76-rc1
Signature · 1 line
1.8.4.3
16.01.2014 05:58, Steven Rostedt пишет:
Quoted 3 lines
Dear RT Folks,
This is the RT stable review cycle of patch 3.2.53-rt76-rc1.
Yap..., mainline is 3.2.54 !
Signature · 1 line
Pavel.
Quoted 7 lines · On Thu, 16 Jan 2014 13:41:16 +0400 Pavel Vasilyev <[email protected]> wrote:
16.01.2014 05:58, Steven Rostedt пишет:
Quoted 3 lines
Dear RT Folks,
This is the RT stable review cycle of patch 3.2.53-rt76-rc1.
Yap..., mainline is 3.2.54 !
Yeah, but I already had the -rt specific changes merged into 3.2.53 before 3.2.54 was released, and then I discovered the cpu hotplug bug. I did not want to release that -rc until it was solved. Now that it is, I can release this one and then move to 3.2.54.
Thanks,
-- Steve
16.01.2014 18:18, Steven Rostedt пишет:
Quoted 8 lines
Quoted 5 lines · On Thu, 16 Jan 2014 13:41:16 +0400 Pavel Vasilyev <[email protected]> wrote:
16.01.2014 05:58, Steven Rostedt пишет:
Quoted 3 lines
Dear RT Folks,
This is the RT stable review cycle of patch 3.2.53-rt76-rc1.
Quoted 7 lines
Quoted 2 lines
Yap..., mainline is 3.2.54 !
Yeah, but I already had the -rt specific changes merged into 3.2.53 before 3.2.54 was released, and then I discovered the cpu hotplug bug. I did not want to release that -rc until it was solved. Now that it is, I can release this one and then move to 3.2.54.
$ xz -cd /tmp/patch-3.2.53-rt75-rt76-rc1.patch.xz | patch -p1 --dry-run
checking file arch/arm/kernel/smp_tlb.c checking file arch/tile/include/asm/smp.h checking file arch/tile/kernel/smp.c
checking file drivers/net/wireless/orinoco/orinoco_usb.c checking file drivers/usb/gadget/f_fs.c checking file drivers/usb/gadget/inode.c checking file fs/buffer.c
checking file include/linux/smp.h
Hunk #1 succeeded at 117 with fuzz 1 (offset 16 lines). Hunk #2 FAILED at 147.
1 out of 2 hunks FAILED
checking file include/linux/spinlock_rt.h checking file kernel/cpu.c
checking file kernel/rtmutex.c
checking file kernel/smp.c
Hunk #1 FAILED at 712.
1 out of 1 hunk FAILED
checking file kernel/softirq.c
checking file kernel/timer.c
checking file localversion-rt
include/linux/smp.h REJECT: #define on_each_cpu_mask() and #define on_each_cpu_cond() and same in kernel/smp.c
Signature · 1 line
Pavel.
Quoted 42 lines · On Thu, 16 Jan 2014 18:36:32 +0400 Pavel Vasilyev <[email protected]> wrote:
16.01.2014 18:18, Steven Rostedt пишет:
Quoted 8 lines
Quoted 5 lines · On Thu, 16 Jan 2014 13:41:16 +0400 Pavel Vasilyev <[email protected]> wrote:
16.01.2014 05:58, Steven Rostedt пишет:
Quoted 3 lines
Dear RT Folks,
This is the RT stable review cycle of patch 3.2.53-rt76-rc1.
Quoted 7 lines
Quoted 2 lines
Yap..., mainline is 3.2.54 !
Yeah, but I already had the -rt specific changes merged into 3.2.53 before 3.2.54 was released, and then I discovered the cpu hotplug bug. I did not want to release that -rc until it was solved. Now that it is, I can release this one and then move to 3.2.54.
$ xz -cd /tmp/patch-3.2.53-rt75-rt76-rc1.patch.xz | patch -p1 --dry-runchecking file
arch/arm/kernel/smp_tlb.cchecking filearch/tile/include/asm/smp.hchecking filearch/tile/kernel/smp.c
checking filedrivers/net/wireless/orinoco/orinoco_usb.cchecking filedrivers/usb/gadget/f_fs.cchecking filedrivers/usb/gadget/inode.cchecking filefs/buffer.c
checking fileinclude/linux/smp.h
Hunk #1 succeeded at 117 with fuzz 1 (offset 16 lines). Hunk #2 FAILED at 147.
1 out of 2 hunks FAILED
checking fileinclude/linux/spinlock_rt.hchecking filekernel/cpu.c
checking filekernel/rtmutex.c
checking filekernel/smp.c
Hunk #1 FAILED at 712.
1 out of 1 hunk FAILED
checking filekernel/softirq.c
checking filekernel/timer.c
checking file localversion-rt
Quoted 4 lines
include/linux/smp.hREJECT: #defineon_each_cpu_mask()and #defineon_each_cpu_cond()and same inkernel/smp.c
Ouch, thanks for letting me know. I'll give it a try to make sure that the patch is the same code that I tested.
-- Steve
Quoted 25 lines · On Thu, 16 Jan 2014 18:36:32 +0400 Pavel Vasilyev <[email protected]> wrote:
$ xz -cd /tmp/patch-3.2.53-rt75-rt76-rc1.patch.xz | patch -p1 --dry-runchecking file
arch/arm/kernel/smp_tlb.cchecking filearch/tile/include/asm/smp.hchecking filearch/tile/kernel/smp.c
checking filedrivers/net/wireless/orinoco/orinoco_usb.cchecking filedrivers/usb/gadget/f_fs.cchecking filedrivers/usb/gadget/inode.cchecking filefs/buffer.c
checking fileinclude/linux/smp.h
Hunk #1 succeeded at 117 with fuzz 1 (offset 16 lines). Hunk #2 FAILED at 147.
1 out of 2 hunks FAILED
checking fileinclude/linux/spinlock_rt.hchecking filekernel/cpu.c
checking filekernel/rtmutex.c
checking filekernel/smp.c
Hunk #1 FAILED at 712.
1 out of 1 hunk FAILED
checking filekernel/softirq.c
checking filekernel/timer.c
checking file localversion-rt
Quoted 4 lines
include/linux/smp.hREJECT: #defineon_each_cpu_mask()and #defineon_each_cpu_cond()and same inkernel/smp.c
$ git checkout v3.2.53-rt75 [..] $ xzcat /tmp/patch-3.2.53-rt75-rt76-rc1.patch.xz | patch -p1 --dry-run checking file arch/arm/kernel/smp_tlb.c checking file arch/tile/include/asm/smp.h checking file arch/tile/kernel/smp.c checking file drivers/net/wireless/orinoco/orinoco_usb.c checking file drivers/usb/gadget/f_fs.c checking file drivers/usb/gadget/inode.c checking file fs/buffer.c checking file include/linux/smp.h checking file include/linux/spinlock_rt.h checking file kernel/cpu.c checking file kernel/rtmutex.c checking file kernel/smp.c checking file kernel/softirq.c checking file kernel/timer.c checking file localversion-rt $
Did you start with v3.2.53-rt75?
-- Steve
16.01.2014 20:08, Steven Rostedt пишет:
Quoted 7 lines
Quoted 2 lines · On Thu, 16 Jan 2014 18:36:32 +0400 Pavel Vasilyev <[email protected]> wrote:
$ xz -cd /tmp/patch-3.2.53-rt75-rt76-rc1.patch.xz | patch -p1 --dry-runDid you start with v3.2.53-rt75?
No, 3.2.54, already corrected.
Signature · 1 line
Pavel.
Quoted 3 lines · Pavel Vasilyev
$ xz -cd /tmp/patch-3.2.53-rt75-rt76-rc1.patch.xz | patch -p1 --dry-run
…
Quoted 3 lines
checking file
include/linux/smp.hHunk #1 succeeded at 117 with fuzz 1 (offset 16 lines). Hunk #2 FAILED at 147. 1 out of 2 hunks FAILED
I just fetched the 3.2.53 tar file & Steven's patches and I applied the incremental patch and the all-in-one patch and I don't see this fallout.
Sebastian
--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
On 16.01.2014 02:58, Steven Rostedt wrote:
...
Quoted 2 lines
Please scream at me if I messed something up. Please test the patches too.
Hi Steven,
i just tried the incremental patch on our kernel and it applied without problems. But when I try to build it with only "Basic RT" configured, I get this error message:
kernel/softirq.c: In function 'invoke_softirq':kernel/softirq.c:626:2: error: 'else' without a previous 'if'
The source code before that line currently looks like this
#ifndef CONFIG_PREEMPT_RT_FULL
if (!force_irqthreads)
lockdep_softirq_from_hardirq();
__do_softirq();
else {Is one of the lines in the wrong place or is it just missing brackets?
Best regards
Rolf
Quoted 16 lines · On Fri, 17 Jan 2014 14:01:04 +0100 Rolf Peukert <[email protected]> wrote:
On 16.01.2014 02:58, Steven Rostedt wrote:
...Quoted 2 lines
Please scream at me if I messed something up. Please test the patches too.
Hi Steven,
i just tried the incremental patch on our kernel and it applied without problems. But when I try to build it with only "Basic RT" configured, I get this error message:
kernel/softirq.c: In function 'invoke_softirq':kernel/softirq.c:626:2: error: 'else' without a previous 'if'The source code before that line currently looks like this
Quoted 7 lines
#ifndef CONFIG_PREEMPT_RT_FULL if (!force_irqthreads) lockdep_softirq_from_hardirq(); __do_softirq(); else {Is one of the lines in the wrong place or is it just missing brackets?
Looks to be missing brackets. Thanks for reporting this. This was probably a bad merge.
I'll fix this up and do an official release of 3.2.53-rt76.
I guess I should test that config too. :-/
Thanks,
-- Steve
Quoted 8 lines · On Fri, 17 Jan 2014 08:21:11 -0500 Steven Rostedt <[email protected]> wrote:
Quoted 8 lines
The source code before that line currently looks like this
#ifndef CONFIG_PREEMPT_RT_FULL if (!force_irqthreads) lockdep_softirq_from_hardirq(); __do_softirq(); else {
Quoted 8 lines
Quoted 1 line
Is one of the lines in the wrong place or is it just missing brackets?
Looks to be missing brackets. Thanks for reporting this. This was probably a bad merge.
I'll fix this up and do an official release of 3.2.53-rt76.
I guess I should test that config too. :-/
Ah, the bug was in the #ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED section. Which is not compiled with x86.
OK, I need to start testing against PPC and ARM. I'll add that to my todo list.
-- Steve