qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Steve Sistare <steven.sistare@oracle.com>
To: qemu-devel@nongnu.org
Cc: "Juan Quintela" <quintela@redhat.com>,
	"Peter Xu" <peterx@redhat.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Thomas Huth" <thuth@redhat.com>,
	"Daniel P. Berrangé" <berrange@redhat.com>,
	"Fabiano Rosas" <farosas@suse.de>,
	"Leonardo Bras" <leobras@redhat.com>,
	"Steve Sistare" <steven.sistare@oracle.com>
Subject: [PATCH V7 02/12] cpus: stop vm in suspended runstate
Date: Wed,  6 Dec 2023 09:12:29 -0800	[thread overview]
Message-ID: <1701882772-356078-4-git-send-email-steven.sistare@oracle.com> (raw)
In-Reply-To: <1701882772-356078-1-git-send-email-steven.sistare@oracle.com>

Currently, a vm in the suspended state is not completely stopped.  The VCPUs
have been paused, but the cpu clock still runs, and runstate notifiers for
the transition to stopped have not been called.  This causes problems for
live migration.  Stale cpu timers_state is saved to the migration stream,
causing time errors in the guest when it wakes from suspend, and state that
would have been modified by runstate notifiers is wrong.

Modify vm_stop to completely stop the vm if the current state is suspended,
transition to RUN_STATE_PAUSED, and remember that the machine was suspended.
Modify vm_start to restore the suspended state.

This affects all callers of vm_stop and vm_start, notably, the qapi stop and
cont commands.  For example:

    (qemu) info status
    VM status: paused (suspended)

    (qemu) stop
    (qemu) info status
    VM status: paused

    (qemu) system_wakeup
    Error: Unable to wake up: guest is not in suspended state

    (qemu) cont
    (qemu) info status
    VM status: paused (suspended)

    (qemu) system_wakeup
    (qemu) info status
    VM status: running

Suggested-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
---
 include/sysemu/runstate.h |  5 +++++
 qapi/misc.json            | 10 ++++++++--
 system/cpus.c             | 23 +++++++++++++++--------
 system/runstate.c         |  3 +++
 4 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/include/sysemu/runstate.h b/include/sysemu/runstate.h
index 88a67e2..867e53c 100644
--- a/include/sysemu/runstate.h
+++ b/include/sysemu/runstate.h
@@ -40,6 +40,11 @@ static inline bool shutdown_caused_by_guest(ShutdownCause cause)
     return cause >= SHUTDOWN_CAUSE_GUEST_SHUTDOWN;
 }
 
+static inline bool runstate_is_live(RunState state)
+{
+    return state == RUN_STATE_RUNNING || state == RUN_STATE_SUSPENDED;
+}
+
 void vm_start(void);
 
 /**
diff --git a/qapi/misc.json b/qapi/misc.json
index cda2eff..efb8d44 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -134,7 +134,7 @@
 ##
 # @stop:
 #
-# Stop all guest VCPU execution.
+# Stop all guest VCPU and VM execution.
 #
 # Since: 0.14
 #
@@ -143,6 +143,9 @@
 #     the guest remains paused once migration finishes, as if the -S
 #     option was passed on the command line.
 #
+#     In the "suspended" state, it will completely stop the VM and
+#     cause a transition to the "paused" state. (Since 9.0)
+#
 # Example:
 #
 # -> { "execute": "stop" }
@@ -153,7 +156,7 @@
 ##
 # @cont:
 #
-# Resume guest VCPU execution.
+# Resume guest VCPU and VM execution.
 #
 # Since: 0.14
 #
@@ -165,6 +168,9 @@
 #     guest starts once migration finishes, removing the effect of the
 #     -S command line option if it was passed.
 #
+#     If the VM was previously suspended, and not been reset or woken,
+#     this command will transition back to the "suspended" state. (Since 9.0)
+#
 # Example:
 #
 # -> { "execute": "cont" }
diff --git a/system/cpus.c b/system/cpus.c
index 9f631ab..f162435 100644
--- a/system/cpus.c
+++ b/system/cpus.c
@@ -277,11 +277,15 @@ bool vm_get_suspended(void)
 static int do_vm_stop(RunState state, bool send_stop)
 {
     int ret = 0;
+    RunState oldstate = runstate_get();
 
-    if (runstate_is_running()) {
+    if (runstate_is_live(oldstate)) {
+        vm_was_suspended = (oldstate == RUN_STATE_SUSPENDED);
         runstate_set(state);
         cpu_disable_ticks();
-        pause_all_vcpus();
+        if (oldstate == RUN_STATE_RUNNING) {
+            pause_all_vcpus();
+        }
         vm_state_notify(0, state);
         if (send_stop) {
             qapi_event_send_stop();
@@ -694,11 +698,13 @@ int vm_stop(RunState state)
 
 /**
  * Prepare for (re)starting the VM.
- * Returns -1 if the vCPUs are not to be restarted (e.g. if they are already
- * running or in case of an error condition), 0 otherwise.
+ * Returns 0 if the vCPUs should be restarted, -1 on an error condition,
+ * and 1 otherwise.
  */
 int vm_prepare_start(bool step_pending)
 {
+    int ret = vm_was_suspended ? 1 : 0;
+    RunState state = vm_was_suspended ? RUN_STATE_SUSPENDED : RUN_STATE_RUNNING;
     RunState requested;
 
     qemu_vmstop_requested(&requested);
@@ -729,9 +735,10 @@ int vm_prepare_start(bool step_pending)
     qapi_event_send_resume();
 
     cpu_enable_ticks();
-    runstate_set(RUN_STATE_RUNNING);
-    vm_state_notify(1, RUN_STATE_RUNNING);
-    return 0;
+    runstate_set(state);
+    vm_state_notify(1, state);
+    vm_was_suspended = false;
+    return ret;
 }
 
 void vm_start(void)
