|
|
|
|
|
|
|
|
|
|
xen-changelog
[Xen-changelog] [xen-unstable] acpi sleep: Rearrange code for entering s
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1271327780 -3600
# Node ID 11423ce78ee0ff314351c10842dcac9af6e11d1e
# Parent 85ab727868ea68bef59947f676f03a1669a83fae
acpi sleep: Rearrange code for entering system sleep states.
We cannot freeze_domains in hypercall-continuation context any more,
since that is a softirq context which can interrupt an arbitrary
vcpu. Hence sleeping all vcpus in that context can easily deadlock
(against the vcpu we interrupted). So rearrange the code to
freeze_domains before calling continue_hypercall_on_cpu().
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
xen/arch/x86/acpi/power.c | 38 +++++++++++++++++++++++++-------------
1 files changed, 25 insertions(+), 13 deletions(-)
diff -r 85ab727868ea -r 11423ce78ee0 xen/arch/x86/acpi/power.c
--- a/xen/arch/x86/acpi/power.c Thu Apr 15 11:33:39 2010 +0100
+++ b/xen/arch/x86/acpi/power.c Thu Apr 15 11:36:20 2010 +0100
@@ -149,15 +149,7 @@ static int enter_state(u32 state)
int error;
unsigned long cr4;
- if ( (state <= ACPI_STATE_S0) || (state > ACPI_S_STATES_MAX) )
- return -EINVAL;
-
- if ( !spin_trylock(&pm_lock) )
- return -EBUSY;
-
- printk(XENLOG_INFO "Preparing system for ACPI S%d state.", state);
-
- freeze_domains();
+ BUG_ON(!spin_is_locked(&pm_lock));
disable_nonboot_cpus();
if ( num_online_cpus() != 1 )
@@ -246,6 +238,9 @@ static long enter_state_helper(void *dat
*/
int acpi_enter_sleep(struct xenpf_enter_acpi_sleep *sleep)
{
+ int rc;
+ u32 state;
+
if ( !IS_PRIV(current->domain) || !acpi_sinfo.pm1a_cnt_blk.address )
return -EPERM;
@@ -258,14 +253,31 @@ int acpi_enter_sleep(struct xenpf_enter_
return -EINVAL;
}
- if ( sleep->flags )
+ state = sleep->sleep_state;
+ if ( sleep->flags ||
+ (state <= ACPI_STATE_S0) || (state > ACPI_S_STATES_MAX) )
return -EINVAL;
+
+ if ( !spin_trylock(&pm_lock) )
+ return -EBUSY;
acpi_sinfo.pm1a_cnt_val = sleep->pm1a_cnt_val;
acpi_sinfo.pm1b_cnt_val = sleep->pm1b_cnt_val;
- acpi_sinfo.sleep_state = sleep->sleep_state;
-
- return continue_hypercall_on_cpu(0, enter_state_helper, &acpi_sinfo);
+ acpi_sinfo.sleep_state = state;
+
+ printk(XENLOG_INFO "Preparing system for ACPI S%d state.", state);
+
+ freeze_domains();
+
+ rc = continue_hypercall_on_cpu(0, enter_state_helper, &acpi_sinfo);
+ if ( rc )
+ {
+ /* Continuation will not execute: undo our own work so far. */
+ thaw_domains();
+ spin_unlock(&pm_lock);
+ }
+
+ return rc;
}
static int acpi_get_wake_status(void)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|
<Prev in Thread] |
Current Thread |
[Next in Thread> |
- [Xen-changelog] [xen-unstable] acpi sleep: Rearrange code for entering system sleep states.,
Xen patchbot-unstable <=
|
|
|
|
|