[RFC]Patch to accomodate cpu_pda changes in x86_64 kernels
by Rachita Kothiyal
Hi Dave,
Following the changes in the way cpu_pda is accessed
on x86_64 kernels, running crash to analyse kdump based
crash dumps gave the following error:
crash: cannot resolve "cpu_pda"
The following patch fixes this. Kindly review.
Thanks
Rachita
Signed-off-by: Rachita Kothiyal <rachita(a)in.ibm.com>
---
defs.h | 10 ++++
x86_64.c | 139 ++++++++++++++++++++++++++++++++++++++++++++-------------------
2 files changed, 108 insertions(+), 41 deletions(-)
diff -puN x86_64.c~crash-fix-cpu-pda x86_64.c
--- crash-4.0-2.19/x86_64.c~crash-fix-cpu-pda 2006-01-31 17:21:35.430960480 +0530
+++ crash-4.0-2.19-rachita/x86_64.c 2006-01-31 17:23:44.893279216 +0530
@@ -367,7 +367,7 @@ x86_64_cpu_pda_init(void)
{
int i, cpus, nr_pda, cpunumber;
char *cpu_pda_buf;
- ulong level4_pgt, data_offset;
+ ulong level4_pgt, data_offset, *cpu_pda_addr;
struct syment *sp, *nsp;
ulong offset, istacksize;
@@ -383,36 +383,68 @@ x86_64_cpu_pda_init(void)
cpu_pda_buf = GETBUF(SIZE(x8664_pda));
- if (!(nr_pda = get_array_length("cpu_pda", NULL, 0)))
- nr_pda = NR_CPUS;
-
- for (i = cpus = 0; i < nr_pda; i++) {
- if (!CPU_PDA_READ(i, cpu_pda_buf))
- break;
- if (VALID_MEMBER(x8664_pda_level4_pgt)) {
- level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt));
- if (!VALID_LEVEL4_PGT_ADDR(level4_pgt))
+ if (symbol_exists("_cpu_pda")) {
+ if (!(nr_pda = get_array_length("_cpu_pda", NULL, 0)))
+ nr_pda = NR_CPUS;
+ cpu_pda_addr = GETBUF(sizeof(unsigned long));
+ for (i = cpus = 0; i < nr_pda; i++) {
+ *cpu_pda_addr = NULL;
+ if (!_CPU_PDA_READ(i, cpu_pda_buf))
break;
- }
- cpunumber = INT(cpu_pda_buf + OFFSET(x8664_pda_cpunumber));
- if (cpunumber != cpus)
- break;
- cpus++;
- if (VALID_MEMBER(x8664_pda_data_offset)) {
- data_offset = ULONG(cpu_pda_buf +
- OFFSET(x8664_pda_data_offset));
- kt->__per_cpu_offset[i] = data_offset;
- kt->flags |= PER_CPU_OFF;
- } else
- data_offset = 0;
+ if (VALID_MEMBER(x8664_pda_level4_pgt)) {
+ level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt));
+ if (!VALID_LEVEL4_PGT_ADDR(level4_pgt))
+ break;
+ }
+ cpunumber = INT(cpu_pda_buf + OFFSET(x8664_pda_cpunumber));
+ if (cpunumber != cpus)
+ break;
+ cpus++;
- machdep->machspec->stkinfo.ibase[i] = ULONG(cpu_pda_buf +
- OFFSET(x8664_pda_irqstackptr));
+ if (VALID_MEMBER(x8664_pda_data_offset)) {
+ data_offset = ULONG(cpu_pda_buf +
+ OFFSET(x8664_pda_data_offset));
+ kt->__per_cpu_offset[i] = data_offset;
+ kt->flags |= PER_CPU_OFF;
+ } else
+ data_offset = 0;
+ machdep->machspec->stkinfo.ibase[i] = ULONG(cpu_pda_buf +
+ OFFSET(x8664_pda_irqstackptr));
+ if (CRASHDEBUG(2))
+ fprintf(fp, "CPU%d: level4_pgt: %lx data_offset: %lx\n",
+ i, level4_pgt, data_offset);
+ }
+ FREEBUF(cpu_pda_addr);
+ } else if (symbol_exists("cpu_pda")) {
+ if (!(nr_pda = get_array_length("cpu_pda", NULL, 0)))
+ nr_pda = NR_CPUS;
+ for (i = cpus = 0; i < nr_pda; i++) {
+ if (!CPU_PDA_READ(i, cpu_pda_buf))
+ break;
+ if (VALID_MEMBER(x8664_pda_level4_pgt)) {
+ level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt));
+ if (!VALID_LEVEL4_PGT_ADDR(level4_pgt))
+ break;
+ }
+ cpunumber = INT(cpu_pda_buf + OFFSET(x8664_pda_cpunumber));
+ if (cpunumber != cpus)
+ break;
+ cpus++;
- if (CRASHDEBUG(2))
- fprintf(fp, "CPU%d: level4_pgt: %lx data_offset: %lx\n",
- i, level4_pgt, data_offset);
+ if (VALID_MEMBER(x8664_pda_data_offset)) {
+ data_offset = ULONG(cpu_pda_buf +
+ OFFSET(x8664_pda_data_offset));
+ kt->__per_cpu_offset[i] = data_offset;
+ kt->flags |= PER_CPU_OFF;
+ } else
+ data_offset = 0;
+ machdep->machspec->stkinfo.ibase[i] = ULONG(cpu_pda_buf +
+ OFFSET(x8664_pda_irqstackptr));
+ if (CRASHDEBUG(2))
+ fprintf(fp, "CPU%d: level4_pgt: %lx data_offset: %lx\n",
+ i, level4_pgt, data_offset);
+ }
}
@@ -2718,29 +2750,51 @@ x86_64_get_smp_cpus(void)
{
int i, cpus, nr_pda, cpunumber;
char *cpu_pda_buf;
- ulong level4_pgt;
+ ulong level4_pgt, *cpu_pda_addr;
if (!VALID_STRUCT(x8664_pda))
return 1;
cpu_pda_buf = GETBUF(SIZE(x8664_pda));
- if (!(nr_pda = get_array_length("cpu_pda", NULL, 0)))
- nr_pda = NR_CPUS;
+ if (symbol_exists("_cpu_pda")){
+ if (!(nr_pda = get_array_length("_cpu_pda", NULL, 0)))
+ nr_pda = NR_CPUS;
+ cpu_pda_addr = GETBUF(sizeof(unsigned long));
+ for (i = cpus = 0; i < nr_pda; i++) {
+ *cpu_pda_addr = NULL;
+ if (!_CPU_PDA_READ(i, cpu_pda_buf))
+ break;
- for (i = cpus = 0; i < nr_pda; i++) {
- if (!CPU_PDA_READ(i, cpu_pda_buf))
- break;
+ if (VALID_MEMBER(x8664_pda_level4_pgt)) {
+ level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt));
+ if (!VALID_LEVEL4_PGT_ADDR(level4_pgt))
+ break;
+ }
+ cpunumber = INT(cpu_pda_buf + OFFSET(x8664_pda_cpunumber));
+ if (cpunumber != cpus)
+ break;
+ cpus++;
+ }
+ FREEBUF(cpu_pda_addr);
+ }
+ else if (symbol_exists("cpu_pda")){
+ if (!(nr_pda = get_array_length("cpu_pda", NULL, 0)))
+ nr_pda = NR_CPUS;
+ for (i = cpus = 0; i < nr_pda; i++) {
+ if (!CPU_PDA_READ(i, cpu_pda_buf))
+ break;
- if (VALID_MEMBER(x8664_pda_level4_pgt)) {
- level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt));
- if (!VALID_LEVEL4_PGT_ADDR(level4_pgt))
+ if (VALID_MEMBER(x8664_pda_level4_pgt)) {
+ level4_pgt = ULONG(cpu_pda_buf + OFFSET(x8664_pda_level4_pgt));
+ if (!VALID_LEVEL4_PGT_ADDR(level4_pgt))
+ break;
+ }
+ cpunumber = INT(cpu_pda_buf + OFFSET(x8664_pda_cpunumber));
+ if (cpunumber != cpus)
break;
+ cpus++;
}
- cpunumber = INT(cpu_pda_buf + OFFSET(x8664_pda_cpunumber));
- if (cpunumber != cpus)
- break;
- cpus++;
}
FREEBUF(cpu_pda_buf);
@@ -2828,7 +2882,10 @@ x86_64_display_cpu_data(void)
boot_cpu = TRUE;
cpus = 1;
}
- cpu_pda = symbol_value("cpu_pda");
+ if (symbol_exists("_cpu_pda"))
+ cpu_pda = symbol_value("_cpu_pda");
+ else if (symbol_exists("cpu_pda"))
+ cpu_pda = symbol_value("cpu_pda");
for (cpu = 0; cpu < cpus; cpu++) {
if (boot_cpu)
diff -puN defs.h~crash-fix-cpu-pda defs.h
--- crash-4.0-2.19/defs.h~crash-fix-cpu-pda 2006-01-31 17:25:59.479818952 +0530
+++ crash-4.0-2.19-rachita/defs.h 2006-01-31 17:26:23.969096016 +0530
@@ -1840,6 +1840,16 @@ struct load_module {
#define PAGEBASE(X) (((ulong)(X)) & (ulong)machdep->pagemask)
+#define _CPU_PDA_READ(CPU, BUFFER) \
+ ((STRNEQ("_cpu_pda", closest_symbol((symbol_value("_cpu_pda") + \
+ ((CPU) * sizeof(unsigned long)))))) && \
+ (readmem(symbol_value("_cpu_pda") + ((CPU) * sizeof(unsigned long)),\
+ KVADDR, cpu_pda_addr, sizeof(unsigned long), "_cpu_pda addr", \
+ FAULT_ON_ERROR)) && \
+ (readmem(*cpu_pda_addr , \
+ KVADDR, (BUFFER), SIZE(x8664_pda), "cpu_pda entry", \
+ FAULT_ON_ERROR)))
+
#define CPU_PDA_READ(CPU, BUFFER) \
(STRNEQ("cpu_pda", closest_symbol((symbol_value("cpu_pda") + \
((CPU) * SIZE(x8664_pda))))) && \
_
18 years, 10 months
crash version 4.0-2.19 is available
by Dave Anderson
Thanks to Xavier for the bug report, and Jun'ichi for the debug work:
- Fix for the "bt" command on ia64 kernels with 64K page size.
18 years, 10 months
backtrace problem with crash 0.2.18 on 2.6.14 vanilia kernel ia64
by xb
Hello,
I built crash 4.0-2.18 on ia64 platform and run it on a vanilla 2.6.14
running kernel.
It starts OK, and has some commands working.
Unfortunately, it seems that the backtrace command does not do anything
(calls unwind_v3(), but does nothing) on a live system.
I just typed:
bt 1
to get the init task backtrace (sleeping state).
crash is very usefull to have such informations on a live system.
Do you have any idea ?
Thanks in advance.
Xavier
[root@pf37a xb]# bin/crash vmlinux-2.6.14
crash 4.0-2.18
Copyright (C) 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
Copyright (C) 2004, 2005, 2006 IBM Corporation
Copyright (C) 1999-2006 Hewlett-Packard Co
Copyright (C) 2005 Fujitsu Limited
Copyright (C) 2005 NEC Corporation
Copyright (C) 1999, 2002 Silicon Graphics, Inc.
Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
This program is free software, covered by the GNU General Public License,
and you are welcome to change it and/or distribute copies of it under
certain conditions. Enter "help copying" to see the conditions.
This program has absolutely no warranty. Enter "help warranty" for details.
GNU gdb 6.1
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "ia64-unknown-linux-gnu"...
unwind_init_v3
KERNEL: vmlinux-2.6.14
DUMPFILE: /dev/mem
CPUS: 6
DATE: Mon Jan 9 19:14:18 2006
UPTIME: 48 days, 13:04:50
LOAD AVERAGE: 0.26, 0.30, 0.14
TASKS: 125
NODENAME: pf37a
RELEASE: 2.6.14
VERSION: #1 SMP Mon Nov 21 13:27:22 CET 2005
MACHINE: ia64 (1600 Mhz)
MEMORY: 31.9 GB
PID: 7592
COMMAND: "crash"
TASK: e00000012c8a0000 [THREAD_INFO: e00000012c8a0d60]
CPU: 0
STATE: TASK_RUNNING (ACTIVE)
crash> bt
PID: 7592 TASK: e00000012c8a0000 CPU: 0 COMMAND: "crash"
(active)
crash> bt 1
PID: 1 TASK: e0000023ff220000 CPU: 0 COMMAND: "init"
crash>
crash> help -m
flags: 8000352
(NEW_UNWIND|NEW_UNW_V3|UNW_READ|UNW_PTREGS|UNW_R0|D
EVMEMRD)
kvbase: a000000000000000
identity_map_base: e000000000000000
pagesize: 65536
pageshift: 16
pagemask: ffffffffffff0000
pageoffset: ffff
stacksize: 32768
hz: 1024
mhz: 1024
memsize: 34269102080 (0x7fa990000)
bits: 64
nr_irqs: 256
eframe_search: ia64_eframe_search()
back_trace: ia64_back_trace_cmd()
get_processor_speed: ia64_processor_speed()
uvtop: ia64_uvtop()
kvtop: ia64_kvtop()
get_task_pgd: ia64_get_task_pgd()
dump_irq: ia64_dump_irq()
get_stack_frame: ia64_get_stack_frame()
get_stackbase: ia64_get_stackbase()
get_stacktop: ia64_get_stacktop()
translate_pte: ia64_translate_pte()
memory_size: generic_memory_size()
vmalloc_start: ia64_vmalloc_start()
is_task_addr: ia64_is_task_addr()
verify_symbol: ia64_verify_symbol()
dis_filter: ia64_dis_filter()
cmd_mach: ia64_cmd_mach()
get_smp_cpus: ia64_get_smp_cpus()
is_kvaddr: generic_is_kvaddr()
is_uvaddr: generic_is_uvaddr()
verify_paddr: ia64_verify_paddr()
init_kernel_pgd: NULL
value_to_symbol: generic_machdep_value_to_symbol()
line_number_hooks: ia64_line_number_hooks
last_pgd_read: 0
last_pmd_read: 0
last_ptbl_read: 0
pgd: 600000000013a650
pmd: 600000000014a660
ptbl: 600000000015a670
ptrs_per_pgd: 8192
cmdline_arg: (null)
machspec: ia64_machine_specific
cpu_data_address: e000000004b00030
unimpl_va_mask: 0
unimpl_pa_mask: 7ffc000000000000
unw: 60000000000de800
unw_tables_offset: 8
unw_kernel_table_offset: 288
unw_pt_regs_offsets: 224
script_index: 0
script_cache: 600000000a96c9e0 0% (0 of 0)
mem_limit: 0
kernel_region: 5
kernel_start: a000000100000000
phys_start: 4008320 (4000000)
vmalloc_start: a000000200000000
ia64_memmap: 6000000000ab3780
efi_memmap_size: 1728
efi_memdesc_size: 48
unwind_init: unwind_init_v3()
unwind: unwind_v3()
dump_unwind_stats: dump_unwind_stats_v3()
unwind_debug: unwind_debug_v3()
ia64_init_stack_size: 0
crash> ps
PID PPID CPU TASK ST %MEM VSZ RSS COMM
0 0 0 a000000100730000 RU 0.0 0 0 [swapper]
> 0 1 1 e0000001039f0000 RU 0.0 0 0 [swapper]
> 0 1 2 e000000103a20000 RU 0.0 0 0 [swapper]
> 0 1 3 e000000103a40000 RU 0.0 0 0 [swapper]
> 0 1 4 e000000103a60000 RU 0.0 0 0 [swapper]
> 0 1 5 e000000103a80000 RU 0.0 0 0 [swapper]
1 0 1 e0000023ff220000 IN 0.0 5184 3648 init
2 1 0 e0000001039b0000 IN 0.0 0 0 [migration/0]
3 1 0 e0000023ff230000 IN 0.0 0 0 [ksoftirqd/0]
4 1 0 e0000001039d0000 IN 0.0 0 0 [watchdog/0]
.....
18 years, 10 months
crash version 4.0-2.18 is available
by Dave Anderson
- Fix for "files" command for 2.6.14 and later kernels, in which
the files_struct data structure contains the new fdtable data
structure. (rachita(a)in.ibm.com)
- Fix for an "invalid lvalue in assignment" compile-time error
generated from gdb-6.1/bfd/coff-alpha.c that prevents the embedded
gdb from building with newer compilers. (troy.heber(a)hp.com)
18 years, 10 months
Re: [Crash-utility] Re: [RFC] Patch for fixing 'files' command: TAKE 3
by anderson@prospeed.net
> Hi Dave
>
> I see your point. Sorry for all the confusion.
> I now discard using THIS_KERNEL_VERSION(), and
> use VALID_MEMBER() instead.
>
> Sending along the revised patch. Kindly review.
>
> Thanks
> Rachita
Hi Rachita,
This looks good -- the only thing I'll change is to print out the
offsets unconditionally in dump_offset_table() -- I actually
want to see everything in the table, including the -1's for
the invalid members.
Red Hat's on a break until January 3rd, so I probably won't
get to it unti then.
Thanks,
Dave
18 years, 11 months