All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dima Stepanov <dimastep@yandex-team.ru>
To: Raphael Norwitz <raphael.s.norwitz@gmail.com>
Cc: kwolf@redhat.com, qemu-block@nongnu.org, mst@redhat.com,
	jasowang@redhat.com, dgilbert@redhat.com,
	QEMU <qemu-devel@nongnu.org>,
	Raphael Norwitz <raphael.norwitz@nutanix.com>,
	fengli@smartx.com, yc-core@yandex-team.ru, pbonzini@redhat.com,
	marcandre.lureau@redhat.com, mreitz@redhat.com
Subject: Re: [PATCH v3 2/2] vhost-user-blk: delay vhost_user_blk_disconnect
Date: Mon, 25 May 2020 11:54:05 +0300	[thread overview]
Message-ID: <20200525085354.GA7592@dimastep-nix> (raw)
In-Reply-To: <CAFubqFsqm+xo7uVSi6EfTvFdJ7dLm1+xfr9LvrUZK_nktDdiXA@mail.gmail.com>

On Mon, May 25, 2020 at 12:00:10AM -0400, Raphael Norwitz wrote:
> I'm mostly happy with this. A couple comments.
> 
> On Wed, May 20, 2020 at 11:54 AM Dima Stepanov <dimastep@yandex-team.ru> wrote:
> >
> > A socket write during vhost-user communication may trigger a disconnect
> > event, calling vhost_user_blk_disconnect() and clearing all the
> > vhost_dev structures holding data that vhost-user functions expect to
> > remain valid to roll back initialization correctly. Delay the cleanup to
> > keep vhost_dev structure valid.
> > There are two possible states to handle:
> > 1. RUN_STATE_PRELAUNCH: skip bh oneshot call and perform disconnect in
> > the caller routine.
> > 2. RUN_STATE_RUNNING: delay by using bh
> >
> > BH changes are based on the similar changes for the vhost-user-net
> > device:
> >   commit e7c83a885f865128ae3cf1946f8cb538b63cbfba
> >   "vhost-user: delay vhost_user_stop"
> >
> I'd also give credit to Li Feng here - he sent a similar patch:
> 
> https://lists.gnu.org/archive/html/qemu-devel/2020-04/msg02255.html
Yes, thanks for pointing me to it.

