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

Dave Anderson anderson at redhat.com
Mon Apr 27 13:27:22 UTC 2009


----- "Michael Holzheu" <holzheu at linux.vnet.ibm.com> wrote:

> 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 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!

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 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");
> 
> 
> --
> Crash-utility mailing list
> Crash-utility at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility




More information about the Crash-utility mailing list