----- "Daisuke Nishimura" <nishimura@xxxxxxxxxxxxxxxxx> wrote: > Hi, Dave. > > It's a very and very dirty hack, but some of my colleagues say that > a dump file of 2.6.30-rcX can be analyzed by this patch. > > I hope it would be some help for you. > > Thanks, > Daisuke Nishimura. Actually it's not so dirty at all -- it's pretty well done! I was also tinkering with a few new schemes yesterday, and did make it to the "crash> " prompt as well. But I was allowing the kt->__per_cpu_offset[] array to be initialized in kernel_init() (line 195) as is done for x86, althougyh I think now that I prefer the way that you guys have done it. I also was trying to come up with a clean way to deal with the x86_64 "per_cpu__xxx" symbols being contained in the in the crash kernel symbol list. With my test crash -- and I presume the same with your patch -- the symbol list look like this: crash> sym -l 0 (D) __per_cpu_start 0 (D) per_cpu__irq_stack_union 4000 (D) per_cpu__gdt_page 5000 (d) per_cpu__exception_stacks b000 (D) per_cpu__current_task b008 (d) per_cpu__is_idle b010 (D) per_cpu__old_rsp b018 (D) per_cpu__irq_regs b020 (D) per_cpu__vector_irq b420 (d) per_cpu__cpu_devices b478 (D) per_cpu__cyc2ns b480 (d) per_cpu__cpuid4_info b488 (d) per_cpu__cache_kobject b490 (d) per_cpu__index_kobject b4a0 (D) per_cpu__irq_stack_ptr b4a8 (D) per_cpu__kernel_stack b4b0 (D) per_cpu__irq_count b4c0 (D) per_cpu__orig_ist ... [ snip ] ... 10540 (D) per_cpu__irq_stat 10580 (D) per_cpu__cpu_info 10680 (D) per_cpu__cpu_tlbstate 106c0 (d) per_cpu__runqueues 10fc0 (d) per_cpu__sched_clock_data 10fe0 (D) __per_cpu_end ffffffff80200000 (T) _text ffffffff80200000 (T) startup_64 ffffffff802000b7 (t) ident_complete ... The problem with having symbols below "_text" in this case is that commands like "rd -s" or other memory dumps that do symbolic translations of numeric values run into the per_cpu symbols. So for example, a page of zeroes would look like this: crash> rd empty_zero_page 10 ffffffff80833000: 0000000000000000 0000000000000000 ................ ffffffff80833010: 0000000000000000 0000000000000000 ................ ffffffff80833020: 0000000000000000 0000000000000000 ................ ffffffff80833030: 0000000000000000 0000000000000000 ................ ffffffff80833040: 0000000000000000 0000000000000000 ................ crash> rd -s empty_zero_page 10 ffffffff80833000: per_cpu__irq_stack_union per_cpu__irq_stack_union ffffffff80833010: per_cpu__irq_stack_union per_cpu__irq_stack_union ffffffff80833020: per_cpu__irq_stack_union per_cpu__irq_stack_union ffffffff80833030: per_cpu__irq_stack_union per_cpu__irq_stack_union ffffffff80833040: per_cpu__irq_stack_union per_cpu__irq_stack_union crash> In fact, *any* value would translate to a symbol: crash> rd ffff88007e4ee820 10 ffff88007e4ee820: 0000000000400000 0000000000409000 ..@.......@..... ffff88007e4ee830: ffff88007e4eead8 0000000000000025 ..N~....%....... ffff88007e4ee840: 0000000008001875 ffff88007e4eeb09 u.........N~.... ffff88007e4ee850: 0000000000000000 0000000000000000 ................ ffff88007e4ee860: ffff88007e4ee860 ffff88007e4ee860 `.N~....`.N~.... crash> rd -s ffff88007e4ee820 10 ffff88007e4ee820: __per_cpu_end+4124704 __per_cpu_end+4161568 ffff88007e4ee830: __per_cpu_end+-131939276301576 per_cpu__irq_stack_union+37 ffff88007e4ee840: __per_cpu_end+134154389 __per_cpu_end+-131939276301527 ffff88007e4ee850: per_cpu__irq_stack_union per_cpu__irq_stack_union ffff88007e4ee860: __per_cpu_end+-131939276302208 __per_cpu_end+-131939276302208 crash> So clearly there will have to be special handling for those symbols, because sometimes a caller will *want* to receive information re: those symbols, and other times will not. (i.e. in symbol_exists(), value_search(), etc.) It was never a problem in the past because the per_cpu__xxx symbols were not "real" symbol values, but they were very large numberic values in the kernel symbol list. So in any case, we're on the same page, and I do like what you've done. Thank you very much for having already looked into this! Dave > > Signed-off-by: Daisuke Nishimura <nishimura@xxxxxxxxxxxxxxxxx> > --- > defs.h | 1 + > x86_64.c | 78 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- > 2 files changed, 74 insertions(+), 5 deletions(-) > > diff --git a/defs.h b/defs.h > index e5e3538..32b2e1e 100755 > --- a/defs.h > +++ b/defs.h > @@ -3851,6 +3851,7 @@ struct machine_specific { > #define PHYS_BASE (0x80) > #define VM_XEN_RHEL4 (0x100) > #define VMEMMAP (0x200) > +#define KSYMS_PERCPU (0x400) > > #define VM_FLAGS (VM_ORIG|VM_2_6_11|VM_XEN|VM_XEN_RHEL4) > > diff --git a/x86_64.c b/x86_64.c > index 993827e..4813f96 100755 > --- a/x86_64.c > +++ b/x86_64.c > @@ -71,6 +71,7 @@ static int x86_64_is_uvaddr(ulong, struct > task_context *); > void x86_64_compiler_warning_stub(void); > static void x86_64_init_kernel_pgd(void); > static void x86_64_cpu_pda_init(void); > +static void x86_64_per_cpu_init(void); > static void x86_64_ist_init(void); > static void x86_64_post_init(void); > static void parse_cmdline_arg(void); > @@ -290,7 +291,10 @@ x86_64_init(int when) > MEMBER_OFFSET_INIT(user_regs_struct_ss, > "user_regs_struct", "ss"); > STRUCT_SIZE_INIT(user_regs_struct, "user_regs_struct"); > - x86_64_cpu_pda_init(); > + if (STRUCT_EXISTS("x8664_pda")) > + x86_64_cpu_pda_init(); > + else > + x86_64_per_cpu_init(); > x86_64_ist_init(); > if ((machdep->machspec->irqstack = (char *) > malloc(machdep->machspec->stkinfo.isize)) == NULL) > @@ -677,6 +681,51 @@ x86_64_cpu_pda_init(void) > FREEBUF(cpu_pda_buf); > } > > +static void > +x86_64_per_cpu_init(void) > +{ > + int i, cpus, cpunumber; > + ulong istacksize; > + > + if (!(kt->flags & PER_CPU_OFF)) > + return; > + > + if (!symbol_exists("per_cpu__cpu_number") || !symbol_exists("per_cpu__irq_stack_ptr")) > + return; > + > + for (i = cpus = 0; i < NR_CPUS; i++) { > + readmem(symbol_value("per_cpu__cpu_number") + kt->__per_cpu_offset[i], > + KVADDR, &cpunumber, sizeof(int), > + "cpu number (per_cpu)", FAULT_ON_ERROR); > + if (cpunumber != cpus) > + break; > + cpus++; > + > + readmem(symbol_value("per_cpu__irq_stack_ptr") + kt->__per_cpu_offset[i], > + KVADDR, &machdep->machspec->stkinfo.ibase[i], > + sizeof(ulong), "irq stack ptr (per cpu)", FAULT_ON_ERROR); > + } > + > + istacksize = 16384; /* 16K */ > + machdep->machspec->stkinfo.isize = istacksize; > + > + /* > + * Adjust the kernel top-of-stack values down to their base. > + */ > + for (i = 0; i < NR_CPUS; i++) { > + if (machdep->machspec->stkinfo.ibase[i]) > + machdep->machspec->stkinfo.ibase[i] -= (istacksize-64); > + else > + break; > + } > + > + kt->cpus = cpus; > + if (kt->cpus > 1) > + kt->flags |= SMP; > + > + verify_spinlock(); > +} > + > /* > * Gather the ist addresses for each CPU. > */ > @@ -754,7 +803,7 @@ x86_64_ist_init(void) > */ > sp = value_search(ms->stkinfo.ebase[0][0], &offset); > if (!sp || offset || !STREQ(sp->name, > "boot_exception_stacks")) { > - if (symbol_value("boot_exception_stacks")) { > + if (symbol_exists("boot_exception_stacks")) { > error(WARNING, > "cpu 0 first exception stack: %lx\n > boot_exception_stacks: %lx\n\n", > ms->stkinfo.ebase[0][0], > @@ -1706,8 +1755,12 @@ x86_64_verify_symbol(const char *name, ulong > value, char type) > { > if (STREQ(name, "_text") || STREQ(name, "_stext")) > machdep->flags |= KSYMS_START; > + if (STREQ(name, "__per_cpu_start")) > + machdep->flags |= KSYMS_PERCPU; > + if (STREQ(name, "__per_cpu_end")) > + machdep->flags &= ~KSYMS_PERCPU; > > - if (!name || !strlen(name) || !(machdep->flags & KSYMS_START)) > + if (!name || !strlen(name) || !(machdep->flags & (KSYMS_START | KSYMS_PERCPU))) > return FALSE; > return TRUE; > } > @@ -3943,8 +3996,23 @@ x86_64_get_smp_cpus(void) > char *cpu_pda_buf; > ulong level4_pgt, cpu_pda_addr; > > - if (!VALID_STRUCT(x8664_pda)) > - return 1; > + if (!VALID_STRUCT(x8664_pda)) { > + if (!(kt->flags & PER_CPU_OFF)) > + return 1; > + > + if (!symbol_exists("per_cpu__cpu_number")) > + return 1; > + > + for (i = cpus = 0; i < NR_CPUS; i++) { > + readmem(symbol_value("per_cpu__cpu_number") + kt->__per_cpu_offset[i], > + KVADDR, &cpunumber, sizeof(int), > + "cpu number (per_cpu)",FAULT_ON_ERROR); > + if (cpunumber != cpus) > + break; > + cpus++; > + } > + return cpus; > + } > > cpu_pda_buf = GETBUF(SIZE(x8664_pda)); > -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility