mirror of https://github.com/crash-utility/crash
Fix for Linux 3.11 and later ARM kernels, in which all non-panicking
cpus offline themselves during a kdump procedure. This causes an invalid cpu count determination during crash session initialization from an ARM vmcore. The patch utilizes the cpu count found in the cpu_active_map if it is greater than the count in the cpu_online_map. In addition, the maximum NR_CPUS value for the ARM architecture has been raised from 4 to 32. (sdu.liu@huawei.com)
This commit is contained in:
parent
a91e410866
commit
8bff022b52
2
arm.c
2
arm.c
|
@ -1518,7 +1518,7 @@ arm_display_machine_stats(void)
|
|||
static int
|
||||
arm_get_smp_cpus(void)
|
||||
{
|
||||
return get_cpus_online();
|
||||
return MAX(get_cpus_active(), get_cpus_online());
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
7
defs.h
7
defs.h
|
@ -131,7 +131,7 @@
|
|||
#define NR_CPUS (512)
|
||||
#endif
|
||||
#ifdef ARM
|
||||
#define NR_CPUS (4)
|
||||
#define NR_CPUS (32)
|
||||
#endif
|
||||
#ifdef ARM64
|
||||
#define NR_CPUS (4096) /* TBD */
|
||||
|
@ -658,6 +658,10 @@ struct kernel_table { /* kernel data */
|
|||
#define PRESENT (0x2)
|
||||
#define ONLINE (0x4)
|
||||
#define NMI (0x8)
|
||||
#define POSSIBLE_MAP (POSSIBLE)
|
||||
#define PRESENT_MAP (PRESENT)
|
||||
#define ONLINE_MAP (ONLINE)
|
||||
#define ACTIVE_MAP (0x10)
|
||||
int BUG_bytes;
|
||||
ulong xen_flags;
|
||||
#define WRITABLE_PAGE_TABLES (0x1)
|
||||
|
@ -4795,6 +4799,7 @@ void set_cpu(int);
|
|||
void clear_machdep_cache(void);
|
||||
struct stack_hook *gather_text_list(struct bt_info *);
|
||||
int get_cpus_online(void);
|
||||
int get_cpus_active(void);
|
||||
int get_cpus_present(void);
|
||||
int get_cpus_possible(void);
|
||||
int get_highest_cpu_online(void);
|
||||
|
|
|
@ -119,7 +119,7 @@ map_cpus_to_prstatus_kdump_cmprs(void)
|
|||
nrcpus = (kt->kernel_NR_CPUS ? kt->kernel_NR_CPUS : NR_CPUS);
|
||||
|
||||
for (i = 0, j = 0; i < nrcpus; i++) {
|
||||
if (in_cpu_map(ONLINE, i)) {
|
||||
if (in_cpu_map(ONLINE_MAP, i)) {
|
||||
dd->nt_prstatus_percpu[i] = nt_ptr[j++];
|
||||
dd->num_prstatus_notes =
|
||||
MAX(dd->num_prstatus_notes, i+1);
|
||||
|
@ -1193,7 +1193,7 @@ get_diskdump_panic_task(void)
|
|||
if (kernel_symbol_exists("crashing_cpu") &&
|
||||
cpu_map_addr("online")) {
|
||||
get_symbol_data("crashing_cpu", sizeof(int), &i);
|
||||
if ((i >= 0) && in_cpu_map(ONLINE, i)) {
|
||||
if ((i >= 0) && in_cpu_map(ONLINE_MAP, i)) {
|
||||
if (CRASHDEBUG(1))
|
||||
error(INFO, "get_diskdump_panic_task: "
|
||||
"active_set[%d]: %lx\n",
|
||||
|
|
76
kernel.c
76
kernel.c
|
@ -795,9 +795,10 @@ cpu_maps_init(void)
|
|||
ulong cpu_flag;
|
||||
char *name;
|
||||
} mapinfo[] = {
|
||||
{ POSSIBLE, "possible" },
|
||||
{ PRESENT, "present" },
|
||||
{ ONLINE, "online" },
|
||||
{ POSSIBLE_MAP, "possible" },
|
||||
{ PRESENT_MAP, "present" },
|
||||
{ ONLINE_MAP, "online" },
|
||||
{ ACTIVE_MAP, "active" },
|
||||
};
|
||||
|
||||
if ((len = STRUCT_SIZE("cpumask_t")) < 0)
|
||||
|
@ -864,26 +865,33 @@ in_cpu_map(int map, int cpu)
|
|||
|
||||
switch (map)
|
||||
{
|
||||
case POSSIBLE:
|
||||
case POSSIBLE_MAP:
|
||||
if (!cpu_map_addr("possible")) {
|
||||
error(INFO, "cpu_possible_map does not exist\n");
|
||||
return FALSE;
|
||||
}
|
||||
return (kt->cpu_flags[cpu] & POSSIBLE);
|
||||
return (kt->cpu_flags[cpu] & POSSIBLE_MAP);
|
||||
|
||||
case PRESENT:
|
||||
case PRESENT_MAP:
|
||||
if (!cpu_map_addr("present")) {
|
||||
error(INFO, "cpu_present_map does not exist\n");
|
||||
return FALSE;
|
||||
}
|
||||
return (kt->cpu_flags[cpu] & PRESENT);
|
||||
return (kt->cpu_flags[cpu] & PRESENT_MAP);
|
||||
|
||||
case ONLINE:
|
||||
case ONLINE_MAP:
|
||||
if (!cpu_map_addr("online")) {
|
||||
error(INFO, "cpu_online_map does not exist\n");
|
||||
return FALSE;
|
||||
}
|
||||
return (kt->cpu_flags[cpu] & ONLINE);
|
||||
return (kt->cpu_flags[cpu] & ONLINE_MAP);
|
||||
|
||||
case ACTIVE_MAP:
|
||||
if (!cpu_map_addr("active")) {
|
||||
error(INFO, "cpu_active_map does not exist\n");
|
||||
return FALSE;
|
||||
}
|
||||
return (kt->cpu_flags[cpu] & ACTIVE_MAP);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
@ -5321,7 +5329,7 @@ dump_kernel_table(int verbose)
|
|||
fprintf(fp, " cpu_possible_map: ");
|
||||
if (cpu_map_addr("possible")) {
|
||||
for (i = 0; i < nr_cpus; i++) {
|
||||
if (kt->cpu_flags[i] & POSSIBLE)
|
||||
if (kt->cpu_flags[i] & POSSIBLE_MAP)
|
||||
fprintf(fp, "%d ", i);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
|
@ -5330,7 +5338,7 @@ dump_kernel_table(int verbose)
|
|||
fprintf(fp, " cpu_present_map: ");
|
||||
if (cpu_map_addr("present")) {
|
||||
for (i = 0; i < nr_cpus; i++) {
|
||||
if (kt->cpu_flags[i] & PRESENT)
|
||||
if (kt->cpu_flags[i] & PRESENT_MAP)
|
||||
fprintf(fp, "%d ", i);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
|
@ -5339,12 +5347,22 @@ dump_kernel_table(int verbose)
|
|||
fprintf(fp, " cpu_online_map: ");
|
||||
if (cpu_map_addr("online")) {
|
||||
for (i = 0; i < nr_cpus; i++) {
|
||||
if (kt->cpu_flags[i] & ONLINE)
|
||||
if (kt->cpu_flags[i] & ONLINE_MAP)
|
||||
fprintf(fp, "%d ", i);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
} else
|
||||
fprintf(fp, "(does not exist)\n");
|
||||
fprintf(fp, " cpu_active_map: ");
|
||||
if (cpu_map_addr("active")) {
|
||||
for (i = 0; i < nr_cpus; i++) {
|
||||
if (kt->cpu_flags[i] & ACTIVE_MAP)
|
||||
fprintf(fp, "%d ", i);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
} else
|
||||
fprintf(fp, "(does not exist)\n");
|
||||
|
||||
no_cpu_flags:
|
||||
fprintf(fp, " vmcoreinfo: \n");
|
||||
fprintf(fp, " log_buf_SYMBOL: %lx\n", kt->vmcoreinfo.log_buf_SYMBOL);
|
||||
|
@ -7972,6 +7990,40 @@ get_highest_cpu_online()
|
|||
return highest;
|
||||
}
|
||||
|
||||
/*
|
||||
* If it exists, return the number of cpus in the cpu_active_map.
|
||||
*/
|
||||
int
|
||||
get_cpus_active()
|
||||
{
|
||||
int i, len, active;
|
||||
char *buf;
|
||||
ulong *maskptr, addr;
|
||||
|
||||
if (!(addr = cpu_map_addr("active")))
|
||||
return 0;
|
||||
|
||||
len = cpu_map_size("active");
|
||||
buf = GETBUF(len);
|
||||
|
||||
active = 0;
|
||||
|
||||
if (readmem(addr, KVADDR, buf, len,
|
||||
"cpu_active_map", RETURN_ON_ERROR)) {
|
||||
|
||||
maskptr = (ulong *)buf;
|
||||
for (i = 0; i < (len/sizeof(ulong)); i++, maskptr++)
|
||||
active += count_bits_long(*maskptr);
|
||||
|
||||
if (CRASHDEBUG(1))
|
||||
error(INFO, "get_cpus_active: active: %d\n", active);
|
||||
}
|
||||
|
||||
FREEBUF(buf);
|
||||
|
||||
return active;
|
||||
}
|
||||
|
||||
/*
|
||||
* If it exists, return the number of cpus in the cpu_present_map.
|
||||
*/
|
||||
|
|
|
@ -92,7 +92,7 @@ map_cpus_to_prstatus(void)
|
|||
nrcpus = (kt->kernel_NR_CPUS ? kt->kernel_NR_CPUS : NR_CPUS);
|
||||
|
||||
for (i = 0, j = 0; i < nrcpus; i++) {
|
||||
if (in_cpu_map(ONLINE, i))
|
||||
if (in_cpu_map(ONLINE_MAP, i))
|
||||
nd->nt_prstatus_percpu[i] = nt_ptr[j++];
|
||||
}
|
||||
|
||||
|
@ -769,7 +769,7 @@ get_netdump_panic_task(void)
|
|||
crashing_cpu = -1;
|
||||
if (kernel_symbol_exists("crashing_cpu")) {
|
||||
get_symbol_data("crashing_cpu", sizeof(int), &i);
|
||||
if ((i >= 0) && in_cpu_map(ONLINE, i)) {
|
||||
if ((i >= 0) && in_cpu_map(ONLINE_MAP, i)) {
|
||||
crashing_cpu = i;
|
||||
if (CRASHDEBUG(1))
|
||||
error(INFO,
|
||||
|
|
6
ppc.c
6
ppc.c
|
@ -1,8 +1,8 @@
|
|||
/* ppc.c - core analysis suite
|
||||
*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
|
||||
* Copyright (C) 2002-2007, 2010-2013 David Anderson
|
||||
* Copyright (C) 2002-2007, 2010-2013 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2002-2007, 2010-2014 David Anderson
|
||||
* Copyright (C) 2002-2007, 2010-2014 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -2036,7 +2036,7 @@ ppc_relocate_nt_prstatus_percpu(void **nt_prstatus_percpu,
|
|||
*num_prstatus_notes = 0;
|
||||
nrcpus = (kt->kernel_NR_CPUS ? kt->kernel_NR_CPUS : NR_CPUS);
|
||||
for (i = 0, j = 0; i < nrcpus; i++) {
|
||||
if (!in_cpu_map(ONLINE, i))
|
||||
if (!in_cpu_map(ONLINE_MAP, i))
|
||||
continue;
|
||||
if (verify_crash_note_in_kernel(i))
|
||||
nt_prstatus_percpu[i] = nt_ptr[j++];
|
||||
|
|
22
ppc64.c
22
ppc64.c
|
@ -1,7 +1,7 @@
|
|||
/* ppc64.c -- core analysis suite
|
||||
*
|
||||
* Copyright (C) 2004-2013 David Anderson
|
||||
* Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2014 David Anderson
|
||||
* Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004, 2006 Haren Myneni, IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -2861,16 +2861,18 @@ ppc64_get_cpu_map(void)
|
|||
int map;
|
||||
|
||||
if (cpu_map_addr("possible"))
|
||||
map = POSSIBLE;
|
||||
map = POSSIBLE_MAP;
|
||||
else if (cpu_map_addr("present"))
|
||||
map = PRESENT;
|
||||
map = PRESENT_MAP;
|
||||
else if (cpu_map_addr("online"))
|
||||
map = ONLINE;
|
||||
map = ONLINE_MAP;
|
||||
else if (cpu_map_addr("active"))
|
||||
map = ACTIVE_MAP;
|
||||
else {
|
||||
map = 0;
|
||||
error(FATAL,
|
||||
"PPC64: cannot find 'cpu_possible_map' or\
|
||||
'cpu_present_map' or 'cpu_online_map' symbols\n");
|
||||
"PPC64: cannot find 'cpu_possible_map', "
|
||||
"'cpu_present_map', 'cpu_online_map' or 'cpu_active_map' symbols\n");
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
@ -2911,15 +2913,15 @@ ppc64_init_cpu_info(void)
|
|||
}
|
||||
switch (map)
|
||||
{
|
||||
case POSSIBLE:
|
||||
case POSSIBLE_MAP:
|
||||
if (cpus > kt->cpus) {
|
||||
i = get_highest_cpu_online() + 1;
|
||||
if (i > kt->cpus)
|
||||
kt->cpus = i;
|
||||
}
|
||||
break;
|
||||
case ONLINE:
|
||||
case PRESENT:
|
||||
case ONLINE_MAP:
|
||||
case PRESENT_MAP:
|
||||
kt->cpus = cpus;
|
||||
break;
|
||||
}
|
||||
|
|
8
s390.c
8
s390.c
|
@ -1,8 +1,8 @@
|
|||
/* s390.c - core analysis suite
|
||||
*
|
||||
* Copyright (C) 2001, 2002 Mission Critical Linux, Inc.
|
||||
* Copyright (C) 2002-2006, 2009-2010, 2012-2013 David Anderson
|
||||
* Copyright (C) 2002-2006, 2009-2010, 2012-2013 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2002-2006, 2009-2010, 2012-2014 David Anderson
|
||||
* Copyright (C) 2002-2006, 2009-2010, 2012-2014 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2005, 2006, 2010 Michael Holzheu, IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -558,7 +558,7 @@ s390_has_cpu(struct bt_info *bt)
|
|||
{
|
||||
int cpu = bt->tc->processor;
|
||||
|
||||
if (is_task_active(bt->task) && (kt->cpu_flags[cpu] & ONLINE))
|
||||
if (is_task_active(bt->task) && (kt->cpu_flags[cpu] & ONLINE_MAP))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
|
@ -619,7 +619,7 @@ s390_back_trace_cmd(struct bt_info *bt)
|
|||
error(WARNING,
|
||||
"instruction pointer argument ignored on this architecture!\n");
|
||||
}
|
||||
if (is_task_active(bt->task) && !(kt->cpu_flags[cpu] & ONLINE)) {
|
||||
if (is_task_active(bt->task) && !(kt->cpu_flags[cpu] & ONLINE_MAP)) {
|
||||
fprintf(fp, " CPU offline\n");
|
||||
return;
|
||||
}
|
||||
|
|
8
s390x.c
8
s390x.c
|
@ -1,8 +1,8 @@
|
|||
/* s390.c - core analysis suite
|
||||
*
|
||||
* Copyright (C) 2001, 2002 Mission Critical Linux, Inc.
|
||||
* Copyright (C) 2002-2006, 2009-2013 David Anderson
|
||||
* Copyright (C) 2002-2006, 2009-2013 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2002-2006, 2009-2014 David Anderson
|
||||
* Copyright (C) 2002-2006, 2009-2014 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2005, 2006, 2010-2013 Michael Holzheu, IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -872,7 +872,7 @@ s390x_has_cpu(struct bt_info *bt)
|
|||
{
|
||||
int cpu = bt->tc->processor;
|
||||
|
||||
if (is_task_active(bt->task) && (kt->cpu_flags[cpu] & ONLINE))
|
||||
if (is_task_active(bt->task) && (kt->cpu_flags[cpu] & ONLINE_MAP))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
|
@ -1165,7 +1165,7 @@ static void s390x_back_trace_cmd(struct bt_info *bt)
|
|||
error(WARNING,
|
||||
"instruction pointer argument ignored on this architecture!\n");
|
||||
}
|
||||
if (is_task_active(bt->task) && !(kt->cpu_flags[cpu] & ONLINE)) {
|
||||
if (is_task_active(bt->task) && !(kt->cpu_flags[cpu] & ONLINE_MAP)) {
|
||||
fprintf(fp, " CPU offline\n");
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue