Hi Dave,
I found some time to fix the cpu_map issue in 2.6.29.
Here my proposal:
Thanks, man -- much appreciated...
From: Michael Holzheu <holzheu(a)linux.vnet.ibm.com>
In Linux 2.6.29 the cpu_(online, possible, present, active)_map global variables
have been moved to cpu_(...)_mask variables that are pointers to structures
with bitmaps now. This patch allows crash to work with the new variables.
Note: The cpu_map_size() function now only uses STRUCT_SIZE("cpumask_t")
to get the size of the cpu map. I removed the get_symbol_type() call
since STRUCT_SIZE("cpumask_t") should always work.
Correct me if I am wrong here!
Actually, this would break backwards compatibility. The "cpu_online_map"
used to be an "unsigned long", back when NR_CPUS was hardwired to 32.
So the get_symbol_type() is used to differentiate between that type and
its current invocation as a variably-sized cpumask_t struct based upon
NR_CPUS.
So yes, while STRUCT_SIZE("cpumask_t") would always be appropriate for that
data type, it would fail for the older kernel types which don't use it.
Dave
Signed-off-by: Michael Holzheu <holzheu(a)linux.vnet.ibm.com>
---
defs.h | 1
kernel.c | 111
++++++++++++++++++++++++++++++++++++++++++------------------
ppc64.c | 4 +-
s390.c | 3 +
s390x.c | 3 +
xen_hyper.c | 2 -
6 files changed, 86 insertions(+), 38 deletions(-)
Index: crash-4.0-8.9/defs.h
===================================================================
--- crash-4.0-8.9.orig/defs.h
+++ crash-4.0-8.9/defs.h
@@ -3647,6 +3647,7 @@ int in_cpu_map(int, int);
void paravirt_init(void);
void print_stack_text_syms(struct bt_info *, ulong, ulong);
void back_trace(struct bt_info *);
+ulong cpu_map_addr(const char *type);
#define BT_RAW (0x1ULL)
#define BT_SYMBOLIC_ARGS (0x2ULL)
#define BT_FULL (0x4ULL)
Index: crash-4.0-8.9/kernel.c
===================================================================
--- crash-4.0-8.9.orig/kernel.c
+++ crash-4.0-8.9/kernel.c
@@ -533,6 +533,65 @@ kernel_init()
}
/*
+ * Get cpu map (possible, online, etc.) address from cpu mask (since
2.6.29)
+ */
+static ulong
+get_cpu_map_addr_from_mask(const char *type)
+{
+ ulong cpu_mask_addr, cpu_map_addr;
+ char cpu_mask_symbol[32];
+ char *cpu_mask_buf;
+ int cpu_mask_size;
+
+ sprintf(cpu_mask_symbol, "cpu_%s_mask", type);
+
+ if (!symbol_exists(cpu_mask_symbol))
+ return 0;
+
+ cpu_mask_addr = symbol_value(cpu_mask_symbol);
+ cpu_mask_size = STRUCT_SIZE("cpumask");
+ cpu_mask_buf = malloc(cpu_mask_size);
+ if (!cpu_mask_buf)
+ error(FATAL, "get_cpu_map_addr_from_mask: out of memory\n");
+ readmem(cpu_mask_addr, KVADDR, cpu_mask_buf, cpu_mask_size,
+ cpu_mask_symbol, FAULT_ON_ERROR);
+ cpu_map_addr = ULONG(cpu_mask_buf + MEMBER_OFFSET("cpumask",
"bits"));
+ free(cpu_mask_buf);
+
+ return cpu_map_addr;
+}
+
+/*
+ * Get cpu map address. Types are: possible, online, present and
active
+ */
+ulong
+cpu_map_addr(const char *type)
+{
+ char cpu_map_symbol[32];
+
+ sprintf(cpu_map_symbol, "cpu_%s_map", type);
+ if (symbol_exists(cpu_map_symbol))
+ return symbol_value(cpu_map_symbol);
+ else
+ return get_cpu_map_addr_from_mask(type);
+}
+
+/*
+ * Get cpu map (possible, online, etc.) size
+ */
+static int
+cpu_map_size(void)
+{
+ int len;
+
+ len = STRUCT_SIZE("cpumask_t");
+ if (len < 0)
+ return sizeof(ulong);
+ else
+ return len;
+}
+
+/*
* If the cpu_present_map, cpu_online_map and cpu_possible_maps
exist,
* set up the kt->cpu_flags[NR_CPUS] with their settings.
*/
@@ -546,9 +605,9 @@ cpu_maps_init(void)
ulong cpu_flag;
char *name;
} mapinfo[] = {
- { POSSIBLE, "cpu_possible_map" },
- { PRESENT, "cpu_present_map" },
- { ONLINE, "cpu_online_map" },
+ { POSSIBLE, "possible" },
+ { PRESENT, "present" },
+ { ONLINE, "online" },
};
if ((len = STRUCT_SIZE("cpumask_t")) < 0)
@@ -557,12 +616,13 @@ cpu_maps_init(void)
buf = GETBUF(len);
for (m = 0; m < sizeof(mapinfo)/sizeof(struct mapinfo); m++) {
- if (!kernel_symbol_exists(mapinfo[m].name))
+ if (!cpu_map_addr(mapinfo[m].name))
continue;
- if (!readmem(symbol_value(mapinfo[m].name), KVADDR, buf, len,
+ if (!readmem(cpu_map_addr(mapinfo[m].name), KVADDR, buf, len,
mapinfo[m].name, RETURN_ON_ERROR)) {
- error(WARNING, "cannot read %s\n", mapinfo[m].name);
+ error(WARNING, "cannot read cpu_%s_map\n",
+ mapinfo[m].name);
continue;
}
@@ -578,7 +638,7 @@ cpu_maps_init(void)
}
if (CRASHDEBUG(1)) {
- fprintf(fp, "%s: ", mapinfo[m].name);
+ fprintf(fp, "cpu_%s_map: ", mapinfo[m].name);
for (i = 0; i < NR_CPUS; i++) {
if (kt->cpu_flags[i] & mapinfo[m].cpu_flag)
fprintf(fp, "%d ", i);
@@ -605,21 +665,21 @@ in_cpu_map(int map, int cpu)
switch (map)
{
case POSSIBLE:
- if (!kernel_symbol_exists("cpu_possible_map")) {
+ if (!cpu_map_addr("possible")) {
error(INFO, "cpu_possible_map does not exist\n");
return FALSE;
}
return (kt->cpu_flags[cpu] & POSSIBLE);
case PRESENT:
- if (!kernel_symbol_exists("cpu_present_map")) {
+ if (!cpu_map_addr("present")) {
error(INFO, "cpu_present_map does not exist\n");
return FALSE;
}
return (kt->cpu_flags[cpu] & PRESENT);
case ONLINE:
- if (!kernel_symbol_exists("cpu_online_map")) {
+ if (!cpu_map_addr("online")) {
error(INFO, "cpu_online_map does not exist\n");
return FALSE;
}
@@ -4187,7 +4247,7 @@ dump_kernel_table(int verbose)
}
fprintf(fp, "\n");
fprintf(fp, " cpu_possible_map: ");
- if (kernel_symbol_exists("cpu_possible_map")) {
+ if (cpu_map_addr("possible")) {
for (i = 0; i < nr_cpus; i++) {
if (kt->cpu_flags[i] & POSSIBLE)
fprintf(fp, "%d ", i);
@@ -4196,7 +4256,7 @@ dump_kernel_table(int verbose)
} else
fprintf(fp, "(does not exist)\n");
fprintf(fp, " cpu_present_map: ");
- if (kernel_symbol_exists("cpu_present_map")) {
+ if (cpu_map_addr("present")) {
for (i = 0; i < nr_cpus; i++) {
if (kt->cpu_flags[i] & PRESENT)
fprintf(fp, "%d ", i);
@@ -4205,7 +4265,7 @@ dump_kernel_table(int verbose)
} else
fprintf(fp, "(does not exist)\n");
fprintf(fp, " cpu_online_map: ");
- if (kernel_symbol_exists("cpu_online_map")) {
+ if (cpu_map_addr("online")) {
for (i = 0; i < nr_cpus; i++) {
if (kt->cpu_flags[i] & ONLINE)
fprintf(fp, "%d ", i);
@@ -5927,20 +5987,15 @@ get_cpus_online()
char *buf;
ulong *maskptr;
- if (!symbol_exists("cpu_online_map"))
+ if (!cpu_map_addr("online"))
return 0;
- if (LKCD_KERNTYPES()) {
- if ((len = STRUCT_SIZE("cpumask_t")) < 0)
- error(FATAL, "cannot determine type cpumask_t\n");
- } else
- len = get_symbol_type("cpu_online_map", NULL, &req) ==
- TYPE_CODE_UNDEF ? sizeof(ulong) : req.length;
+ len = cpu_map_size();
buf = GETBUF(len);
online = 0;
- if (readmem(symbol_value("cpu_online_map"), KVADDR, buf,
len,
+ if (readmem(cpu_map_addr("online"), KVADDR, buf, len,
"cpu_online_map", RETURN_ON_ERROR)) {
maskptr = (ulong *)buf;
@@ -5969,12 +6024,7 @@ get_cpus_present()
if (!symbol_exists("cpu_present_map"))
return 0;
- if (LKCD_KERNTYPES()) {
- if ((len = STRUCT_SIZE("cpumask_t")) < 0)
- error(FATAL, "cannot determine type cpumask_t\n");
- } else
- len = get_symbol_type("cpu_present_map", NULL, &req) ==
- TYPE_CODE_UNDEF ? sizeof(ulong) : req.length;
+ len = cpu_map_size();
buf = GETBUF(len);
present = 0;
@@ -6008,12 +6058,7 @@ get_cpus_possible()
if (!symbol_exists("cpu_possible_map"))
return 0;
- if (LKCD_KERNTYPES()) {
- if ((len = STRUCT_SIZE("cpumask_t")) < 0)
- error(FATAL, "cannot determine type cpumask_t\n");
- } else
- len = get_symbol_type("cpu_possible_map", NULL, &req) ==
- TYPE_CODE_UNDEF ? sizeof(ulong) : req.length;
+ len = cpu_map_size();
buf = GETBUF(len);
possible = 0;
Index: crash-4.0-8.9/s390.c
===================================================================
--- crash-4.0-8.9.orig/s390.c
+++ crash-4.0-8.9/s390.c
@@ -1001,7 +1001,8 @@ s390_get_smp_cpus(void)
{
unsigned long map = 0, addr;
int i, cpu_num = 0;
- addr=symbol_value("cpu_online_map");
+
+ addr = cpu_map_addr("online");
readmem(addr, KVADDR, &map,sizeof(long),
"cpu_online_map",FAULT_ON_ERROR);
for(i = 0; i < sizeof(map)*8;i++){
if(map & 0x1UL)
Index: crash-4.0-8.9/s390x.c
===================================================================
--- crash-4.0-8.9.orig/s390x.c
+++ crash-4.0-8.9/s390x.c
@@ -1031,7 +1031,8 @@ s390x_get_smp_cpus(void)
{
unsigned long map = 0, addr;
int i, cpu_num = 0;
- addr=symbol_value("cpu_online_map");
+
+ addr = cpu_map_addr("online");
readmem(addr, KVADDR, &map,sizeof(long),
"cpu_online_map",FAULT_ON_ERROR);
for(i = 0; i < sizeof(map)*8;i++){
if(map & 0x1UL)
Index: crash-4.0-8.9/ppc64.c
===================================================================
--- crash-4.0-8.9.orig/ppc64.c
+++ crash-4.0-8.9/ppc64.c
@@ -2407,9 +2407,9 @@ ppc64_paca_init(void)
if (!symbol_exists("paca"))
error(FATAL, "PPC64: Could not find 'paca' symbol\n");
- if (symbol_exists("cpu_present_map"))
+ if (cpu_map_addr("present"))
map = PRESENT;
- else if (symbol_exists("cpu_online_map"))
+ else if (cpu_map_addr("online"))
map = ONLINE;
else
error(FATAL,
Index: crash-4.0-8.9/xen_hyper.c
===================================================================
--- crash-4.0-8.9.orig/xen_hyper.c
+++ crash-4.0-8.9/xen_hyper.c
@@ -1815,7 +1815,7 @@ xen_hyper_get_cpu_info(void)
error(FATAL, "cannot malloc cpumask space.\n");
}
/* kakuma: It may be better to use cpu_present_map. */
- addr = symbol_value("cpu_online_map");
+ addr = cpu_map_addr("online");
if (!readmem(addr, KVADDR, xht->cpumask,
XEN_HYPER_SIZE(cpumask_t), "cpu_online_map", RETURN_ON_ERROR)) {
error(FATAL, "cannot read cpu_online_map.\n");
--
Crash-utility mailing list
Crash-utility(a)redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility