[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH for-7.1 4/8] nbd: keep send_mutex/free_sema handling outside
From: |
Eric Blake |
Subject: |
Re: [PATCH for-7.1 4/8] nbd: keep send_mutex/free_sema handling outside nbd_co_do_establish_connection |
Date: |
Wed, 13 Apr 2022 10:42:51 -0500 |
User-agent: |
NeoMutt/20211029-6-a115bf |
On Tue, Apr 12, 2022 at 09:42:00PM +0200, Paolo Bonzini wrote:
> Elevate s->in_flight early so that other incoming requests will wait
> on the CoQueue in nbd_co_send_request; restart them after getting back
> from nbd_reconnect_attempt. This could be after the reconnect timer or
> nbd_cancel_in_flight have cancelled the attempt, so there is no
> need anymore to cancel the requests there.
>
> nbd_co_send_request now handles both stopping and restarting pending
> requests after a successful connection, and there is no need to
> hold send_mutex in nbd_co_do_establish_connection. The current setup
> is confusing because nbd_co_do_establish_connection is called both with
> send_mutex taken and without it. Before the patch it uses free_sema which
> (at least in theory...) is protected by send_mutex, after the patch it
> does not anymore.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> block/coroutines.h | 4 +--
> block/nbd.c | 66 ++++++++++++++++++++++------------------------
> 2 files changed, 33 insertions(+), 37 deletions(-)
>
> +++ b/block/nbd.c
> @@ -359,25 +354,25 @@ int coroutine_fn
> nbd_co_do_establish_connection(BlockDriverState *bs,
> /* called under s->send_mutex */
> static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s)
> {
> - assert(nbd_client_connecting(s));
> - assert(s->in_flight == 0);
> -
> - if (nbd_client_connecting_wait(s) && s->reconnect_delay &&
> - !s->reconnect_delay_timer)
> - {
> - /*
> - * It's first reconnect attempt after switching to
> - * NBD_CLIENT_CONNECTING_WAIT
> - */
> - reconnect_delay_timer_init(s,
> - qemu_clock_get_ns(QEMU_CLOCK_REALTIME) +
> - s->reconnect_delay * NANOSECONDS_PER_SECOND);
> - }
> + bool blocking = nbd_client_connecting_wait(s);
>
> /*
> * Now we are sure that nobody is accessing the channel, and no one will
> * try until we set the state to CONNECTED.
> */
> + assert(nbd_client_connecting(s));
> + assert(s->in_flight == 1);
> +
> + if (blocking && !s->reconnect_delay_timer) {
> + /*
> + * It's first reconnect attempt after switching to
While moving this, we could add the missing article: "It's the first"
> + * NBD_CLIENT_CONNECTING_WAIT
> + */
> + g_assert(s->reconnect_delay);
> + reconnect_delay_timer_init(s,
> + qemu_clock_get_ns(QEMU_CLOCK_REALTIME) +
> + s->reconnect_delay * NANOSECONDS_PER_SECOND);
> + }
>
> /* Finalize previous connection if any */
> if (s->ioc) {
> @@ -388,7 +383,9 @@ static coroutine_fn void
> nbd_reconnect_attempt(BDRVNBDState *s)
> s->ioc = NULL;
> }
>
> - nbd_co_do_establish_connection(s->bs, NULL);
> + qemu_co_mutex_unlock(&s->send_mutex);
> + nbd_co_do_establish_connection(s->bs, blocking, NULL);
> + qemu_co_mutex_lock(&s->send_mutex);
>
> /*
> * The reconnect attempt is done (maybe successfully, maybe not), so
> @@ -474,21 +471,21 @@ static int coroutine_fn
> nbd_co_send_request(BlockDriverState *bs,
> qemu_co_mutex_lock(&s->send_mutex);
>
> while (s->in_flight == MAX_NBD_REQUESTS ||
> - (!nbd_client_connected(s) && s->in_flight > 0))
> - {
> + (!nbd_client_connected(s) && s->in_flight > 0)) {
Mixing in a style change here. Not the end of the world.
The cosmetics are trivial, and the real change of enlarging the scope
of in_flight makes sense to me.
Reviewed-by: Eric Blake <eblake@redhat.com>
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
[PATCH for-7.1 6/8] nbd: move s->state under requests_lock, Paolo Bonzini, 2022/04/12
[PATCH for-7.1 7/8] nbd: take receive_mutex when reading requests[].receiving, Paolo Bonzini, 2022/04/12