On Mon, 2006-02-13 at 16:59 -0500, Dave Anderson wrote: > Badari Pulavarty wrote: > > > Hi, > > > > After 2.6.15, ppc64 per_cpu_offsets are moved to "paca" > > structure. Here is the patch to make crash read per-cpu-offsets > > from paca structure. > > > > Without this patch, you get following error while running > > crash. Please apply. > > > > crash: cannot determine idle task addresses from init_tasks[] or > > runqueues[] > > > > crash: cannot resolve "init_task_union" > > > > Thanks, > > Badari > > > > Hi Badari, > > This looks just fine to me. Can you verify that "make Warn" compiles it > cleanly? It looks like it should, but I don't have a ppc64 readily available. > > Also, a minor nit -- for debug purposes only -- can you add this new > "ppc64_paca" size display to the dump_offset_table() routine -- just > under the "x8664_pda" size display? > Okay. Here is the new version. I haven't introduced any warnings in this round, but I did in my previous round. I cleaned those now. I also added paca size display to dump_offset_table(). BTW: crash is broken for CONFIG_SPARSEMEM (which seems to be default for ppc64). I had to hack it every time to make crash work on ppc64. Do you want to include temporary hack to make crash work till it gets fixed for real. (with the hack most commands work, but some memory related commands show wrong data). Thanks, Badari
After 2.6.15 ppc64 per_cpu_offset are stored in paca. So, we need to read these from paca now. Signed-off-by: Badari Pulavarty <pbadari@xxxxxxxxxx> --- crash-4.0-2.20/defs.h 2006-02-03 07:13:04.000000000 -0800 +++ crash-4.0-2.20.new/defs.h 2006-02-13 15:30:59.000000000 -0800 @@ -1318,6 +1318,7 @@ struct size_table { /* stash of long radix_tree_root; long radix_tree_node; long x8664_pda; + long ppc64_paca; long gate_struct; long tss_struct; long task_struct_start_time; @@ -1410,6 +1411,7 @@ struct builtin_debug_table { #define ULONGLONG(ADDR) *((ulonglong *)((char *)(ADDR))) #define ULONG_PTR(ADDR) *((ulong **)((char *)(ADDR))) #define USHORT(ADDR) *((ushort *)((char *)(ADDR))) +#define SHORT(ADDR) *((short *)((char *)(ADDR))) #define VOID_PTR(ADDR) *((void **)((char *)(ADDR))) struct node_table { --- crash-4.0-2.20/ppc64.c 2006-02-03 07:13:04.000000000 -0800 +++ crash-4.0-2.20.new/ppc64.c 2006-02-13 15:31:21.000000000 -0800 @@ -48,6 +48,7 @@ static char * ppc64_check_eframe(struct static void ppc64_print_eframe(char *, struct ppc64_pt_regs *, struct bt_info *); static void parse_cmdline_arg(void); +static void ppc64_paca_init(void); struct machine_specific ppc64_machine_specific = { { 0 }, 0, 0 }; @@ -161,6 +162,8 @@ ppc64_init(int when) m->l3_shift = m->l2_shift + m->l2_index_size; m->l4_shift = m->l3_shift + m->l3_index_size; } + + ppc64_paca_init(); machdep->vmalloc_start = ppc64_vmalloc_start; MEMBER_OFFSET_INIT(thread_struct_pg_tables, "thread_struct", "pg_tables"); @@ -332,10 +335,10 @@ ppc64_dump_machdep_table(ulong arg) fprintf(fp, " ptbl: %lx\n", (ulong)machdep->ptbl); fprintf(fp, " ptrs_per_pgd: %d\n", machdep->ptrs_per_pgd); fprintf(fp, " machspec: %lx\n", (ulong)machdep->machspec); - fprintf(fp, " pgd_index_size: %ld\n", machdep->machspec->l4_index_size); - fprintf(fp, " pud_index_size: %ld\n", machdep->machspec->l3_index_size); - fprintf(fp, " pmd_index_size: %ld\n", machdep->machspec->l2_index_size); - fprintf(fp, " pte_index_size: %ld\n", machdep->machspec->l1_index_size); + fprintf(fp, " pgd_index_size: %d\n", machdep->machspec->l4_index_size); + fprintf(fp, " pud_index_size: %d\n", machdep->machspec->l3_index_size); + fprintf(fp, " pmd_index_size: %d\n", machdep->machspec->l2_index_size); + fprintf(fp, " pte_index_size: %d\n", machdep->machspec->l1_index_size); } /* @@ -2222,4 +2225,47 @@ parse_cmdline_arg(void) fprintf(fp, "\n"); } +static void +ppc64_paca_init(void) +{ + int i, cpus, nr_paca; + char *cpu_paca_buf; + ulong data_offset; + ulong per_cpu_offset; + ulong cpuid_offset; + signed short cpuid; + + if (!symbol_exists("paca")) + return; + + if (!MEMBER_EXISTS("paca_struct", "data_offset")) + return; + + STRUCT_SIZE_INIT(ppc64_paca, "paca_struct"); + cpuid_offset = MEMBER_OFFSET("paca_struct", "hw_cpu_id"); + data_offset = MEMBER_OFFSET("paca_struct", "data_offset"); + + cpu_paca_buf = GETBUF(SIZE(ppc64_paca)); + + if (!(nr_paca = get_array_length("paca", NULL, 0))) + nr_paca = NR_CPUS; + + for (i = cpus = 0; i < nr_paca; i++) { + readmem(symbol_value("paca") + (i * SIZE(ppc64_paca)), + KVADDR, cpu_paca_buf, SIZE(ppc64_paca), + "paca entry", FAULT_ON_ERROR); + + cpuid = SHORT(cpu_paca_buf + cpuid_offset); + if (cpuid == -1) + continue; + + per_cpu_offset = ULONG(cpu_paca_buf + data_offset); + kt->__per_cpu_offset[i] = per_cpu_offset; + kt->flags |= PER_CPU_OFF; + cpus++; + } + kt->cpus = cpus; + if (kt->cpus > 1) + kt->flags |= SMP; +} #endif /* PPC64 */ --- crash-4.0-2.20/symbols.c 2006-02-03 07:13:04.000000000 -0800 +++ crash-4.0-2.20.new/symbols.c 2006-02-13 15:32:38.000000000 -0800 @@ -6626,6 +6626,8 @@ dump_offset_table(char *spec, ulong make fprintf(fp, " x8664_pda: %ld\n", SIZE(x8664_pda)); + fprintf(fp, " ppc64_paca: %ld\n", + SIZE(ppc64_paca)); fprintf(fp, " gate_struct: %ld\n", SIZE(gate_struct)); fprintf(fp, " tss_struct: %ld\n",