@@ -745,7 +752,7 @@ void vm_start(void)
    current state is forgotten forever */
 int vm_stop_force_state(RunState state)
 {
-    if (runstate_is_running()) {
+    if (runstate_is_live(runstate_get())) {
         return vm_stop(state);
     } else {
         int ret;
diff --git a/system/runstate.c b/system/runstate.c
index ea9d6c2..e2fa204 100644
--- a/system/runstate.c
+++ b/system/runstate.c
@@ -108,6 +108,7 @@ static const RunStateTransition runstate_transitions_def[] = {
     { RUN_STATE_PAUSED, RUN_STATE_POSTMIGRATE },
     { RUN_STATE_PAUSED, RUN_STATE_PRELAUNCH },
     { RUN_STATE_PAUSED, RUN_STATE_COLO},
+    { RUN_STATE_PAUSED, RUN_STATE_SUSPENDED},
 
     { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING },
     { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE },
@@ -161,6 +162,7 @@ static const RunStateTransition runstate_transitions_def[] = {
     { RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE },
     { RUN_STATE_SUSPENDED, RUN_STATE_PRELAUNCH },
     { RUN_STATE_SUSPENDED, RUN_STATE_COLO},
+    { RUN_STATE_SUSPENDED, RUN_STATE_PAUSED},
 
     { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
     { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
@@ -502,6 +504,7 @@ void qemu_system_reset(ShutdownCause reason)
         qapi_event_send_reset(shutdown_caused_by_guest(reason), reason);
     }
     cpu_synchronize_all_post_reset();
+    vm_set_suspended(false);
 }
 
 /*
-- 
1.8.3.1



  parent reply	other threads:[~2023-12-06 17:14 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-06 17:12 [PATCH V7 00/12] fix migration of suspended runstate Steve Sistare
2023-12-06 17:12 ` [PATCH V7 01/12] cpus: vm_was_suspended Steve Sistare
2023-12-06 17:12 ` [PATCH 01/14] temporary: define CLONE_NEWCGROUP qemu-8.2.0 Steve Sistare
2023-12-06 17:12 ` Steve Sistare [this message]
2023-12-06 17:12 ` [PATCH 02/14] temp: allow python 3.6 qemu-8.2 Steve Sistare
2023-12-06 17:12 ` [PATCH V7 03/12] cpus: check running not RUN_STATE_RUNNING Steve Sistare
2023-12-06 17:12 ` [PATCH 03/14] cpus: vm_was_suspended Steve Sistare
2023-12-06 17:12 ` [PATCH 04/14] cpus: stop vm in suspended runstate Steve Sistare
2023-12-06 17:12 ` [PATCH V7 04/12] cpus: vm_resume Steve Sistare
2023-12-06 17:12 ` [PATCH 05/14] cpus: check running not RUN_STATE_RUNNING Steve Sistare
2023-12-06 17:12 ` [PATCH V7 05/12] migration: propagate suspended runstate Steve Sistare
2023-12-06 17:12 ` [PATCH 06/14] cpus: vm_resume Steve Sistare
2023-12-06 17:12 ` [PATCH V7 06/12] migration: preserve suspended runstate Steve Sistare
2023-12-06 17:12 ` [PATCH V7 07/12] migration: preserve suspended for snapshot Steve Sistare
2023-12-06 17:12 ` [PATCH 07/14] migration: propagate suspended runstate Steve Sistare
2023-12-06 17:12 ` [PATCH V7 08/12] migration: preserve suspended for bg_migration Steve Sistare
2023-12-06 17:12 ` [PATCH 08/14] migration: preserve suspended runstate Steve Sistare
2023-12-06 17:12 ` [PATCH 09/14] migration: preserve suspended for snapshot Steve Sistare
2023-12-06 17:12 ` [PATCH V7 09/12] tests/qtest: migration events Steve Sistare
2023-12-06 17:12 ` [PATCH 10/14] migration: preserve suspended for bg_migration Steve Sistare
2023-12-06 17:12 ` [PATCH V7 10/12] tests/qtest: option to suspend during migration Steve Sistare
2023-12-06 17:12 ` [PATCH 11/14] tests/qtest: migration events Steve Sistare
2023-12-06 17:12 ` [PATCH V7 11/12] tests/qtest: precopy migration with suspend Steve Sistare
2023-12-06 17:12 ` [PATCH 12/14] tests/qtest: option to suspend during migration Steve Sistare
2023-12-06 17:12 ` [PATCH V7 12/12] tests/qtest: postcopy migration with suspend Steve Sistare
2023-12-06 17:12 ` [PATCH 13/14] tests/qtest: precopy " Steve Sistare
2023-12-06 17:12 ` [PATCH 14/14] tests/qtest: postcopy " Steve Sistare
2023-12-06 17:16 ` [PATCH V7 00/12] fix migration of suspended runstate Steven Sistare
  -- strict thread matches above, loose matches on Subject: below --
2023-12-06 17:23 Steve Sistare
2023-12-06 17:23 ` [PATCH V7 02/12] cpus: stop vm in " Steve Sistare
2023-12-06 18:45   ` Philippe Mathieu-Daudé
2023-12-06 19:19     ` Steven Sistare
2023-12-06 20:48       ` Philippe Mathieu-Daudé
2023-12-06 21:09         ` Philippe Mathieu-Daudé
2023-12-11  6:25           ` Peter Xu
2023-12-11 13:37   ` Steven Sistare

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1701882772-356078-4-git-send-email-steven.sistare@oracle.com \
    --to=steven.sistare@oracle.com \
    --cc=berrange@redhat.com \
    --cc=farosas@suse.de \
    --cc=leobras@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peterx@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).