qemu-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]