From patchwork Fri Apr 27 20:40:15 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Capitulino X-Patchwork-Id: 155591 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B87DDB7137 for ; Sat, 28 Apr 2012 06:40:39 +1000 (EST) Received: from localhost ([::1]:52275 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SNry1-0006q8-Hc for incoming@patchwork.ozlabs.org; Fri, 27 Apr 2012 16:40:37 -0400 Received: from eggs.gnu.org ([208.118.235.92]:51875) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SNrxj-0006dN-FF for qemu-devel@nongnu.org; Fri, 27 Apr 2012 16:40:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SNrxh-0000MT-Gi for qemu-devel@nongnu.org; Fri, 27 Apr 2012 16:40:19 -0400 Received: from mx1.redhat.com ([209.132.183.28]:31176) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SNrxh-0000KP-8n for qemu-devel@nongnu.org; Fri, 27 Apr 2012 16:40:17 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q3RKeEYZ016025 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 27 Apr 2012 16:40:14 -0400 Received: from localhost (ovpn-116-78.ams2.redhat.com [10.36.116.78]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q3RKeCq2004171; Fri, 27 Apr 2012 16:40:13 -0400 From: Luiz Capitulino To: qemu-devel@nongnu.org Date: Fri, 27 Apr 2012 17:40:15 -0300 Message-Id: <1335559216-13849-3-git-send-email-lcapitulino@redhat.com> In-Reply-To: <1335559216-13849-1-git-send-email-lcapitulino@redhat.com> References: <1335559216-13849-1-git-send-email-lcapitulino@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: kraxel@redhat.com, mdroth@linux.vnet.ibm.com Subject: [Qemu-devel] [PATCH 2/3] runstate: introduce suspended state X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- 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;