[PATCH] kdump: dynamic per cpu allocation of memory for saving cpu registers

- In case of system crash, current state of cpu registers is saved in memory
  in elf note format.  So far memory for storing elf notes was being allocated
  statically for NR_CPUS.

- This patch introduces dynamic allocation of memory for storing elf notes.
  It uses alloc_percpu() interface.  This should lead to better memory usage.

- Introduced based on Andi Kleen's and Eric W. Biederman's suggestions.

- This patch also moves memory allocation for elf notes from architecture
  dependent portion to architecture independent portion.  Now crash_notes is
  architecture independent.  The whole idea is that size of memory to be
  allocated per cpu (MAX_NOTE_BYTES) can be architecture dependent and
  allocation of this memory can be architecture independent.

Signed-off-by: Vivek Goyal <vgoyal@in.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Vivek Goyal 2006-01-09 20:51:41 -08:00 committed by Linus Torvalds
parent 8240941157
commit cc57165874
10 changed files with 21 additions and 24 deletions

View File

@ -25,7 +25,6 @@
#include <mach_ipi.h> #include <mach_ipi.h>
note_buf_t crash_notes[NR_CPUS];
/* This keeps a track of which one is crashing cpu. */ /* This keeps a track of which one is crashing cpu. */
static int crashing_cpu; static int crashing_cpu;
@ -72,7 +71,9 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
* squirrelled away. ELF notes happen to provide * squirrelled away. ELF notes happen to provide
* all of that that no need to invent something new. * all of that that no need to invent something new.
*/ */
buf = &crash_notes[cpu][0]; buf = (u32*)per_cpu_ptr(crash_notes, cpu);
if (!buf)
return;
memset(&prstatus, 0, sizeof(prstatus)); memset(&prstatus, 0, sizeof(prstatus));
prstatus.pr_pid = current->pid; prstatus.pr_pid = current->pid;
elf_core_copy_regs(&prstatus.pr_reg, regs); elf_core_copy_regs(&prstatus.pr_reg, regs);

View File

@ -28,12 +28,6 @@ typedef NORET_TYPE void (*relocate_new_kernel_t)(
const extern unsigned char relocate_new_kernel[]; const extern unsigned char relocate_new_kernel[];
const extern unsigned int relocate_new_kernel_size; const extern unsigned int relocate_new_kernel_size;
/*
* Provide a dummy crash_notes definition while crash dump arrives to ppc.
* This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
*/
note_buf_t crash_notes[NR_CPUS];
void machine_shutdown(void) void machine_shutdown(void)
{ {
if (ppc_md.machine_shutdown) if (ppc_md.machine_shutdown)

View File

@ -10,8 +10,6 @@
#include <linux/threads.h> #include <linux/threads.h>
#include <linux/kexec.h> #include <linux/kexec.h>
note_buf_t crash_notes[NR_CPUS];
void machine_crash_shutdown(struct pt_regs *regs) void machine_crash_shutdown(struct pt_regs *regs)
{ {
} }

View File

@ -19,8 +19,6 @@
#include <asm/nmi.h> #include <asm/nmi.h>
#include <asm/hw_irq.h> #include <asm/hw_irq.h>
note_buf_t crash_notes[NR_CPUS];
void machine_crash_shutdown(struct pt_regs *regs) void machine_crash_shutdown(struct pt_regs *regs)
{ {
/* This function is only called after the system /* This function is only called after the system

View File

@ -26,8 +26,5 @@
#define KEXEC_ARCH KEXEC_ARCH_386 #define KEXEC_ARCH KEXEC_ARCH_386
#define MAX_NOTE_BYTES 1024 #define MAX_NOTE_BYTES 1024
typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
extern note_buf_t crash_notes[];
#endif /* _I386_KEXEC_H */ #endif /* _I386_KEXEC_H */

View File

@ -38,9 +38,6 @@
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC
#define MAX_NOTE_BYTES 1024 #define MAX_NOTE_BYTES 1024
typedef u32 note_buf_t[MAX_NOTE_BYTES / sizeof(u32)];
extern note_buf_t crash_notes[];
#ifdef __powerpc64__ #ifdef __powerpc64__
extern void kexec_smp_wait(void); /* get and clear naca physid, wait for extern void kexec_smp_wait(void); /* get and clear naca physid, wait for

View File

@ -35,8 +35,5 @@
#define KEXEC_ARCH KEXEC_ARCH_S390 #define KEXEC_ARCH KEXEC_ARCH_S390
#define MAX_NOTE_BYTES 1024 #define MAX_NOTE_BYTES 1024
typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
extern note_buf_t crash_notes[];
#endif /*_S390_KEXEC_H */ #endif /*_S390_KEXEC_H */

View File

@ -26,8 +26,5 @@
#define KEXEC_ARCH KEXEC_ARCH_X86_64 #define KEXEC_ARCH KEXEC_ARCH_X86_64
#define MAX_NOTE_BYTES 1024 #define MAX_NOTE_BYTES 1024
typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
extern note_buf_t crash_notes[];
#endif /* _X86_64_KEXEC_H */ #endif /* _X86_64_KEXEC_H */

View File

@ -125,6 +125,8 @@ extern struct kimage *kexec_image;
/* Location of a reserved region to hold the crash kernel. /* Location of a reserved region to hold the crash kernel.
*/ */
extern struct resource crashk_res; extern struct resource crashk_res;
typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
extern note_buf_t *crash_notes;
#else /* !CONFIG_KEXEC */ #else /* !CONFIG_KEXEC */
struct pt_regs; struct pt_regs;

View File

@ -26,6 +26,9 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
/* Per cpu memory for storing cpu states in case of system crash. */
note_buf_t* crash_notes;
/* Location of the reserved area for the crash kernel */ /* Location of the reserved area for the crash kernel */
struct resource crashk_res = { struct resource crashk_res = {
.name = "Crash kernel", .name = "Crash kernel",
@ -1060,3 +1063,16 @@ void crash_kexec(struct pt_regs *regs)
xchg(&kexec_lock, 0); xchg(&kexec_lock, 0);
} }
} }
static int __init crash_notes_memory_init(void)
{
/* Allocate memory for saving cpu registers. */
crash_notes = alloc_percpu(note_buf_t);
if (!crash_notes) {
printk("Kexec: Memory allocation for saving cpu register"
" states failed\n");
return -ENOMEM;
}
return 0;
}
module_init(crash_notes_memory_init)