All of lore.kernel.org
 help / color / mirror / Atom feed
From: will.deacon@arm.com (Will Deacon)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] arm64: traps: disable irq in die()
Date: Tue, 4 Jul 2017 18:17:47 +0100	[thread overview]
Message-ID: <20170704171746.GM22175@arm.com> (raw)
In-Reply-To: <1498640652-23338-2-git-send-email-qiaozhou@asrmicro.com>

On Wed, Jun 28, 2017 at 05:04:12PM +0800, Qiao Zhou wrote:
> In current die(), the irq is disabled for __die() handle, not
> including the possible panic() handling. Since the log in __die()
> can take several hundreds ms, new irq might come and interrupt
> current die().
> 
> If the process calling die() holds some critical resource, and some
> other process scheduled later also needs it, then it would deadlock.
> The first panic will not be executed.
> 
> So here disable irq for the whole flow of die().

Could you give an example of this going wrong, please?

> 
> Signed-off-by: Qiao Zhou <qiaozhou@asrmicro.com>
> ---
>  arch/arm64/kernel/traps.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
> index 0805b44..b12bf0f 100644
> --- a/arch/arm64/kernel/traps.c
> +++ b/arch/arm64/kernel/traps.c
> @@ -274,10 +274,13 @@ static DEFINE_RAW_SPINLOCK(die_lock);
>  void die(const char *str, struct pt_regs *regs, int err)
>  {
>  	int ret;
> +	unsigned long flags;
> +
> +	local_irq_save(flags);
>  
>  	oops_enter();
>  
> -	raw_spin_lock_irq(&die_lock);
> +	raw_spin_lock(&die_lock);

Can we instead move the taking of the die_lock before oops_enter, or does
that break something else?

>  	console_verbose();
>  	bust_spinlocks(1);
>  	ret = __die(str, err, regs);
> @@ -287,13 +290,16 @@ void die(const char *str, struct pt_regs *regs, int err)
>  
>  	bust_spinlocks(0);
>  	add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
> -	raw_spin_unlock_irq(&die_lock);
> +	raw_spin_unlock(&die_lock);
>  	oops_exit();
>  
>  	if (in_interrupt())
>  		panic("Fatal exception in interrupt");
>  	if (panic_on_oops)
>  		panic("Fatal exception");
> +
> +	local_irq_restore(flags);

We could also move the unlock_irq down here.

Will

WARNING: multiple messages have this Message-ID (diff)
From: Will Deacon <will.deacon@arm.com>
To: Qiao Zhou <qiaozhou@asrmicro.com>
Cc: catalin.marinas@arm.com, mark.rutland@arm.com,
	suzuki.poulose@arm.com, mingo@kernel.org, andre.przywara@arm.com,
	marc.zyngier@arm.com, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, zhizhouzhang@asrmicro.com
Subject: Re: [PATCH] arm64: traps: disable irq in die()
Date: Tue, 4 Jul 2017 18:17:47 +0100	[thread overview]
Message-ID: <20170704171746.GM22175@arm.com> (raw)
In-Reply-To: <1498640652-23338-2-git-send-email-qiaozhou@asrmicro.com>

On Wed, Jun 28, 2017 at 05:04:12PM +0800, Qiao Zhou wrote:
> In current die(), the irq is disabled for __die() handle, not
> including the possible panic() handling. Since the log in __die()
> can take several hundreds ms, new irq might come and interrupt
> current die().
> 
> If the process calling die() holds some critical resource, and some
> other process scheduled later also needs it, then it would deadlock.
> The first panic will not be executed.
> 
> So here disable irq for the whole flow of die().

Could you give an example of this going wrong, please?

> 
> Signed-off-by: Qiao Zhou <qiaozhou@asrmicro.com>
> ---
>  arch/arm64/kernel/traps.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
> index 0805b44..b12bf0f 100644
> --- a/arch/arm64/kernel/traps.c
> +++ b/arch/arm64/kernel/traps.c
> @@ -274,10 +274,13 @@ static DEFINE_RAW_SPINLOCK(die_lock);
>  void die(const char *str, struct pt_regs *regs, int err)
>  {
>  	int ret;
> +	unsigned long flags;
> +
> +	local_irq_save(flags);
>  
>  	oops_enter();
>  
> -	raw_spin_lock_irq(&die_lock);
> +	raw_spin_lock(&die_lock);

Can we instead move the taking of the die_lock before oops_enter, or does
that break something else?

>  	console_verbose();
>  	bust_spinlocks(1);
>  	ret = __die(str, err, regs);
> @@ -287,13 +290,16 @@ void die(const char *str, struct pt_regs *regs, int err)
>  
>  	bust_spinlocks(0);
>  	add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
> -	raw_spin_unlock_irq(&die_lock);
> +	raw_spin_unlock(&die_lock);
>  	oops_exit();
>  
>  	if (in_interrupt())
>  		panic("Fatal exception in interrupt");
>  	if (panic_on_oops)
>  		panic("Fatal exception");
> +
> +	local_irq_restore(flags);

We could also move the unlock_irq down here.

Will

  reply	other threads:[~2017-07-04 17:17 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-28  9:04 [PATCH] *** arm64: traps: disable irq in die() *** Qiao Zhou
2017-06-28  9:04 ` Qiao Zhou
2017-06-28  9:04 ` [PATCH] arm64: traps: disable irq in die() Qiao Zhou
2017-06-28  9:04   ` Qiao Zhou
2017-07-04 17:17   ` Will Deacon [this message]
2017-07-04 17:17     ` Will Deacon
2017-07-05  3:16     ` qiaozhou
2017-07-05  3:16       ` qiaozhou

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=20170704171746.GM22175@arm.com \
    --to=will.deacon@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.