# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1169222769 0
# Node ID b4a8000e76db6b4b273412b5b7d552fae6168ae6
# Parent 50cb739a68b6b9ed0c419ea3310e6903fcaa8455
Make xen_suspend handle resume.
Don't destroy xenstore watches on suspend, and only recreate them when
resuming in a new domain. Likewise, only invoke frontend device resume
code when in a new domain (the resume functions all tear down the
existing function and wait for the backend to negotiate a new one,
which does not happen in the source domain).
Signed-off-by: Brendan Cully <brendan@xxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c | 33 +++++++++++------
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c | 5 ++
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c | 16 +++-----
linux-2.6-xen-sparse/include/xen/xenbus.h | 4 +-
4 files changed, 36 insertions(+), 22 deletions(-)
diff -r 50cb739a68b6 -r b4a8000e76db
linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c Fri Jan 19
15:36:54 2007 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c Fri Jan 19
16:06:09 2007 +0000
@@ -85,13 +85,20 @@ static void pre_suspend(void)
mfn_to_pfn(xen_start_info->console.domU.mfn);
}
-static void post_suspend(void)
+static void post_suspend(int suspend_cancelled)
{
int i, j, k, fpp;
extern unsigned long max_pfn;
extern unsigned long *pfn_to_mfn_frame_list_list;
extern unsigned long *pfn_to_mfn_frame_list[];
+ if (suspend_cancelled) {
+ 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);
+ }
+
set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
@@ -120,13 +127,13 @@ static void post_suspend(void)
#define switch_idle_mm() ((void)0)
#define mm_pin_all() ((void)0)
#define pre_suspend() ((void)0)
-#define post_suspend() ((void)0)
+#define post_suspend(x) ((void)0)
#endif
int __xen_suspend(void)
{
- int err;
+ int err, suspend_cancelled;
extern void time_resume(void);
@@ -158,16 +165,17 @@ int __xen_suspend(void)
pre_suspend();
/*
- * We'll stop somewhere inside this hypercall. When it returns,
- * we'll start resuming after the restore.
+ * This hypercall returns 1 if suspend was cancelled or the domain was
+ * merely checkpointed, and 0 if it is resuming in a new domain.
*/
- HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
+ suspend_cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
- post_suspend();
+ post_suspend(suspend_cancelled);
gnttab_resume();
- irq_resume();
+ if (!suspend_cancelled)
+ irq_resume();
time_resume();
@@ -175,9 +183,12 @@ int __xen_suspend(void)
local_irq_enable();
- xencons_resume();
-
- xenbus_resume();
+ if (!suspend_cancelled) {
+ xencons_resume();
+ xenbus_resume();
+ } else {
+ xenbus_suspend_cancel();
+ }
smp_resume();
diff -r 50cb739a68b6 -r b4a8000e76db
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Fri Jan 19
15:36:54 2007 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Fri Jan 19
16:06:09 2007 +0000
@@ -736,6 +736,11 @@ void xenbus_resume(void)
}
EXPORT_SYMBOL_GPL(xenbus_resume);
+void xenbus_suspend_cancel(void)
+{
+ xs_suspend_cancel();
+}
+EXPORT_SYMBOL_GPL(xenbus_suspend_cancel);
/* A flag to determine if xenstored is 'ready' (i.e. has started) */
int xenstored_ready = 0;
diff -r 50cb739a68b6 -r b4a8000e76db
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Fri Jan 19
15:36:54 2007 +0000
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Fri Jan 19
16:06:09 2007 +0000
@@ -668,17 +668,7 @@ EXPORT_SYMBOL_GPL(unregister_xenbus_watc
void xs_suspend(void)
{
- struct xenbus_watch *watch;
- char token[sizeof(watch) * 2 + 1];
-
down_write(&xs_state.suspend_mutex);
-
- /* No need for watches_lock: the suspend_mutex is sufficient. */
- list_for_each_entry(watch, &watches, list) {
- sprintf(token, "%lX", (long)watch);
- xs_unwatch(watch->node, token);
- }
-
mutex_lock(&xs_state.request_mutex);
}
@@ -695,6 +685,12 @@ void xs_resume(void)
xs_watch(watch->node, token);
}
+ up_write(&xs_state.suspend_mutex);
+}
+
+void xs_suspend_cancel(void)
+{
+ mutex_unlock(&xs_state.request_mutex);
up_write(&xs_state.suspend_mutex);
}
diff -r 50cb739a68b6 -r b4a8000e76db linux-2.6-xen-sparse/include/xen/xenbus.h
--- a/linux-2.6-xen-sparse/include/xen/xenbus.h Fri Jan 19 15:36:54 2007 +0000
+++ b/linux-2.6-xen-sparse/include/xen/xenbus.h Fri Jan 19 16:06:09 2007 +0000
@@ -160,13 +160,15 @@ void unregister_xenbus_watch(struct xenb
void unregister_xenbus_watch(struct xenbus_watch *watch);
void xs_suspend(void);
void xs_resume(void);
+void xs_suspend_cancel(void);
/* Used by xenbus_dev to borrow kernel's store connection. */
void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg);
-/* Called from xen core code. */
+/* Prepare for domain suspend: then resume or cancel the suspend. */
void xenbus_suspend(void);
void xenbus_resume(void);
+void xenbus_suspend_cancel(void);
#define XENBUS_IS_ERR_READ(str) ({ \
if (!IS_ERR(str) && strlen(str) == 0) { \
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|