2007-08-22 12:09:45

by Ken'ichi Ohmichi

[permalink] [raw]
Subject: [PATCH 0/3] vmcoreinfo support for dump filtering


Hi Andrew,

This patch set frees the restriction that makedumpfile users should
install a vmlinux file (including the debugging information) into
each system.

makedumpfile command is the dump filtering feature for kdump.
It creates a small dumpfile by filtering unnecessary pages for the
analysis. To distinguish unnecessary pages, it needs a vmlinux file
including the debugging information. These days, the debugging package
becomes a huge file, and it is hard to install it into each system.

To solve the problem, kdump developers discussed it at lkml and kexec-ml.
As the result, we reached the conclusion that necessary information
for dump filtering (called "vmcoreinfo") should be embedded into the
first kernel file and it should be accessed through /proc/vmcore
during the second kernel.
(http://www.uwsg.iu.edu/hypermail/linux/kernel/0707.0/1806.html)

Dan Aloni created the patch set for the above implementation.
(http://www.uwsg.iu.edu/hypermail/linux/kernel/0707.1/1053.html)

And I updated it for multi architectures and memory models.
(http://lists.infradead.org/pipermail/kexec/2007-August/000479.html)


PATCH SET:
[1/3] [linux] Add vmcoreinfo
The patch is for linux-2.6.22.
The patch adds the vmcoreinfo data. Its address and size are output
to /sys/kernel/vmcoreinfo.

[2/3] [kexec-tools] Pass vmcoreinfo's address and size
The patch is for kexec-tools-testing-20070330.
(http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/)
kexec command gets the address and size of the vmcoreinfo data from
/sys/kernel/vmcoreinfo, and passes them to the second kernel through
ELF header of /proc/vmcore. When the second kernel is booting, the
kernel gets them from the ELF header and creates vmcoreinfo's PT_NOTE
segment into /proc/vmcore.

[3/3] [makedumpfile] Extract vmcoreinfo from /proc/vmcore
The patch is for makedumpfile v1.1.6.
(https://sourceforge.net/projects/makedumpfile/)
makedumpfile command extracts the vmcoreinfo data from /proc/vmcore
and uses it for dump filtering.

Usage:
- Run the first kernel applied with [PATCH 1/3].
- Preload the second kernel by the kexec-tools applied with [PATCH 2/3].
- Cause panic and switch to the second kernel.
- Get a dumpfile by the makedumpfile applied with [PATCH 3/3]:
(Ex.) # makedumpfile -cd31 /proc/vmcore dumpfile


Thanks
Ken'ichi Ohmichi


2007-08-22 12:11:35

by Ken'ichi Ohmichi

[permalink] [raw]
Subject: [PATCH 1/3] [linux] Add vmcoreinfo


[1/3] [linux] Add vmcoreinfo
The patch is for linux-2.6.22.
The patch adds the vmcoreinfo data.
Its address and size are output to /sys/kernel/vmcoreinfo.


Thanks
Ken'ichi Ohmichi

---
Signed-off-by: Dan Aloni <[email protected]>
Signed-off-by: Ken'ichi Ohmichi <[email protected]>
Signed-off-by: Bernhard Walle <[email protected]>
Signed-off-by: Daisuke Nishimura <[email protected]>

---
diff -rpuN a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c
--- a/arch/i386/kernel/machine_kexec.c 2007-08-23 00:03:30.000000000 +0900
+++ b/arch/i386/kernel/machine_kexec.c 2007-08-23 00:47:38.000000000 +0900
@@ -10,6 +10,7 @@
#include <linux/kexec.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/numa.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
@@ -169,3 +170,15 @@ static int __init parse_crashkernel(char
return 0;
}
early_param("crashkernel", parse_crashkernel);
+
+void arch_crash_save_vmcoreinfo(void)
+{
+#ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
+ SYMBOL(node_data);
+ LENGTH(node_data, MAX_NUMNODES);
+#endif
+#ifdef CONFIG_X86_PAE
+ CONFIG(X86_PAE);
+#endif
+}
+
diff -rpuN a/arch/ia64/kernel/machine_kexec.c b/arch/ia64/kernel/machine_kexec.c
--- a/arch/ia64/kernel/machine_kexec.c 2007-08-23 00:03:30.000000000 +0900
+++ b/arch/ia64/kernel/machine_kexec.c 2007-08-23 00:47:38.000000000 +0900
@@ -15,6 +15,8 @@
#include <linux/cpu.h>
#include <linux/irq.h>
#include <linux/efi.h>
+#include <linux/numa.h>
+#include <linux/mmzone.h>
#include <asm/mmu_context.h>
#include <asm/setup.h>
#include <asm/delay.h>
@@ -125,3 +127,31 @@ void machine_kexec(struct kimage *image)
unw_init_running(ia64_machine_kexec, image);
for(;;);
}
+
+void arch_crash_save_vmcoreinfo(void)
+{
+#ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
+ SYMBOL(pgdat_list);
+ LENGTH(pgdat_list, MAX_NUMNODES);
+
+ SYMBOL(node_memblk);
+ LENGTH(node_memblk, NR_NODE_MEMBLKS);
+ SIZE(node_memblk_s);
+ OFFSET(node_memblk_s, start_paddr);
+ OFFSET(node_memblk_s, size);
+#endif
+#ifdef CONFIG_PGTABLE_3
+ CONFIG(PGTABLE_3);
+#elif CONFIG_PGTABLE_4
+ CONFIG(PGTABLE_4);
+#endif
+}
+
+unsigned long paddr_vmcoreinfo_note(void)
+{
+ unsigned long vaddr, paddr;
+ vaddr = (unsigned long)(char *)&vmcoreinfo_note;
+ asm volatile ("tpa %0 = %1" : "=r"(paddr) : "r"(vaddr) : "memory");
+ return paddr;
+}
+
diff -rpuN a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
--- a/arch/ia64/mm/discontig.c 2007-08-23 00:03:30.000000000 +0900
+++ b/arch/ia64/mm/discontig.c 2007-08-23 00:47:38.000000000 +0900
@@ -47,7 +47,7 @@ struct early_node_data {
static struct early_node_data mem_data[MAX_NUMNODES] __initdata;
static nodemask_t memory_less_mask __initdata;

-static pg_data_t *pgdat_list[MAX_NUMNODES];
+pg_data_t *pgdat_list[MAX_NUMNODES];

/*
* To prevent cache aliasing effects, align per-node structures so that they
diff -rpuN a/arch/x86_64/kernel/machine_kexec.c b/arch/x86_64/kernel/machine_kexec.c
--- a/arch/x86_64/kernel/machine_kexec.c 2007-08-23 00:03:30.000000000 +0900
+++ b/arch/x86_64/kernel/machine_kexec.c 2007-08-23 00:47:38.000000000 +0900
@@ -10,6 +10,7 @@
#include <linux/kexec.h>
#include <linux/string.h>
#include <linux/reboot.h>
+#include <linux/numa.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <asm/mmu_context.h>
@@ -257,3 +258,11 @@ static int __init setup_crashkernel(char
}
early_param("crashkernel", setup_crashkernel);

+void arch_crash_save_vmcoreinfo(void)
+{
+#ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
+ SYMBOL(node_data);
+ LENGTH(node_data, MAX_NUMNODES);
+#endif
+}
+
diff -rpuN a/include/asm-ia64/numa.h b/include/asm-ia64/numa.h
--- a/include/asm-ia64/numa.h 2007-08-23 00:03:33.000000000 +0900
+++ b/include/asm-ia64/numa.h 2007-08-23 00:47:38.000000000 +0900
@@ -24,6 +24,7 @@

extern u16 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
extern cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
+extern pg_data_t *pgdat_list[MAX_NUMNODES];

/* Stuff below this line could be architecture independent */

diff -rpuN a/include/linux/kexec.h b/include/linux/kexec.h
--- a/include/linux/kexec.h 2007-08-23 00:03:33.000000000 +0900
+++ b/include/linux/kexec.h 2007-08-23 00:47:38.000000000 +0900
@@ -121,6 +121,23 @@ extern struct page *kimage_alloc_control
extern void crash_kexec(struct pt_regs *);
int kexec_should_crash(struct task_struct *);
void crash_save_cpu(struct pt_regs *regs, int cpu);
+void crash_save_vmcoreinfo(void);
+void arch_crash_save_vmcoreinfo(void);
+void vmcoreinfo_append_str(const char *fmt, ...);
+unsigned long paddr_vmcoreinfo_note(void);
+
+#define SYMBOL(name) \
+ vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name)
+#define SIZE(name) \
+ vmcoreinfo_append_str("SIZE(%s)=%d\n", #name, sizeof(struct name))
+#define OFFSET(name, field) \
+ vmcoreinfo_append_str("OFFSET(%s.%s)=%d\n", #name, #field, \
+ &(((struct name *)0)->field))
+#define LENGTH(name, value) \
+ vmcoreinfo_append_str("LENGTH(%s)=%d\n", #name, value)
+#define CONFIG(name) \
+ vmcoreinfo_append_str("CONFIG_%s=y\n", #name)
+
extern struct kimage *kexec_image;
extern struct kimage *kexec_crash_image;

@@ -148,11 +165,20 @@ extern struct kimage *kexec_crash_image;

#define KEXEC_FLAGS (KEXEC_ON_CRASH) /* List of defined/legal kexec flags */

+#define VMCOREINFO_BYTES (4096)
+#define VMCOREINFO_NOTE_NAME "VMCOREINFO"
+#define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4)
+#define VMCOREINFO_NOTE_SIZE (KEXEC_NOTE_HEAD_BYTES*2 + VMCOREINFO_BYTES \
+ + VMCOREINFO_NOTE_NAME_BYTES)
+
/* Location of a reserved region to hold the crash kernel.
*/
extern struct resource crashk_res;
typedef u32 note_buf_t[KEXEC_NOTE_BYTES/4];
extern note_buf_t *crash_notes;
+extern u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
+extern unsigned int vmcoreinfo_size;
+extern unsigned int vmcoreinfo_max_size;


#else /* !CONFIG_KEXEC */
diff -rpuN a/kernel/kexec.c b/kernel/kexec.c
--- a/kernel/kexec.c 2007-08-23 00:03:30.000000000 +0900
+++ b/kernel/kexec.c 2007-08-23 00:48:40.000000000 +0900
@@ -22,16 +22,26 @@
#include <linux/hardirq.h>
#include <linux/elf.h>
#include <linux/elfcore.h>
+#include <linux/utsrelease.h>
+#include <linux/utsname.h>
+#include <linux/numa.h>

#include <asm/page.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/semaphore.h>
+#include <asm/sections.h>

/* Per cpu memory for storing cpu states in case of system crash. */
note_buf_t* crash_notes;

+/* vmcoreinfo stuff */
+unsigned char vmcoreinfo_data[VMCOREINFO_BYTES];
+u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
+unsigned int vmcoreinfo_size = 0;
+unsigned int vmcoreinfo_max_size = sizeof(vmcoreinfo_data);
+
/* Location of the reserved area for the crash kernel */
struct resource crashk_res = {
.name = "Crash kernel",
@@ -1061,6 +1071,7 @@ void crash_kexec(struct pt_regs *regs)
if (kexec_crash_image) {
struct pt_regs fixed_regs;
crash_setup_regs(&fixed_regs, regs);
+ crash_save_vmcoreinfo();
machine_crash_shutdown(&fixed_regs);
machine_kexec(kexec_crash_image);
}
@@ -1135,3 +1146,102 @@ static int __init crash_notes_memory_ini
return 0;
}
module_init(crash_notes_memory_init)
+
+void crash_save_vmcoreinfo(void)
+{
+ u32 *buf;
+
+ if (!vmcoreinfo_size)
+ return;
+
+ vmcoreinfo_append_str("CRASHTIME=%d", xtime.tv_sec);
+
+ buf = (u32 *)vmcoreinfo_note;
+
+ buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
+ vmcoreinfo_size);
+
+ final_note(buf);
+}
+
+void vmcoreinfo_append_str(const char *fmt, ...)
+{
+ va_list args;
+ char buf[0x50];
+ int r;
+
+ va_start(args, fmt);
+ r = vsnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+
+ if (r + vmcoreinfo_size > vmcoreinfo_max_size)
+ r = vmcoreinfo_max_size - vmcoreinfo_size;
+
+ memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r);
+
+ vmcoreinfo_size += r;
+}
+
+/*
+ * provide an empty default implementation here -- architecture
+ * code may override this
+ */
+void __attribute__ ((weak)) arch_crash_save_vmcoreinfo(void)
+{}
+
+unsigned long __attribute__ ((weak)) paddr_vmcoreinfo_note(void)
+{
+ return __pa((unsigned long)(char *)&vmcoreinfo_note);
+}
+
+static int __init crash_save_vmcoreinfo_init(void)
+{
+ vmcoreinfo_append_str("OSRELEASE=%s\n", UTS_RELEASE);
+ vmcoreinfo_append_str("PAGESIZE=%d\n", PAGE_SIZE);
+
+ SYMBOL(init_uts_ns);
+ SYMBOL(node_online_map);
+ SYMBOL(swapper_pg_dir);
+ SYMBOL(_stext);
+
+#ifndef CONFIG_NEED_MULTIPLE_NODES
+ SYMBOL(mem_map);
+ SYMBOL(contig_page_data);
+#endif
+#ifdef CONFIG_SPARSEMEM
+ SYMBOL(mem_section);
+ LENGTH(mem_section, NR_SECTION_ROOTS);
+ SIZE(mem_section);
+ OFFSET(mem_section, section_mem_map);
+#endif
+ SIZE(page);
+ SIZE(pglist_data);
+ SIZE(zone);
+ SIZE(free_area);
+ SIZE(list_head);
+ OFFSET(page, flags);
+ OFFSET(page, _count);
+ OFFSET(page, mapping);
+ OFFSET(page, lru);
+ OFFSET(pglist_data, node_zones);
+ OFFSET(pglist_data, nr_zones);
+#ifdef CONFIG_FLAT_NODE_MEM_MAP
+ OFFSET(pglist_data, node_mem_map);
+#endif
+ OFFSET(pglist_data, node_start_pfn);
+ OFFSET(pglist_data, node_spanned_pages);
+ OFFSET(pglist_data, node_id);
+ OFFSET(zone, free_area);
+ OFFSET(zone, vm_stat);
+ OFFSET(zone, spanned_pages);
+ OFFSET(free_area, free_list);
+ OFFSET(list_head, next);
+ OFFSET(list_head, prev);
+ LENGTH(zone.free_area, MAX_ORDER);
+
+ arch_crash_save_vmcoreinfo();
+
+ return 0;
+}
+
+module_init(crash_save_vmcoreinfo_init)
diff -rpuN a/kernel/ksysfs.c b/kernel/ksysfs.c
--- a/kernel/ksysfs.c 2007-08-23 00:03:30.000000000 +0900
+++ b/kernel/ksysfs.c 2007-08-23 00:47:53.000000000 +0900
@@ -60,6 +60,15 @@ static ssize_t kexec_crash_loaded_show(s
return sprintf(page, "%d\n", !!kexec_crash_image);
}
KERNEL_ATTR_RO(kexec_crash_loaded);
+
+static ssize_t vmcoreinfo_show(struct kset *kset, char *page)
+{
+ return sprintf(page, "%lx %x\n",
+ paddr_vmcoreinfo_note(),
+ vmcoreinfo_max_size);
+}
+KERNEL_ATTR_RO(vmcoreinfo);
+
#endif /* CONFIG_KEXEC */

decl_subsys(kernel, NULL, NULL);
@@ -73,6 +82,7 @@ static struct attribute * kernel_attrs[]
#ifdef CONFIG_KEXEC
&kexec_loaded_attr.attr,
&kexec_crash_loaded_attr.attr,
+ &vmcoreinfo_attr.attr,
#endif
NULL
};
_

2007-08-22 12:14:01

by Ken'ichi Ohmichi

[permalink] [raw]
Subject: [PATCH 2/3] [kexec-tools] Pass vmcoreinfo's address and size


[2/3] [kexec-tools] Pass vmcoreinfo's address and size
The patch is for kexec-tools-testing-20070330.
(http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/)
kexec command gets the address and size of the vmcoreinfo data from
/sys/kernel/vmcoreinfo, and passes them to the second kernel through
ELF header of /proc/vmcore. When the second kernel is booting, the
kernel gets them from the ELF header and creates vmcoreinfo's PT_NOTE
segment into /proc/vmcore.


Thanks
Ken'ichi Ohmichi

---
Signed-off-by: Dan Aloni <[email protected]>
Signed-off-by: Ken'ichi Ohmichi <[email protected]>

---
diff -rpuN backup/kexec-tools-testing-20070330/kexec/crashdump-elf.c kexec-tools/kexec/crashdump-elf.c
--- backup/kexec-tools-testing-20070330/kexec/crashdump-elf.c 2007-03-30 13:34:36.000000000 +0900
+++ kexec-tools/kexec/crashdump-elf.c 2007-08-03 14:45:47.000000000 +0900
@@ -36,6 +36,8 @@ int FUNC(struct kexec_info *info,
char *bufp;
long int nr_cpus = 0;
uint64_t notes_addr, notes_len;
+ uint64_t vmcoreinfo_addr, vmcoreinfo_len;
+ int has_vmcoreinfo = 0;
int (*get_note_info)(int cpu, uint64_t *addr, uint64_t *len);

if (xen_present())
@@ -47,7 +49,11 @@ int FUNC(struct kexec_info *info,
return -1;
}

- sz = sizeof(EHDR) + nr_cpus * sizeof(PHDR) + ranges * sizeof(PHDR);
+ if (get_kernel_vmcoreinfo(&vmcoreinfo_addr, &vmcoreinfo_len) == 0) {
+ has_vmcoreinfo = 1;
+ }
+
+ sz = sizeof(EHDR) + (nr_cpus + has_vmcoreinfo) * sizeof(PHDR) + ranges * sizeof(PHDR);

/*
* Certain architectures such as x86_64 and ia64 require a separate
@@ -148,6 +154,21 @@ int FUNC(struct kexec_info *info,
dfprintf_phdr(stdout, "Elf header", phdr);
}

+ if (has_vmcoreinfo) {
+ phdr = (PHDR *) bufp;
+ bufp += sizeof(PHDR);
+ phdr->p_type = PT_NOTE;
+ phdr->p_flags = 0;
+ phdr->p_offset = phdr->p_paddr = vmcoreinfo_addr;
+ phdr->p_vaddr = 0;
+ phdr->p_filesz = phdr->p_memsz = vmcoreinfo_len;
+ /* Do we need any alignment of segments? */
+ phdr->p_align = 0;
+
+ (elf->e_phnum)++;
+ dfprintf_phdr(stdout, "vmcoreinfo header", phdr);
+ }
+
/* Setup an PT_LOAD type program header for the region where
* Kernel is mapped if info->kern_size is non-zero.
*/
diff -rpuN backup/kexec-tools-testing-20070330/kexec/crashdump.c kexec-tools/kexec/crashdump.c
--- backup/kexec-tools-testing-20070330/kexec/crashdump.c 2007-03-30 13:34:36.000000000 +0900
+++ kexec-tools/kexec/crashdump.c 2007-08-03 14:45:05.000000000 +0900
@@ -108,3 +108,35 @@ int get_crash_notes_per_cpu(int cpu, uin

return 0;
}
+
+/* Returns the physical address of start of crash notes buffer for a kernel. */
+int get_kernel_vmcoreinfo(uint64_t *addr, uint64_t *len)
+{
+ char kdump_info[PATH_MAX];
+ char line[MAX_LINE];
+ int count;
+ FILE *fp;
+ unsigned long long temp, temp2;
+
+ *addr = 0;
+ *len = 0;
+
+ sprintf(kdump_info, "/sys/kernel/vmcoreinfo");
+ fp = fopen(kdump_info, "r");
+ if (!fp) {
+ die("Could not open \"%s\": %s\n", kdump_info,
+ strerror(errno));
+ return -1;
+ }
+
+ if (!fgets(line, sizeof(line), fp))
+ die("Cannot parse %s: %s\n", kdump_info, strerror(errno));
+ count = sscanf(line, "%Lx %Lx", &temp, &temp2);
+ if (count != 2)
+ die("Cannot parse %s: %s\n", kdump_info, strerror(errno));
+
+ *addr = (uint64_t) temp;
+ *len = (uint64_t) temp2;
+
+ return 0;
+}
diff -rpuN backup/kexec-tools-testing-20070330/kexec/crashdump.h kexec-tools/kexec/crashdump.h
--- backup/kexec-tools-testing-20070330/kexec/crashdump.h 2007-03-30 13:34:36.000000000 +0900
+++ kexec-tools/kexec/crashdump.h 2007-08-03 14:45:05.000000000 +0900
@@ -2,6 +2,7 @@
#define CRASHDUMP_H

extern int get_crash_notes_per_cpu(int cpu, uint64_t *addr, uint64_t *len);
+extern int get_kernel_vmcoreinfo(uint64_t *addr, uint64_t *len);

/* Need to find a better way to determine per cpu notes section size. */
#define MAX_NOTE_BYTES 1024
_

2007-08-22 12:18:08

by Ken'ichi Ohmichi

[permalink] [raw]
Subject: [PATCH 3/3] [makedumpfile] Extract vmcoreinfo from /proc/vmcore


[3/3] [makedumpfile] Extract vmcoreinfo from /proc/vmcore
The patch is for makedumpfile v1.1.6.
(https://sourceforge.net/projects/makedumpfile/)
makedumpfile command extracts the vmcoreinfo data from /proc/vmcore
and uses it for dump filtering.


Thanks
Ken'ichi Ohmichi

---
Signed-off-by: Ken'ichi Ohmichi <[email protected]>

---
diff -puN backup/v1.1.6/ia64.c makedumpfile/ia64.c
--- backup/v1.1.6/ia64.c 2007-08-13 12:01:55.000000000 +0900
+++ makedumpfile/ia64.c 2007-08-17 14:23:32.000000000 +0900
@@ -70,6 +70,10 @@ get_machdep_info_ia64()
else
info->vmalloc_start = KERNEL_VMALLOC_BASE;

+ if ((vt.mem_flags & MEMORY_PAGETABLE_4L)
+ || (vt.mem_flags & MEMORY_PAGETABLE_3L))
+ return TRUE;
+
/*
* Check the pgtable (3 Levels or 4 Levels).
*/
diff -puN backup/v1.1.6/makedumpfile.c makedumpfile/makedumpfile.c
--- backup/v1.1.6/makedumpfile.c 2007-08-13 12:01:55.000000000 +0900
+++ makedumpfile/makedumpfile.c 2007-08-17 14:26:20.000000000 +0900
@@ -608,7 +608,7 @@ open_files_for_creating_dumpfile()
if (info->flag_read_vmcoreinfo) {
if (!open_vmcoreinfo("r"))
return FALSE;
- } else if (info->dump_level > DL_EXCLUDE_ZERO) {
+ } else if (dwarf_info.vmlinux_name) {
if (!open_kernel_file())
return FALSE;
}
@@ -2053,8 +2053,17 @@ read_vmcoreinfo_basic_info()
return FALSE;
}
}
- if (get_release && page_size)
- break;
+ if (strncmp(buf, STR_CONFIG_X86_PAE,
+ strlen(STR_CONFIG_X86_PAE)) == 0)
+ vt.mem_flags |= MEMORY_X86_PAE;
+
+ if (strncmp(buf, STR_CONFIG_PGTABLE_3,
+ strlen(STR_CONFIG_PGTABLE_3)) == 0)
+ vt.mem_flags |= MEMORY_PAGETABLE_4L;
+
+ if (strncmp(buf, STR_CONFIG_PGTABLE_4,
+ strlen(STR_CONFIG_PGTABLE_4)) == 0)
+ vt.mem_flags |= MEMORY_PAGETABLE_3L;
}
info->page_size = page_size;
info->page_shift = ffs(info->page_size) - 1;
@@ -2215,6 +2224,172 @@ read_vmcoreinfo()
return TRUE;
}

