From: hillf.zj@alibaba-inc.com (Hillf Danton)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3] arm: Fix backtrace generation when IPI is masked
Date: Wed, 16 Sep 2015 10:43:41 +0800 [thread overview]
Message-ID: <00d201d0f029$80210f40$80632dc0$@alibaba-inc.com> (raw)
In-Reply-To: <1442328005-13661-1-git-send-email-daniel.thompson@linaro.org>
>
> Currently on ARM when <SysRq-L> is triggered from an interrupt handler
> (e.g. a SysRq issued using UART or kbd) the main CPU will wedge for ten
> seconds with interrupts masked before issuing a backtrace for every CPU
> except itself.
>
> The new backtrace code introduced by commit 96f0e00378d4 ("ARM: add
> basic support for on-demand backtrace of other CPUs") does not work
> correctly when run from an interrupt handler because IPI_CPU_BACKTRACE
> is used to generate the backtrace on all CPUs but cannot preempt the
> current calling context.
>
> This can be fixed by detecting that the calling context cannot be
> preempted and issuing the backtrace directly in this case. Issuing
> directly leaves us without any pt_regs to pass to nmi_cpu_backtrace()
> so we also modify the generic code to call dump_stack() when its
> argument is NULL.
>
> Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
> ---
Acked-by: Hillf Danton <hillf.zj@alibaba-inc.com>
>
> Notes:
> Changes in v3:
>
> * Added comments to describe how raise_nmi() and nmi_cpu_backtrace()
> interact with backtrace_mask (Russell King).
>
> Changes in v2:
>
> * Improved commit message to better describe the changes to the generic
> code (Hillf Danton).
>
> arch/arm/kernel/smp.c | 9 +++++++++
> lib/nmi_backtrace.c | 11 ++++++++++-
> 2 files changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
> index 48185a773852..0c4e7fdb9636 100644
> --- a/arch/arm/kernel/smp.c
> +++ b/arch/arm/kernel/smp.c
> @@ -748,6 +748,15 @@ core_initcall(register_cpufreq_notifier);
>
> static void raise_nmi(cpumask_t *mask)
> {
> + /*
> + * Generate the backtrace directly if we are running in a calling
> + * context that is not preemptible by the backtrace IPI. Note
> + * that nmi_cpu_backtrace() automatically removes the current cpu
> + * from mask.
> + */
> + if (cpumask_test_cpu(smp_processor_id(), mask) && irqs_disabled())
> + nmi_cpu_backtrace(NULL);
> +
> smp_cross_call(mask, IPI_CPU_BACKTRACE);
> }
>
> diff --git a/lib/nmi_backtrace.c b/lib/nmi_backtrace.c
> index 88d3d32e5923..6019c53c669e 100644
> --- a/lib/nmi_backtrace.c
> +++ b/lib/nmi_backtrace.c
> @@ -43,6 +43,12 @@ static void print_seq_line(struct nmi_seq_buf *s, int start, int end)
> printk("%.*s", (end - start) + 1, buf);
> }
>
> +/*
> + * When raise() is called it will be is passed a pointer to the
> + * backtrace_mask. Architectures that call nmi_cpu_backtrace()
> + * directly from their raise() functions may rely on the mask
> + * they are passed being updated as a side effect of this call.
> + */
> void nmi_trigger_all_cpu_backtrace(bool include_self,
> void (*raise)(cpumask_t *mask))
> {
> @@ -149,7 +155,10 @@ bool nmi_cpu_backtrace(struct pt_regs *regs)
> /* Replace printk to write into the NMI seq */
> this_cpu_write(printk_func, nmi_vprintk);
> pr_warn("NMI backtrace for cpu %d\n", cpu);
> - show_regs(regs);
> + if (regs)
> + show_regs(regs);
> + else
> + dump_stack();
> this_cpu_write(printk_func, printk_func_save);
>
> cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
> --
> 2.4.3
WARNING: multiple messages have this Message-ID (diff)
From: "Hillf Danton" <hillf.zj@alibaba-inc.com>
To: "'Daniel Thompson'" <daniel.thompson@linaro.org>,
"'Russell King'" <linux@arm.linux.org.uk>
Cc: <linux-arm-kernel@lists.infradead.org>,
<linux-kernel@vger.kernel.org>, <patches@linaro.org>,
<linaro-kernel@lists.linaro.org>,
"'Thomas Gleixner'" <tglx@linutronix.de>
Subject: Re: [PATCH v3] arm: Fix backtrace generation when IPI is masked
Date: Wed, 16 Sep 2015 10:43:41 +0800 [thread overview]
Message-ID: <00d201d0f029$80210f40$80632dc0$@alibaba-inc.com> (raw)
In-Reply-To: <1442328005-13661-1-git-send-email-daniel.thompson@linaro.org>
>
> Currently on ARM when <SysRq-L> is triggered from an interrupt handler
> (e.g. a SysRq issued using UART or kbd) the main CPU will wedge for ten
> seconds with interrupts masked before issuing a backtrace for every CPU
> except itself.
>
> The new backtrace code introduced by commit 96f0e00378d4 ("ARM: add
> basic support for on-demand backtrace of other CPUs") does not work
> correctly when run from an interrupt handler because IPI_CPU_BACKTRACE
> is used to generate the backtrace on all CPUs but cannot preempt the
> current calling context.
>
> This can be fixed by detecting that the calling context cannot be
> preempted and issuing the backtrace directly in this case. Issuing
> directly leaves us without any pt_regs to pass to nmi_cpu_backtrace()
> so we also modify the generic code to call dump_stack() when its
> argument is NULL.
>
> Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
> ---
Acked-by: Hillf Danton <hillf.zj@alibaba-inc.com>
>
> Notes:
> Changes in v3:
>
> * Added comments to describe how raise_nmi() and nmi_cpu_backtrace()
> interact with backtrace_mask (Russell King).
>
> Changes in v2:
>
> * Improved commit message to better describe the changes to the generic
> code (Hillf Danton).
>
> arch/arm/kernel/smp.c | 9 +++++++++
> lib/nmi_backtrace.c | 11 ++++++++++-
> 2 files changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
> index 48185a773852..0c4e7fdb9636 100644
> --- a/arch/arm/kernel/smp.c
> +++ b/arch/arm/kernel/smp.c
> @@ -748,6 +748,15 @@ core_initcall(register_cpufreq_notifier);
>
> static void raise_nmi(cpumask_t *mask)
> {
> + /*
> + * Generate the backtrace directly if we are running in a calling
> + * context that is not preemptible by the backtrace IPI. Note
> + * that nmi_cpu_backtrace() automatically removes the current cpu
> + * from mask.
> + */
> + if (cpumask_test_cpu(smp_processor_id(), mask) && irqs_disabled())
> + nmi_cpu_backtrace(NULL);
> +
> smp_cross_call(mask, IPI_CPU_BACKTRACE);
> }
>
> diff --git a/lib/nmi_backtrace.c b/lib/nmi_backtrace.c
> index 88d3d32e5923..6019c53c669e 100644
> --- a/lib/nmi_backtrace.c
> +++ b/lib/nmi_backtrace.c
> @@ -43,6 +43,12 @@ static void print_seq_line(struct nmi_seq_buf *s, int start, int end)
> printk("%.*s", (end - start) + 1, buf);
> }
>
> +/*
> + * When raise() is called it will be is passed a pointer to the
> + * backtrace_mask. Architectures that call nmi_cpu_backtrace()
> + * directly from their raise() functions may rely on the mask
> + * they are passed being updated as a side effect of this call.
> + */
> void nmi_trigger_all_cpu_backtrace(bool include_self,
> void (*raise)(cpumask_t *mask))
> {
> @@ -149,7 +155,10 @@ bool nmi_cpu_backtrace(struct pt_regs *regs)
> /* Replace printk to write into the NMI seq */
> this_cpu_write(printk_func, nmi_vprintk);
> pr_warn("NMI backtrace for cpu %d\n", cpu);
> - show_regs(regs);
> + if (regs)
> + show_regs(regs);
> + else
> + dump_stack();
> this_cpu_write(printk_func, printk_func_save);
>
> cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));
> --
> 2.4.3
next prev parent reply other threads:[~2015-09-16 2:43 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-14 9:18 [PATCH] arm: Fix backtrace generation when IPI is masked Daniel Thompson
2015-09-14 9:18 ` Daniel Thompson
2015-09-15 11:05 ` [PATCH v2] " Daniel Thompson
2015-09-15 11:05 ` Daniel Thompson
2015-09-15 11:30 ` Russell King - ARM Linux
2015-09-15 11:30 ` Russell King - ARM Linux
2015-09-15 13:15 ` Daniel Thompson
2015-09-15 13:15 ` Daniel Thompson
2015-09-15 13:42 ` Russell King - ARM Linux
2015-09-15 13:42 ` Russell King - ARM Linux
2015-09-15 14:40 ` [PATCH v3] " Daniel Thompson
2015-09-15 14:40 ` Daniel Thompson
2015-09-16 2:43 ` Hillf Danton [this message]
2015-09-16 2:43 ` Hillf Danton
2015-09-22 10:59 ` Thomas Gleixner
2015-09-22 10:59 ` Thomas Gleixner
2015-10-03 15:40 ` Russell King - ARM Linux
2015-10-03 15:40 ` Russell King - ARM Linux
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='00d201d0f029$80210f40$80632dc0$@alibaba-inc.com' \
--to=hillf.zj@alibaba-inc.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.