Sophie

Sophie

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

kernel-2.6.18-128.1.10.el5.src.rpm

From: Gerd Hoffmann <kraxel@redhat.com>
Subject: [RHEL-5.1 PATCH 10/10] xen: save/restore fix
Date: Fri, 15 Jun 2007 10:58:11 +0200
Bugzilla: 222128
Message-Id: <467254A3.2010508@redhat.com>
Changelog: [xen] save/restore fix


  Hi,

This patch fixes a locking bug in the save/restore path, needed to make 
save/restore work reliable for SMP guests.

cheers,
  Gerd

# HG changeset patch
# User kfraser@localhost.localdomain
# Date 1172685319 0
# Node ID c3c03089c59ef515766636dd4afef6573f3b6b42
# Parent  8ba425b640b3c7f81c17eb45972eff6eabe9f94d
linux: More save/restore fixes. Fix deadlock of cpu_hotplug_lock vs
workqueue_mutex. This is a new deadlock since the workqueue_mutex is
acquired in the workqueue_cpu_calbback() function across
CPU_UP_PREPARE->CPU_ONLINE.

The fix is for us not to rudely grab the cpu_hotplug_lock() during
save/restore -- it's really not necessary.

This patch is applicable to any of our 2.6 kernels, but is absolutely
required from 2.6.18 onwards.

Signed-off-by: Keir Fraser <keir@xensource.com>

---
 drivers/xen/core/cpu_hotplug.c |   37 +++++++++++--------------------------
 drivers/xen/core/smpboot.c     |    6 ++++--
 include/xen/cpu_hotplug.h      |    6 ------
 3 files changed, 15 insertions(+), 34 deletions(-)

Index: linux-2.6.18.noarch/drivers/xen/core/cpu_hotplug.c
===================================================================
--- linux-2.6.18.noarch.orig/drivers/xen/core/cpu_hotplug.c
+++ linux-2.6.18.noarch/drivers/xen/core/cpu_hotplug.c
@@ -122,29 +122,19 @@ arch_initcall(setup_vcpu_hotplug_event);
 
 int smp_suspend(void)
 {
-	int i, err;
-
-	lock_cpu_hotplug();
+	int cpu, err;
 
-	/*
-	 * Take all other CPUs offline. We hold the hotplug mutex to
-	 * avoid other processes bringing up CPUs under our feet.
-	 */
-	while (num_online_cpus() > 1) {
-		unlock_cpu_hotplug();
-		for_each_online_cpu(i) {
-			if (i == 0)
-				continue;
-			err = cpu_down(i);
-			if (err) {
-				printk(KERN_CRIT "Failed to take all CPUs "
-				       "down: %d.\n", err);
-				for_each_possible_cpu(i)
-					vcpu_hotplug(i);
-				return err;
-			}
+	for_each_online_cpu(cpu) {
+		if (cpu == 0)
+			continue;
+		err = cpu_down(cpu);
+		if (err) {
+			printk(KERN_CRIT "Failed to take all CPUs "
+			       "down: %d.\n", err);
+			for_each_possible_cpu(cpu)
+				vcpu_hotplug(cpu);
+			return err;
 		}
-		lock_cpu_hotplug();
 	}
 
 	return 0;
@@ -155,11 +145,6 @@ void smp_resume(void)
 	int cpu;
 
 	for_each_possible_cpu(cpu)
-		cpu_initialize_context(cpu);
-
-	unlock_cpu_hotplug();
-
-	for_each_possible_cpu(cpu)
 		vcpu_hotplug(cpu);
 }
 
Index: linux-2.6.18.noarch/drivers/xen/core/smpboot.c
===================================================================
--- linux-2.6.18.noarch.orig/drivers/xen/core/smpboot.c
+++ linux-2.6.18.noarch/drivers/xen/core/smpboot.c
@@ -50,6 +50,7 @@ cpumask_t cpu_online_map;
 EXPORT_SYMBOL(cpu_online_map);
 cpumask_t cpu_possible_map;
 EXPORT_SYMBOL(cpu_possible_map);
+cpumask_t cpu_initialized_map;
 
 struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
 EXPORT_SYMBOL(cpu_data);
@@ -159,7 +160,7 @@ static void cpu_bringup_and_idle(void)
 	cpu_idle();
 }
 
-void cpu_initialize_context(unsigned int cpu)
+static void cpu_initialize_context(unsigned int cpu)
 {
 	vcpu_guest_context_t ctxt;
 	struct task_struct *idle = idle_task(cpu);
@@ -169,7 +170,7 @@ void cpu_initialize_context(unsigned int
 	struct Xgt_desc_struct *gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
 #endif
 
-	if (cpu == 0)
+	if (cpu_test_and_set(cpu, cpu_initialized_map))
 		return;
 
 	memset(&ctxt, 0, sizeof(ctxt));
@@ -400,6 +401,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
 	rc = cpu_up_check(cpu);
 	if (rc)
 		return rc;
+	cpu_initialize_context(cpu);
 
 	if (num_online_cpus() == 1)
 		alternatives_smp_switch(1);
Index: linux-2.6.18.noarch/include/xen/cpu_hotplug.h
===================================================================
--- linux-2.6.18.noarch.orig/include/xen/cpu_hotplug.h
+++ linux-2.6.18.noarch/include/xen/cpu_hotplug.h
@@ -6,12 +6,6 @@
 
 #if defined(CONFIG_HOTPLUG_CPU)
 
-#if defined(CONFIG_X86)
-void cpu_initialize_context(unsigned int cpu);
-#else
-#define cpu_initialize_context(cpu)	((void)0)
-#endif
-
 int cpu_up_check(unsigned int cpu);
 void init_xenbus_allowed_cpumask(void);
 int smp_suspend(void);