Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 89877e42827f16fa5f86b1df0c2860b1 > files > 2474

kernel-2.6.18-128.1.10.el5.src.rpm

From: Aristeu Rozanski <aris@redhat.com>
Date: Wed, 20 Aug 2008 13:17:04 -0400
Subject: [x86] nmi: change nmi_active usage
Message-id: 20080820171650.788102000@redhat.com
O-Subject: [RHEL5.3 PATCH 18/25] nmi: change nmi_active usage on i386
Bugzilla: 447618

https://bugzilla.redhat.com/show_bug.cgi?id=447618

add nmi_watchdog_active and use it to count the number of CPUs with the NMI
watchdog enabled. keep it in sync with nmi_active variable for kABI reasons.

upstream: f2802e7f571c05f9a901b1f5bd144aa730ccc88e

update: using a different name instead of making nmi_active atomic (kABI)

diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index 8b66535..98ea080 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -47,6 +47,12 @@ static unsigned int lapic_nmi_owner;
 #define LAPIC_NMI_WATCHDOG	(1<<0)
 #define LAPIC_NMI_RESERVED	(1<<1)
 
+/*
+ * the upstream variable 'nmi_active' is called 'nmi_watchdog_active' on
+ * RHEL-5 for kABI reasons.
+ */
+atomic_t nmi_watchdog_active = ATOMIC_INIT(0);
+
 static DEFINE_PER_CPU(short, wd_enabled);
 
 /* nmi_active:
@@ -147,6 +153,9 @@ static int __init check_nmi_watchdog(void)
 	unsigned int *prev_nmi_count;
 	int cpu;
 
+	if (!atomic_read(&nmi_watchdog_active))
+		return 0;
+
 	if (nmi_watchdog == NMI_NONE)
 		return 0;
 
@@ -178,12 +187,19 @@ static int __init check_nmi_watchdog(void)
 				cpu,
 				prev_nmi_count[cpu],
 				nmi_count(cpu));
-			nmi_active = 0;
+			if (atomic_dec_and_test(&nmi_watchdog_active))
+				nmi_active = 0;
 			lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG;
 			kfree(prev_nmi_count);
 			return -1;
 		}
 	}
+	if (!atomic_read(&nmi_watchdog_active)) {
+		atomic_set(&nmi_watchdog_active, -1);
+		nmi_active = -1;
+		return -1;
+	}
+
 	endflag = 1;
 	printk("OK.\n");
 
@@ -269,20 +285,25 @@ void release_lapic_nmi(void)
 		enable_lapic_nmi_watchdog();
 }
 
+static int old_ioapic_count;
 void disable_timer_nmi_watchdog(void)
 {
-	if ((nmi_watchdog != NMI_IO_APIC) || (nmi_active <= 0))
+	if ((nmi_watchdog != NMI_IO_APIC) ||
+	    (atomic_read(&nmi_watchdog_active) <= 0))
 		return;
 
 	unset_nmi_callback();
+	old_ioapic_count = atomic_read(&nmi_watchdog_active);
+	atomic_set(&nmi_watchdog_active, -1);
 	nmi_active = -1;
 	nmi_watchdog = NMI_NONE;
 }
 
 void enable_timer_nmi_watchdog(void)
 {
-	if (nmi_active < 0) {
+	if (atomic_read(&nmi_watchdog_active) < 0) {
 		nmi_watchdog = NMI_IO_APIC;
+		atomic_set(&nmi_watchdog_active, old_ioapic_count);
 		touch_nmi_watchdog();
 		nmi_active = 1;
 	}
@@ -322,7 +343,7 @@ static int __init init_lapic_nmi_sysfs(void)
 {
 	int error;
 
-	if (nmi_active == 0 || nmi_watchdog != NMI_LOCAL_APIC)
+	if (atomic_read(&nmi_watchdog_active) == 0 || nmi_watchdog != NMI_LOCAL_APIC)
 		return 0;
 
 	error = sysdev_class_register(&nmi_sysclass);
@@ -383,7 +404,8 @@ void setup_apic_nmi_watchdog (void)
 		/* FALL THROUGH */
 	case NMI_IO_APIC:
 		__get_cpu_var(wd_enabled) = 1;
-		atomic_inc(&nmi_active);
+		if (atomic_inc_return(&nmi_watchdog_active) == 1)
+			nmi_active = 1;
 	}
 }