Hi Dave,

I found some time to fix the cpu_map issue in 2.6.29.
Here my proposal:

From: Michael Holzheu <holz...@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!

Signed-off-by: Michael Holzheu <holz...@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@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to