+int
+get_pt_note_info(int *flag_elf64, off_t *offset, unsigned long *size)
+{
+ Elf64_Phdr phdr64;
+ Elf32_Phdr phdr32;
+ int i, phnum, num_load, elf_format;
+
+ (*offset) = 0;
+ (*size) = 0;
+
+ elf_format = check_elf_format(info->fd_memory, info->name_memory,
+ &phnum, &num_load);
+
+ if (elf_format == ELF64)
+ (*flag_elf64) = TRUE;
+ else if (elf_format == ELF32)
+ (*flag_elf64) = FALSE;
+ else {
+ return FALSE;
+ }
+ for (i = 0; i < phnum; i++) {
+ if (flag_elf64) { /* ELF64 */
+ if (!get_elf64_phdr(info->fd_memory, info->name_memory,
+ i, &phdr64)) {
+ ERRMSG("Can't find Phdr %d.\n", i);
+ return FALSE;
+ }
+ if (phdr64.p_type != PT_NOTE)
+ continue;
+
+ (*offset) = phdr64.p_offset;
+ (*size) = phdr64.p_filesz;
+ break;
+ } else { /* ELF32 */
+ if (!get_elf32_phdr(info->fd_memory, info->name_memory,
+ i, &phdr32)) {
+ ERRMSG("Can't find Phdr %d.\n", i);
+ return FALSE;
+ }
+ if (phdr32.p_type != PT_NOTE)
+ continue;
+
+ (*offset) = phdr32.p_offset;
+ (*size) = phdr32.p_filesz;
+ break;
+ }
+ }
+ if (offset == 0 || size == 0) {
+ ERRMSG("Can't find PT_NOTE Phdr.\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+int
+is_vmcoreinfo_in_vmcore(int *flag_found)
+{
+ off_t offset, off_note;
+ int flag_elf64;
+ unsigned long sz_note;
+ char buf[VMCOREINFO_NOTE_NAME_BYTES];
+ Elf64_Nhdr note64;
+ Elf32_Nhdr note32;
+
+ const off_t failed = (off_t)-1;
+
+ (*flag_found) = FALSE;
+
+ /*
+ * Get information about PT_NOTE segment.
+ */
+ if (!get_pt_note_info(&flag_elf64, &off_note, &sz_note))
+ return FALSE;
+
+ offset = off_note;
+ while (offset < off_note + sz_note) {
+ if (lseek(info->fd_memory, offset, SEEK_SET) == failed) {
+ ERRMSG("Can't seek the dump memory(%s). %s\n",
+ info->name_memory, strerror(errno));
+ return FALSE;
+ }
+ if (flag_elf64) {
+ if (read(info->fd_memory, &note64, sizeof(note64))
+ != sizeof(note64)) {
+ ERRMSG("Can't read the dump memory(%s). %s\n",
+ info->name_memory, strerror(errno));
+ return FALSE;
+ }
+ } else {
+ if (read(info->fd_memory, &note32, sizeof(note32))
+ != sizeof(note32)) {
+ ERRMSG("Can't read the dump memory(%s). %s\n",
+ info->name_memory, strerror(errno));
+ return FALSE;
+ }
+ }
+ if (read(info->fd_memory, &buf, sizeof(buf)) != sizeof(buf)) {
+ ERRMSG("Can't read the dump memory(%s). %s\n",
+ info->name_memory, strerror(errno));
+ return FALSE;
+ }
+ if (strncmp(VMCOREINFO_NOTE_NAME, buf,
+ VMCOREINFO_NOTE_NAME_BYTES)) {
+ offset += sizeof(Elf64_Nhdr)
+ + ((note64.n_namesz + 3) & ~3)
+ + ((note64.n_descsz + 3) & ~3);
+ continue;
+ }
+ if (flag_elf64) {
+ info->offset_vmcoreinfo = offset + (sizeof(note64)
+ + ((note64.n_namesz + 3) & ~3));
+ info->size_vmcoreinfo = note64.n_descsz;
+ } else {
+ info->offset_vmcoreinfo = offset + (sizeof(note64)
+ + ((note32.n_namesz + 3) & ~3));
+ info->size_vmcoreinfo = note32.n_descsz;
+ }
+ (*flag_found) = TRUE;
+ break;
+ }
+ return TRUE;
+}
+
+/*
+ * Extract vmcoreinfo from /proc/vmcore and output it to /tmp/vmcoreinfo.tmp.
+ */
+int
+copy_vmcoreinfo()
+{
+ int fd;
+ char buf[VMCOREINFO_BYTES];
+ const off_t failed = (off_t)-1;
+
+ if (!info->offset_vmcoreinfo || !info->size_vmcoreinfo)
+ return FALSE;
+
+ if ((fd = mkstemp(info->name_vmcoreinfo)) < 0) {
+ ERRMSG("Can't open the vmcoreinfo file(%s). %s\n",
+ info->name_vmcoreinfo, strerror(errno));
+ return FALSE;
+ }
+ if (lseek(info->fd_memory, info->offset_vmcoreinfo, SEEK_SET)
+ == failed) {
+ ERRMSG("Can't seek the dump memory(%s). %s\n",
+ info->name_memory, strerror(errno));
+ return FALSE;
+ }
+ if (read(info->fd_memory, &buf, info->size_vmcoreinfo)
+ != info->size_vmcoreinfo) {
+ ERRMSG("Can't read the dump memory(%s). %s\n",
+ info->name_memory, strerror(errno));
+ return FALSE;
+ }
+ if (write(fd, &buf, info->size_vmcoreinfo) != info->size_vmcoreinfo) {
+ ERRMSG("Can't write the vmcoreinfo file(%s). %s\n",
+ info->name_vmcoreinfo, strerror(errno));
+ return FALSE;
+ }
+ if (close(fd) < 0) {
+ ERRMSG("Can't close the vmcoreinfo file(%s). %s\n",
+ info->name_vmcoreinfo, strerror(errno));
+ return FALSE;
+ }
+ return TRUE;
+}
+
/*
* Get the number of online nodes.
*/
@@ -2892,12 +3067,20 @@ get_mem_map()
int
initial()
{
+ int vmcoreinfo_in_vmcore = FALSE;
+
if (!get_elf_info())
return FALSE;

if (!get_phys_base())
return FALSE;

+ if (info->dump_level <= DL_EXCLUDE_ZERO) {
+ if (!get_mem_map_without_mm())
+ return FALSE;
+ else
+ return TRUE;
+ }
/*
* Get the debug information for analysis from the vmcoreinfo file
*/
@@ -2907,22 +3090,53 @@ initial()
/*
* Get the debug information for analysis from the kernel file
*/
- } else {
- if (info->dump_level <= DL_EXCLUDE_ZERO) {
- if (!get_mem_map_without_mm())
- return FALSE;
- else
- return TRUE;
- } else {
- if (!get_symbol_info())
- return FALSE;
- }
+ } else if (info->flag_vmlinux) {
+ if (!get_symbol_info())
+ return FALSE;
+
if (!get_structure_info())
return FALSE;

if (!get_srcfile_info())
return FALSE;
+ /*
+ * Get the debug information for analysis from /proc/vmcore
+ */
+ } else {
+ /*
+ * Check weather /proc/vmcore contains vmcoreinfo,
+ * and get both the offset and the size.
+ */
+ if (!is_vmcoreinfo_in_vmcore(&vmcoreinfo_in_vmcore))
+ return FALSE;
+
+ if (!vmcoreinfo_in_vmcore) {
+ MSG("%s doesn't contain vmcoreinfo.\n", info->name_memory);
+ MSG("'-x' or '-i' must be specified.\n");
+ return FALSE;
+ }
+ /*
+ * Copy vmcoreinfo to /tmp/vmcoreinfoXXXXXX.
+ */
+ if ((info->name_vmcoreinfo
+ = malloc(sizeof(FILENAME_VMCOREINFO))) == NULL) {
+ ERRMSG("Can't allocate memory for the filename. %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+ strcpy(info->name_vmcoreinfo, FILENAME_VMCOREINFO);
+ if (!copy_vmcoreinfo())
+ return FALSE;
+ /*
+ * Read vmcoreinfo from /tmp/vmcoreinfoXXXXXX.
+ */
+ if (!open_vmcoreinfo("r"))
+ return FALSE;
+ if (!read_vmcoreinfo())
+ return FALSE;
+ unlink(info->name_vmcoreinfo);
}
+
if (!get_machdep_info())
return FALSE;

diff -puN backup/v1.1.6/makedumpfile.h makedumpfile/makedumpfile.h
--- backup/v1.1.6/makedumpfile.h 2007-08-13 12:01:55.000000000 +0900
+++ makedumpfile/makedumpfile.h 2007-08-17 14:24:57.000000000 +0900
@@ -70,6 +70,7 @@ enum {
*/
#define MEMORY_PAGETABLE_4L (1 << 0)
#define MEMORY_PAGETABLE_3L (1 << 1)
+#define MEMORY_X86_PAE (1 << 2)

/*
* Type of address
@@ -366,15 +367,26 @@ do { \
#define LATEST_VERSION (0x02060016) /* linux-2.6.22 */

/*
+ * vmcoreinfo in /proc/vmcore
+ */
+#define VMCOREINFO_BYTES (4096)
+#define VMCOREINFO_NOTE_NAME "VMCOREINFO"
+#define VMCOREINFO_NOTE_NAME_BYTES (sizeof(VMCOREINFO_NOTE_NAME))
+#define FILENAME_VMCOREINFO "/tmp/vmcoreinfoXXXXXX"
+
+/*
* field name of vmcoreinfo file
*/
-#define STR_OSRELEASE "OSRELEASE="
-#define STR_PAGESIZE "PAGESIZE="
-#define STR_SYMBOL(X) "SYMBOL("X")="
-#define STR_SIZE(X) "SIZE("X")="
-#define STR_OFFSET(X) "OFFSET("X")="
-#define STR_LENGTH(X) "LENGTH("X")="
-#define STR_SRCFILE(X) "SRCFILE("X")="
+#define STR_OSRELEASE "OSRELEASE="
+#define STR_PAGESIZE "PAGESIZE="
+#define STR_SYMBOL(X) "SYMBOL("X")="
+#define STR_SIZE(X) "SIZE("X")="
+#define STR_OFFSET(X) "OFFSET("X")="
+#define STR_LENGTH(X) "LENGTH("X")="
+#define STR_SRCFILE(X) "SRCFILE("X")="
+#define STR_CONFIG_X86_PAE "CONFIG_X86_PAE=y"
+#define STR_CONFIG_PGTABLE_4 "CONFIG_PGTABLE_4=y"
+#define STR_CONFIG_PGTABLE_3 "CONFIG_PGTABLE_3=y"

/*
* common value
@@ -664,6 +676,12 @@ struct DumpInfo {
char release[STRLEN_OSRELEASE];

/*
+ * vmcoreinfo in dump memory image info:
+ */
+ off_t offset_vmcoreinfo;
+ unsigned long size_vmcoreinfo;
+
+ /*
* for Xen extraction
*/
unsigned long xen_heap_start; /* start mfn of xen heap area */
diff -puN backup/v1.1.6/x86.c makedumpfile/x86.c
--- backup/v1.1.6/x86.c 2007-08-13 12:01:55.000000000 +0900
+++ makedumpfile/x86.c 2007-08-17 14:23:32.000000000 +0900
@@ -21,10 +21,11 @@ int
get_machdep_info_x86()
{
/* PAE */
- if ((SYMBOL(pkmap_count) != NOT_FOUND_SYMBOL)
- && (SYMBOL(pkmap_count_next) != NOT_FOUND_SYMBOL)
- && ((SYMBOL(pkmap_count_next)-SYMBOL(pkmap_count))/sizeof(int))
- == 512) {
+ if ((vt.mem_flags & MEMORY_X86_PAE)
+ || ((SYMBOL(pkmap_count) != NOT_FOUND_SYMBOL)
+ && (SYMBOL(pkmap_count_next) != NOT_FOUND_SYMBOL)
+ && ((SYMBOL(pkmap_count_next)-SYMBOL(pkmap_count))/sizeof(int))
+ == 512)) {
DEBUG_MSG("\n");
DEBUG_MSG("PAE : ON\n");
info->section_size_bits = _SECTION_SIZE_BITS_PAE;
_

2007-08-22 22:41:20

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 0/3] vmcoreinfo support for dump filtering

On Wed, 22 Aug 2007 21:08:38 +0900
"Ken'ichi Ohmichi" <[email protected]> wrote:

>
> Hi Andrew,
>
> This patch set frees the restriction that makedumpfile users should
> install a vmlinux file (including the debugging information) into
> each system.
>
> makedumpfile command is the dump filtering feature for kdump.
> It creates a small dumpfile by filtering unnecessary pages for the
> analysis. To distinguish unnecessary pages, it needs a vmlinux file
> including the debugging information. These days, the debugging package
> becomes a huge file, and it is hard to install it into each system.
>
> To solve the problem, kdump developers discussed it at lkml and kexec-ml.
> As the result, we reached the conclusion that necessary information
> for dump filtering (called "vmcoreinfo") should be embedded into the
> first kernel file and it should be accessed through /proc/vmcore
> during the second kernel.
> (http://www.uwsg.iu.edu/hypermail/linux/kernel/0707.0/1806.html)
>
> Dan Aloni created the patch set for the above implementation.
> (http://www.uwsg.iu.edu/hypermail/linux/kernel/0707.1/1053.html)
>
> And I updated it for multi architectures and memory models.
> (http://lists.infradead.org/pipermail/kexec/2007-August/000479.html)

so... will this permit us to generate kdump files whcih don't have any
pagecache or anonymous memory in them?


> +void vmcoreinfo_append_str(const char *fmt, ...);

This should have suitable __attribute__s so that the compiler can check its
use. See many examples in include/linux/kernel.h, around line 120.

> +/* vmcoreinfo stuff */
> +unsigned char vmcoreinfo_data[VMCOREINFO_BYTES];
> +u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
> +unsigned int vmcoreinfo_size = 0;

Please always run scripts/checkpatch.pl against your diffs.

> +unsigned int vmcoreinfo_max_size = sizeof(vmcoreinfo_data);

unsigned int = size_t? Perhaps vmcoreinfo_max_size should have size_t
type?

> +void crash_save_vmcoreinfo(void)
> +{
> + u32 *buf;
> +
> + if (!vmcoreinfo_size)
> + return;
> +
> + vmcoreinfo_append_str("CRASHTIME=%d", xtime.tv_sec);

open-coded access to xtime probably isn't appropriate here. Consider using
get_seconds(). That might be more accurate on tickless kernels, too.


> + buf = (u32 *)vmcoreinfo_note;
> +
> + buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
> + vmcoreinfo_size);
> +
> + final_note(buf);
> +}
> +
> +}
> +
> +static int __init crash_save_vmcoreinfo_init(void)
> +{
> + vmcoreinfo_append_str("OSRELEASE=%s\n", UTS_RELEASE);
> + vmcoreinfo_append_str("PAGESIZE=%d\n", PAGE_SIZE);

I expect the virtualisation guys would be bothered by an open-coded access
to UTS_RELEASE. I guess it doesn't matter much here, but perhaps it'd be
setting a better example to use init_uts_ns.name.release?


2007-08-23 05:47:19

by Vivek Goyal

[permalink] [raw]
Subject: Re: [PATCH 0/3] vmcoreinfo support for dump filtering

On Wed, Aug 22, 2007 at 09:08:38PM +0900, Ken'ichi Ohmichi wrote:
>
> Hi Andrew,
>
> This patch set frees the restriction that makedumpfile users should
> install a vmlinux file (including the debugging information) into
> each system.
>
> makedumpfile command is the dump filtering feature for kdump.
> It creates a small dumpfile by filtering unnecessary pages for the
> analysis. To distinguish unnecessary pages, it needs a vmlinux file
> including the debugging information. These days, the debugging package
> becomes a huge file, and it is hard to install it into each system.
>
> To solve the problem, kdump developers discussed it at lkml and kexec-ml.
> As the result, we reached the conclusion that necessary information
> for dump filtering (called "vmcoreinfo") should be embedded into the
> first kernel file and it should be accessed through /proc/vmcore
> during the second kernel.
> (http://www.uwsg.iu.edu/hypermail/linux/kernel/0707.0/1806.html)
>
> Dan Aloni created the patch set for the above implementation.
> (http://www.uwsg.iu.edu/hypermail/linux/kernel/0707.1/1053.html)
>
> And I updated it for multi architectures and memory models.
> (http://lists.infradead.org/pipermail/kexec/2007-August/000479.html)
>
>
> PATCH SET:
> [1/3] [linux] Add vmcoreinfo
> The patch is for linux-2.6.22.
> The patch adds the vmcoreinfo data. Its address and size are output
> to /sys/kernel/vmcoreinfo.
>

Looks good to me.

Thanks
Vivek

2007-08-23 10:23:41

by Ken'ichi Ohmichi

[permalink] [raw]
Subject: Re: [PATCH 0/3] vmcoreinfo support for dump filtering


Hi Andrew,

Thank you for the comments, I updated the patch.

2007/08/22 15:40:36 -0700, Andrew Morton <[email protected]> wrote:
>> This patch set frees the restriction that makedumpfile users should
>> install a vmlinux file (including the debugging information) into
>> each system.
>>
>> makedumpfile command is the dump filtering feature for kdump.
>> It creates a small dumpfile by filtering unnecessary pages for the
>> analysis. To distinguish unnecessary pages, it needs a vmlinux file
>> including the debugging information. These days, the debugging package
>> becomes a huge file, and it is hard to install it into each system.
>>
>> To solve the problem, kdump developers discussed it at lkml and kexec-ml.
>> As the result, we reached the conclusion that necessary information
>> for dump filtering (called "vmcoreinfo") should be embedded into the
>> first kernel file and it should be accessed through /proc/vmcore
>> during the second kernel.
>> (http://www.uwsg.iu.edu/hypermail/linux/kernel/0707.0/1806.html)
>>
>> Dan Aloni created the patch set for the above implementation.
>> (http://www.uwsg.iu.edu/hypermail/linux/kernel/0707.1/1053.html)
>>
>> And I updated it for multi architectures and memory models.
>> (http://lists.infradead.org/pipermail/kexec/2007-August/000479.html)
>
>so... will this permit us to generate kdump files whcih don't have any
>pagecache or anonymous memory in them?

Yes, makedumpfile can do it. Moreover it can generate kdump files which
don't have free pages or zero-filled pages too.


>> +void vmcoreinfo_append_str(const char *fmt, ...);
>
>This should have suitable __attribute__s so that the compiler can check its
>use. See many examples in include/linux/kernel.h, around line 120.

OK. I added __attribute__ ((format (printf, 1, 2))) to the defination
for vmcoreinfo_append_str(), and I fixed the coding problems related
to this change.


>> +/* vmcoreinfo stuff */
>> +unsigned char vmcoreinfo_data[VMCOREINFO_BYTES];
>> +u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
>> +unsigned int vmcoreinfo_size = 0;
>
>Please always run scripts/checkpatch.pl against your diffs.

OK, I confirmed that the attached patch does not have any problems
by scripts/checkpatch.pl.


>> +unsigned int vmcoreinfo_max_size = sizeof(vmcoreinfo_data);
>
>unsigned int = size_t? Perhaps vmcoreinfo_max_size should have size_t
>type?

You are right. In the attached patch, both vmcoreinfo_max_size and
vmcoreinfo_size are defined as size_t.


>> +void crash_save_vmcoreinfo(void)
>> +{
>> + u32 *buf;
>> +
>> + if (!vmcoreinfo_size)
>> + return;
>> +
>> + vmcoreinfo_append_str("CRASHTIME=%d", xtime.tv_sec);
>
>open-coded access to xtime probably isn't appropriate here. Consider using
>get_seconds(). That might be more accurate on tickless kernels, too.

OK, I fixed it as you said.


>> +static int __init crash_save_vmcoreinfo_init(void)
>> +{
>> + vmcoreinfo_append_str("OSRELEASE=%s\n", UTS_RELEASE);
>> + vmcoreinfo_append_str("PAGESIZE=%d\n", PAGE_SIZE);
>
>I expect the virtualisation guys would be bothered by an open-coded access
>to UTS_RELEASE. I guess it doesn't matter much here, but perhaps it'd be
>setting a better example to use init_uts_ns.name.release?

OK, I fixed it as you said.


Thanks
Ken'ichi Ohmichi

---
Signed-off-by: Dan Aloni <[email protected]>
Signed-off-by: Ken'ichi Ohmichi <[email protected]>
Signed-off-by: Bernhard Walle <[email protected]>
Signed-off-by: Daisuke Nishimura <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>

---
diff -rpuN a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c
--- a/arch/i386/kernel/machine_kexec.c 2007-08-23 16:31:11.000000000 +0900
+++ b/arch/i386/kernel/machine_kexec.c 2007-08-23 16:32:01.000000000 +0900
@@ -10,6 +10,7 @@
#include <linux/kexec.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/numa.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
@@ -169,3 +170,15 @@ static int __init parse_crashkernel(char
return 0;
}
early_param("crashkernel", parse_crashkernel);
+
+void arch_crash_save_vmcoreinfo(void)
+{
+#ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
+ SYMBOL(node_data);
+ LENGTH(node_data, MAX_NUMNODES);
+#endif
+#ifdef CONFIG_X86_PAE
+ CONFIG(X86_PAE);
+#endif
+}
+
diff -rpuN a/arch/ia64/kernel/machine_kexec.c b/arch/ia64/kernel/machine_kexec.c
--- a/arch/ia64/kernel/machine_kexec.c 2007-08-23 16:31:14.000000000 +0900
+++ b/arch/ia64/kernel/machine_kexec.c 2007-08-23 16:32:01.000000000 +0900
@@ -15,10 +15,13 @@
#include <linux/cpu.h>
#include <linux/irq.h>
#include <linux/efi.h>
+#include <linux/numa.h>
+#include <linux/mmzone.h>
#include <asm/mmu_context.h>
#include <asm/setup.h>
#include <asm/delay.h>
#include <asm/meminit.h>
+#include <asm/processor.h>

typedef NORET_TYPE void (*relocate_new_kernel_t)(
unsigned long indirection_page,
@@ -125,3 +128,28 @@ void machine_kexec(struct kimage *image)
unw_init_running(ia64_machine_kexec, image);
for(;;);
}
+
+void arch_crash_save_vmcoreinfo(void)
+{
+#ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
+ SYMBOL(pgdat_list);
+ LENGTH(pgdat_list, MAX_NUMNODES);
+
+ SYMBOL(node_memblk);
+ LENGTH(node_memblk, NR_NODE_MEMBLKS);
+ SIZE(node_memblk_s);
+ OFFSET(node_memblk_s, start_paddr);
+ OFFSET(node_memblk_s, size);
+#endif
+#ifdef CONFIG_PGTABLE_3
+ CONFIG(PGTABLE_3);
+#elif CONFIG_PGTABLE_4
+ CONFIG(PGTABLE_4);
+#endif
+}
+
+unsigned long paddr_vmcoreinfo_note(void)
+{
+ return ia64_tpa((unsigned long)(char *)&vmcoreinfo_note);
+}
+
diff -rpuN a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
--- a/arch/ia64/mm/discontig.c 2007-08-23 16:31:14.000000000 +0900
+++ b/arch/ia64/mm/discontig.c 2007-08-23 16:32:01.000000000 +0900
@@ -47,7 +47,7 @@ struct early_node_data {
static struct early_node_data mem_data[MAX_NUMNODES] __initdata;
static nodemask_t memory_less_mask __initdata;

-static pg_data_t *pgdat_list[MAX_NUMNODES];
+pg_data_t *pgdat_list[MAX_NUMNODES];

/*
* To prevent cache aliasing effects, align per-node structures so that they
diff -rpuN a/arch/x86_64/kernel/machine_kexec.c b/arch/x86_64/kernel/machine_kexec.c
--- a/arch/x86_64/kernel/machine_kexec.c 2007-08-23 16:31:11.000000000 +0900
+++ b/arch/x86_64/kernel/machine_kexec.c 2007-08-23 16:32:01.000000000 +0900
@@ -10,6 +10,7 @@
#include <linux/kexec.h>
#include <linux/string.h>
#include <linux/reboot.h>
+#include <linux/numa.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <asm/mmu_context.h>
@@ -257,3 +258,11 @@ static int __init setup_crashkernel(char
}
early_param("crashkernel", setup_crashkernel);

+void arch_crash_save_vmcoreinfo(void)
+{
+#ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
+ SYMBOL(node_data);
+ LENGTH(node_data, MAX_NUMNODES);
+#endif
+}
+
diff -rpuN a/include/asm-ia64/numa.h b/include/asm-ia64/numa.h
--- a/include/asm-ia64/numa.h 2007-08-23 16:31:05.000000000 +0900
+++ b/include/asm-ia64/numa.h 2007-08-23 16:32:01.000000000 +0900
@@ -24,6 +24,7 @@

extern u16 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
extern cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
+extern pg_data_t *pgdat_list[MAX_NUMNODES];

/* Stuff below this line could be architecture independent */

diff -rpuN a/include/linux/kexec.h b/include/linux/kexec.h
--- a/include/linux/kexec.h 2007-08-23 16:31:05.000000000 +0900
+++ b/include/linux/kexec.h 2007-08-23 16:29:26.000000000 +0900
@@ -121,6 +121,25 @@ extern struct page *kimage_alloc_control
extern void crash_kexec(struct pt_regs *);
int kexec_should_crash(struct task_struct *);
void crash_save_cpu(struct pt_regs *regs, int cpu);
+void crash_save_vmcoreinfo(void);
+void arch_crash_save_vmcoreinfo(void);
+void vmcoreinfo_append_str(const char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+unsigned long paddr_vmcoreinfo_note(void);
+
+#define SYMBOL(name) \
+ vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name)
+#define SIZE(name) \
+ vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
+ (unsigned long)sizeof(struct name))
+#define OFFSET(name, field) \
+ vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
+ (unsigned long)&(((struct name *)0)->field))
+#define LENGTH(name, value) \
+ vmcoreinfo_append_str("LENGTH(%s)=%lu\n", #name, (unsigned long)value)
+#define CONFIG(name) \
+ vmcoreinfo_append_str("CONFIG_%s=y\n", #name)
+
extern struct kimage *kexec_image;
extern struct kimage *kexec_crash_image;

@@ -148,11 +167,20 @@ extern struct kimage *kexec_crash_image;

#define KEXEC_FLAGS (KEXEC_ON_CRASH) /* List of defined/legal kexec flags */

+#define VMCOREINFO_BYTES (4096)
+#define VMCOREINFO_NOTE_NAME "VMCOREINFO"
+#define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4)
+#define VMCOREINFO_NOTE_SIZE (KEXEC_NOTE_HEAD_BYTES*2 + VMCOREINFO_BYTES \
+ + VMCOREINFO_NOTE_NAME_BYTES)
+
/* Location of a reserved region to hold the crash kernel.
*/
extern struct resource crashk_res;
typedef u32 note_buf_t[KEXEC_NOTE_BYTES/4];
extern note_buf_t *crash_notes;
+extern u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
+extern size_t vmcoreinfo_size;
+extern size_t vmcoreinfo_max_size;


#else /* !CONFIG_KEXEC */
diff -rpuN a/kernel/kexec.c b/kernel/kexec.c
--- a/kernel/kexec.c 2007-08-23 16:31:06.000000000 +0900
+++ b/kernel/kexec.c 2007-08-23 16:32:01.000000000 +0900
@@ -22,16 +22,26 @@
#include <linux/hardirq.h>
#include <linux/elf.h>
#include <linux/elfcore.h>
+#include <linux/utsrelease.h>
+#include <linux/utsname.h>
+#include <linux/numa.h>

#include <asm/page.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/semaphore.h>
+#include <asm/sections.h>

/* Per cpu memory for storing cpu states in case of system crash. */
note_buf_t* crash_notes;

+/* vmcoreinfo stuff */
+unsigned char vmcoreinfo_data[VMCOREINFO_BYTES];
+u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
+size_t vmcoreinfo_size = 0;
+size_t vmcoreinfo_max_size = sizeof(vmcoreinfo_data);
+
/* Location of the reserved area for the crash kernel */
struct resource crashk_res = {
.name = "Crash kernel",
@@ -1061,6 +1071,7 @@ void crash_kexec(struct pt_regs *regs)
if (kexec_crash_image) {
struct pt_regs fixed_regs;
crash_setup_regs(&fixed_regs, regs);
+ crash_save_vmcoreinfo();
machine_crash_shutdown(&fixed_regs);
machine_kexec(kexec_crash_image);
}
@@ -1135,3 +1146,102 @@ static int __init crash_notes_memory_ini
return 0;
}
module_init(crash_notes_memory_init)
+
+void crash_save_vmcoreinfo(void)
+{
+ u32 *buf;
+
+ if (!vmcoreinfo_size)
+ return;
+
+ vmcoreinfo_append_str("CRASHTIME=%ld", get_seconds());
+
+ buf = (u32 *)vmcoreinfo_note;
+
+ buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
+ vmcoreinfo_size);
+
+ final_note(buf);
+}
+
+void vmcoreinfo_append_str(const char *fmt, ...)
+{
+ va_list args;
+ char buf[0x50];
+ int r;
+
+ va_start(args, fmt);
+ r = vsnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+
+ if (r + vmcoreinfo_size > vmcoreinfo_max_size)
+ r = vmcoreinfo_max_size - vmcoreinfo_size;
+
+ memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r);
+
+ vmcoreinfo_size += r;
+}
+
+/*
+ * provide an empty default implementation here -- architecture
+ * code may override this
+ */
+void __attribute__ ((weak)) arch_crash_save_vmcoreinfo(void)
+{}
+
+unsigned long __attribute__ ((weak)) paddr_vmcoreinfo_note(void)
+{
+ return __pa((unsigned long)(char *)&vmcoreinfo_note);
+}
+
+static int __init crash_save_vmcoreinfo_init(void)
+{
+ vmcoreinfo_append_str("OSRELEASE=%s\n", init_uts_ns.name.release);
+ vmcoreinfo_append_str("PAGESIZE=%ld\n", PAGE_SIZE);
+
+ SYMBOL(init_uts_ns);
+ SYMBOL(node_online_map);
+ SYMBOL(swapper_pg_dir);
+ SYMBOL(_stext);
+
+#ifndef CONFIG_NEED_MULTIPLE_NODES
+ SYMBOL(mem_map);
+ SYMBOL(contig_page_data);
+#endif
+#ifdef CONFIG_SPARSEMEM
+ SYMBOL(mem_section);
+ LENGTH(mem_section, NR_SECTION_ROOTS);
+ SIZE(mem_section);
+ OFFSET(mem_section, section_mem_map);
+#endif
+ SIZE(page);
+ SIZE(pglist_data);
+ SIZE(zone);
+ SIZE(free_area);
+ SIZE(list_head);
+ OFFSET(page, flags);
+ OFFSET(page, _count);
+ OFFSET(page, mapping);
+ OFFSET(page, lru);
+ OFFSET(pglist_data, node_zones);
+ OFFSET(pglist_data, nr_zones);
+#ifdef CONFIG_FLAT_NODE_MEM_MAP
+ OFFSET(pglist_data, node_mem_map);
+#endif
+ OFFSET(pglist_data, node_start_pfn);
+ OFFSET(pglist_data, node_spanned_pages);
+ OFFSET(pglist_data, node_id);
+ OFFSET(zone, free_area);
+ OFFSET(zone, vm_stat);
+ OFFSET(zone, spanned_pages);
+ OFFSET(free_area, free_list);
+ OFFSET(list_head, next);
+ OFFSET(list_head, prev);
+ LENGTH(zone.free_area, MAX_ORDER);
+
+ arch_crash_save_vmcoreinfo();
+
+ return 0;
+}
+
+module_init(crash_save_vmcoreinfo_init)
diff -rpuN a/kernel/ksysfs.c b/kernel/ksysfs.c
--- a/kernel/ksysfs.c 2007-08-23 16:31:06.000000000 +0900
+++ b/kernel/ksysfs.c 2007-08-23 16:32:01.000000000 +0900
@@ -60,6 +60,15 @@ static ssize_t kexec_crash_loaded_show(s
return sprintf(page, "%d\n", !!kexec_crash_image);
}
KERNEL_ATTR_RO(kexec_crash_loaded);
+
+static ssize_t vmcoreinfo_show(struct kset *kset, char *page)
+{
+ return sprintf(page, "%lx %x\n",
+ paddr_vmcoreinfo_note(),
+ (unsigned int)vmcoreinfo_max_size);
+}
+KERNEL_ATTR_RO(vmcoreinfo);
+
#endif /* CONFIG_KEXEC */

decl_subsys(kernel, NULL, NULL);
@@ -73,6 +82,7 @@ static struct attribute * kernel_attrs[]
#ifdef CONFIG_KEXEC
&kexec_loaded_attr.attr,
&kexec_crash_loaded_attr.attr,
+ &vmcoreinfo_attr.attr,
#endif
NULL
};
_

2007-09-03 08:17:55

by Ken'ichi Ohmichi

[permalink] [raw]
Subject: Re: [PATCH 0/3] vmcoreinfo support for dump filtering


Hi,

2007/08/22 21:08:38 +0900, Ken'ichi Ohmichi <[email protected]> wrote:
>
>Hi Andrew,
>
>This patch set frees the restriction that makedumpfile users should
>install a vmlinux file (including the debugging information) into
>each system.
>
>makedumpfile command is the dump filtering feature for kdump.
>It creates a small dumpfile by filtering unnecessary pages for the
>analysis. To distinguish unnecessary pages, it needs a vmlinux file
>including the debugging information. These days, the debugging package
>becomes a huge file, and it is hard to install it into each system.
>
>To solve the problem, kdump developers discussed it at lkml and kexec-ml.
>As the result, we reached the conclusion that necessary information
>for dump filtering (called "vmcoreinfo") should be embedded into the
>first kernel file and it should be accessed through /proc/vmcore
>during the second kernel.
>(http://www.uwsg.iu.edu/hypermail/linux/kernel/0707.0/1806.html)
>
>Dan Aloni created the patch set for the above implementation.
>(http://www.uwsg.iu.edu/hypermail/linux/kernel/0707.1/1053.html)
>
>And I updated it for multi architectures and memory models.
>(http://lists.infradead.org/pipermail/kexec/2007-August/000479.html)
>
>
>PATCH SET:
>[1/3] [linux] Add vmcoreinfo
> The patch is for linux-2.6.22.
> The patch adds the vmcoreinfo data. Its address and size are output
> to /sys/kernel/vmcoreinfo.

The patch for linux (add-vmcoreinfo.patch) is included in 2.6.23-rc4-mm1.
http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.23-rc4/2.6.23-rc4-mm1/announce.txt

Thank you for your cooperation.


>[2/3] [kexec-tools] Pass vmcoreinfo's address and size
> The patch is for kexec-tools-testing-20070330.
> (http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/)
> kexec command gets the address and size of the vmcoreinfo data from
> /sys/kernel/vmcoreinfo, and passes them to the second kernel through
> ELF header of /proc/vmcore. When the second kernel is booting, the
> kernel gets them from the ELF header and creates vmcoreinfo's PT_NOTE
> segment into /proc/vmcore.

Horms, could you please merge the above patch ?


>[3/3] [makedumpfile] Extract vmcoreinfo from /proc/vmcore
> The patch is for makedumpfile v1.1.6.
> (https://sourceforge.net/projects/makedumpfile/)
> makedumpfile command extracts the vmcoreinfo data from /proc/vmcore
> and uses it for dump filtering.

I will release the next makedumpfile with the above patch.


Thanks
Ken'ichi Ohmichi

2007-10-17 02:33:20

by Simon Horman

[permalink] [raw]
Subject: Re: [PATCH 2/3] [kexec-tools] Pass vmcoreinfo's address and size

On Wed, Aug 22, 2007 at 09:13:39PM +0900, Ken'ichi Ohmichi wrote:
>
> [2/3] [kexec-tools] Pass vmcoreinfo's address and size
> The patch is for kexec-tools-testing-20070330.
> (http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/)
> kexec command gets the address and size of the vmcoreinfo data from
> /sys/kernel/vmcoreinfo, and passes them to the second kernel through
> ELF header of /proc/vmcore. When the second kernel is booting, the
> kernel gets them from the ELF header and creates vmcoreinfo's PT_NOTE
> segment into /proc/vmcore.

Sorry for the long delay, I completely missed this patch.

The kexec-tools change seems ok to me. What is the status of
the kernel portion of the change? Do you still want the
kexec-tools portion applied?

>
> Thanks
> Ken'ichi Ohmichi
>
> ---
> Signed-off-by: Dan Aloni <[email protected]>
> Signed-off-by: Ken'ichi Ohmichi <[email protected]>
>
> ---
> diff -rpuN backup/kexec-tools-testing-20070330/kexec/crashdump-elf.c kexec-tools/kexec/crashdump-elf.c
> --- backup/kexec-tools-testing-20070330/kexec/crashdump-elf.c 2007-03-30 13:34:36.000000000 +0900
> +++ kexec-tools/kexec/crashdump-elf.c 2007-08-03 14:45:47.000000000 +0900
> @@ -36,6 +36,8 @@ int FUNC(struct kexec_info *info,
> char *bufp;
> long int nr_cpus = 0;
> uint64_t notes_addr, notes_len;
> + uint64_t vmcoreinfo_addr, vmcoreinfo_len;
> + int has_vmcoreinfo = 0;
> int (*get_note_info)(int cpu, uint64_t *addr, uint64_t *len);
>
> if (xen_present())
> @@ -47,7 +49,11 @@ int FUNC(struct kexec_info *info,
> return -1;
> }
>
> - sz = sizeof(EHDR) + nr_cpus * sizeof(PHDR) + ranges * sizeof(PHDR);
> + if (get_kernel_vmcoreinfo(&vmcoreinfo_addr, &vmcoreinfo_len) == 0) {
> + has_vmcoreinfo = 1;
> + }
> +
> + sz = sizeof(EHDR) + (nr_cpus + has_vmcoreinfo) * sizeof(PHDR) + ranges * sizeof(PHDR);
>
> /*
> * Certain architectures such as x86_64 and ia64 require a separate
> @@ -148,6 +154,21 @@ int FUNC(struct kexec_info *info,
> dfprintf_phdr(stdout, "Elf header", phdr);
> }
>
> + if (has_vmcoreinfo) {
> + phdr = (PHDR *) bufp;
> + bufp += sizeof(PHDR);
> + phdr->p_type = PT_NOTE;
> + phdr->p_flags = 0;
> + phdr->p_offset = phdr->p_paddr = vmcoreinfo_addr;
> + phdr->p_vaddr = 0;
> + phdr->p_filesz = phdr->p_memsz = vmcoreinfo_len;
> + /* Do we need any alignment of segments? */
> + phdr->p_align = 0;
> +
> + (elf->e_phnum)++;
> + dfprintf_phdr(stdout, "vmcoreinfo header", phdr);
> + }
> +
> /* Setup an PT_LOAD type program header for the region where
> * Kernel is mapped if info->kern_size is non-zero.
> */
> diff -rpuN backup/kexec-tools-testing-20070330/kexec/crashdump.c kexec-tools/kexec/crashdump.c
> --- backup/kexec-tools-testing-20070330/kexec/crashdump.c 2007-03-30 13:34:36.000000000 +0900
> +++ kexec-tools/kexec/crashdump.c 2007-08-03 14:45:05.000000000 +0900
> @@ -108,3 +108,35 @@ int get_crash_notes_per_cpu(int cpu, uin
>
> return 0;
> }
> +
> +/* Returns the physical address of start of crash notes buffer for a kernel. */
> +int get_kernel_vmcoreinfo(uint64_t *addr, uint64_t *len)
> +{
> + char kdump_info[PATH_MAX];
> + char line[MAX_LINE];
> + int count;
> + FILE *fp;
> + unsigned long long temp, temp2;
> +
> + *addr = 0;
> + *len = 0;
> +
> + sprintf(kdump_info, "/sys/kernel/vmcoreinfo");
> + fp = fopen(kdump_info, "r");
> + if (!fp) {
> + die("Could not open \"%s\": %s\n", kdump_info,
> + strerror(errno));
> + return -1;
> + }
> +
> + if (!fgets(line, sizeof(line), fp))
> + die("Cannot parse %s: %s\n", kdump_info, strerror(errno));
> + count = sscanf(line, "%Lx %Lx", &temp, &temp2);
> + if (count != 2)
> + die("Cannot parse %s: %s\n", kdump_info, strerror(errno));
> +
> + *addr = (uint64_t) temp;
> + *len = (uint64_t) temp2;
> +
> + return 0;
> +}
> diff -rpuN backup/kexec-tools-testing-20070330/kexec/crashdump.h kexec-tools/kexec/crashdump.h
> --- backup/kexec-tools-testing-20070330/kexec/crashdump.h 2007-03-30 13:34:36.000000000 +0900
> +++ kexec-tools/kexec/crashdump.h 2007-08-03 14:45:05.000000000 +0900
> @@ -2,6 +2,7 @@
> #define CRASHDUMP_H
>
> extern int get_crash_notes_per_cpu(int cpu, uint64_t *addr, uint64_t *len);
> +extern int get_kernel_vmcoreinfo(uint64_t *addr, uint64_t *len);
>
> /* Need to find a better way to determine per cpu notes section size. */
> #define MAX_NOTE_BYTES 1024
> _
>
> _______________________________________________
> kexec mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/kexec

2007-10-17 05:19:56

by Ken'ichi Ohmichi

[permalink] [raw]
Subject: Re: [PATCH 2/3] [kexec-tools] Pass vmcoreinfo's address and size


Hi Simon,

Simon Horman wrote:
> On Wed, Aug 22, 2007 at 09:13:39PM +0900, Ken'ichi Ohmichi wrote:
>> [2/3] [kexec-tools] Pass vmcoreinfo's address and size
>> The patch is for kexec-tools-testing-20070330.
>> (http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/)
>> kexec command gets the address and size of the vmcoreinfo data from
>> /sys/kernel/vmcoreinfo, and passes them to the second kernel through
>> ELF header of /proc/vmcore. When the second kernel is booting, the
>> kernel gets them from the ELF header and creates vmcoreinfo's PT_NOTE
>> segment into /proc/vmcore.
>
> Sorry for the long delay, I completely missed this patch.
>
> The kexec-tools change seems ok to me. What is the status of
> the kernel portion of the change?

The kernel portion is merged into linux-2.6.23-mm1.
According to Andrew's mail "-mm merge plans for 2.6.24", its status is
"The infamous misc. Will re-review and will merge basically all of them".

http://www.ussg.iu.edu/hypermail/linux/kernel/0710.0/0313.html


> Do you still want the kexec-tools portion applied?

Yes, I hope so.


Thanks
Ken'ichi Ohmichi

2007-10-17 05:29:37

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 2/3] [kexec-tools] Pass vmcoreinfo's address and size

On Wed, 17 Oct 2007 14:16:19 +0900 "Ken'ichi Ohmichi" <[email protected]> wrote:

> Simon Horman wrote:
> > On Wed, Aug 22, 2007 at 09:13:39PM +0900, Ken'ichi Ohmichi wrote:
> >> [2/3] [kexec-tools] Pass vmcoreinfo's address and size
> >> The patch is for kexec-tools-testing-20070330.
> >> (http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/)
> >> kexec command gets the address and size of the vmcoreinfo data from
> >> /sys/kernel/vmcoreinfo, and passes them to the second kernel through
> >> ELF header of /proc/vmcore. When the second kernel is booting, the
> >> kernel gets them from the ELF header and creates vmcoreinfo's PT_NOTE
> >> segment into /proc/vmcore.
> >
> > Sorry for the long delay, I completely missed this patch.
> >
> > The kexec-tools change seems ok to me. What is the status of
> > the kernel portion of the change?
>
> The kernel portion is merged into linux-2.6.23-mm1.
> According to Andrew's mail "-mm merge plans for 2.6.24", its status is
> "The infamous misc. Will re-review and will merge basically all of them".

It's all in this evening's batch, which is going through final QA (heh)
now. Is looking OK.

2007-10-17 13:38:06

by Simon Horman

[permalink] [raw]
Subject: Re: [PATCH 2/3] [kexec-tools] Pass vmcoreinfo's address and size

On Wed, Oct 17, 2007 at 02:16:19PM +0900, Ken'ichi Ohmichi wrote:
>
> Hi Simon,
>
> Simon Horman wrote:
> > On Wed, Aug 22, 2007 at 09:13:39PM +0900, Ken'ichi Ohmichi wrote:
> >> [2/3] [kexec-tools] Pass vmcoreinfo's address and size
> >> The patch is for kexec-tools-testing-20070330.
> >> (http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/)
> >> kexec command gets the address and size of the vmcoreinfo data from
> >> /sys/kernel/vmcoreinfo, and passes them to the second kernel through
> >> ELF header of /proc/vmcore. When the second kernel is booting, the
> >> kernel gets them from the ELF header and creates vmcoreinfo's PT_NOTE
> >> segment into /proc/vmcore.
> >
> > Sorry for the long delay, I completely missed this patch.
> >
> > The kexec-tools change seems ok to me. What is the status of
> > the kernel portion of the change?
>
> The kernel portion is merged into linux-2.6.23-mm1.
> According to Andrew's mail "-mm merge plans for 2.6.24", its status is
> "The infamous misc. Will re-review and will merge basically all of them".
>
> http://www.ussg.iu.edu/hypermail/linux/kernel/0710.0/0313.html
>
>
> > Do you still want the kexec-tools portion applied?
>
> Yes, I hope so.

Thanks, I'll try and look over it tomorrow.

2007-10-17 17:19:36

by Tony Luck

[permalink] [raw]
Subject: Re: [PATCH 0/3] vmcoreinfo support for dump filtering

> This patch set frees the restriction that makedumpfile users should
> install a vmlinux file (including the debugging information) into
> each system.

This patch went from Andrew to Linus last night, and looks at first
glance to be the reason why the ia64 build is broken this morning
when using the arch/ia64/configs/tiger_defconfig configuration.

Here are the error messages:
arch/ia64/kernel/machine_kexec.c: In function `arch_crash_save_vmcoreinfo':
arch/ia64/kernel/machine_kexec.c:131: error: `pgdat_list' undeclared
(first use in this function)
arch/ia64/kernel/machine_kexec.c:131: error: (Each undeclared
identifier is reported only once
arch/ia64/kernel/machine_kexec.c:131: error: for each function it appears in.)
arch/ia64/kernel/machine_kexec.c:134: error: `node_memblk' undeclared
(first use in this function)
arch/ia64/kernel/machine_kexec.c:135: error: `NR_NODE_MEMBLKS'
undeclared (first use in this function)
arch/ia64/kernel/machine_kexec.c:136: error: invalid application of
`sizeof' to incomplete type `node_memblk_s'
arch/ia64/kernel/machine_kexec.c:137: error: dereferencing pointer to
incomplete type
arch/ia64/kernel/machine_kexec.c:138: error: dereferencing pointer to
incomplete type
make[1]: *** [arch/ia64/kernel/machine_kexec.o] Error 1

-Tony

2007-10-17 20:21:16

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 0/3] vmcoreinfo support for dump filtering

On Wed, 17 Oct 2007 10:19:18 -0700
"Tony Luck" <[email protected]> wrote:

> > This patch set frees the restriction that makedumpfile users should
> > install a vmlinux file (including the debugging information) into
> > each system.
>
> This patch went from Andrew to Linus last night, and looks at first
> glance to be the reason why the ia64 build is broken this morning
> when using the arch/ia64/configs/tiger_defconfig configuration.
>
> Here are the error messages:
> arch/ia64/kernel/machine_kexec.c: In function `arch_crash_save_vmcoreinfo':
> arch/ia64/kernel/machine_kexec.c:131: error: `pgdat_list' undeclared
> (first use in this function)
> arch/ia64/kernel/machine_kexec.c:131: error: (Each undeclared
> identifier is reported only once
> arch/ia64/kernel/machine_kexec.c:131: error: for each function it appears in.)
> arch/ia64/kernel/machine_kexec.c:134: error: `node_memblk' undeclared
> (first use in this function)
> arch/ia64/kernel/machine_kexec.c:135: error: `NR_NODE_MEMBLKS'
> undeclared (first use in this function)
> arch/ia64/kernel/machine_kexec.c:136: error: invalid application of
> `sizeof' to incomplete type `node_memblk_s'
> arch/ia64/kernel/machine_kexec.c:137: error: dereferencing pointer to
> incomplete type
> arch/ia64/kernel/machine_kexec.c:138: error: dereferencing pointer to
> incomplete type
> make[1]: *** [arch/ia64/kernel/machine_kexec.o] Error 1
>

This?


--- a/arch/ia64/kernel/machine_kexec.c~ia64-fix-non-numa-build
+++ a/arch/ia64/kernel/machine_kexec.c
@@ -17,6 +17,8 @@
#include <linux/efi.h>
#include <linux/numa.h>
#include <linux/mmzone.h>
+
+#include <asm/numa.h>
#include <asm/mmu_context.h>
#include <asm/setup.h>
#include <asm/delay.h>
@@ -127,7 +129,7 @@ void machine_kexec(struct kimage *image)

void arch_crash_save_vmcoreinfo(void)
{
-#ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
+#if defined(CONFIG_ARCH_DISCONTIGMEM_ENABLE) && defined(CONFIG_NUMA)
VMCOREINFO_SYMBOL(pgdat_list);
VMCOREINFO_LENGTH(pgdat_list, MAX_NUMNODES);

_

(the asm/numa.h include isn't needed by this patch, but strictly should be
there, as this file refers to things which are defined in asm/numa.h)

(it's weird that linux/numa.h doesn't include asm/numa.h)

(please tell me if you want me to send this to Linus)

2007-10-17 21:38:23

by Tony Luck

[permalink] [raw]
Subject: RE: [PATCH 0/3] vmcoreinfo support for dump filtering

> This?

That does the trick, yes.

> (please tell me if you want me to send this to Linus)

I've put it in my tree now ... so I'll ask Linus to pull
it from there.

-Tony

2007-10-18 05:37:54

by Simon Horman

[permalink] [raw]
Subject: Re: [PATCH 2/3] [kexec-tools] Pass vmcoreinfo's address and size

On Wed, Oct 17, 2007 at 02:16:19PM +0900, Ken'ichi Ohmichi wrote:
>
> Hi Simon,
>
> Simon Horman wrote:
> > On Wed, Aug 22, 2007 at 09:13:39PM +0900, Ken'ichi Ohmichi wrote:
> >> [2/3] [kexec-tools] Pass vmcoreinfo's address and size
> >> The patch is for kexec-tools-testing-20070330.
> >> (http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/)
> >> kexec command gets the address and size of the vmcoreinfo data from
> >> /sys/kernel/vmcoreinfo, and passes them to the second kernel through
> >> ELF header of /proc/vmcore. When the second kernel is booting, the
> >> kernel gets them from the ELF header and creates vmcoreinfo's PT_NOTE
> >> segment into /proc/vmcore.
> >
> > Sorry for the long delay, I completely missed this patch.
> >
> > The kexec-tools change seems ok to me. What is the status of
> > the kernel portion of the change?
>
> The kernel portion is merged into linux-2.6.23-mm1.
> According to Andrew's mail "-mm merge plans for 2.6.24", its status is
> "The infamous misc. Will re-review and will merge basically all of them".
>
> http://www.ussg.iu.edu/hypermail/linux/kernel/0710.0/0313.html
>
>
> > Do you still want the kexec-tools portion applied?
>
> Yes, I hope so.

Thanks, applied :-)

2007-10-18 09:16:58

by tachibana

[permalink] [raw]
Subject: Re: [PATCH 2/3] [kexec-tools] Pass vmcoreinfo's address and size


Hi Simon,

On Thu, 18 Oct 2007 14:37:41 +0900, Simon Horman <[email protected]> wrote:
> On Wed, Oct 17, 2007 at 02:16:19PM +0900, Ken'ichi Ohmichi wrote:
> >
> > Hi Simon,
> >
> > Simon Horman wrote:
> > > On Wed, Aug 22, 2007 at 09:13:39PM +0900, Ken'ichi Ohmichi wrote:
> > >> [2/3] [kexec-tools] Pass vmcoreinfo's address and size
> > >> The patch is for kexec-tools-testing-20070330.
> > >> (http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/)
> > >> kexec command gets the address and size of the vmcoreinfo data from
> > >> /sys/kernel/vmcoreinfo, and passes them to the second kernel through
> > >> ELF header of /proc/vmcore. When the second kernel is booting, the
> > >> kernel gets them from the ELF header and creates vmcoreinfo's PT_NOTE
> > >> segment into /proc/vmcore.
> > >
> > > Sorry for the long delay, I completely missed this patch.
> > >
> > > The kexec-tools change seems ok to me. What is the status of
> > > the kernel portion of the change?
> >
> > The kernel portion is merged into linux-2.6.23-mm1.
> > According to Andrew's mail "-mm merge plans for 2.6.24", its status is
> > "The infamous misc. Will re-review and will merge basically all of them".
> >
> > http://www.ussg.iu.edu/hypermail/linux/kernel/0710.0/0313.html
> >
> >
> > > Do you still want the kexec-tools portion applied?
> >
> > Yes, I hope so.
>
> Thanks, applied :-)

Thank you for applying ;-)

But it has the compatibility problem that the kexec command fails on
kernels which don't have /sys/kernel/vmcoreinfo:

# ls /sys/kernel/
debug kexec_crash_loaded kexec_loaded security uevent_helper
uevent_seqnum
#
(There is not /sys/kernel/vmcoreinfo.)

#
# kexec -p --args-linux vmlinuz --initrd=initrd.img
Could not open "/sys/kernel/vmcoreinfo": No such file or directory
#

To fix the problem, could you please apply the attached patch ?
The fixed part is the same as the patch in the following mail.

To: kexec-ml <[email protected]>
Subject: [PATCH 2/2] [kexec-tools] Pass vmcoreinfo's address and size #2
From: "Ken'ichi Ohmichi" <[email protected]>
Date: Fri, 7 Sep 2007 18:10:02 +0900


Thanks
tachibana

---
diff -rpuN a/kexec/crashdump.c b/kexec/crashdump.c
--- a/kexec/crashdump.c 2007-10-18 15:20:56.000000000 +0900
+++ b/kexec/crashdump.c 2007-10-18 15:22:21.000000000 +0900
@@ -122,12 +122,8 @@ int get_kernel_vmcoreinfo(uint64_t *addr
*len = 0;

sprintf(kdump_info, "/sys/kernel/vmcoreinfo");
- fp = fopen(kdump_info, "r");
- if (!fp) {
- die("Could not open \"%s\": %s\n", kdump_info,
- strerror(errno));
- return -1;
- }
+ if (!(fp = fopen(kdump_info, "r")))
+ return 0;

if (!fgets(line, sizeof(line), fp))
die("Cannot parse %s: %s\n", kdump_info, strerror(errno));
_

2007-10-19 03:38:54

by Simon Horman

[permalink] [raw]
Subject: Re: [PATCH 2/3] [kexec-tools] Pass vmcoreinfo's address and size

On Thu, Oct 18, 2007 at 06:14:07PM +0900, [email protected] wrote:
>
> Hi Simon,
>
> On Thu, 18 Oct 2007 14:37:41 +0900, Simon Horman <[email protected]> wrote:
> > On Wed, Oct 17, 2007 at 02:16:19PM +0900, Ken'ichi Ohmichi wrote:
> > >
> > > Hi Simon,
> > >
> > > Simon Horman wrote:
> > > > On Wed, Aug 22, 2007 at 09:13:39PM +0900, Ken'ichi Ohmichi wrote:
> > > >> [2/3] [kexec-tools] Pass vmcoreinfo's address and size
> > > >> The patch is for kexec-tools-testing-20070330.
> > > >> (http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/)
> > > >> kexec command gets the address and size of the vmcoreinfo data from
> > > >> /sys/kernel/vmcoreinfo, and passes them to the second kernel through
> > > >> ELF header of /proc/vmcore. When the second kernel is booting, the
> > > >> kernel gets them from the ELF header and creates vmcoreinfo's PT_NOTE
> > > >> segment into /proc/vmcore.
> > > >
> > > > Sorry for the long delay, I completely missed this patch.
> > > >
> > > > The kexec-tools change seems ok to me. What is the status of
> > > > the kernel portion of the change?
> > >
> > > The kernel portion is merged into linux-2.6.23-mm1.
> > > According to Andrew's mail "-mm merge plans for 2.6.24", its status is
> > > "The infamous misc. Will re-review and will merge basically all of them".
> > >
> > > http://www.ussg.iu.edu/hypermail/linux/kernel/0710.0/0313.html
> > >
> > >
> > > > Do you still want the kexec-tools portion applied?
> > >
> > > Yes, I hope so.
> >
> > Thanks, applied :-)
>
> Thank you for applying ;-)
>
> But it has the compatibility problem that the kexec command fails on
> kernels which don't have /sys/kernel/vmcoreinfo:
>
> # ls /sys/kernel/
> debug kexec_crash_loaded kexec_loaded security uevent_helper
> uevent_seqnum
> #
> (There is not /sys/kernel/vmcoreinfo.)
>
> #
> # kexec -p --args-linux vmlinuz --initrd=initrd.img
> Could not open "/sys/kernel/vmcoreinfo": No such file or directory
> #
>
> To fix the problem, could you please apply the attached patch ?
> The fixed part is the same as the patch in the following mail.

Thanks, applied.