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

[Xen-devel] [PATCH 07 of 10] Add new shutdown mode for checkpoint



# HG changeset patch
# User Brendan Cully <brendan@xxxxxxxxx>
# Date 1166166342 28800
# Node ID d39e577379a3375d7340ef265d472f957694d8a0
# Parent  dc4d3d58b1d24199101c782a2890b03bfb82fe28
Add new shutdown mode for checkpoint.

When control/shutdown = checkpoint, invoke an alternate suspend path
that doesn't disconnect from back ends, and only reconnects when the
image has been restored into a new domain.

Signed-off-by: Brendan Cully <brendan@xxxxxxxxx>

diff -r dc4d3d58b1d2 -r d39e577379a3 
linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c    Thu Dec 14 
23:05:42 2006 -0800
+++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c    Thu Dec 14 
23:05:42 2006 -0800
@@ -85,6 +85,20 @@ static void pre_suspend(void)
                mfn_to_pfn(xen_start_info->console.domU.mfn);
 }
 
+static void pre_checkpoint(void)
+{
+       xen_start_info->store_mfn = mfn_to_pfn(xen_start_info->store_mfn);
+       xen_start_info->console.domU.mfn =
+               mfn_to_pfn(xen_start_info->console.domU.mfn);
+}
+
+static void post_checkpoint(void)
+{
+       xen_start_info->store_mfn = pfn_to_mfn(xen_start_info->store_mfn);
+       xen_start_info->console.domU.mfn =
+               pfn_to_mfn(xen_start_info->console.domU.mfn);
+}
+
 static void post_suspend(void)
 {
        int i, j, k, fpp;
@@ -183,3 +197,70 @@ int __xen_suspend(void)
 
        return err;
 }
+
+int __xen_checkpoint(void)
+{
+       int err;
+
+       extern void time_resume(void);
+
+       BUG_ON(smp_processor_id() != 0);
+       BUG_ON(in_interrupt());
+
+#if defined(__i386__) || defined(__x86_64__)
+       if (xen_feature(XENFEAT_auto_translated_physmap)) {
+               printk(KERN_WARNING "Cannot suspend in "
+                      "auto_translated_physmap mode.\n");
+               return -EOPNOTSUPP;
+       }
+#endif
+
+       err = smp_suspend();
+       if (err)
+               return err;
+
+       xenbus_lock();
+
+       preempt_disable();
+
+       mm_pin_all();
+       local_irq_disable();
+       preempt_enable();
+
+       pre_checkpoint();
+
+       /*
+        * We'll stop somewhere inside this hypercall. When it returns,
+        * we'll start resuming after the restore.
+        */
+       err = HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
+
+       if (err) {
+               /* We are resuming in a new domain -- reconnect */
+               post_suspend();
+
+               gnttab_resume();
+
+               irq_resume();
+
+               time_resume();
+
+               switch_idle_mm();
+
+               local_irq_enable();
+
+               xencons_resume();
+
+               xenbus_resume();
+       } else {
+               post_checkpoint();
+
+               local_irq_enable();
+
+               xenbus_unlock();
+       }
+       
+       smp_resume();
+
+       return err;
+}
diff -r dc4d3d58b1d2 -r d39e577379a3 
linux-2.6-xen-sparse/drivers/xen/core/reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c    Thu Dec 14 23:05:42 
2006 -0800
+++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c    Thu Dec 14 23:05:42 
2006 -0800
@@ -11,15 +11,16 @@
 
 MODULE_LICENSE("Dual BSD/GPL");
 
-#define SHUTDOWN_INVALID  -1
-#define SHUTDOWN_POWEROFF  0
-#define SHUTDOWN_SUSPEND   2
+#define SHUTDOWN_INVALID   -1
+#define SHUTDOWN_POWEROFF   0
+#define SHUTDOWN_SUSPEND    2
 /* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
  * report a crash, not be instructed to crash!
  * HALT is the same as POWEROFF, as far as we're concerned.  The tools use
  * the distinction when we return the reason code to them.
  */
-#define SHUTDOWN_HALT      4
+#define SHUTDOWN_HALT       4
+#define SHUTDOWN_CHECKPOINT 5
 
 /* Ignore multiple shutdown requests. */
 static int shutting_down = SHUTDOWN_INVALID;
