From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55955) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aoOjr-0001JW-AW for qemu-devel@nongnu.org; Fri, 08 Apr 2016 01:13:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aoOjo-0006kX-4d for qemu-devel@nongnu.org; Fri, 08 Apr 2016 01:13:47 -0400 Received: from [59.151.112.132] (port=11033 helo=heian.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aoOjn-0006jU-LZ for qemu-devel@nongnu.org; Fri, 08 Apr 2016 01:13:44 -0400 Message-ID: <57073EA1.3030801@cn.fujitsu.com> Date: Fri, 8 Apr 2016 13:16:17 +0800 From: Changlong Xie MIME-Version: 1.0 References: <1460029495-7146-1-git-send-email-pbonzini@redhat.com> In-Reply-To: <1460029495-7146-1-git-send-email-pbonzini@redhat.com> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH] nbd: do not hang nbd_wr_syncv if outside a coroutine and no available data List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini , qemu-devel@nongnu.org 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 > Cc: Daniel P. Berrange > Signed-off-by: Paolo Bonzini > --- > 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; > } >