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

Reply via email to