This patch fixes live migration with PV-on-HVM drivers.
Without this, the kthread_create of the thread to run xen_suspend hangs
forever (at least on RHEL4 64bit).
The comments in the patch explain the problem in more detail.
Signed-off-by: Ben Guthro <bguthro@xxxxxxxxxxxxxxx>
Signed-off-by: Robert Phillips <rphillips@xxxxxxxxxxxxxxx>
diff -r 21dbc5f5a258 drivers/xen/core/reboot.c
--- a/drivers/xen/core/reboot.c Wed Jun 27 11:54:32 2007 -0400
+++ b/drivers/xen/core/reboot.c Wed Jun 27 11:54:43 2007 -0400
@@ -78,6 +78,10 @@ static int kthread_create_on_cpu(int (*f
int cpu)
{
struct task_struct *p;
+ /* NB: kthread_create uses the workqueue and
+ * blocks until the new thread is running,
+ * so it will deadlock if called from the worker thread!
+ */
p = kthread_create(f, arg, name);
if (IS_ERR(p))
return PTR_ERR(p);
@@ -94,7 +98,10 @@ static void __shutdown_handler(void *unu
err = kernel_thread(shutdown_process, NULL,
CLONE_FS | CLONE_FILES);
else
- err = kthread_create_on_cpu(xen_suspend, NULL, "suspend", 0);
+ /* It is safe to call kernel_thread from this
+ * (the worker) thread. */
+ err = kernel_thread(xen_suspend, NULL,
+ CLONE_FS | CLONE_FILES);
if (err < 0) {
printk(KERN_WARNING "Error creating shutdown process (%d): "
@@ -138,8 +145,17 @@ static void shutdown_handler(struct xenb
shutting_down = SHUTDOWN_POWEROFF;
else if (strcmp(str, "reboot") == 0)
ctrl_alt_del();
- else if (strcmp(str, "suspend") == 0)
+ else if (strcmp(str, "suspend") == 0) {
shutting_down = SHUTDOWN_SUSPEND;
+ /* Create new thread from this (the xenwatch) thread.
+ * If called from worker thread, we'll deadlock. */
+ err = kthread_create_on_cpu(xen_suspend, NULL, "suspend", 0);
+ if (err < 0) {
+ printk(KERN_WARNING "Error creating shutdown process (%d):
"
+ "retrying...\n", -err);
+ schedule_delayed_work(&shutdown_work, HZ/2);
+ }
+ }
else if (strcmp(str, "halt") == 0)
shutting_down = SHUTDOWN_HALT;
else {
@@ -147,7 +163,8 @@ static void shutdown_handler(struct xenb
shutting_down = SHUTDOWN_INVALID;
}
- if (shutting_down != SHUTDOWN_INVALID)
+ if (shutting_down != SHUTDOWN_INVALID &&
+ shutting_down != SHUTDOWN_SUSPEND)
schedule_work(&shutdown_work);
kfree(str);
diff -r 21dbc5f5a258 drivers/xen/xenbus/xenbus_dev.c
--- a/drivers/xen/xenbus/xenbus_dev.c Wed Jun 27 11:54:32 2007 -0400
+++ b/drivers/xen/xenbus/xenbus_dev.c Wed Jun 27 11:54:35 2007 -0400
@@ -386,7 +386,7 @@ static unsigned int xenbus_dev_poll(stru
return 0;
}
-static const struct file_operations xenbus_dev_file_ops = {
+static struct file_operations xenbus_dev_file_ops = {
.read = xenbus_dev_read,
.write = xenbus_dev_write,
.open = xenbus_dev_open,
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|