From: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
To: kexec@lists.infradead.org
Subject: [PATCH v2 11/14] Procees CPUs based on online ones
Date: Fri, 28 Oct 2011 18:49:03 +0900 [thread overview]
Message-ID: <20111028094903.20940.82939.stgit@localhost6.localdomain6> (raw)
In-Reply-To: <20111028094454.20940.1209.stgit@localhost6.localdomain6>
Assign the number of online cpus to nr_cpus member in diskset header,
and create NR_PRSTATUS for each online cpu. This behaviour is sound
with respect to kdump's and crash's on kdump-compressed format.
Signed-off-by: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
---
makedumpfile.c | 27 +++++++++++----
makedumpfile.h | 3 ++
sadump_info.c | 100 +++++++++++++++++++++++++++++++++++++++++++++-----------
sadump_info.h | 4 +-
4 files changed, 106 insertions(+), 28 deletions(-)
diff --git a/makedumpfile.c b/makedumpfile.c
index 750dcb6..44f6ee6 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -826,6 +826,9 @@ get_symbol_info(void)
SYMBOL_INIT(crash_notes, "crash_notes");
SYMBOL_INIT(__per_cpu_load, "__per_cpu_load");
SYMBOL_INIT(__per_cpu_offset, "__per_cpu_offset");
+ SYMBOL_INIT(cpu_online_mask, "cpu_online_mask");
+ if (SYMBOL(cpu_online_mask) == NOT_FOUND_SYMBOL)
+ SYMBOL_INIT(cpu_online_mask, "cpu_online_map");
if (SYMBOL(node_data) != NOT_FOUND_SYMBOL)
SYMBOL_ARRAY_TYPE_INIT(node_data, "node_data");
@@ -962,6 +965,13 @@ get_structure_info(void)
OFFSET_INIT(elf_prstatus.pr_reg, "elf_prstatus", "pr_reg");
/*
+ * Get size of cpumask and cpumask_t.
+ */
+ SIZE_INIT(cpumask, "cpumask");
+
+ TYPEDEF_SIZE_INIT(cpumask_t, "cpumask_t");
+
+ /*
* Get offset of the user_regs_struct members.
*/
SIZE_INIT(user_regs_struct, "user_regs_struct");
@@ -2489,8 +2499,6 @@ initial(void)
return FALSE;
} else if (info->flag_sadump) {
- int nr_cpus;
-
if (info->flag_elf_dumpfile) {
MSG("'-E' option is disable, ");
MSG("because %s is sadump %s format.\n",
@@ -2503,11 +2511,6 @@ initial(void)
if (!sadump_initialize_bitmap_memory())
return FALSE;
- if (!sadump_get_nr_cpus(&nr_cpus))
- return FALSE;
-
- set_nr_cpus(nr_cpus);
-
(void) sadump_set_timestamp(&info->timestamp);
/*
@@ -2600,6 +2603,16 @@ out:
if (!get_machdep_info())
return FALSE;
+ if (info->flag_sadump) {
+ int online_cpus;
+
+ online_cpus = sadump_num_online_cpus();
+ if (!online_cpus)
+ return FALSE;
+
+ set_nr_cpus(online_cpus);
+ }
+
if (!check_release())
return FALSE;
diff --git a/makedumpfile.h b/makedumpfile.h
index 67a6b4f..020d99c 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -995,6 +995,7 @@ struct symbol_table {
unsigned long long crash_notes;
unsigned long long __per_cpu_offset;
unsigned long long __per_cpu_load;
+ unsigned long long cpu_online_mask;
};
struct size_table {
@@ -1024,6 +1025,8 @@ struct size_table {
long percpu_data;
long elf_prstatus;
long user_regs_struct;
+ long cpumask;
+ long cpumask_t;
};
struct offset_table {
diff --git a/sadump_info.c b/sadump_info.c
index 0b9c524..2538da6 100644
--- a/sadump_info.c
+++ b/sadump_info.c
@@ -46,6 +46,14 @@
KEXEC_CORE_NOTE_NAME_BYTES + \
KEXEC_CORE_NOTE_DESC_BYTES )
+#define for_each_online_cpu(cpu) \
+ for (cpu = 0; cpu < BITPERBYTE * si->cpumask_size; ++cpu) \
+ if (is_online_cpu(cpu))
+
+enum {
+ BITPERWORD = BITPERBYTE * sizeof(unsigned long)
+};
+
struct sadump_diskset_info {
char *name_memory;
int fd_memory;
@@ -67,7 +75,8 @@ struct sadump_info {
unsigned long *__per_cpu_offset;
unsigned long __per_cpu_load;
FILE *file_elf_note;
-
+ char *cpu_online_mask_buf;
+ size_t cpumask_size;
};
static char *guid_to_str(efi_guid_t *guid, char *buf, size_t buflen);
@@ -81,6 +90,7 @@ static int read_sadump_header_diskset(int diskid, struct sadump_diskset_info *sd
static unsigned long long pfn_to_block(unsigned long long pfn);
static int lookup_diskset(unsigned long long whole_offset, int *diskid,
unsigned long long *disk_offset);
+static int cpu_online_mask_init(void);
static int per_cpu_init(void);
static int get_data_from_elf_note_desc(const char *note_buf, uint32_t n_descsz,
char *name, uint32_t n_type, char **data);
@@ -88,6 +98,7 @@ static int alignfile(unsigned long *offset);
static int
write_elf_note_header(char *name, void *data, size_t descsz, uint32_t type,
unsigned long *offset, unsigned long *desc_offset);
+static int is_online_cpu(int cpu);
static unsigned long legacy_per_cpu_ptr(unsigned long ptr, int cpu);
static unsigned long per_cpu_ptr(unsigned long ptr, int cpu);
static int get_prstatus_from_crash_notes(int cpu, char *prstatus_buf);
@@ -250,8 +261,10 @@ sadump_generate_elf_note_from_dumpfile(void)
strerror(errno));
goto cleanup;
}
+ if (!cpu_online_mask_init())
+ goto cleanup;
offset = 0;
- for (x_cpu = 0; x_cpu < get_nr_cpus(); ++x_cpu) {
+ for_each_online_cpu(x_cpu) {
struct elf_prstatus prstatus;
memset(&prstatus, 0, sizeof(prstatus));
@@ -756,35 +769,71 @@ sadump_initialize_bitmap_memory(void)
return TRUE;
}
-int
-sadump_get_nr_cpus(int *nr_cpus)
+static int
+cpu_online_mask_init(void)
{
- unsigned long offset;
- struct sadump_smram_cpu_state scs, zero;
- uint32_t x_cpu;
- int count;
+ ulong cpu_online_mask_addr;
- memset(&zero, 0, sizeof(zero));
+ if (si->cpu_online_mask_buf && si->cpumask_size)
+ return TRUE;
- offset = si->sub_hdr_offset + sizeof(uint32_t) +
- si->sh_memory->nr_cpus * sizeof(struct sadump_apic_state);
+ if (SYMBOL(cpu_online_mask) == NOT_FOUND_SYMBOL ||
+ (SIZE(cpumask) == NOT_FOUND_STRUCTURE &&
+ SIZE(cpumask_t) == NOT_FOUND_STRUCTURE))
+ return FALSE;
- count = 0;
- for (x_cpu = 0; x_cpu < si->sh_memory->nr_cpus; ++x_cpu) {
- if (!read_device(&scs, sizeof(scs), &offset))
- return FALSE;
- if (memcmp(&scs, &zero, sizeof(scs)) != 0)
- count++;
+ si->cpumask_size = SIZE(cpumask) == NOT_FOUND_STRUCTURE
+ ? SIZE(cpumask_t)
+ : SIZE(cpumask);
+
+ if (!(si->cpu_online_mask_buf = calloc(1, si->cpumask_size))) {
+ ERRMSG("Can't allocate cpu_online_mask buffer. %s\n",
+ strerror(errno));
+ return FALSE;
}
- *nr_cpus = count;
+ if (SIZE(cpumask) == NOT_FOUND_STRUCTURE)
+ cpu_online_mask_addr = SYMBOL(cpu_online_mask);
+
+ else {
+ if (!readmem(VADDR, SYMBOL(cpu_online_mask),
+ &cpu_online_mask_addr, sizeof(unsigned long))) {
+ ERRMSG("Can't read cpu_online_mask pointer.\n");
+ return FALSE;
+ }
+
+ }
- DEBUG_MSG("sadump: nr_cpus: %d\n", *nr_cpus);
+ if (!readmem(VADDR, cpu_online_mask_addr, si->cpu_online_mask_buf,
+ si->cpumask_size)) {
+ ERRMSG("Can't read cpu_online_mask memory.\n");
+ return FALSE;
+ }
return TRUE;
}
int
+sadump_num_online_cpus(void)
+{
+ int cpu, count = 0;
+
+ if (!cpu_online_mask_init())
+ return FALSE;
+
+ DEBUG_MSG("sadump: online cpus:");
+
+ for_each_online_cpu(cpu) {
+ count++;
+ DEBUG_MSG(" %d", cpu);
+ }
+
+ DEBUG_MSG("\nsadump: nr_cpus: %d\n", count);
+
+ return count;
+}
+
+int
sadump_set_timestamp(struct timeval *ts)
{
static struct tm t;
@@ -1201,6 +1250,17 @@ write_elf_note_header(char *name, void *data, size_t descsz, uint32_t type,
return TRUE;
}
+static int
+is_online_cpu(int cpu)
+{
+ unsigned long mask;
+
+ mask = ULONG(si->cpu_online_mask_buf +
+ (cpu / BITPERWORD) * sizeof(unsigned long));
+
+ return (mask & (1UL << (cpu % BITPERWORD))) ? TRUE : FALSE;
+}
+
static unsigned long
legacy_per_cpu_ptr(unsigned long ptr, int cpu)
{
@@ -1710,6 +1770,8 @@ free_sadump_info(void)
free(si->block_table);
if (si->file_elf_note)
fclose(si->file_elf_note);
+ if (si->cpu_online_mask_buf)
+ free(si->cpu_online_mask_buf);
}
#endif /* defined(__x86__) && defined(__x86_64__) */
diff --git a/sadump_info.h b/sadump_info.h
index c1f948f..f90ea5a 100644
--- a/sadump_info.h
+++ b/sadump_info.h
@@ -40,7 +40,7 @@ static inline int sadump_virt_phys_base(void)
int check_and_get_sadump_header_info(char *filename);
int sadump_copy_1st_bitmap_from_memory(void);
int sadump_initialize_bitmap_memory(void);
-int sadump_get_nr_cpus(int *nr_cpus);
+int sadump_num_online_cpus(void);
int sadump_set_timestamp(struct timeval *ts);
unsigned long long sadump_get_max_mapnr(void);
int readpmem_sadump(unsigned long long paddr, void *bufptr, size_t size);
@@ -81,7 +81,7 @@ static inline int sadump_initialize_bitmap_memory(void)
return FALSE;
}
-static inline int sadump_get_nr_cpus(int *nr_cpus)
+static inline int sadump_num_online_cpus(void);
{
return 0;
}
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
next prev parent reply other threads:[~2011-10-28 9:49 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-28 9:48 [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format HATAYAMA Daisuke
2011-10-28 9:48 ` [PATCH v2 01/14] Add sadump module header file HATAYAMA Daisuke
2011-10-28 9:48 ` [PATCH v2 02/14] Extend DumpInfo structure HATAYAMA Daisuke
2011-10-28 9:48 ` [PATCH v2 03/14] Implement command-line processing HATAYAMA Daisuke
2011-10-28 9:48 ` [PATCH v2 04/14] Verify and read VMCORE(s) in sadump-related formats HATAYAMA Daisuke
2011-10-28 9:48 ` [PATCH v2 05/14] Export helpers for bitmap table handling HATAYAMA Daisuke
2011-10-28 9:48 ` [PATCH v2 06/14] Initialize internal data according to sadump-related formats HATAYAMA Daisuke
2011-10-28 9:48 ` [PATCH v2 07/14] Initialize debug information for ELF note extraction HATAYAMA Daisuke
2011-10-28 9:48 ` [PATCH v2 08/14] Implement readmem() interface on sadump-related formats HATAYAMA Daisuke
2011-10-28 9:48 ` [PATCH v2 09/14] Estimate phys_base based on linux_banner position HATAYAMA Daisuke
2011-10-28 9:48 ` [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information HATAYAMA Daisuke
2011-12-20 8:18 ` Atsushi Kumagai
2011-12-20 9:31 ` HATAYAMA Daisuke
2011-12-21 8:22 ` Atsushi Kumagai
2011-12-21 8:39 ` HATAYAMA Daisuke
2011-10-28 9:49 ` HATAYAMA Daisuke [this message]
2011-10-28 9:49 ` [PATCH v2 12/14] Read kexec backup region HATAYAMA Daisuke
2011-10-28 9:49 ` [PATCH v2 13/14] Add description of sadump-related formts in usage information HATAYAMA Daisuke
2011-10-28 9:49 ` [PATCH v2 14/14] Add description of sadump-related formats in manual page HATAYAMA Daisuke
2011-10-28 12:05 ` [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format tachibana
2011-12-15 6:47 ` HATAYAMA Daisuke
2011-12-15 8:55 ` tachibana
2011-12-15 9:09 ` HATAYAMA Daisuke
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20111028094903.20940.82939.stgit@localhost6.localdomain6 \
--to=d.hatayama@jp.fujitsu.com \
--cc=kexec@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.