From: Mike Galbraith <bitbucket@online.de>
To: Steven Rostedt <rostedt@goodmis.org>
Cc: linux-kernel@vger.kernel.org,
linux-rt-users <linux-rt-users@vger.kernel.org>,
Thomas Gleixner <tglx@linutronix.de>,
Carsten Emde <C.Emde@osadl.org>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
John Kacur <jkacur@redhat.com>
Subject: Re: [PATCH RT 4/8] rtmutex: use a trylock for waiter lock in trylock
Date: Thu, 16 Jan 2014 04:08:57 +0100 [thread overview]
Message-ID: <1389841737.5418.14.camel@marge.simpson.net> (raw)
In-Reply-To: <20140116020324.637491369@goodmis.org>
On Wed, 2014-01-15 at 20:58 -0500, Steven Rostedt wrote:
> 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.
> ------------------
>
> From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
>
> 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.
>
> Cc: stable-rt@vger.kernel.org
> Reported-by: Mike Galbraith <bitbucket@online.de>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
> include/linux/spinlock_rt.h | 1 +
> kernel/rtmutex.c | 31 +++++++++++++++++++++++++++----
> kernel/timer.c | 2 +-
> 3 files changed, 29 insertions(+), 5 deletions(-)
>
> diff --git a/include/linux/spinlock_rt.h b/include/linux/spinlock_rt.h
> index 3b555b4..28edba7 100644
> --- a/include/linux/spinlock_rt.h
> +++ b/include/linux/spinlock_rt.h
> @@ -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);
> diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c
> index 6075f17..d759326 100644
> --- a/kernel/rtmutex.c
> +++ b/kernel/rtmutex.c
> @@ -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)) {
> diff --git a/kernel/timer.c b/kernel/timer.c
> index 7fa30e0..b7ef082 100644
> --- a/kernel/timer.c
> +++ b/kernel/timer.c
> @@ -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;
> }
next prev parent reply other threads:[~2014-01-16 3:09 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-16 1:58 [PATCH RT 0/8] Linux 3.2.53-rt76-rc1 Steven Rostedt
2014-01-16 1:58 ` [PATCH RT 1/8] cpu_down: move migrate_enable() back Steven Rostedt
2014-01-16 1:58 ` [PATCH RT 2/8] swait: Add a few more users Steven Rostedt
2014-01-16 1:58 ` [PATCH RT 3/8] lockdep: Correctly annotate hardirq context in irq_exit() Steven Rostedt
2014-01-16 1:58 ` [PATCH RT 4/8] rtmutex: use a trylock for waiter lock in trylock Steven Rostedt
2014-01-16 3:08 ` Mike Galbraith [this message]
2014-01-17 4:22 ` Steven Rostedt
2014-01-17 5:17 ` Mike Galbraith
2014-01-31 22:07 ` Sebastian Andrzej Siewior
2014-02-01 4:21 ` Mike Galbraith
2014-02-01 4:54 ` Mike Galbraith
2014-01-16 1:58 ` [PATCH RT 5/8] smp: introduce a generic on_each_cpu_mask() function Steven Rostedt
2014-01-16 1:58 ` [PATCH RT 6/8] smp: add func to IPI cpus based on parameter func Steven Rostedt
2014-01-16 1:58 ` [PATCH RT 7/8] fs: only send IPI to invalidate LRU BH when needed Steven Rostedt
2014-01-16 1:58 ` [PATCH RT 8/8] Linux 3.2.53-rt76-rc1 Steven Rostedt
2014-01-16 9:41 ` [PATCH RT 0/8] " Pavel Vasilyev
2014-01-16 14:18 ` Steven Rostedt
2014-01-16 14:36 ` Pavel Vasilyev
2014-01-16 15:09 ` Steven Rostedt
2014-01-16 16:08 ` Steven Rostedt
2014-01-16 17:19 ` Pavel Vasilyev
2014-01-16 16:18 ` Sebastian Andrzej Siewior
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1389841737.5418.14.camel@marge.simpson.net \
--to=bitbucket@online.de \
--cc=C.Emde@osadl.org \
--cc=bigeasy@linutronix.de \
--cc=jkacur@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rt-users@vger.kernel.org \
--cc=rostedt@goodmis.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox