> -----Original Message-----
> Subject: [PATCH v11 4/6] arm64: smp: Add arch support for backtrace using
> pseudo-NMI
> 
> Enable arch_trigger_cpumask_backtrace() support on arm64. This enables
> things much like they are enabled on arm32 (including some of the
> funky logic around NR_IPI, nr_ipi, and MAX_IPI) but with the
> difference that, unlike arm32, we'll try to enable the backtrace to
> use pseudo-NMI.
> 
> NOTE: this patch is a squash of the little bit of code adding the
> ability to mark an IPI to try to use pseudo-NMI plus the little bit of
> code to hook things up for kgdb. This approach was decided upon in the
> discussion of v9 [1].
> 
> This patch depends on commit 36759e343ff9 ("nmi_backtrace: allow

Hi,
Is this commit ID valid? I believe this commit is not included in the
mainline yet. Other than this,
 Reviewed-by: Misono Tomohiro <misono.tomoh...@fujitsu.com>

Regards,
Tomohiro

> excluding an arbitrary CPU") since that commit changed the prototype
> of arch_trigger_cpumask_backtrace(), which this patch implements.
> 
> [1] https://lore.kernel.org/r/ZORY51mF4alI41G1@FVFF77S0Q05N
> 
> Co-developed-by: Sumit Garg <sumit.g...@linaro.org>
> Signed-off-by: Sumit Garg <sumit.g...@linaro.org>
> Co-developed-by: Mark Rutland <mark.rutl...@arm.com>
> Signed-off-by: Mark Rutland <mark.rutl...@arm.com>
> Signed-off-by: Douglas Anderson <diand...@chromium.org>
> ---
> 
> Changes in v11:
> - Adjust comment about NR_IPI/MAX_IPI.
> - Don't use confusing "backed by" idiom in comment.
> - Made arm64_backtrace_ipi() static.
> 
> Changes in v10:
> - Backtrace now directly supported in smp.c
> - Squash backtrace into patch adding support for pseudo-NMI IPIs.
> 
> Changes in v9:
> - Added comments that we might not be using NMI always.
> - Fold in v8 patch #10 ("Fallback to a regular IPI if NMI isn't enabled")
> - Moved header file out of "include" since it didn't need to be there.
> - Remove arm64_supports_nmi()
> - Renamed "NMI IPI" to "debug IPI" since it might not be backed by NMI.
> - arch_trigger_cpumask_backtrace() no longer returns bool
> 
> Changes in v8:
> - Removed "#ifdef CONFIG_SMP" since arm64 is always SMP
> - debug_ipi_setup() and debug_ipi_teardown() no longer take cpu param
> 
>  arch/arm64/include/asm/irq.h |  3 ++
>  arch/arm64/kernel/smp.c      | 86
> +++++++++++++++++++++++++++++++-----
>  2 files changed, 78 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h
> index fac08e18bcd5..50ce8b697ff3 100644
> --- a/arch/arm64/include/asm/irq.h
> +++ b/arch/arm64/include/asm/irq.h
> @@ -6,6 +6,9 @@
> 
>  #include <asm-generic/irq.h>
> 
> +void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int
> exclude_cpu);
> +#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
> +
>  struct pt_regs;
> 
>  int set_handle_irq(void (*handle_irq)(struct pt_regs *));
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index a5848f1ef817..c8896cbc5327 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -33,6 +33,7 @@
>  #include <linux/kernel_stat.h>
>  #include <linux/kexec.h>
>  #include <linux/kvm_host.h>
> +#include <linux/nmi.h>
> 
>  #include <asm/alternative.h>
>  #include <asm/atomic.h>
> @@ -72,12 +73,18 @@ enum ipi_msg_type {
>       IPI_CPU_CRASH_STOP,
>       IPI_TIMER,
>       IPI_IRQ_WORK,
> -     NR_IPI
> +     NR_IPI,
> +     /*
> +      * Any enum >= NR_IPI and < MAX_IPI is special and not tracable
> +      * with trace_ipi_*
> +      */
> +     IPI_CPU_BACKTRACE = NR_IPI,
> +     MAX_IPI
>  };
> 
>  static int ipi_irq_base __read_mostly;
>  static int nr_ipi __read_mostly = NR_IPI;
> -static struct irq_desc *ipi_desc[NR_IPI] __read_mostly;
> +static struct irq_desc *ipi_desc[MAX_IPI] __read_mostly;
> 
>  static void ipi_setup(int cpu);
> 
> @@ -845,6 +852,22 @@ static void __noreturn ipi_cpu_crash_stop(unsigned int
> cpu, struct pt_regs *regs
>  #endif
>  }
> 
> +static void arm64_backtrace_ipi(cpumask_t *mask)
> +{
> +     __ipi_send_mask(ipi_desc[IPI_CPU_BACKTRACE], mask);
> +}
> +
> +void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int
> exclude_cpu)
> +{
> +     /*
> +      * NOTE: though nmi_trigger_cpumask_backtrace has "nmi_" in the
> name,
> +      * nothing about it truly needs to be implemented using an NMI, it's
> +      * just that it's _allowed_ to work with NMIs. If ipi_should_be_nmi()
> +      * returned false our backtrace attempt will just use a regular IPI.
> +      */
> +     nmi_trigger_cpumask_backtrace(mask, exclude_cpu,
> arm64_backtrace_ipi);
> +}
> +
>  /*
>   * Main handler for inter-processor interrupts
>   */
> @@ -888,6 +911,14 @@ static void do_handle_IPI(int ipinr)
>               break;
>  #endif
> 
> +     case IPI_CPU_BACKTRACE:
> +             /*
> +              * NOTE: in some cases this _won't_ be NMI context. See the
> +              * comment in arch_trigger_cpumask_backtrace().
> +              */
> +             nmi_cpu_backtrace(get_irq_regs());
> +             break;
> +
>       default:
>               pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
>               break;
> @@ -909,6 +940,19 @@ static void smp_cross_call(const struct cpumask *target,
> unsigned int ipinr)
>       __ipi_send_mask(ipi_desc[ipinr], target);
>  }
> 
> +static bool ipi_should_be_nmi(enum ipi_msg_type ipi)
> +{
> +     if (!system_uses_irq_prio_masking())
> +             return false;
> +
> +     switch (ipi) {
> +     case IPI_CPU_BACKTRACE:
> +             return true;
> +     default:
> +             return false;
> +     }
> +}
> +
>  static void ipi_setup(int cpu)
>  {
>       int i;
> @@ -916,8 +960,14 @@ static void ipi_setup(int cpu)
>       if (WARN_ON_ONCE(!ipi_irq_base))
>               return;
> 
> -     for (i = 0; i < nr_ipi; i++)
> -             enable_percpu_irq(ipi_irq_base + i, 0);
> +     for (i = 0; i < nr_ipi; i++) {
> +             if (ipi_should_be_nmi(i)) {
> +                     prepare_percpu_nmi(ipi_irq_base + i);
> +                     enable_percpu_nmi(ipi_irq_base + i, 0);
> +             } else {
> +                     enable_percpu_irq(ipi_irq_base + i, 0);
> +             }
> +     }
>  }
> 
>  #ifdef CONFIG_HOTPLUG_CPU
> @@ -928,8 +978,14 @@ static void ipi_teardown(int cpu)
>       if (WARN_ON_ONCE(!ipi_irq_base))
>               return;
> 
> -     for (i = 0; i < nr_ipi; i++)
> -             disable_percpu_irq(ipi_irq_base + i);
> +     for (i = 0; i < nr_ipi; i++) {
> +             if (ipi_should_be_nmi(i)) {
> +                     disable_percpu_nmi(ipi_irq_base + i);
> +                     teardown_percpu_nmi(ipi_irq_base + i);
> +             } else {
> +                     disable_percpu_irq(ipi_irq_base + i);
> +             }
> +     }
>  }
>  #endif
> 
> @@ -937,15 +993,23 @@ void __init set_smp_ipi_range(int ipi_base, int n)
>  {
>       int i;
> 
> -     WARN_ON(n < NR_IPI);
> -     nr_ipi = min(n, NR_IPI);
> +     WARN_ON(n < MAX_IPI);
> +     nr_ipi = min(n, MAX_IPI);
> 
>       for (i = 0; i < nr_ipi; i++) {
>               int err;
> 
> -             err = request_percpu_irq(ipi_base + i, ipi_handler,
> -                                      "IPI", &cpu_number);
> -             WARN_ON(err);
> +             if (ipi_should_be_nmi(i)) {
> +                     err = request_percpu_nmi(ipi_base + i, ipi_handler,
> +                                              "IPI", &cpu_number);
> +                     WARN(err, "Could not request IPI %d as NMI,
> err=%d\n",
> +                          i, err);
> +             } else {
> +                     err = request_percpu_irq(ipi_base + i, ipi_handler,
> +                                              "IPI", &cpu_number);
> +                     WARN(err, "Could not request IPI %d as IRQ,
> err=%d\n",
> +                          i, err);
> +             }
> 
>               ipi_desc[i] = irq_to_desc(ipi_base + i);
>               irq_set_status_flags(ipi_base + i, IRQ_HIDDEN);
> --
> 2.42.0.rc1.204.g551eb34607-goog
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


_______________________________________________
Kgdb-bugreport mailing list
Kgdb-bugreport@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kgdb-bugreport

Reply via email to