@@ -29,8 +30,10 @@ static DECLARE_WORK(shutdown_work, __shu
 
 #ifdef CONFIG_XEN
 int __xen_suspend(void);
+int __xen_checkpoint(void);
 #else
 #define __xen_suspend() (void)0
+#define __xen_checkpoint() (void)0
 #endif
 
 static int shutdown_process(void *__unused)
@@ -61,7 +64,10 @@ static int shutdown_process(void *__unus
 
 static int xen_suspend(void *__unused)
 {
-       __xen_suspend();
+       if (shutting_down == SHUTDOWN_CHECKPOINT)
+               __xen_checkpoint();
+       else
+               __xen_suspend();
        shutting_down = SHUTDOWN_INVALID;
        return 0;
 }
@@ -84,7 +90,8 @@ static void __shutdown_handler(void *unu
 {
        int err;
 
-       if (shutting_down != SHUTDOWN_SUSPEND)
+       if (shutting_down != SHUTDOWN_SUSPEND
+           && shutting_down != SHUTDOWN_CHECKPOINT)
                err = kernel_thread(shutdown_process, NULL,
                                    CLONE_FS | CLONE_FILES);
        else
@@ -132,6 +139,8 @@ static void shutdown_handler(struct xenb
                kill_proc(1, SIGINT, 1); /* interrupt init */
        else if (strcmp(str, "suspend") == 0)
                shutting_down = SHUTDOWN_SUSPEND;
+       else if (strcmp(str, "checkpoint") == 0)
+               shutting_down = SHUTDOWN_CHECKPOINT;
        else if (strcmp(str, "halt") == 0)
                shutting_down = SHUTDOWN_HALT;
        else {
diff -r dc4d3d58b1d2 -r d39e577379a3 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Thu Dec 14 
23:05:42 2006 -0800
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Thu Dec 14 
23:05:42 2006 -0800
@@ -727,6 +727,18 @@ void xenbus_suspend(void)
 }
 EXPORT_SYMBOL_GPL(xenbus_suspend);
 
+void xenbus_lock(void)
+{
+       xs_lock();
+}
+EXPORT_SYMBOL_GPL(xenbus_lock);
+
+void xenbus_unlock(void)
+{
+       xs_unlock();
+}
+EXPORT_SYMBOL_GPL(xenbus_unlock);
+
 void xenbus_resume(void)
 {
        xb_init_comms();
diff -r dc4d3d58b1d2 -r d39e577379a3 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Thu Dec 14 
23:05:42 2006 -0800
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c       Thu Dec 14 
23:05:42 2006 -0800
@@ -666,6 +666,18 @@ void unregister_xenbus_watch(struct xenb
 }
 EXPORT_SYMBOL_GPL(unregister_xenbus_watch);
 
+void xs_lock(void)
+{
+       down_write(&xs_state.suspend_mutex);
+       mutex_lock(&xs_state.request_mutex);
+}
+
+void xs_unlock(void)
+{
+       mutex_unlock(&xs_state.request_mutex);
+       up_write(&xs_state.suspend_mutex);
+}
+
 void xs_suspend(void)
 {
        struct xenbus_watch *watch;
diff -r dc4d3d58b1d2 -r d39e577379a3 linux-2.6-xen-sparse/include/xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/xen/xenbus.h Thu Dec 14 23:05:42 2006 -0800
+++ b/linux-2.6-xen-sparse/include/xen/xenbus.h Thu Dec 14 23:05:42 2006 -0800
@@ -158,6 +158,8 @@ void unregister_xenstore_notifier(struct
 
 int register_xenbus_watch(struct xenbus_watch *watch);
 void unregister_xenbus_watch(struct xenbus_watch *watch);
+void xs_lock(void);
+void xs_unlock(void);
 void xs_suspend(void);
 void xs_resume(void);
 
@@ -167,6 +169,8 @@ void *xenbus_dev_request_and_reply(struc
 /* Called from xen core code. */
 void xenbus_suspend(void);
 void xenbus_resume(void);
+void xenbus_lock(void);
+void xenbus_unlock(void);
 
 #define XENBUS_IS_ERR_READ(str) ({                     \
        if (!IS_ERR(str) && strlen(str) == 0) {         \

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


 


Rackspace

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