Hello,
I made a first experimental patch to apply on Nan hai´s patch for 2.6.15.4.
I registered an INIT notifier for monarch and slave cpus to call kexec
and restart on a kdump kernel using the INIT trigger. This only work on
a single processor kernel because hotplug is not reliable at this moment.
So, I changed the panic and sysrq call to kexec to use IPI INIT instead
of just a maskable IPI.
Now, all cpus call ´crash_save_this_cpu´, but I don´t save regs from
INIT signal. How do you think you will save cpus datas ? In a specific
exported structure like in LKCD ? How will they be used by gdb ?
I have some questions :
- Should the priority of the kexec INIT notifier be the highest to be
run first or lowest to see the backtrace of all tasks on the system ?
- We could avoid to send an INIT IPI if we have a single processor
system, but the stack management will be different.
- Which INIT data and where save them ?
- We can use a second lock for the kdump image : kdump_lock
- We could avoid to send an INIT IPI to the cpu which has paniced, but
the stack will be different.
I have found a bug : if I load a kdump kernel and I execute ´kexec -e´,
I lost the network connection ?! I have to run ´/etc/init.d/network restart´
I don´t know if all code is in the good file, it is a first experimental
patch and I would like to have Nan hai´s opinion before going further.
Do you have an idea when you will release the merged patch with kdump ?
Thank you !
Best regards,
Benoit
#Author Benoit Welterlen - [EMAIL PROTECTED]
diff -uNr linux-2.6.15.4.kdump.firstkernel/arch/ia64/kernel/crash.c linux-2.6.15.4.kdump.firstkernel.welty/arch/ia64/kernel/crash.c
--- linux-2.6.15.4.kdump.firstkernel/arch/ia64/kernel/crash.c 2006-03-15 08:33:06.000000000 +0100
+++ linux-2.6.15.4.kdump.firstkernel.welty/arch/ia64/kernel/crash.c 2006-03-22 14:42:08.000000000 +0100
@@ -10,6 +10,7 @@
#include <linux/elf.h>
#include <linux/elfcore.h>
+static int kdump_lock = 0;
note_buf_t crash_notes[NR_CPUS];
static void device_shootdown(void)
@@ -53,7 +54,7 @@
memset(buf, 0, sizeof(struct elf_note));
}
-static void crash_save_this_cpu(void)
+void crash_save_this_cpu(void)
{
void *buf;
struct elf_prstatus prstatus;
@@ -94,11 +95,32 @@
final_note(buf);
}
-void machine_crash_shutdown(void)
+void machine_crash_shutdown(struct pt_regs *regs)
{
crash_save_this_cpu();
device_shootdown();
-#ifdef CONFIG_SMP
- smp_send_stop();
-#endif
+}
+
+void ia64_crash_kexec(struct pt_regs *regs)
+{
+ int cpu;
+ int locked;
+
+ /* Take the kdump_lock here to prevent an
+ * other CPU to send IPI INIT too.
+ */
+ locked = xchg(&kdump_lock, 1);
+ if (!locked) {
+ printk("Send an IPI INIT to all cpus \n");
+ for_each_online_cpu(cpu) {
+ if (cpu != smp_processor_id()){
+ printk("Send IPI INIT to cpu nr. %i\n",cpu);
+ platform_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0);
+ }
+ }
+ /* Send an IPI to myself to have the same stack as an INIT case */
+ printk("Send IPI INIT to myself cpu nr. %i\n",smp_processor_id());
+ platform_send_ipi(smp_processor_id(), 0, IA64_IPI_DM_INIT, 0);
+ xchg(&kdump_lock, 0);
+ }
}
diff -uNr linux-2.6.15.4.kdump.firstkernel/arch/ia64/kernel/machine_kexec.c linux-2.6.15.4.kdump.firstkernel.welty/arch/ia64/kernel/machine_kexec.c
--- linux-2.6.15.4.kdump.firstkernel/arch/ia64/kernel/machine_kexec.c 2006-03-15 08:33:06.000000000 +0100
+++ linux-2.6.15.4.kdump.firstkernel.welty/arch/ia64/kernel/machine_kexec.c 2006-03-22 14:17:43.000000000 +0100
@@ -11,11 +11,57 @@
#include <linux/kexec.h>
#include <asm/meminit.h>
#include <asm/delay.h>
+#include <asm/kdebug.h>
+static int
+kexec_slave_init_process(struct notifier_block *self, unsigned long val, void *data)
+{
+ if (val != DIE_INIT_SLAVE_PROCESS)
+ return NOTIFY_DONE;
+
+ printk(KERN_ERR "kexec INIT slave : Saving cpu nr. %i datas \n", smp_processor_id());
+
+ crash_save_this_cpu();
+ return NOTIFY_DONE;
+}
+
+static int
+kexec_monarch_init_process(struct notifier_block *self, unsigned long val, void *data)
+{
+ if (val != DIE_INIT_MONARCH_PROCESS)
+ return NOTIFY_DONE;
+
+ printk(KERN_ERR "kexec INIT monarch : A debug kernel will be started if a debug image has been loaded \n");
+
+ crash_kexec(NULL);
+ return NOTIFY_DONE;
+}
+
int
machine_kexec_prepare(struct kimage * image)
{
- return 0;
+ /* Register the kexec monarch init handler */
+ static struct notifier_block kexec_init_monarch_nb = {
+ .notifier_call = kexec_monarch_init_process,
+ .priority = 1 /* We need to notified first ?! */
+ };
+ /* Register the kexec slave init handler */
+ static struct notifier_block kexec_init_slave_nb = {
+ .notifier_call = kexec_slave_init_process,
+ .priority = 0 /* We need to notified last */
+ };
+
+ if (register_die_notifier(&kexec_init_monarch_nb))
+ printk(KERN_ERR "Failed to register kexec monarch INIT process\n");
+ else
+ printk("%s: registered OS INIT monarch kexec handler with SAL\n", __FUNCTION__);
+
+ if (register_die_notifier(&kexec_init_slave_nb))
+ printk(KERN_ERR "Failed to register kexec monarch INIT process\n");
+ else
+ printk("%s: registered OS INIT slave kexec handler with SAL\n", __FUNCTION__);
+
+ return 0;
}
void
@@ -65,3 +111,4 @@
for(;;);
}
+
diff -uNr linux-2.6.15.4.kdump.firstkernel/drivers/char/sysrq.c linux-2.6.15.4.kdump.firstkernel.welty/drivers/char/sysrq.c
--- linux-2.6.15.4.kdump.firstkernel/drivers/char/sysrq.c 2006-02-10 08:22:48.000000000 +0100
+++ linux-2.6.15.4.kdump.firstkernel.welty/drivers/char/sysrq.c 2006-03-22 14:21:32.000000000 +0100
@@ -100,7 +100,11 @@
static void sysrq_handle_crashdump(int key, struct pt_regs *pt_regs,
struct tty_struct *tty)
{
+#ifdef CONFIG_IA64
+ ia64_crash_kexec(pt_regs);
+#else
crash_kexec(pt_regs);
+#endif
}
static struct sysrq_key_op sysrq_crashdump_op = {
.handler = sysrq_handle_crashdump,
diff -uNr linux-2.6.15.4.kdump.firstkernel/include/asm-ia64/kexec.h linux-2.6.15.4.kdump.firstkernel.welty/include/asm-ia64/kexec.h
--- linux-2.6.15.4.kdump.firstkernel/include/asm-ia64/kexec.h 2006-03-15 08:33:12.000000000 +0100
+++ linux-2.6.15.4.kdump.firstkernel.welty/include/asm-ia64/kexec.h 2006-03-22 14:22:55.000000000 +0100
@@ -23,6 +23,8 @@
/* The native architecture */
#define KEXEC_ARCH KEXEC_ARCH_IA_64
+extern void ia64_crash_kexec(struct pt_regs *regs);
+
#define MAX_NOTE_BYTES 1024
typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
extern note_buf_t crash_notes[];
diff -uNr linux-2.6.15.4.kdump.firstkernel/include/linux/kexec.h linux-2.6.15.4.kdump.firstkernel.welty/include/linux/kexec.h
--- linux-2.6.15.4.kdump.firstkernel/include/linux/kexec.h 2006-03-15 08:33:12.000000000 +0100
+++ linux-2.6.15.4.kdump.firstkernel.welty/include/linux/kexec.h 2006-03-22 14:19:00.000000000 +0100
@@ -105,6 +105,7 @@
extern void crash_kexec(struct pt_regs *);
int kexec_should_crash(struct task_struct *);
extern struct kimage *kexec_image;
+extern void crash_save_this_cpu(void);
#define KEXEC_ON_CRASH 0x00000001
#define KEXEC_ARCH_MASK 0xffff0000
diff -uNr linux-2.6.15.4.kdump.firstkernel/kernel/panic.c linux-2.6.15.4.kdump.firstkernel.welty/kernel/panic.c
--- linux-2.6.15.4.kdump.firstkernel/kernel/panic.c 2006-02-10 08:22:48.000000000 +0100
+++ linux-2.6.15.4.kdump.firstkernel.welty/kernel/panic.c 2006-03-22 14:21:54.000000000 +0100
@@ -83,7 +83,11 @@
* everything else.
* Do we want to call this before we try to display a message?
*/
+#ifdef CONFIG_IA64
+ ia64_crash_kexec(NULL);
+#else
crash_kexec(NULL);
+#endif
#ifdef CONFIG_SMP
/*
_______________________________________________
fastboot mailing list
[email protected]
https://lists.osdl.org/mailman/listinfo/fastboot