[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 2/3] runstate: introduce suspended state
From: |
Luiz Capitulino |
Subject: |
[Qemu-devel] [PATCH 2/3] runstate: introduce suspended state |
Date: |
Fri, 27 Apr 2012 17:40:15 -0300 |
QEMU enters in this state when the guest suspends to ram (S3).
This is important so that HMP users and QMP clients can know that
the guest is suspended. QMP clients also have an event for this,
but events are not reliable and are limited (ie. a client can
connect to QEMU after the event has been emitted).
Having a different state for S3 brings a new issue, though.
Currently, when the guest suspends QEMU is kept in
RUN_STATE_RUNNING state. This has two implications:
1. We report to the HMP user or QMP client that the guest
is 'running', which is not true
2. QEMU doesn't know the guest entered S3, this means that
some parts of QEMU (eg. the input hardware) keeps working
normally during S3
With this patch, item 1 is fixed, but item 2 becomes an issue
because now QEMU is not 'running' anymore and this can confuse
the drivers that are expected to keep working during suspend.
There are two solutions to this problem:
1. Define that RUN_STATE_SUSPENDED is actually a "running"
state. This means that runstate_is_running() will return
true when the guest is in S3
2. Keep RUN_STATE_SUSPENDED as a paused state and hard-code
checks for RUN_STATE_SUSPENDED for the parts of QEMU that
want to run normally when the guest is in S3
This patch does 2 because it fits better in RunState's design.
Signed-off-by: Luiz Capitulino <address@hidden>
---
input.c | 2 +-
qapi-schema.json | 4 +++-
qmp.c | 2 ++
vl.c | 6 ++++++
4 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/input.c b/input.c
index 6b5c2c3..47e6900 100644
--- a/input.c
+++ b/input.c
@@ -130,7 +130,7 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry)
void kbd_put_keycode(int keycode)
{
- if (!runstate_is_running()) {
+ if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
return;
}
if (qemu_put_kbd_event) {
diff --git a/qapi-schema.json b/qapi-schema.json
index 0166ec2..4dbcb26 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -116,12 +116,14 @@
#
# @shutdown: guest is shut down (and -no-shutdown is in use)
#
+# @suspended: guest is suspended (ACPI S3)
+#
# @watchdog: the watchdog action is configured to pause and has been triggered
##
{ 'enum': 'RunState',
'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',
'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
- 'running', 'save-vm', 'shutdown', 'watchdog' ] }
+ 'running', 'save-vm', 'shutdown', 'suspended', 'watchdog' ] }
##
# @StatusInfo:
diff --git a/qmp.c b/qmp.c
index a182b51..fee9fb2 100644
--- a/qmp.c
+++ b/qmp.c
@@ -151,6 +151,8 @@ void qmp_cont(Error **errp)
runstate_check(RUN_STATE_SHUTDOWN)) {
error_set(errp, QERR_RESET_REQUIRED);
return;
+ } else if (runstate_check(RUN_STATE_SUSPENDED)) {
+ return;
}
bdrv_iterate(iostatus_bdrv_it, NULL);
diff --git a/vl.c b/vl.c
index ae91a8a..2d828c8 100644
--- a/vl.c
+++ b/vl.c
@@ -366,6 +366,10 @@ static const RunStateTransition runstate_transitions_def[]
= {
{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
{ RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
+ { RUN_STATE_RUNNING, RUN_STATE_SUSPENDED },
+ { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
+ { RUN_STATE_SUSPENDED, RUN_STATE_RUNNING },
+
{ RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
{ RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
@@ -1420,6 +1424,7 @@ static void qemu_system_suspend(void)
{
pause_all_vcpus();
notifier_list_notify(&suspend_notifiers, NULL);
+ runstate_set(RUN_STATE_SUSPENDED);
monitor_protocol_event(QEVENT_SUSPEND, NULL);
is_suspended = true;
}
@@ -1447,6 +1452,7 @@ void qemu_system_wakeup_request(WakeupReason reason)
if (!(wakeup_reason_mask & (1 << reason))) {
return;
}
+ runstate_set(RUN_STATE_RUNNING);
monitor_protocol_event(QEVENT_WAKEUP, NULL);
notifier_list_notify(&wakeup_notifiers, &reason);
reset_requested = 1;
--
1.7.9.2.384.g4a92a