[Libguestfs] [PATCH libnbd 2/3] states: Add handle h->wflags field.
Eric Blake
eblake at redhat.com
Mon Jun 10 22:22:05 UTC 2019
On 6/9/19 1:14 PM, Richard W.M. Jones wrote:
>
> There's an obvious bug in this patch in that it doesn't reset the
> h->wflags field in all cases. Updated patch below.
>
> I rechecked the performance measurements and they are the same after
> the updated patch.
>
> Rich.
>
>>From 15a687b50acecebcfd3dc6222d93e6df984b83c6 Mon Sep 17 00:00:00 2001
> From: "Richard W.M. Jones" <rjones at redhat.com>
> Date: Sat, 8 Jun 2019 19:12:22 +0100
> Subject: [PATCH] states: Add handle h->wflags field.
>
> This field contains optimization flags (ie. MSG_MORE) which are passed
> through to the socket layer if it supports them. The flags are reset
> automatically when we move to another state.
> ---
> generator/states.c | 10 +++++++---
> lib/internal.h | 1 +
> 2 files changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/generator/states.c b/generator/states.c
> index e879a83..b0dab83 100644
> --- a/generator/states.c
> +++ b/generator/states.c
> @@ -91,8 +91,8 @@ send_from_wbuf (struct nbd_handle *h)
> ssize_t r;
>
> if (h->wlen == 0)
> - return 0; /* move to next state */
> - r = h->sock->ops->send (h, h->sock, h->wbuf, h->wlen, 0);
> + goto next_state;
> + r = h->sock->ops->send (h, h->sock, h->wbuf, h->wlen, h->wflags);
> if (r == -1) {
> if (errno == EAGAIN || errno == EWOULDBLOCK)
> return 1; /* more data */
> @@ -102,9 +102,13 @@ send_from_wbuf (struct nbd_handle *h)
> h->wbuf += r;
> h->wlen -= r;
> if (h->wlen == 0)
> - return 0; /* move to next state */
> + goto next_state;
> else
> return 1; /* more data */
Hmm. If we blocked, do we still want to use MSG_MORE on the next
resumption of send()? Or should we blindly clear h->wflags as soon as
we block as well as when we move to the next state?
In practice, will we ever block when MSG_MORE is set? Ideally, we won't
overflow a TCP segment except on the final payload portion of
NBD_CMD_WRITE. Or are you hoping to set MSG_MORE even on other commands,
if there is a request queue, so that we can bundle multiple commands
into a single TCP segment?
Okay, I think that it's okay to always replay MSG_MORE when resuming a
write() that blocked, even if we'll never hit that situation unless we
rework a caller to pass MSG_MORE even for the last byte of one request
when we know the request queue is non-empty so another request is
immediately ready to also transmit.
> +
> + next_state:
> + h->wflags = 0; /* reset this when moving to next state */
> + return 0; /* move to next state */
> }
>
> /*----- End of prologue. -----*/
> diff --git a/lib/internal.h b/lib/internal.h
> index 1ffb5b7..e7be05b 100644
> --- a/lib/internal.h
> +++ b/lib/internal.h
> @@ -110,6 +110,7 @@ struct nbd_handle {
> /* As above, but for writing using send_from_wbuf. */
> const void *wbuf;
> size_t wlen;
> + int wflags;
>
> /* Static buffer used for short amounts of data, such as handshake
> * and commands.
>
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization: qemu.org | libvirt.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libguestfs/attachments/20190610/7c2d572c/attachment.sig>
More information about the Libguestfs
mailing list