Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1223964 > unrolled thread

[PATCH] arm: Fix backtrace generation when IPI is masked

Started byDaniel Thompson <daniel.thompson@linaro.org>
First post2015-09-14 11:20 +0200
Last post2015-09-16 04:50 +0200
Articles 7 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH] arm: Fix backtrace generation when IPI is masked Daniel Thompson <daniel.thompson@linaro.org> - 2015-09-14 11:20 +0200
    [PATCH v2] arm: Fix backtrace generation when IPI is masked Daniel Thompson <daniel.thompson@linaro.org> - 2015-09-15 13:10 +0200
      Re: [PATCH v2] arm: Fix backtrace generation when IPI is masked Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-09-15 13:40 +0200
        Re: [PATCH v2] arm: Fix backtrace generation when IPI is masked Daniel Thompson <daniel.thompson@linaro.org> - 2015-09-15 15:20 +0200
          Re: [PATCH v2] arm: Fix backtrace generation when IPI is masked Russell King - ARM Linux <linux@arm.linux.org.uk> - 2015-09-15 15:50 +0200
    [PATCH v3] arm: Fix backtrace generation when IPI is masked Daniel Thompson <daniel.thompson@linaro.org> - 2015-09-15 16:50 +0200
      Re: [PATCH v3] arm: Fix backtrace generation when IPI is masked "Hillf Danton" <hillf.zj@alibaba-inc.com> - 2015-09-16 04:50 +0200

#1223964 — [PATCH] arm: Fix backtrace generation when IPI is masked

FromDaniel Thompson <daniel.thompson@linaro.org>
Date2015-09-14 11:20 +0200
Subject[PATCH] arm: Fix backtrace generation when IPI is masked
Message-ID<q8y5B-1Tq-23@gated-at.bofh.it>
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. Some small
changes to the generic code are required to support this.

Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
---
 arch/arm/kernel/smp.c | 7 +++++++
 lib/nmi_backtrace.c   | 5 ++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 48185a773852..4d8a80328c74 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -748,6 +748,13 @@ 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.
+	 */
+	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..be0466a80d0b 100644
--- a/lib/nmi_backtrace.c
+++ b/lib/nmi_backtrace.c
@@ -149,7 +149,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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1225003 — [PATCH v2] arm: Fix backtrace generation when IPI is masked

FromDaniel Thompson <daniel.thompson@linaro.org>
Date2015-09-15 13:10 +0200
Subject[PATCH v2] arm: Fix backtrace generation when IPI is masked
Message-ID<q8WhA-2ZO-23@gated-at.bofh.it>
In reply to#1223964
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>
---

Notes:
    Changes in v2:
    
    * Improved commit message to better describe the changes to the generic
      code (Hillf Danton).

 arch/arm/kernel/smp.c | 7 +++++++
 lib/nmi_backtrace.c   | 5 ++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 48185a773852..4d8a80328c74 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -748,6 +748,13 @@ 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.
+	 */
+	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..be0466a80d0b 100644
--- a/lib/nmi_backtrace.c
+++ b/lib/nmi_backtrace.c
@@ -149,7 +149,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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225015 — Re: [PATCH v2] arm: Fix backtrace generation when IPI is masked

FromRussell King - ARM Linux <linux@arm.linux.org.uk>
Date2015-09-15 13:40 +0200
SubjectRe: [PATCH v2] arm: Fix backtrace generation when IPI is masked
Message-ID<q8WKC-3xw-13@gated-at.bofh.it>
In reply to#1225003
On Tue, Sep 15, 2015 at 12:05:12PM +0100, Daniel Thompson wrote:
> 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 patch needs a little more work - what happens to the IPI_CPU_BACKTRACE
we've sent to ourselves?  (It fires after the interrupt handler for the
UART/kbd has finished.)  It ought to be masked out if we're going to
handle it a different way.

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225088 — Re: [PATCH v2] arm: Fix backtrace generation when IPI is masked

FromDaniel Thompson <daniel.thompson@linaro.org>
Date2015-09-15 15:20 +0200
SubjectRe: [PATCH v2] arm: Fix backtrace generation when IPI is masked
Message-ID<q8Yjo-5Tb-23@gated-at.bofh.it>
In reply to#1225015
On 15/09/15 12:30, Russell King - ARM Linux wrote:
> On Tue, Sep 15, 2015 at 12:05:12PM +0100, Daniel Thompson wrote:
>> 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 patch needs a little more work - what happens to the IPI_CPU_BACKTRACE
> we've sent to ourselves?  (It fires after the interrupt handler for the
> UART/kbd has finished.)  It ought to be masked out if we're going to
> handle it a different way.

Actually it already gets masked out. The argument to raise_nmi() points 
to a data structure owned by the backtrace library functions and this 
structure if altered during the execution of nmi_cpu_backtrace() to 
clear the calling CPU.

I had originally planned to use cpumask_test_and_clear_cpu() for the 
conditional branch but that would be broken because nmi_cpu_backtrace() 
would become a nop if we clear anything from the mask before calling it!

I guess I should add a comment about this to save us from broken but 
"obviously correct" cleanups in the future...


Daniel.



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225116 — Re: [PATCH v2] arm: Fix backtrace generation when IPI is masked

FromRussell King - ARM Linux <linux@arm.linux.org.uk>
Date2015-09-15 15:50 +0200
SubjectRe: [PATCH v2] arm: Fix backtrace generation when IPI is masked
Message-ID<q8YMq-6qZ-9@gated-at.bofh.it>
In reply to#1225088
On Tue, Sep 15, 2015 at 02:15:10PM +0100, Daniel Thompson wrote:
> Actually it already gets masked out. The argument to raise_nmi() points to a
> data structure owned by the backtrace library functions and this structure
> if altered during the execution of nmi_cpu_backtrace() to clear the calling
> CPU.
> 
> I had originally planned to use cpumask_test_and_clear_cpu() for the
> conditional branch but that would be broken because nmi_cpu_backtrace()
> would become a nop if we clear anything from the mask before calling it!
> 
> I guess I should add a comment about this to save us from broken but
> "obviously correct" cleanups in the future...

Absolutely.

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225245 — [PATCH v3] arm: Fix backtrace generation when IPI is masked

FromDaniel Thompson <daniel.thompson@linaro.org>
Date2015-09-15 16:50 +0200
Subject[PATCH v3] arm: Fix backtrace generation when IPI is masked
Message-ID<q8ZIv-7Nu-23@gated-at.bofh.it>
In reply to#1223964
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>
---

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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1225685 — Re: [PATCH v3] arm: Fix backtrace generation when IPI is masked

From"Hillf Danton" <hillf.zj@alibaba-inc.com>
Date2015-09-16 04:50 +0200
SubjectRe: [PATCH v3] arm: Fix backtrace generation when IPI is masked
Message-ID<q9aXg-86m-9@gated-at.bofh.it>
In reply to#1225245
> 
> 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web