----- Original Message ----- > > Current code is setting {hard,soft}irq_ctx[] to (irq_ctx **), because > per_cpu symbol itself is pointer of specified type (irq_ctx *). > > But, I wonder how this works in past, the code is expecting > {hard,soft}_ctx[] are (irq_ctx *). This fixes by deref per_cpu in > initialization, and set expected pointers. > > Tested on i386 v3.10. > You are correct -- apparently it never did work. The reason why I never noticed with RHEL kernels is that up until linux-2.6.29, the IRQ stacks were declared as a static NR_CPUS-bounded array: #ifdef CONFIG_4KSTACKS /* * per-CPU IRQ handling contexts (thread information and stack) */ union irq_ctx { struct thread_info tinfo; u32 stack[THREAD_SIZE/sizeof(u32)]; }; static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly; static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly; static char softirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss; static char hardirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss; Then in linux-2.6.30, they were changed to be per-cpu variables: #ifdef CONFIG_4KSTACKS /* * per-CPU IRQ handling contexts (thread information and stack) */ union irq_ctx { struct thread_info tinfo; u32 stack[THREAD_SIZE/sizeof(u32)]; } __attribute__((aligned(PAGE_SIZE))); static DEFINE_PER_CPU(union irq_ctx *, hardirq_ctx); static DEFINE_PER_CPU(union irq_ctx *, softirq_ctx); static DEFINE_PER_CPU_PAGE_ALIGNED(union irq_ctx, hardirq_stack); static DEFINE_PER_CPU_PAGE_ALIGNED(union irq_ctx, softirq_stack); We never ran into the bug in 32-bit x86 RHEL6 (2.6.32-based) kernels because we did not configure CONFIG_4KSTACKS. Later on, the CONFIG_4KSTACKS restriction looks like it was removed, but we stopped supporting 32-bit x86 in RHEL7. And nobody ever reported it from any other x86 kernel sources. I also note that in linux-3.15 the data structure name and variables were changed to: struct irq_stack { u32 stack[THREAD_SIZE/sizeof(u32)]; } __aligned(THREAD_SIZE); DECLARE_PER_CPU(struct irq_stack *, hardirq_stack); DECLARE_PER_CPU(struct irq_stack *, softirq_stack); So your patch would need more work for 3.15 and later kernels. Thanks, Dave > --- > task.c | 28 ++++++++++++++++++++++++---- > 1 file changed, 24 insertions(+), 4 deletions(-) > > diff -puN task.c~ia32-irq-stack-fix task.c > --- crash-64/task.c~ia32-irq-stack-fix 2017-02-08 17:37:33.126367767 +0900 > +++ crash-64-hirofumi/task.c 2017-02-08 17:46:06.900703326 +0900 > @@ -570,10 +570,20 @@ irqstacks_init(void) > if ((hard_sp = per_cpu_symbol_search("per_cpu__hardirq_ctx"))) { > if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF)) { > for (i = 0; i < NR_CPUS; i++) { > + ulong ptr; > + > if (!kt->__per_cpu_offset[i]) > continue; > - tt->hardirq_ctx[i] = hard_sp->value + > - kt->__per_cpu_offset[i]; > + ptr = hard_sp->value + kt->__per_cpu_offset[i]; > + > + if (!readmem(ptr, KVADDR, &ptr, > + sizeof(void *), "hardirq ctx", > + RETURN_ON_ERROR)) { > + error(INFO, "cannot read hardirq_ctx[%d] at %lx\n", > + i, ptr); > + continue; > + } > + tt->hardirq_ctx[i] = ptr; > } > } else > tt->hardirq_ctx[0] = hard_sp->value; > @@ -604,10 +614,20 @@ irqstacks_init(void) > if ((soft_sp = per_cpu_symbol_search("per_cpu__softirq_ctx"))) { > if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF)) { > for (i = 0; i < NR_CPUS; i++) { > + ulong ptr; > + > if (!kt->__per_cpu_offset[i]) > continue; > - tt->softirq_ctx[i] = soft_sp->value + > - kt->__per_cpu_offset[i]; > + ptr = soft_sp->value + kt->__per_cpu_offset[i]; > + > + if (!readmem(ptr, KVADDR, &ptr, > + sizeof(void *), "softirq ctx", > + RETURN_ON_ERROR)) { > + error(INFO, "cannot read softirq_ctx[%d] at %lx\n", > + i, ptr); > + continue; > + } > + tt->softirq_ctx[i] = ptr; > } > } else > tt->softirq_ctx[0] = soft_sp->value; > > -- > OGAWA Hirofumi <hirofumi mail parknet co jp> -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility