direct-io.hg

changeset 13519:b4a8000e76db

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@cs.ubc.ca>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Fri Jan 19 16:06:09 2007 +0000 (2007-01-19)
parents 50cb739a68b6
children f89126a59073
files linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c linux-2.6-xen-sparse/include/xen/xenbus.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c	Fri Jan 19 15:36:54 2007 +0000
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c	Fri Jan 19 16:06:09 2007 +0000
     1.3 @@ -85,13 +85,20 @@ static void pre_suspend(void)
     1.4  		mfn_to_pfn(xen_start_info->console.domU.mfn);
     1.5  }
     1.6  
     1.7 -static void post_suspend(void)
     1.8 +static void post_suspend(int suspend_cancelled)
     1.9  {
    1.10  	int i, j, k, fpp;
    1.11  	extern unsigned long max_pfn;
    1.12  	extern unsigned long *pfn_to_mfn_frame_list_list;
    1.13  	extern unsigned long *pfn_to_mfn_frame_list[];
    1.14  
    1.15 +	if (suspend_cancelled) {
    1.16 +		xen_start_info->store_mfn =
    1.17 +			pfn_to_mfn(xen_start_info->store_mfn);
    1.18 +		xen_start_info->console.domU.mfn =
    1.19 +			pfn_to_mfn(xen_start_info->console.domU.mfn);
    1.20 +	}
    1.21 +	
    1.22  	set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
    1.23  
    1.24  	HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
    1.25 @@ -120,13 +127,13 @@ static void post_suspend(void)
    1.26  #define switch_idle_mm()	((void)0)
    1.27  #define mm_pin_all()		((void)0)
    1.28  #define pre_suspend()		((void)0)
    1.29 -#define post_suspend()		((void)0)
    1.30 +#define post_suspend(x)		((void)0)
    1.31  
    1.32  #endif
    1.33  
    1.34  int __xen_suspend(void)
    1.35  {
    1.36 -	int err;
    1.37 +	int err, suspend_cancelled;
    1.38  
    1.39  	extern void time_resume(void);
    1.40  
    1.41 @@ -158,16 +165,17 @@ int __xen_suspend(void)
    1.42  	pre_suspend();
    1.43  
    1.44  	/*
    1.45 -	 * We'll stop somewhere inside this hypercall. When it returns,
    1.46 -	 * we'll start resuming after the restore.
    1.47 +	 * This hypercall returns 1 if suspend was cancelled or the domain was
    1.48 +	 * merely checkpointed, and 0 if it is resuming in a new domain.
    1.49  	 */
    1.50 -	HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
    1.51 +	suspend_cancelled = HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
    1.52  
    1.53 -	post_suspend();
    1.54 +	post_suspend(suspend_cancelled);
    1.55  
    1.56  	gnttab_resume();
    1.57  
    1.58 -	irq_resume();
    1.59 +	if (!suspend_cancelled)
    1.60 +		irq_resume();
    1.61  
    1.62  	time_resume();
    1.63  
    1.64 @@ -175,9 +183,12 @@ int __xen_suspend(void)
    1.65  
    1.66  	local_irq_enable();
    1.67  
    1.68 -	xencons_resume();
    1.69 -
    1.70 -	xenbus_resume();
    1.71 +	if (!suspend_cancelled) {
    1.72 +		xencons_resume();
    1.73 +		xenbus_resume();
    1.74 +	} else {
    1.75 +		xenbus_suspend_cancel();
    1.76 +	}
    1.77  
    1.78  	smp_resume();
    1.79  
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Fri Jan 19 15:36:54 2007 +0000
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Fri Jan 19 16:06:09 2007 +0000
     2.3 @@ -736,6 +736,11 @@ void xenbus_resume(void)
     2.4  }
     2.5  EXPORT_SYMBOL_GPL(xenbus_resume);
     2.6  
     2.7 +void xenbus_suspend_cancel(void)
     2.8 +{
     2.9 +	xs_suspend_cancel();
    2.10 +}
    2.11 +EXPORT_SYMBOL_GPL(xenbus_suspend_cancel);
    2.12  
    2.13  /* A flag to determine if xenstored is 'ready' (i.e. has started) */
    2.14  int xenstored_ready = 0;
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Fri Jan 19 15:36:54 2007 +0000
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Fri Jan 19 16:06:09 2007 +0000
     3.3 @@ -668,17 +668,7 @@ EXPORT_SYMBOL_GPL(unregister_xenbus_watc
     3.4  
     3.5  void xs_suspend(void)
     3.6  {
     3.7 -	struct xenbus_watch *watch;
     3.8 -	char token[sizeof(watch) * 2 + 1];
     3.9 -
    3.10  	down_write(&xs_state.suspend_mutex);
    3.11 -
    3.12 -	/* No need for watches_lock: the suspend_mutex is sufficient. */
    3.13 -	list_for_each_entry(watch, &watches, list) {
    3.14 -		sprintf(token, "%lX", (long)watch);
    3.15 -		xs_unwatch(watch->node, token);
    3.16 -	}
    3.17 -
    3.18  	mutex_lock(&xs_state.request_mutex);
    3.19  }
    3.20  
    3.21 @@ -698,6 +688,12 @@ void xs_resume(void)
    3.22  	up_write(&xs_state.suspend_mutex);
    3.23  }
    3.24  
    3.25 +void xs_suspend_cancel(void)
    3.26 +{
    3.27 +	mutex_unlock(&xs_state.request_mutex);
    3.28 +	up_write(&xs_state.suspend_mutex);
    3.29 +}
    3.30 +
    3.31  static int xenwatch_handle_callback(void *data)
    3.32  {
    3.33  	struct xs_stored_msg *msg = data;
     4.1 --- a/linux-2.6-xen-sparse/include/xen/xenbus.h	Fri Jan 19 15:36:54 2007 +0000
     4.2 +++ b/linux-2.6-xen-sparse/include/xen/xenbus.h	Fri Jan 19 16:06:09 2007 +0000
     4.3 @@ -160,13 +160,15 @@ int register_xenbus_watch(struct xenbus_
     4.4  void unregister_xenbus_watch(struct xenbus_watch *watch);
     4.5  void xs_suspend(void);
     4.6  void xs_resume(void);
     4.7 +void xs_suspend_cancel(void);
     4.8  
     4.9  /* Used by xenbus_dev to borrow kernel's store connection. */
    4.10  void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg);
    4.11  
    4.12 -/* Called from xen core code. */
    4.13 +/* Prepare for domain suspend: then resume or cancel the suspend. */
    4.14  void xenbus_suspend(void);
    4.15  void xenbus_resume(void);
    4.16 +void xenbus_suspend_cancel(void);
    4.17  
    4.18  #define XENBUS_IS_ERR_READ(str) ({			\
    4.19  	if (!IS_ERR(str) && strlen(str) == 0) {		\