[Crash-utility] [PATCH] Support cpu_map/cpu_mask changes in 2.6.29

Michael Holzheu holzheu at linux.vnet.ibm.com
Mon Apr 27 12:48:29 UTC 2009


Hi Dave,

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

From: Michael Holzheu <holzheu at 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 <holzheu at 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");





More information about the Crash-utility mailing list