Hi Marc, On 01/09/2020 15:43, Marc Zyngier wrote: > Let's switch the arm code to the core accounting, which already > does everything we need. > > Reviewed-by: Valentin Schneider <valentin.schnei...@arm.com> > Signed-off-by: Marc Zyngier <m...@kernel.org> > --- > arch/arm/include/asm/hardirq.h | 17 ----------------- > arch/arm/kernel/smp.c | 20 ++++---------------- > 2 files changed, 4 insertions(+), 33 deletions(-)
This appears to be causing a NULL pointer dereference on beaglebone-black, it got bisected automatically several times. None of the other platforms in the KernelCI labs appears to be affected. Here's the error in the full job log, with next-20200923: https://storage.staging.kernelci.org/kernelci/staging.kernelci.org/staging-20200924.0/arm/multi_v7_defconfig/gcc-8/lab-baylibre/baseline-beaglebone-black.html#L460 and some meta-data: https://staging.kernelci.org/test/case/id/5f6bea67f724eb1b34dce584/ The full bisection report is available here: https://groups.io/g/kernelci-results-staging/message/2094 I've also run it again with a debug build to locate the problem, see below. > diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h > index 7a88f160b1fb..b95848ed2bc7 100644 > --- a/arch/arm/include/asm/hardirq.h > +++ b/arch/arm/include/asm/hardirq.h > @@ -6,29 +6,12 @@ > #include <linux/threads.h> > #include <asm/irq.h> > > -/* number of IPIS _not_ including IPI_CPU_BACKTRACE */ > -#define NR_IPI 7 > - > typedef struct { > unsigned int __softirq_pending; > -#ifdef CONFIG_SMP > - unsigned int ipi_irqs[NR_IPI]; > -#endif > } ____cacheline_aligned irq_cpustat_t; > > #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t > above */ > > -#define __inc_irq_stat(cpu, member) __IRQ_STAT(cpu, member)++ > -#define __get_irq_stat(cpu, member) __IRQ_STAT(cpu, member) > - > -#ifdef CONFIG_SMP > -u64 smp_irq_stat_cpu(unsigned int cpu); > -#else > -#define smp_irq_stat_cpu(cpu) 0 > -#endif > - > -#define arch_irq_stat_cpu smp_irq_stat_cpu > - > #define __ARCH_IRQ_EXIT_IRQS_DISABLED 1 > > #endif /* __ASM_HARDIRQ_H */ > diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c > index d51e64955a26..aead847ac8b9 100644 > --- a/arch/arm/kernel/smp.c > +++ b/arch/arm/kernel/smp.c > @@ -65,6 +65,7 @@ enum ipi_msg_type { > IPI_CPU_STOP, > IPI_IRQ_WORK, > IPI_COMPLETION, > + NR_IPI, > /* > * CPU_BACKTRACE is special and not included in NR_IPI > * or tracable with trace_ipi_* > @@ -529,27 +530,16 @@ void show_ipi_list(struct seq_file *p, int prec) > unsigned int cpu, i; > > for (i = 0; i < NR_IPI; i++) { > + unsigned int irq = irq_desc_get_irq(ipi_desc[i]); It looks like irq_desc_get_irq() gets called with a NULL pointer (well, 0x0000001c): (gdb) l *0xc030ef38 0xc030ef38 is in show_ipi_list (../include/linux/irqdesc.h:123). 118 return container_of(data->common, struct irq_desc, irq_common_data); 119 } 120 121 static inline unsigned int irq_desc_get_irq(struct irq_desc *desc) 122 { 123 return desc->irq_data.irq; 124 } 125 126 static inline struct irq_data *irq_desc_get_irq_data(struct irq_desc *desc) 127 { Full job log: https://lava.baylibre.com/scheduler/job/142375#L727 I haven't looked any further but hopefully this should be a good enough clue to find the root cause. I don't know if you have a platform at hand to reproduce the issue, please let me know if you need some help with debugging or testing a fix. Hope this helps, Guillaume > seq_printf(p, "%*s%u: ", prec - 1, "IPI", i); > > for_each_online_cpu(cpu) > - seq_printf(p, "%10u ", > - __get_irq_stat(cpu, ipi_irqs[i])); > + seq_printf(p, "%10u ", kstat_irqs_cpu(irq, cpu)); > > seq_printf(p, " %s\n", ipi_types[i]); > } > } > > -u64 smp_irq_stat_cpu(unsigned int cpu) > -{ > - u64 sum = 0; > - int i; > - > - for (i = 0; i < NR_IPI; i++) > - sum += __get_irq_stat(cpu, ipi_irqs[i]); > - > - return sum; > -} > - > void arch_send_call_function_ipi_mask(const struct cpumask *mask) > { > smp_cross_call(mask, IPI_CALL_FUNC); > @@ -630,10 +620,8 @@ static void do_handle_IPI(int ipinr) > { > unsigned int cpu = smp_processor_id(); > > - if ((unsigned)ipinr < NR_IPI) { > + if ((unsigned)ipinr < NR_IPI) > trace_ipi_entry_rcuidle(ipi_types[ipinr]); > - __inc_irq_stat(cpu, ipi_irqs[ipinr]); > - } > > switch (ipinr) { > case IPI_WAKEUP: >