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

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

--
Crash-utility mailing list
Crash-utility@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to