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

[Xen-changelog] [xen-unstable] x86: Fix cpu online/offline bug: mce memory leak.



# HG changeset patch
# User Liu, Jinsong <jinsong.liu@xxxxxxxxx>
# Date 1299061866 0
# Node ID f71212f712fd8dad7997785fd61edca28c0d9536
# Parent  666006a3a4ad3e4015fa0610aae6ebda3d271523
x86: Fix cpu online/offline bug: mce memory leak.

Current Xen mce logic didn't free mcabanks. This would be a memory
leak when cpu offline.  When repeatly do cpu online/offline, this
memory leak would make xenpool shrink, and at a time point, will call
alloc_heap_pages --> flush_area_mask, which
ASSERT(local_irq_is_enabled()).  However, cpu online is irq disable,
so it finally result in Xen crash.

This patch fix the memory leak bug, and tested OK over 50,000 round
cpu online/offline.

Signed-off-by: Liu, Jinsong <jinsong.liu@xxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxx>
---


diff -r 666006a3a4ad -r f71212f712fd xen/arch/x86/cpu/mcheck/mce_intel.c
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c       Wed Mar 02 10:23:23 2011 +0000
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c       Wed Mar 02 10:31:06 2011 +0000
@@ -1227,9 +1227,24 @@
     mce_uhandler_num = sizeof(intel_mce_uhandlers)/sizeof(struct 
mca_error_handler);
 }
 
-static int intel_init_mca_banks(void)
+static void cpu_mcabank_free(unsigned int cpu)
 {
-    struct mca_banks *mb1, *mb2, * mb3;
+    struct mca_banks *mb1, *mb2, *mb3, *mb4;
+
+    mb1 = per_cpu(mce_clear_banks, cpu);
+    mb2 = per_cpu(no_cmci_banks, cpu);
+    mb3 = per_cpu(mce_banks_owned, cpu);
+    mb4 = per_cpu(poll_bankmask, cpu);
+
+    mcabanks_free(mb1);
+    mcabanks_free(mb2);
+    mcabanks_free(mb3);
+    mcabanks_free(mb4);
+}
+
+static int cpu_mcabank_alloc(unsigned int cpu)
+{
+    struct mca_banks *mb1, *mb2, *mb3;
 
     mb1 = mcabanks_alloc();
     mb2 = mcabanks_alloc();
@@ -1237,9 +1252,9 @@
     if (!mb1 || !mb2 || !mb3)
         goto out;
 
-    __get_cpu_var(mce_clear_banks) = mb1;
-    __get_cpu_var(no_cmci_banks) = mb2;
-    __get_cpu_var(mce_banks_owned) = mb3;
+    per_cpu(mce_clear_banks, cpu) = mb1;
+    per_cpu(no_cmci_banks, cpu) = mb2;
+    per_cpu(mce_banks_owned, cpu) = mb3;
 
     return 0;
 out:
@@ -1249,11 +1264,46 @@
     return -ENOMEM;
 }
 
+static int cpu_callback(
+    struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+    unsigned int cpu = (unsigned long)hcpu;
+    int rc = 0;
+
+    switch ( action )
+    {
+    case CPU_UP_PREPARE:
+        rc = cpu_mcabank_alloc(cpu);
+        break;
+    case CPU_DYING:
+        cpu_mcheck_disable();
+        break;
+    case CPU_UP_CANCELED:
+    case CPU_DEAD:
+        cpu_mcheck_distribute_cmci();
+        cpu_mcabank_free(cpu);
+        break;
+    default:
+        break;
+    }
+
+    return !rc ? NOTIFY_DONE : notifier_from_errno(rc);
+}
+
+static struct notifier_block cpu_nfb = {
+    .notifier_call = cpu_callback
+};
+
 /* p4/p6 family have similar MCA initialization process */
 enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c)
 {
-    if (intel_init_mca_banks())
-         return mcheck_none;
+    if ( smp_processor_id() == 0 )
+    {
+        /* Early MCE initialisation for BSP. */
+        if ( cpu_mcabank_alloc(0) )
+            BUG();
+        register_cpu_notifier(&cpu_nfb);
+    }
 
     intel_init_mca(c);
 
@@ -1298,31 +1348,3 @@
     return ret;
 }
 
-static int cpu_callback(
-    struct notifier_block *nfb, unsigned long action, void *hcpu)
-{
-    switch ( action )
-    {
-    case CPU_DYING:
-        cpu_mcheck_disable();
-        break;
-    case CPU_DEAD:
-        cpu_mcheck_distribute_cmci();
-        break;
-    default:
-        break;
-    }
-
-    return NOTIFY_DONE;
-}
-
-static struct notifier_block cpu_nfb = {
-    .notifier_call = cpu_callback
-};
-
-static int __init intel_mce_initcall(void)
-{
-    register_cpu_notifier(&cpu_nfb);
-    return 0;
-}
-presmp_initcall(intel_mce_initcall);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.