Skip to contentSkip to conversation

add IRQ context simulation in mce-inject

PATCH Superseded Chen Gong 2 participants 3 messages Sep 19, 2011 – Oct 21, 2011 x86

lore
Share & tools
lore

Chen Gong

author
#0 lore raw

PATCH 1/1 add IRQ context simulation in mce-inject

From: Chen Gong <[email protected]>

Current mce-inject can simulate some kinds of scenarios, such as one CPU working in process context, and other CPUs working in NMI context. To extend the coverage of test range, a new IRQ context for other CPUs is added.

---
 arch/x86/include/asm/mce.h              |    1 +
 arch/x86/kernel/cpu/mcheck/mce-inject.c |   34 +++++++++++++++++++++++++++---
 2 files changed, 31 insertions(+), 4 deletions(-)
arch/x86/include/asm/mce.h +1 -0
index c9321f3..2490e8c 100644
@@ -54,6 +54,7 @@
 #define MCJ_CTX_IRQ		2    /* inject context: IRQ */
 #define MCJ_NMI_BROADCAST	4    /* do NMI broadcasting */
 #define MCJ_EXCEPTION		8    /* raise as exception */
+#define MCJ_IRQ_BRAODCAST	0x10 /* do IRQ broadcasting */
  /* Fields are zero when not available */
 struct mce {
arch/x86/kernel/cpu/mcheck/mce-inject.c +29 -4
index 0ed633c..8f7a119 100644
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/fs.h>
+#include <linux/preempt.h>
 #include <linux/smp.h>
 #include <linux/notifier.h>
 #include <linux/kdebug.h>
@@ -94,6 +95,18 @@ static int mce_raise_notify(struct notifier_block *self,
 	return NOTIFY_STOP;
 }
 +static void mce_irq_ipi(void *info)
+{
+	int cpu = smp_processor_id();
+	struct mce *m = &__get_cpu_var(injectm);
+
+	if (cpumask_test_cpu(cpu, mce_inject_cpumask) &&
+		m->inject_flags & MCJ_EXCEPTION) {
+		cpumask_clear_cpu(cpu, mce_inject_cpumask);
+		raise_exception(m, NULL);
+	}
+}
+
 static struct notifier_block mce_raise_nb = {
 	.notifier_call = mce_raise_notify,
 	.priority = NMI_LOCAL_NORMAL_PRIOR,
@@ -146,9 +159,10 @@ static void raise_mce(struct mce *m)
 		return;
  #ifdef CONFIG_X86_LOCAL_APIC
-	if (m->inject_flags & MCJ_NMI_BROADCAST) {
+	if (m->inject_flags & (MCJ_IRQ_BRAODCAST | MCJ_NMI_BROADCAST)) {
 		unsigned long start;
 		int cpu;
+
 		get_online_cpus();
 		cpumask_copy(mce_inject_cpumask, cpu_online_mask);
 		cpumask_clear_cpu(get_cpu(), mce_inject_cpumask);
@@ -158,13 +172,25 @@ static void raise_mce(struct mce *m)
 			    MCJ_CTX(mcpu->inject_flags) != MCJ_CTX_RANDOM)
 				cpumask_clear_cpu(cpu, mce_inject_cpumask);
 		}
-		if (!cpumask_empty(mce_inject_cpumask))
-			apic->send_IPI_mask(mce_inject_cpumask, NMI_VECTOR);
+		if (!cpumask_empty(mce_inject_cpumask)) {
+			if (m->inject_flags & MCJ_IRQ_BRAODCAST) {
+				/*
+				 * don't wait because mce_irq_ipi is necessary
+				 * to be sync with following raise_local
+				 */
+				preempt_disable();
+				smp_call_function_many(mce_inject_cpumask,
+					mce_irq_ipi, NULL, 0);
+				preempt_enable();
+			} else if (m->inject_flags & MCJ_NMI_BROADCAST)
+				apic->send_IPI_mask(mce_inject_cpumask,
+						NMI_VECTOR);
+		}
 		start = jiffies;
 		while (!cpumask_empty(mce_inject_cpumask)) {
 			if (!time_before(jiffies, start + 2*HZ)) {
 				printk(KERN_ERR
-				"Timeout waiting for mce inject NMI %lx\n",
+				"Timeout waiting for mce inject %lx\n",
 					*cpumask_bits(mce_inject_cpumask));
 				break;
 			}
Signature · 1 line
1.7.1
#1 lore raw
Quoted 6 lines · Chen Gong

From: Chen Gong <[email protected]>

Current mce-inject can simulate some kinds of scenarios, such as one CPU working in process context, and other CPUs working in NMI context. To extend the coverage of test range, a new IRQ context for other CPUs is added.

Looks good to me.
-Andi

author
#2 lore raw
Quoted 8 lines · Andi Kleen
Quoted 6 lines · Chen Gong

From: Chen Gong <[email protected]>

Current mce-inject can simulate some kinds of scenarios, such as one CPU working in process context, and other CPUs working in NMI context. To extend the coverage of test range, a new IRQ context for other CPUs is added.

Quoted 4 lines

Looks good to me.
-Andi

--

Hi, Andi

I will resend this patch, do you agree I add you as the "Signed-off-By" in the next post?