[PATCH 2/2] IA64 kdump: MCA notify_die events

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add DIE_MCA_MONARCH_LEAVE and DIE_MCA_RENDZVOUS_LEAVE
events handling in kdump_init_notifier().

We let ia64_mca_handler() and ia64_mca_rendez_int_handler()
to perform the MCA handling. The slave cpus will be sent to the
SAL slave loop on the DIE_MCA_RENDZVOUS_LEAVE event, and the
monarch will start the kdump kernel on the DIE_MCA_MONARCH_LEAVE
event.

I initially created a machine_kdump_on_mca() but decided
to simply use machine_kdump_on_init() in the case of
DIE_MCA_MONARCH_LEAVE since no special handling is needed.


signed-Off-By:  Jay Lan <jlan@xxxxxxx>





Index: linux/arch/ia64/kernel/crash.c
===================================================================
--- linux.orig/arch/ia64/kernel/crash.c	2006-11-10 14:48:53.033147572 -0800
+++ linux/arch/ia64/kernel/crash.c	2006-11-10 14:50:24.014240287 -0800
@@ -24,6 +24,7 @@
 int kdump_status[NR_CPUS];
 atomic_t kdump_cpu_freezed;
 int kdump_on_init = 1;
+extern int kdump_in_progress;
 
 ssize_t
 copy_oldmem_page(unsigned long pfn, char *buf,
@@ -165,12 +166,16 @@ kdump_init_notifier(struct notifier_bloc
 	if (!kdump_on_init)
 		return NOTIFY_DONE;
 
-	if (val != DIE_INIT_MONARCH_ENTER && val != DIE_INIT_SLAVE_ENTER)
+	if (val != DIE_INIT_MONARCH_ENTER &&
+	    val != DIE_INIT_SLAVE_ENTER &&
+	    val != DIE_MCA_RENDZVOUS_LEAVE &&
+	    val != DIE_MCA_MONARCH_LEAVE)
 		return NOTIFY_DONE;
 
 	nd = (struct ia64_mca_notify_die *)args->err;
 	/* Reason code 1 means machine check rendezous*/
-	if (nd->sos->rv_rc == 1)
+	if ((val==DIE_INIT_MONARCH_ENTER || val==DIE_INIT_SLAVE_ENTER) &&
+	    nd->sos->rv_rc == 1)
 		return NOTIFY_DONE;
 
 	if (kdump_sending_init)
@@ -183,6 +188,15 @@ kdump_init_notifier(struct notifier_bloc
 		case DIE_INIT_SLAVE_ENTER:
 			unw_init_running(kdump_cpu_freeze, NULL);
 			break;
+		case DIE_MCA_RENDZVOUS_LEAVE:
+			if (kdump_in_progress)
+				unw_init_running(kdump_cpu_freeze, NULL);
+			break;
+		case DIE_MCA_MONARCH_LEAVE:
+			/* die_register->signr indicate if MCA is recoverable */
+			if (!args->signr)
+				machine_kdump_on_init();
+			break;
 	}
 	return NOTIFY_DONE;
 }
Index: linux/arch/ia64/kernel/mca.c
===================================================================
--- linux.orig/arch/ia64/kernel/mca.c	2006-11-10 14:48:41.773012428 -0800
+++ linux/arch/ia64/kernel/mca.c	2006-11-10 15:17:22.018866761 -0800
@@ -92,6 +92,11 @@
 # define IA64_MCA_DEBUG(fmt...)
 #endif
 
+#ifdef CONFIG_KEXEC
+/* Used by arch/ia64/kernel/crash.c */
+int kdump_in_progress;
+#endif
+
 /* Used by mca_asm.S */
 u32				ia64_mca_serialize;
 DEFINE_PER_CPU(u64, ia64_mca_data); /* == __per_cpu_mca[smp_processor_id()] */
@@ -1066,6 +1071,15 @@ ia64_mca_handler(struct pt_regs *regs, s
 		rh->severity = sal_log_severity_corrected;
 		ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA);
 		sos->os_status = IA64_MCA_CORRECTED;
+#ifdef CONFIG_KEXEC
+	} else {
+		kdump_in_progress = 1;
+		/* In the case of (!recover), notify_die(DIE_MCA_MONARCH_LEAVE)
+		   will not return. A dump kernel will be booted. Need to set
+		   nonarch_cpu here to get slave cpus out of looping in OS.
+		 */
+		monarch_cpu = -1;
+#endif
 	}
 	if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, (long)&nd, 0, recover)
 			== NOTIFY_STOP)


[Index of Archives]     [Linux Kernel]     [Sparc Linux]     [DCCP]     [Linux ARM]     [Yosemite News]     [Linux SCSI]     [Linux x86_64]     [Linux for Ham Radio]

  Powered by Linux