From: Changlong Xie <xiecl.fnst@cn.fujitsu.com>
To: Paolo Bonzini <pbonzini@redhat.com>, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] nbd: do not hang nbd_wr_syncv if outside a coroutine and no available data
Date: Fri, 8 Apr 2016 13:16:17 +0800 [thread overview]
Message-ID: <57073EA1.3030801@cn.fujitsu.com> (raw)
In-Reply-To: <1460029495-7146-1-git-send-email-pbonzini@redhat.com>
On 04/07/2016 07:44 PM, Paolo Bonzini wrote:
> Until commit 1c778ef7 ("nbd: convert to using I/O channels for actual
> socket I/O", 2016-02-16), nbd_wr_sync returned -EAGAIN this scenario.
> nbd_reply_ready required these semantics because it has two conflicting
> requirements:
>
> 1) if a reply can be received on the socket, nbd_reply_ready needs
> to read the header outside coroutine context to identify _which_
> coroutine to enter to process the rest of the reply
>
> 2) on the other hand, nbd_reply_ready can find a false positive if
> another thread (e.g. a VCPU thread running aio_poll) sneaks in and
> calls nbd_reply_ready too. In this case nbd_reply_ready does nothing
> and expects nbd_wr_syncv to return -EAGAIN.
>
> Currently, the solution to the first requirement is to wait in the very
> rare case of a read() that doesn't retrieve the reply header in its
> entirety; this is what nbd_wr_syncv does by calling qio_channel_wait().
> However, the unconditional call to qio_channel_wait() breaks the second
> requirement. To fix this, the patch makes nbd_wr_syncv return -EAGAIN
> if done is zero, similar to the code before commit 1c778ef7.
>
> This is okay because NBD client-side negotiation is the only other case
> that calls nbd_wr_syncv outside a coroutine, and it places the socket
> in blocking mode. On the other hand, it is a bit unpleasant to put
> this in nbd_wr_syncv(), because the function is used by both client
> and server.
>
> The full fix would be to add a counter to NbdClientSession for how
> many bytes have been filled in s->reply. Then a reply can be filled
> by multiple separate invocations of nbd_reply_ready and the
> qio_channel_wait() call can be removed completely. Something to
> consider for 2.7...
>
> Reported-by: Changlong Xie <xiecl.fnst@cn.fujitsu.com>
> Cc: Daniel P. Berrange <berrange@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> nbd/common.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/nbd/common.c b/nbd/common.c
> index a44718c..8ddb2dd 100644
> --- a/nbd/common.c
> +++ b/nbd/common.c
> @@ -50,9 +50,12 @@ ssize_t nbd_wr_syncv(QIOChannel *ioc,
> * qio_channel_yield() that works with AIO contexts
> * and consider using that in this branch */
> qemu_coroutine_yield();
> - } else {
> + } else if (done) {
> + /* XXX this is needed by nbd_reply_ready. */
> qio_channel_wait(ioc,
> do_read ? G_IO_IN : G_IO_OUT);
> + } else {
> + return -EAGAIN;
> }
With this patch, nbd works well now.
Thanks
-Xie
> continue;
> }
>
prev parent reply other threads:[~2016-04-08 5:13 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-07 11:44 [Qemu-devel] [PATCH] nbd: do not hang nbd_wr_syncv if outside a coroutine and no available data Paolo Bonzini
2016-04-07 13:45 ` Daniel P. Berrange
2016-04-08 5:16 ` Changlong Xie [this message]
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=57073EA1.3030801@cn.fujitsu.com \
--to=xiecl.fnst@cn.fujitsu.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.