Kexec based crash dumping
Subsystems (7)
Hi,
The patches that follow contain the initial implementation for kexec based crash dumping that we are working on. I had sent this to the fastboot mailing list a couple of weeks ago and this set of patches includes the changes made as per feedback from Andrew, Eric and others.
Main Idea
- Whenever a panic occurs, reboot to a new kernel using kexec using a small amount of memory (16MB). The rest of the memory is preserved across the reboot.
- In the second kernel, the memory contents from the failed kernel is available as an ELF format file for write-out.
Details on the design and implementation and on how to setup this facility are available in the first of the patches that follow. The patches have been made for the 2.6.8.1 kernel.
Kindly review these patches and provide feedback.
Thanks to Martin Bligh and Suparna for the design ideas and to Adam Litke who hacked up most of the memory preserving reboot code and the dump device abstraction code.
Regards, Hari
Signature · 4 lines
Hariprasad Nellitheertha Linux Technology Center India Software Labs IBM India, Bangalore
Re: [PATCH][1/6]Documentation
Regards, Hari
Signature · 4 lines
Hariprasad Nellitheertha Linux Technology Center India Software Labs IBM India, Bangalore
This patch contains the documentation for the kexec based crash dump tool.
Signed off by Hariprasad Nellitheertha <[email protected]>
---
linux-2.6.8.1-hari/Documentation/kdump.txt | 101 +++++++++++++++++++++++++++++ 1 files changed, 101 insertions(+)
Documentation/kdump.txt new file +101 -0
@@ -0,0 +1,101 @@ +Documentation for kdump - the kexec based crash dumping solution +================================================================ + +DESIGN +====== + +We use kexec to reboot to a second kernel whenever a dump needs to be taken. +This second kernel is booted with with very little memory (current +implementation has this at 16MB). The contents of the 16MB of memory that +the second kernel uses is copied onto a reserved area, before rebooting. So, +we have the entire memory image of the previous kernel preserved. + +In the second kernel, this "old memory" can be accessed in two ways. The +first one is through a device interface. We can create a /dev/hmem or +whatever and write out the memory in raw format. The second interface is +through /proc/vmcore. This exports the dump as an ELF format file which +can be written out using any file copy command (cp, scp, etc). Further, gdb +can be used to perform some minimal debugging on the dump file. + +Note that the two approaches are independent and the patches +can be used depending on the functionality needed. More details on the +patches below. + +PATCHES +======= + +We currently have 6 patches. + +1) kd-doc-<version>.patch - Contains basic documentation (this document!!) +2) kd-reb-<version>.patch - This patch ensures we do a kexec reboot upon panic + and also saves the first 16MB of memory into a backup area +3) kd-copy-<version>.patch - This contains the code for reading the dump pages + in the second kernel. +4) kd-reg-<version>.patch - This patch is for snapshotting the register contents + of all processors on to the backup area before rebooting. +5) kd-elf-<version>.patch - This patch provides an ELF format interface to + the dump, post-reboot. +6) kd-hmem-<version>.patch - This patch contains the code to access the dump as + an /dev/hmem. + +SETUP +===== + +1) Apply the kexec patch on to the appropriate vanilla kernel tree. + The latest version of the kexec patch can be obtained from + http://www.xmission.com/~ebiederm/files/kexec/2.6.8-rc1-kexec1/ + This patch should apply on 2.6.8-rc4 as well. + Older kexec patches can be found at + http://developer.osdl.org/rddunlap/kexec/ + +2) Apply the crash dump patches. + +3) Ensure you have chosen the "kernel crash dumps" option under "Processor + type and features" and also the kexec syscall option under kernel hacking + +4) Load the second kernel to be booted using + + kexec -l <kernel> --append="root=<root-dev> mem=16M dump init 1" + +5) System reboots into the second kernel when a panic occurs. + You could write a module to call panic, for testing purposes. + +6) Write out the dump file using + + cp /proc/vmcore <dump-file> + +You can also access the dump as a device for a linear/raw view. To do this, +you will need the kd-hmem-<version>.patch built into the kernel. To create +the device, type + + mknod /dev/hmem c 1 12 + +Use "dd" with suitable options for count, bs and skip to access specific +portions of the dump. + +ANALYSIS +======== + +You can run gdb on the dump file copied out of /proc/vmcore. Use vmlinux built +with -g and run + + gdb vmlinux <dump-file> + +Stack trace for the task on processor 0, register display, memory display +work fine. + +TODO +==== + +1) Provide a kernel-pages only view for the dump. This could possibly turn up + as /proc/vmcore-kern. +2) Provide register contents of all processors (similar to what multi-threaded + core dumps does). +3) Modify "crash" to make it recognize this dump. +4) Make the i386 kernel boot from any location so we can run the second kernel + from the reserved location instead of the current approach. + +CONTACT +======= + +Hariprasad Nellitheertha - hari at in dot ibm dot com
_
Re: [PATCH][2/6]Memory preserving reboot using kexec
Regards, Hari
Signature · 4 lines
Hariprasad Nellitheertha Linux Technology Center India Software Labs IBM India, Bangalore
This patch contains the code that does the memory preserving reboot. It copies over the first CRASH_BACKUP_SIZE amount of memory into a backup region before handing over to kexec.
Signed off by Hariprasad Nellitheertha <[email protected]> Signed off by Adam Litke <[email protected]>
---
linux-2.6.8.1-hari/arch/i386/Kconfig | 22 +++++++++++ linux-2.6.8.1-hari/arch/i386/kernel/machine_kexec.c | 31 +++++++++++++++ linux-2.6.8.1-hari/arch/i386/kernel/setup.c | 11 +++++ linux-2.6.8.1-hari/include/asm-i386/crash_dump.h | 39 ++++++++++++++++++++ linux-2.6.8.1-hari/include/linux/bootmem.h | 1 linux-2.6.8.1-hari/include/linux/crash_dump.h | 27 +++++++++++++ linux-2.6.8.1-hari/kernel/panic.c | 6 +++ linux-2.6.8.1-hari/mm/bootmem.c | 5 ++ 8 files changed, 142 insertions(+)
arch/i386/Kconfig renamed from arch/i386/Kconfig~kd-reb-268 +22 -0
@@ -865,6 +865,28 @@ config REGPARM generate incorrect output with certain kernel constructs when -mregparm=3 is used. +config CRASH_DUMP + bool "kernel crash dumps (EXPERIMENTAL)" + depends on KEXEC + help + Generate crash dump using kexec. + +config BACKUP_BASE + int "location of the crash dumps backup region" + depends on CRASH_DUMP + default 128 + help + Offset of backup region in terms of MB. Change this if you want + to modify the location of the crash dumps backup region. + +config BACKUP_SIZE + int "Size of the crash dumps backup region" + depends on CRASH_DUMP + range 16 64 + default 16 + help + The size of the backup region, in MB. This is also the size of the + memory that will be used to boot the second kernel after a crash. endmenu
arch/i386/kernel/machine_kexec.c renamed from arch/i386/kernel/machine_kexec.c~kd-reb-268 +31 -0
@@ -9,6 +9,7 @@#include <linux/mm.h> #include <linux/kexec.h> #include <linux/delay.h> +#include <linux/crash_dump.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> #include <asm/tlbflush.h>
@@ -16,6 +17,7 @@#include <asm/io.h> #include <asm/apic.h> #include <asm/cpufeature.h> +#include <asm/hw_irq.h> static void set_idt (void *newidt,__u16 limit)
@@ -76,6 +78,28 @@ const extern unsigned int relocate_new_kextern void use_mm (struct mm_struct *mm);/* +* We are going to do a memory preserving reboot. So, we copy over the +* first xxMB of memory into a backup location. +*/ +void __relocate_base_mem (unsigned long backup_addr,unsigned long backup_size) +{ +unsigned long pfn, pfn_max; +void *src_addr, *dest_addr; +struct page *page; + + pfn_max = backup_size >>PAGE_SHIFT ; +for (pfn =0 ; pfn < pfn_max; pfn++) { + src_addr =phys_to_virt (pfn <<PAGE_SHIFT ); + dest_addr = backup_addr + src_addr; +if (!pfn_valid (pfn)) +continue ; + page =pfn_to_page (pfn); +if (PageReserved (page)) +copy_page (dest_addr, src_addr); + } +} + +/* * Do not allocate memory (or fail in any way) in machine_kexec(). * We are past the point of no return, committed to rebooting now. */
@@ -94,6 +118,13 @@ void machine_kexec(struct kimage *image) reboot_code_buffer =page_to_pfn (image->reboot_code_pages) <<PAGE_SHIFT ; indirection_page = image->head &PAGE_MASK ; +/* +* If we are here to do a crash dump, save the memory from +* 0-16MB before we copy over the kexec kernel image. Otherwise +* our dump will show the wrong kernel entirely. +*/ +relocate_base_mem (); +/* copy it out */ memcpy ((void *)reboot_code_buffer, relocate_new_kernel, relocate_new_kernel_size);
arch/i386/kernel/setup.c renamed from arch/i386/kernel/setup.c~kd-reb-268 +11 -0
@@ -39,6 +39,7 @@#include <linux/efi.h> #include <linux/init.h> #include <linux/edd.h> +#include <linux/crash_dump.h> #include <video/edid.h> #include <asm/e820.h> #include <asm/mpspec.h>
@@ -56,6 +57,7 @@unsigned long init_pg_tables_end__initdata = ~0UL ;int disable_pse__initdata =0 ; +unsigned int dump_enabled;/* * Machine setup..
@@ -347,6 +349,9 @@ static void __init limit_regions(unsigne } } } +/* If we are doing a crash dump, we still need to know the real mem size*/ +set_saved_max_pfn (); +for (i =0 ; i < e820.nr_map; i++) {if (e820.map[i].type ==E820_RAM ) { current_addr = e820.map[i].addr + e820.map[i].size;
@@ -809,6 +814,9 @@ static void __init parse_cmdline_early (if (c ==' ' && !memcmp (from,"highmem=" ,8 )) highmem_pages =memparse (from+8 , &from) >>PAGE_SHIFT ; +if (!memcmp (from,"dump" ,4 )) + dump_enabled =1 ; + c = *(from++);if (!c)break ;
@@ -1082,6 +1090,9 @@ static unsigned long __init setup_memory } }#endif + +crash_reserve_bootmem (); +return max_low_pfn; }#else
include/asm-i386/crash_dump.h new file +39 -0
@@ -0,0 +1,39 @@ +/* asm-i386/crash_dump.h */ +#include <linux/bootmem.h> + +extern unsigned int dump_enabled; + +unsigned long __init find_max_low_pfn (void ); +void __init find_max_pfn (void ); +void __relocate_base_mem (unsigned long ,unsigned long ); + +extern unsigned int crashed; + +#ifdef CONFIG_CRASH_DUMP +#define CRASH_BACKUP_BASE ((unsigned long)CONFIG_BACKUP_BASE * 0x100000) +#define CRASH_BACKUP_SIZE ((unsigned long)CONFIG_BACKUP_SIZE * 0x100000) + +static inline void relocate_base_mem (void ) +{ +if (crashed) +__relocate_base_mem (CRASH_BACKUP_BASE ,CRASH_BACKUP_SIZE ); +} + +static inline void set_saved_max_pfn (void ) +{ +find_max_pfn (); + saved_max_pfn =find_max_low_pfn (); +} + +static inline void crash_reserve_bootmem (void ) +{ +if (!dump_enabled) +reserve_bootmem (CRASH_BACKUP_BASE ,CRASH_BACKUP_SIZE ); +} +#else +#define CRASH_BACKUP_BASE 0x08000000 +#define CRASH_BACKUP_SIZE 0x01000000 +static inline void relocate_base_mem (void ) {} +static inline void set_saved_max_pfn (void ) {} +static inline void crash_reserve_bootmem (void ) {} +#endif
include/linux/bootmem.h renamed from include/linux/bootmem.h~kd-reb-268 +1 -0
@@ -21,6 +21,7 @@ extern unsigned long min_low_pfn;* highest page */ extern unsigned long max_pfn; +extern unsigned long saved_max_pfn;/* * node_bootmem_map is a map pointer - the bits represent all physical
include/linux/crash_dump.h new file +27 -0
@@ -0,0 +1,27 @@ +#include <linux/kexec.h> +#include <linux/smp_lock.h> +#include <linux/device.h> +#include <asm/crash_dump.h> + +#ifdef CONFIG_CRASH_DUMP +static inline void crash_machine_kexec (void ) +{ +struct kimage *image; + +if (crashed) +return ; + + image =xchg (&kexec_image,0 ); +if (image) { + crashed =1 ; +device_shutdown (); +printk (KERN_EMERG "kexec: opening parachute\n" ); +machine_kexec (image); +while (1 ); + }else { +printk (KERN_EMERG "kexec: No kernel image loaded!\n" ); + } +} +#else +static inline void crash_machine_kexec (void ) {} +#endif
kernel/panic.c renamed from kernel/panic.c~kd-reb-268 +6 -0
@@ -19,10 +19,13 @@#include <linux/syscalls.h> #include <linux/interrupt.h> #include <linux/nmi.h> +#include <linux/kexec.h> +#include <linux/crash_dump.h> int panic_timeout;int panic_on_oops;int tainted; +unsigned int crashed;EXPORT_SYMBOL (panic_timeout);
@@ -68,6 +71,9 @@ NORET_TYPE void panic(const char * fmt,sys_sync ();bust_spinlocks (0 ); +/* If we have crashed, perform a kexec reboot, for dump write-out */ +crash_machine_kexec (); +#ifdef CONFIG_SMP smp_send_stop ();#endif
mm/bootmem.c renamed from mm/bootmem.c~kd-reb-268 +5 -0
@@ -27,6 +27,11 @@unsigned long max_low_pfn;unsigned long min_low_pfn;unsigned long max_pfn; +/* +* If we have booted due to a crash, max_pfn will be a very low value. We need +* to know the amount of memory that the previous kernel used. +*/ +unsigned long saved_max_pfn;EXPORT_SYMBOL (max_pfn);/* This is exported so * dma_get_required_mask(), which uses
_
Re: [PATCH][3/6]Interface for copying the dump pages
Regards, Hari
Signature · 4 lines
Hariprasad Nellitheertha Linux Technology Center India Software Labs IBM India, Bangalore
This patch provides the interfaces necessary to read the dump contents, treating it as a high memory device.
Signed off by Hariprasad Nellitheertha <[email protected]>
---
linux-2.6.8.1-hari/arch/i386/mm/highmem.c | 18 ++++++++++ linux-2.6.8.1-hari/drivers/char/mem.c | 44 ++++++++++++++++++++++++++ linux-2.6.8.1-hari/include/asm-i386/highmem.h | 1 linux-2.6.8.1-hari/include/linux/highmem.h | 1 4 files changed, 64 insertions(+)
arch/i386/mm/highmem.c renamed from arch/i386/mm/highmem.c~kd-copy-268 +18 -0
@@ -74,6 +74,24 @@ void kunmap_atomic(void *kvaddr, enum kmpreempt_check_resched (); } +/* This is the same as kmap_atomic but takes in a pfn instead of a +* struct page. +*/ +void *kmap_atomic_pfn (unsigned long pfn,enum km_type type) +{ +enum fixed_addresses idx; +unsigned long vaddr; + +inc_preempt_count (); + + idx = type +KM_TYPE_NR *smp_processor_id (); + vaddr =__fix_to_virt (FIX_KMAP_BEGIN + idx); +set_pte (kmap_pte-idx,pfn_pte (pfn, kmap_prot)); +__flush_tlb_one (vaddr); + +return (void *) vaddr; +} +struct page *kmap_atomic_to_page (void *ptr) {unsigned long idx, vaddr = (unsigned long )ptr;
drivers/char/mem.c renamed from drivers/char/mem.c~kd-copy-268 +44 -0
65 lines not on this page · raw message
include/asm-i386/highmem.h renamed from include/asm-i386/highmem.h~kd-copy-268 +1 -0
@@ -61,6 +61,7 @@ void *kmap(struct page *page);void kunmap (struct page *page);void *kmap_atomic (struct page *page,enum km_type type);void kunmap_atomic (void *kvaddr,enum km_type type); +void *kmap_atomic_pfn (unsigned long pfn,enum km_type type);struct page *kmap_atomic_to_page (void *ptr);#define flush_cache_kmaps () do { } while (0)
include/linux/highmem.h renamed from include/linux/highmem.h~kd-copy-268 +1 -0
@@ -30,6 +30,7 @@ static inline void *kmap(struct page *pa#define kmap_atomic (page, idx) page_address(page)#define kunmap_atomic (addr, idx) do { } while (0) +#define kmap_atomic_pfn (pfn, idx) page_address(pfn_to_page(pfn))#define kmap_atomic_to_page (ptr) virt_to_page(ptr)#endif /* CONFIG_HIGHMEM */
_
Re: [PATCH][4/6]Register snapshotting before kexec-boot
Regards, Hari
Signature · 4 lines
Hariprasad Nellitheertha Linux Technology Center India Software Labs IBM India, Bangalore
This patch contains the code for stopping the other cpus and snapshotting their register values before doing the kexec reboot.
Signed off by Hariprasad Nellitheertha <[email protected]>
---
linux-2.6.8.1-hari/arch/i386/kernel/Makefile | 1 linux-2.6.8.1-hari/arch/i386/kernel/crash_dump.c | 98 ++++++++++ linux-2.6.8.1-hari/arch/i386/kernel/machine_kexec.c | 14 + linux-2.6.8.1-hari/arch/i386/kernel/smp.c | 13 + linux-2.6.8.1-hari/include/asm-i386/crash_dump.h | 32 +++ linux-2.6.8.1-hari/include/asm-i386/mach-default/irq_vectors.h | 1 linux-2.6.8.1-hari/include/asm-i386/smp.h | 1 7 files changed, 156 insertions(+), 4 deletions(-)
arch/i386/kernel/Makefile renamed from arch/i386/kernel/Makefile~kd-reg-268 +1 -0
@@ -24,6 +24,7 @@ obj-$(CONFIG_X86_MPPARSE) += mpparse.o obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o +obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_X86_NUMAQ) += numaq.o obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o obj-$(CONFIG_MODULES) += module.o
arch/i386/kernel/crash_dump.c new file +98 -0
98 lines not on this page · raw message
arch/i386/kernel/machine_kexec.c renamed from arch/i386/kernel/machine_kexec.c~kd-reg-268 +12 -2
@@ -17,8 +17,9 @@#include <asm/io.h> #include <asm/apic.h> #include <asm/cpufeature.h> -#include <asm/hw_irq.h> +struct pt_regs crash_smp_regs[NR_CPUS ]; +u32 crash_smp_current_task[NR_CPUS ];static void set_idt (void *newidt,__u16 limit) {
@@ -97,6 +98,14 @@ void __relocate_base_mem(unsigned long bif (PageReserved (page))copy_page (dest_addr, src_addr); } + +/* Now copy over the saved task pointers and the registers +* to the end of the reserved area +*/ + dest_addr = (void *)(__va (CRASH_BACKUP_BASE +CRASH_BACKUP_SIZE )); +memcpy (dest_addr, crash_smp_regs, (sizeof (struct pt_regs )*NR_CPUS )); + dest_addr +=sizeof (struct pt_regs )*NR_CPUS ; +memcpy (dest_addr, crash_smp_current_task, (sizeof (u32)*NR_CPUS )); }/*
@@ -111,7 +120,8 @@ void machine_kexec(struct kimage *image)/* switch to an mm where the reboot_code_buffer is identity mapped */ use_mm (&init_mm); -stop_apics (); + +crash_dump_stop_cpus ();/* Interrupts aren't acceptable while we reboot */ local_irq_disable ();
arch/i386/kernel/smp.c renamed from arch/i386/kernel/smp.c~kd-reg-268 +12 -1
@@ -143,6 +143,9 @@ inline void __send_IPI_shortcut(unsigned*/ cfg =__prepare_ICR (shortcut, vector); +if (vector ==CRASH_DUMP_VECTOR ) + cfg = (cfg&~APIC_VECTOR_MASK )|APIC_DM_NMI ; +/* * Send the IPI. The write to APIC_ICR fires this off. */
@@ -221,6 +224,9 @@ inline void send_IPI_mask_sequence(cpuma*/ cfg =__prepare_ICR (0 , vector); +if (vector ==CRASH_DUMP_VECTOR ) + cfg = (cfg&~APIC_VECTOR_MASK )|APIC_DM_NMI ; +/* * Send the IPI. The write to APIC_ICR fires this off. */
@@ -467,6 +473,11 @@ void flush_tlb_all(void)on_each_cpu (do_flush_tlb_all,NULL ,1 ,1 ); } +void crash_dump_send_ipi (void ) +{ +send_IPI_allbutself (CRASH_DUMP_VECTOR ); +} +/* * this function sends a 'reschedule' IPI to another CPU. * it goes straight through and wastes no time serializing
@@ -548,7 +559,7 @@ int smp_call_function (void (*func) (voireturn 0 ; } -static void stop_this_cpu (void * dummy) +void stop_this_cpu (void * dummy) {/* * Remove this CPU:
include/asm-i386/crash_dump.h renamed from include/asm-i386/crash_dump.h~kd-reg-268 +31 -1
@@ -1,5 +1,7 @@/* asm-i386/crash_dump.h */ #include <linux/bootmem.h> +#include <asm/hw_irq.h> +#include <asm/apic.h> extern unsigned int dump_enabled;
@@ -8,6 +10,11 @@ void __init find_max_pfn(void);void __relocate_base_mem (unsigned long ,unsigned long );extern unsigned int crashed; +extern struct pt_regs crash_smp_regs[NR_CPUS ]; +extern u32 crash_smp_current_task[NR_CPUS ]; +extern void crash_dump_save_this_cpu (struct pt_regs *,int ); +extern void __crash_dump_stop_cpus (void ); +extern void crash_get_current_regs (struct pt_regs *regs);#ifdef CONFIG_CRASH_DUMP #define CRASH_BACKUP_BASE ((unsigned long)CONFIG_BACKUP_BASE * 0x100000)
@@ -28,7 +35,26 @@ static inline void set_saved_max_pfn(voistatic inline void crash_reserve_bootmem (void ) {if (!dump_enabled) -reserve_bootmem (CRASH_BACKUP_BASE ,CRASH_BACKUP_SIZE ); +reserve_bootmem (CRASH_BACKUP_BASE ,CRASH_BACKUP_SIZE +PAGE_SIZE ); +} + +static inline void crash_dump_stop_cpus (void ) +{ +if (!crashed) +stop_apics (); +else { +int cpu =smp_processor_id (); + + crash_smp_current_task[cpu] = (int )current; +crash_get_current_regs (&crash_smp_regs[cpu]); + +/* This also captures the register states of the other cpus */ +__crash_dump_stop_cpus (); +#if defined(CONFIG_X86_IO_APIC ) +disable_IO_APIC (); +#endif +disconnect_bsp_APIC (); + } }#else #define CRASH_BACKUP_BASE 0x08000000
@@ -36,4 +62,8 @@ static inline void crash_reserve_bootmemstatic inline void relocate_base_mem (void ) {}static inline void set_saved_max_pfn (void ) {}static inline void crash_reserve_bootmem (void ) {} +static inline void crash_dump_stop_cpus (void ) +{ +stop_apics (); +}#endif
include/asm-i386/mach-default/irq_vectors.h renamed from include/asm-i386/mach-default/irq_vectors.h~kd-reg-268 +1 -0
@@ -48,6 +48,7 @@#define INVALIDATE_TLB_VECTOR 0xfd#define RESCHEDULE_VECTOR 0xfc#define CALL_FUNCTION_VECTOR 0xfb +#define CRASH_DUMP_VECTOR 0xfa#define THERMAL_APIC_VECTOR 0xf0/*
include/asm-i386/smp.h renamed from include/asm-i386/smp.h~kd-reg-268 +1 -0
@@ -41,6 +41,7 @@ extern void smp_message_irq(int cpl, voiextern void smp_invalidate_rcv (void );/* Process an NMI */ extern void (*mtrr_hook) (void );extern void zap_low_mappings (void ); +extern void stop_this_cpu (void *);#define MAX_APICID 256
_
Re: [PATCH][5/6]ELF format interface for the dump
Regards, Hari
Signature · 4 lines
Hariprasad Nellitheertha Linux Technology Center India Software Labs IBM India, Bangalore
This patch contains the code that provides an ELF format interface to the previous kernel's memory post kexec reboot.
Signed off by Hariprasad Nellitheertha <[email protected]>
---
linux-2.6.8.1-hari/fs/proc/Makefile | 1 linux-2.6.8.1-hari/fs/proc/kcore.c | 10 - linux-2.6.8.1-hari/fs/proc/proc_misc.c | 13 + linux-2.6.8.1-hari/fs/proc/vmcore.c | 233 ++++++++++++++++++++++++++ linux-2.6.8.1-hari/include/linux/crash_dump.h | 6 linux-2.6.8.1-hari/include/linux/proc_fs.h | 2 6 files changed, 260 insertions(+), 5 deletions(-)
fs/proc/Makefile renamed from fs/proc/Makefile~kd-elf-268 +1 -0
@@ -11,4 +11,5 @@ proc-y += inode.o root.o base.o ge kmsg.o proc_tty.o proc_misc.o proc-$(CONFIG_PROC_KCORE) += kcore.o +proc-$(CONFIG_CRASH_DUMP) += vmcore.o proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o
fs/proc/kcore.c renamed from fs/proc/kcore.c~kd-elf-268 +5 -5
@@ -114,7 +114,7 @@ static size_t get_kcore_size(int *nphdr,/* * determine size of ELF note */ -static int notesize (struct memelfnote *en) +int notesize (struct memelfnote *en) {int sz;
@@ -129,7 +129,7 @@ static int notesize(struct memelfnote *e/* * store a note in the header buffer */ -static char *storenote (struct memelfnote *men,char *bufp) +char *storenote (struct memelfnote *men,char *bufp) {struct elf_note en;
@@ -156,7 +156,7 @@ static char *storenote(struct memelfnote* store an ELF coredump header in the supplied buffer * nphdr is the number of elf_phdr to insert */ -static void elf_kcore_store_hdr (char *bufp,int nphdr,int dataoff) +void elf_kcore_store_hdr (char *bufp,int nphdr,int dataoff,struct kcore_list *clist) {struct elf_prstatus prstatus;/* NT_PRSTATUS */ struct elf_prpsinfo prpsinfo;/* NT_PRPSINFO */
@@ -208,7 +208,7 @@ static void elf_kcore_store_hdr(char *bu nhdr->p_align =0 ;/* setup ELF PT_LOAD program header for every area */ -for (m=kclist; m; m=m->next) { +for (m=clist; m; m=m->next) { phdr = (struct elf_phdr *) bufp; bufp +=sizeof (struct elf_phdr ); offset +=sizeof (struct elf_phdr );
@@ -305,7 +305,7 @@ read_kcore(struct file *file, char __usereturn -ENOMEM ; }memset (elf_buf,0 , elf_buflen); -elf_kcore_store_hdr (elf_buf, nphdr, elf_buflen); +elf_kcore_store_hdr (elf_buf, nphdr, elf_buflen, kclist);read_unlock (&kclist_lock);if (copy_to_user (buffer, elf_buf + *fpos, tsz)) {kfree (elf_buf);
fs/proc/proc_misc.c renamed from fs/proc/proc_misc.c~kd-elf-268 +13 -0
@@ -44,6 +44,8 @@#include <linux/jiffies.h> #include <linux/sysrq.h> #include <linux/vmalloc.h> +#include <linux/bootmem.h> +#include <linux/crash_dump.h> #include <asm/uaccess.h> #include <asm/pgtable.h> #include <asm/io.h>
@@ -628,6 +630,7 @@ static struct file_operations proc_sysrq#endif struct proc_dir_entry *proc_root_kcore; +struct proc_dir_entry *proc_vmcore;static void create_seq_entry (char *name,mode_t mode,struct file_operations *f) {
@@ -689,6 +692,16 @@ void __init proc_misc_init(void) (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE; }#endif +#ifdef CONFIG_CRASH_DUMP +if (dump_enabled) { + proc_vmcore =create_proc_entry ("vmcore" ,S_IRUSR ,NULL ); +if (proc_vmcore) { + proc_vmcore->proc_fops = &proc_vmcore_operations; + proc_vmcore->size = + (size_t )(saved_max_pfn <<PAGE_SHIFT ); + } + } +#endif if (prof_on) { entry =create_proc_entry ("profile" ,S_IWUSR |S_IRUGO ,NULL );if (entry) {
fs/proc/vmcore.c new file +233 -0
233 lines not on this page · raw message
include/linux/crash_dump.h renamed from include/linux/crash_dump.h~kd-elf-268 +6 -0
@@ -3,6 +3,12 @@#include <linux/device.h> #include <asm/crash_dump.h> +extern struct memelfnote memelfnote; +extern int notesize (struct memelfnote *); +extern char *storenote (struct memelfnote *,char *); +extern ssize_t copy_hmem_page (unsigned long ,char *,size_t ,int ); +extern void elf_kcore_store_hdr (char *,int ,int ,struct kcore_list *); +#ifdef CONFIG_CRASH_DUMP static inline void crash_machine_kexec (void ) {
include/linux/proc_fs.h renamed from include/linux/proc_fs.h~kd-elf-268 +2 -0
@@ -82,6 +82,7 @@ extern struct proc_dir_entry *proc_net;extern struct proc_dir_entry *proc_bus;extern struct proc_dir_entry *proc_root_driver;extern struct proc_dir_entry *proc_root_kcore; +extern struct proc_dir_entry *proc_vmcore;extern void proc_root_init (void );extern void proc_misc_init (void );
@@ -112,6 +113,7 @@ extern int proc_readdir(struct file *, vextern struct dentry *proc_lookup (struct inode *,struct dentry *,struct nameidata *);extern struct file_operations proc_kcore_operations; +extern struct file_operations proc_vmcore_operations;extern struct file_operations proc_kmsg_operations;extern struct file_operations ppc_htab_operations;
_
Re: [PATCH][6/6]Device abstraction for linear/raw view of the dump
Regards, Hari
Signature · 4 lines
Hariprasad Nellitheertha Linux Technology Center India Software Labs IBM India, Bangalore
This patch contains the code that enables us to access the previous kernel's memory as /dev/hmem.
Signed off by Hariprasad Nellitheertha <[email protected]> Signed off by Adam Litke <[email protected]>
---
linux-2.6.8.1-hari/Documentation/devices.txt | 1 linux-2.6.8.1-hari/drivers/char/mem.c | 72 +++++++++++++++++++++++++++ 2 files changed, 73 insertions(+)
Documentation/devices.txt renamed from Documentation/devices.txt~kd-hmem-268 +1 -0
@@ -100,6 +100,7 @@ Your cooperation is appreciated. 9 = /dev/urandom Faster, less secure random number gen. 10 = /dev/aio Asyncronous I/O notification interface 11 = /dev/kmsg Writes to this come out as printk's + 12 = /dev/hmem Access to kexec-ed crash dump 1 block RAM disk 0 = /dev/ram0 First RAM disk 1 = /dev/ram1 Second RAM disk
drivers/char/mem.c renamed from drivers/char/mem.c~kd-hmem-268 +72 -0
102 lines not on this page · raw message
_
Re: [PATCH][6/6]Device abstraction for linear/raw view of the dump
Quoted 2 lines
This patch contains the code that enables us to access the previous kernel's memory as
/dev/hmem.
One of the bits of feedback we got at kernel summit was that nobody liked the /dev/hmem name ... could we change it to /dev/oldmem, perhaps?
Thanks,
M.
Re: [PATCH][6/6]Device abstraction for linear/raw view of the dump
Hi Martin,
Quoted 5 lines · Martin J. Bligh
Quoted 2 lines
This patch contains the code that enables us to access the previous kernel's memory as
/dev/hmem.One of the bits of feedback we got at kernel summit was that nobody liked the
/dev/hmemname ... could we change it to/dev/oldmem, perhaps?
I'll change it to /dev/oldmem in the next iteration of the patches.
Quoted 5 lines
Thanks,
M.
Regards, Hari
Signature · 4 lines
Hariprasad Nellitheertha Linux Technology Center India Software Labs IBM India, Bangalore
Re: [PATCH][4/6]Register snapshotting before kexec-boot
In reply to Hariprasad Nellitheerthaarch/i386/kernel/machine_kexec.c void __relocate_base_mem(unsigned long b · line 105
Quoted 5 lines · Hariprasad Nellitheertha
Regards, Hari
arch/i386/kernel/machine_kexec.c renamed from arch/i386/kernel/machine_kexec.c~kd-reg-268 +4
-0+/* Now copy over the saved task pointers and the registers +* to the end of the reserved area +*/ + dest_addr = (void *)(__va (CRASH_BACKUP_BASE +CRASH_BACKUP_SIZE ));
Why the cast? Isn't __va() already returning a void*?
-- Dave
Re: [PATCH][4/6]Register snapshotting before kexec-boot
In reply to Hariprasad NellitheerthaThis patch is needed so that the kexec patches will compile on systems that don't have APIC's enabled.
- Ted
# This is a BitKeeper generated diff -Nru style patch. #
# ChangeSet
# 2004/08/18 09:41:41-04:00 [email protected] # Fix so that kexec patches compile on systems when # CONFIG_X86_LOCAL_APIC is disabled. # # include/asm-i386/crash_dump.h # 2004/08/18 09:41:29-04:00 [email protected] +2 -0 # Fix so that kexec patches compile on systems when # CONFIG_X86_LOCAL_APIC is disabled. # diff -Nru a/include/asm-i386/crash_dump.h b/include/asm-i386/crash_dump.h --- a/include/asm-i386/crash_dump.h 2004-08-18 09:42:15 -04:00 +++ b/include/asm-i386/crash_dump.h 2004-08-18 09:42:15 -04:00 @@ -53,7 +53,9 @@ #if defined(CONFIG_X86_IO_APIC) disable_IO_APIC(); #endif +#if defined(CONFIG_X86_LOCAL_APIC) disconnect_bsp_APIC(); +#endif } } #else
Re: [PATCH][4/6]Register snapshotting before kexec-boot
Hi Ted,
Quoted 2 lines · Theodore Ts'o
This patch is needed so that the kexec patches will compile on systems that don't have APIC's enabled.
Thanks a lot for the patch.
Regards, Hari
Signature · 4 lines
Hariprasad Nellitheertha Linux Technology Center India Software Labs IBM India, Bangalore
Re: [PATCH][3/6]Interface for copying the dump pages
In reply to Hariprasad NellitheerthaQuoted 4 lines · Hariprasad Nellitheertha
Regards, Hari
+/* This is the same askmap_atomicbut takes in a pfn instead of a
+ * struct page.
+ */
How about:
/*
* This is the same as kmap_atomic() but can map memory that doesn't
* necessarily have struct page associated with it.
*/
Quoted 2 lines
+ssize_t
copy_hmem_page(unsigned long pfn, char *buf, size_t csize, int userbuf)
...
drivers/char/mem.c static int mmap_mem(struct file * file, · line 246
Quoted 8 lines
drivers/char/mem.c renamed from drivers/char/mem.c~kd-copy-268 +8
-0+if (pfn ==-1 ) { +/* Give them a zeroed page */ +if (userbuf) { +if (clear_user (buf, csize)) +return -EFAULT ; + }else +memset (buf,0 , csize); + }else {
This is really hackish. If you want to zero a userspace page, just zero it in the caller's code, or call a different function. Zeroing a userspace page has nothing to do with copying a highmem page, and it really shouldn't be here. Just changing it from taking a 0 to a -1 from the last time you posted it doesn't really make it any better.
Also, that function might belong in the same area as copy_highpage(), not in some driver. In any case, it certainly needs a big fat comment explaining why it is special, and different from copy_highpage().
If it shouldn't be moved and really is isolated to the mem.c driver, it needs to be declared static.
-- Dave
Re: [PATCH][2/6]Memory preserving reboot using kexec
In reply to Hariprasad NellitheerthaQuoted 10 lines · Hariprasad Nellitheertha
Regards, Hari
arch/i386/kernel/machine_kexec.c renamed from arch/i386/kernel/machine_kexec.c~kd-reb-268 +7
-0+void __relocate_base_mem (unsigned long backup_addr,unsigned long backup_size) +{ +unsigned long pfn, pfn_max; +void *src_addr, *dest_addr; +struct page *page; + + pfn_max = backup_size >>PAGE_SHIFT ;
arch/i386/kernel/machine_kexec.c const extern unsigned int relocate_new_k · line 100
Quoted 10 lines
arch/i386/kernel/machine_kexec.c renamed from arch/i386/kernel/machine_kexec.c~kd-reb-268 +10
-0+for (pfn =0 ; pfn < pfn_max; pfn++) { + src_addr =phys_to_virt (pfn <<PAGE_SHIFT ); + dest_addr = backup_addr + src_addr; +if (!pfn_valid (pfn)) +continue ; + page =pfn_to_page (pfn); +if (PageReserved (page)) +copy_page (dest_addr, src_addr); + } +}
You're getting a little sloppy with your types in there. I know you probably aren't getting warnings for passing unsigned longs to copy_page(), but you should probably still be passing pointers to it.
I think the general convention is to keep physical addresses in unsigned longs and virtual addresses in pointers. Just keep that in mind.
include/asm-i386/crash_dump.h line 35
Quoted 2 lines
include/asm-i386/crash_dump.h new file +2
-0+#define CRASH_BACKUP_BASE 0x08000000 +#define CRASH_BACKUP_SIZE 0x01000000
What are these numbers? Why do you need to define them when your config option is off?
mm/bootmem.c line 34
Quoted 5 lines
mm/bootmem.c renamed from mm/bootmem.c~kd-reb-268 +5
-0+/* +* If we have booted due to a crash, max_pfn will be a very low value. We need +* to know the amount of memory that the previous kernel used. +*/ +unsigned long saved_max_pfn;
I'd probably put that comment next to the place where saved_max_pfn is used instead of where it is declared.
-- Dave
Quoted 3 lines · Hariprasad Nellitheertha
The patches that follow contain the initial implementation for kexec based crash dumping that we are working on.
It seems to be coming together nicely.
Where do we stand with support for other architectures? Do you expect that each architecture will involve a lot of work?
And how much of the i386 implementation do you expect x86_64 can reuse?
Hi Andrew,
Quoted 9 lines · Andrew Morton
Quoted 3 lines · Hariprasad Nellitheertha
The patches that follow contain the initial implementation for kexec based crash dumping that we are working on.
It seems to be coming together nicely.
Where do we stand with support for other architectures? Do you expect that each architecture will involve a lot of work?
I don't think so. The main architecture dependent components are register snapshotting and silencing of other cpus. These are not new problems to solve as other projects such as LKCD, KDB have already done this for most archs.
Quoted 3 lines
And how much of the i386 implementation do you expect
x86_64can reuse?
We should be able to re-use most of the code. The x86_64 port should be ready pretty quickly once kexec itself is available.
Regards, Hari
Signature · 4 lines
Hariprasad Nellitheertha Linux Technology Center India Software Labs IBM India, Bangalore
Quoted 6 lines · Andrew Morton
Quoted 3 lines · Hariprasad Nellitheertha
The patches that follow contain the initial implementation for kexec based crash dumping that we are working on.
It seems to be coming together nicely.
Well it is coming. There is a lot of exploratory work still needed to find what it takes to reliably get a kernel working in the hostile environment present after a kernel panic. That really has barely begun and it likely to turn up some unexpected architecture specific issues.
Eric
Quoted 6 lines · Hariprasad Nellitheertha
Hi,
The patches that follow contain the initial implementation for kexec based crash dumping that we are working on. I had sent this to the fastboot mailing list a couple of weeks ago and this set of patches includes the changes made as per feedback from Andrew, Eric and others.
One significant change is missing. You do not separate out the two use cases of kexec. So on a system that is configured to use call sys_reboot(LINUX_REBOOT_CMD_KEXEC) on reboot I will get a core dump if using your code.
Or alternatively if I call sys_kexec_load and then something in the shutdown scripts triggers a kernel panic it is not OK to start boot the new kernel instead of taking normal panic behavior.
Until the two uses of kexec are separated they two uses of kexec remain mutually exclusive and incompatible, and it I cannot merge your patches into the existing kexec patchset.
.....
In general I still your kexec on panic code is doing way to much, and I think a lot of that is that you don't have a kernel that will run when loaded at a different physical address.
To that end I have written a patch that accomplishes exactly that. Please see my just released kexec patchset.
Eric
Quoted 9 lines · Eric W. Biederman
Quoted 6 lines · Hariprasad Nellitheertha
Hi,
The patches that follow contain the initial implementation for kexec based crash dumping that we are working on. I had sent this to the fastboot mailing list a couple of weeks ago and this set of patches includes the changes made as per feedback from Andrew, Eric and others.
Quoted 4 lines
One significant change is missing. You do not separate out the two use cases of kexec. So on a system that is configured to use call
sys_reboot(LINUX_REBOOT_CMD_KEXEC)on reboot I will get a core dump if using your code.
In some ways, whether we are doing a "crash dump" reboot or a "normal" kexec reboot is determined by the command line parameters that are passed to the kexec loaded kernel. If we do not restrict the memory size and do not add the keyword "dump" in the command line, it will do a normal kexec reboot. The dump file will not show up in the second kernel.
Quoted 4 lines
Or alternatively if I call
sys_kexec_loadand then something in the shutdown scripts triggers a kernel panic it is not OK to start boot the new kernel instead of taking normal panic behavior.
A way to disable kexec reboot from panic code is indeed needed. I will add the necessary code to do this.
Quoted 5 lines
Until the two uses of kexec are separated they two uses of kexec remain mutually exclusive and incompatible, and it I cannot merge your patches into the existing kexec patchset.
Quoted 8 lines
.....
In general I still your kexec on panic code is doing way to much, and I think a lot of that is that you don't have a kernel that will run when loaded at a different physical address.
To that end I have written a patch that accomplishes exactly that. Please see my just released kexec patchset.
Will work on the necessary changes so we can use your patchset.
Quoted 2 lines
Eric
Thanks and Regards, Hari
Signature · 4 lines
Hariprasad Nellitheertha Linux Technology Center India Software Labs IBM India, Bangalore