> 
> > Signed-off-by: Dima Stepanov <dimastep@yandex-team.ru>
> > ---
> >  hw/block/vhost-user-blk.c | 49 +++++++++++++++++++++++++++++++++++++++++------
> >  1 file changed, 43 insertions(+), 6 deletions(-)
> >
> > diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
> > index 9d8c0b3..447fc9c 100644
> > --- a/hw/block/vhost-user-blk.c
> > +++ b/hw/block/vhost-user-blk.c
> > @@ -337,11 +337,6 @@ static void vhost_user_blk_disconnect(DeviceState *dev)
> >      VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> >      VHostUserBlk *s = VHOST_USER_BLK(vdev);
> >
> > -    if (!s->connected) {
> > -        return;
> > -    }
> > -    s->connected = false;
> > -
> >      if (s->dev.started) {
> >          vhost_user_blk_stop(vdev);
> >      }
> > @@ -349,6 +344,19 @@ static void vhost_user_blk_disconnect(DeviceState *dev)
> >      vhost_dev_cleanup(&s->dev);
> >  }
> >
> > +static void vhost_user_blk_event(void *opaque, QEMUChrEvent event);
> > +
> > +static void vhost_user_blk_chr_closed_bh(void *opaque)
> > +{
> > +    DeviceState *dev = opaque;
> > +    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> > +    VHostUserBlk *s = VHOST_USER_BLK(vdev);
> > +
> > +    vhost_user_blk_disconnect(dev);
> > +    qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, vhost_user_blk_event,
> > +            NULL, opaque, NULL, true);
> > +}
> > +
> >  static void vhost_user_blk_event(void *opaque, QEMUChrEvent event)
> >  {
> >      DeviceState *dev = opaque;
> > @@ -363,7 +371,28 @@ static void vhost_user_blk_event(void *opaque, QEMUChrEvent event)
> >          }
> >          break;
> >      case CHR_EVENT_CLOSED:
> > -        vhost_user_blk_disconnect(dev);
> > +        /*
> > +         * A close event may happen during a read/write, but vhost
> > +         * code assumes the vhost_dev remains setup, so delay the
> > +         * stop & clear. There are two possible paths to hit this
> > +         * disconnect event:
> > +         * 1. When VM is in the RUN_STATE_PRELAUNCH state. The
> > +         * vhost_user_blk_device_realize() is a caller.
> > +         * 2. In tha main loop phase after VM start.
> > +         *
> > +         * For p2 the disconnect event will be delayed. We can't
> > +         * do the same for p1, because we are not running the loop
> > +         * at this moment. So just skip this step and perform
> > +         * disconnect in the caller function.
> > +         */
> > +        if (s->connected && runstate_is_running()) {
> > +            AioContext *ctx = qemu_get_current_aio_context();
> > +
> > +            qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, NULL, NULL,
> > +                    NULL, NULL, false);
> > +            aio_bh_schedule_oneshot(ctx, vhost_user_blk_chr_closed_bh, opaque);
> > +        }
> > +        s->connected = false;
> >          break;
> >      case CHR_EVENT_BREAK:
> >      case CHR_EVENT_MUX_IN:
> > @@ -428,6 +457,14 @@ reconnect:
> >
> >      ret = vhost_dev_get_config(&s->dev, (uint8_t *)&s->blkcfg,
> >                                 sizeof(struct virtio_blk_config));
> 
> I find checking s->connected before ret a little confusing. I think we
> should also enforce a reconnect if s->connected is false. AFIK if
> s->connected is false, ret must also be less than 0, but to be safe
> I’d prefer something like:
> 
> if (ret < 0 || !s->connected) {
>     if (!s->connected) {
>         /*
>          * Perform disconnect before making reconnect. More detailed
>          * comment why it was delayed is in the vhost_user_blk_event()
>          * routine.
>          */
>           vhost_user_blk_disconnect(dev);
>     }
>     if (ret < 0) {
>            error_report(“vhost-user-blk: get block config failed”);
>     }
>     goto reconnect;
> }
> 
True. Thanks to Li Feng's patch i understood that i've overcomplicated the
logic. We don't need this disconnect call here at all.
I'll send a smaller reworked patch in this e-mail thread, just to
continue review and discussion.

> > +    if (!s->connected) {
> > +        /*
> > +         * Perform disconnect before making reconnect. More detailed
> > +         * comment why it was delayed is in the vhost_user_blk_event()
> > +         * routine.
> > +         */
> > +        vhost_user_blk_disconnect(dev);
> > +    }
> >      if (ret < 0) {
> >          error_report("vhost-user-blk: get block config failed");
> >          goto reconnect;
> > --
> > 2.7.4
> >
> >


  reply	other threads:[~2020-05-25  8:55 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-20 15:53 [PATCH v3 0/2] vhost-user reconnect issues during vhost initialization Dima Stepanov
2020-05-20 15:53 ` [PATCH v3 1/2] char-socket: return -1 in case of disconnect during tcp_chr_write Dima Stepanov
2020-05-20 15:53 ` [PATCH v3 2/2] vhost-user-blk: delay vhost_user_blk_disconnect Dima Stepanov
2020-05-25  3:31   ` Jason Wang
2020-05-25  8:27     ` Dima Stepanov
2020-05-25  4:00   ` Raphael Norwitz
2020-05-25  8:54     ` Dima Stepanov [this message]
2020-05-25  8:57   ` Dima Stepanov
2020-05-25 20:56     ` Raphael Norwitz

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=20200525085354.GA7592@dimastep-nix \
    --to=dimastep@yandex-team.ru \
    --cc=dgilbert@redhat.com \
    --cc=fengli@smartx.com \
    --cc=jasowang@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=raphael.norwitz@nutanix.com \
    --cc=raphael.s.norwitz@gmail.com \
    --cc=yc-core@yandex-team.ru \
    /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.