From: Paolo Bonzini <pbonzini@redhat.com>
To: Kevin Wolf <kwolf@redhat.com>
Cc: famz@redhat.com, qemu-devel@nongnu.org, stefanha@redhat.com
Subject: Re: [Qemu-devel] [PATCH] block: asynchronously stop the VM on I/O errors
Date: Tue, 03 Jun 2014 17:51:53 +0200 [thread overview]
Message-ID: <538DEF19.80802@redhat.com> (raw)
In-Reply-To: <20140603143719.GD3264@noname.str.redhat.com>
Il 03/06/2014 16:37, Kevin Wolf ha scritto:
> Am 03.06.2014 um 16:16 hat Paolo Bonzini geschrieben:
>> With virtio-blk dataplane, I/O errors might occur while QEMU is
>> not in the main I/O thread. However, it's invalid to call vm_stop
>> when we're neither in a VCPU thread nor in the main I/O thread,
>> even if we were to take the iothread mutex around it.
>>
>> To avoid this problem, simply raise a request to the main I/O thread,
>> similar to what QEMU does when vm_stop is called from a CPU thread.
>> We know that bdrv_error_action is called from an AIO callback, and
>> the moment at which the callback will fire is not well-defined; it
>> depends on the moment at which the disk or OS finishes the operation,
>> which can happen at any time.
>>
>> Note that QEMU is certainly not in a CPU thread and we do not need to
>> call cpu_stop_current() like vm_stop() does.
>
> Do I understand correctly that this is not a fundamental truth of qemu's
> operation, but holds true only because the drivers that do support
> rerror/werror all use bdrv_aio_readv/writev(), which guarantees that a
> BH is used in error cases? Otherwise I think an I/O handler in a vcpu
> thread could directly call into the block layer and fail immediately
> (might happen for example if we added rerror/werror support to ATAPI).
>
> By delaying the actual state change, does this break the invariant that
> bs->iostatus is BLOCK_DEVICE_IO_STATUS_OK while the VM is running?
These two comments are actually related, in that the invariant was
already not respected if an I/O handler in a VCPU thread could fail
immediately.
Breaking this invariant means that you have a very small window where
{'execute':'cont'} would actually not restart the VM. I think this
should be fixed by dropping the request in vm_start, like this:
diff --git a/vl.c b/vl.c
index db9ea90..09af28a 100644
--- a/vl.c
+++ b/vl.c
@@ -1721,8 +1721,31 @@ void vm_state_notify(int running, RunState state)
}
}
+static RunState vmstop_requested = RUN_STATE_MAX;
+
+/* We use RUN_STATE_MAX but any invalid value will do */
+static bool qemu_vmstop_requested(RunState *r)
+{
+ if (vmstop_requested < RUN_STATE_MAX) {
+ *r = vmstop_requested;
+ vmstop_requested = RUN_STATE_MAX;
+ return true;
+ }
+
+ return false;
+}
+
+void qemu_system_vmstop_request(RunState state)
+{
+ vmstop_requested = state;
+ qemu_notify_event();
+}
+
void vm_start(void)
{
+ RunState dummy;
+
+ qemu_vmstop_requested(&dummy);
if (!runstate_is_running()) {
cpu_enable_ticks();
runstate_set(RUN_STATE_RUNNING);
@@ -1756,7 +1779,6 @@ static NotifierList suspend_notifiers =
static NotifierList wakeup_notifiers =
NOTIFIER_LIST_INITIALIZER(wakeup_notifiers);
static uint32_t wakeup_reason_mask = ~(1 << QEMU_WAKEUP_REASON_NONE);
-static RunState vmstop_requested = RUN_STATE_MAX;
int qemu_shutdown_requested_get(void)
{
@@ -1824,18 +1846,6 @@ static int qemu_debug_requested(void)
return r;
}
-/* We use RUN_STATE_MAX but any invalid value will do */
-static bool qemu_vmstop_requested(RunState *r)
-{
- if (vmstop_requested < RUN_STATE_MAX) {
- *r = vmstop_requested;
- vmstop_requested = RUN_STATE_MAX;
- return true;
- }
-
- return false;
-}
-
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
{
QEMUResetEntry *re = g_malloc0(sizeof(QEMUResetEntry));
@@ -1985,12 +1995,6 @@ void qemu_system_debug_request(void)
qemu_notify_event();
}
-void qemu_system_vmstop_request(RunState state)
-{
- vmstop_requested = state;
- qemu_notify_event();
-}
-
static bool main_loop_should_exit(void)
{
RunState r;
Also, I think that bdrv_emit_qmp_error_event is placed wrong.
It should be called only after setting the iostatus, otherwise
there is a small window where the iostatus is "no error" but
the event has been generated already.
Paolo
next prev parent reply other threads:[~2014-06-03 15:52 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-03 14:16 [Qemu-devel] [PATCH] block: asynchronously stop the VM on I/O errors Paolo Bonzini
2014-06-03 14:37 ` Kevin Wolf
2014-06-03 15:51 ` Paolo Bonzini [this message]
2014-06-04 8:28 ` Kevin Wolf
2014-06-04 9:04 ` Paolo Bonzini
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=538DEF19.80802@redhat.com \
--to=pbonzini@redhat.com \
--cc=famz@redhat.com \
--cc=kwolf@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@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).