----- "Michael Holzheu" <holzheu@xxxxxxxxxxxxxxxxxx> 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@xxxxxxxxxxxxxxxxxx> > > 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@xxxxxxxxxxxxxxxxxx> > --- > 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@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/crash-utility -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility