On Wed, 4 Oct 2023 at 06:44, Hanna Czenczek <hre...@redhat.com> wrote:
>
> On 04.10.23 03:45, Stefan Hajnoczi wrote:
> > The VHOST_USER_RESET_OWNER message is deprecated in the spec:
> >
> >     This is no longer used. Used to be sent to request disabling all
> >     rings, but some back-ends interpreted it to also discard connection
> >     state (this interpretation would lead to bugs).  It is recommended
> >     that back-ends either ignore this message, or use it to disable all
> >     rings.
>
> According to the spec, it is then indeed better to not call it in
> vhost_user_reset_device, because it seems like it would be interpreted
> as something completely different.
>
> However, between the three back-end implementations of vhost-user I know
> of (libvhost-user, DPDK, the vhost crates; four if you count RSD), none
> implement RESET_DEVICE.  libvhost-user and DPDK do implement
> RESET_OWNER, though, and they both do it by resetting the device, not by
> disabling any vring.  The vhost crate also implements RESET_OWNER, but
> it doesn’t do anything but forward it as such to the actual device
> implementation (virtiofsd doesn’t implement this function, so ignores
> it).  It does document that it would disable all vrings, but does so in
> the past and has marked it deprecated (ever since the method was
> introduced in the fourth commit to the repository, making it extremely
> unlikely that anyone would implement it).

Hi Hanna,
vhost-user-backend still seems to reset all vhost-user protocol state,
making RESET_OWNER unusable:
https://github.com/rust-vmm/vhost/blob/main/crates/vhost-user-backend/src/handler.rs#L230

Have I missed something?

Stefan

>
> So I would like to know why the spec says that it would disable all
> vrings, when none of the implementations (qemu, libvhost-user, DPDK)
> agree on that.  Let me look it up:
>
> Before commit c61f09ed855, it did say “stopping” instead of
> “disabling”.  The commit doesn’t explain why it changed this. Commit
> a586e65bbd0 (just a week prior) deprecated the command, changing it from
> “connection is about to be closed, [front-end] will no longer own this
> connection” to “deprecated, used to be sent to request stopping all
> vrings”.  To me, the front-end closing the connection sounds like a good
> point to reset, which would indeed stop all vrings, but not just that.
> Notably, qemu agrees, because RESET_OWNER is used only in the
> vhost_user_reset_device() function. a586e65bbd0^ removed that function’s
> use, though, specifically because it would cause a reset, when the
> intention was just to stop.
>
> So it sounds to me like “used to be sent to request stopping all vrings”
> is rather what vhost_net wanted, but specifically not what the message
> did, which was anything between nothing and a reset, I presume (because
> it never specified what the back-end was supposed to do, though
> apparently libvhost-user and DPDK both took it to mean reset).  Why it
> was then changed to “disabling”, I absolutely cannot say.
>
> Now, the code change here is indeed effectively a no-op, as you deduce
> below, but in the context of the whole series the situation is a bit
> different: As far as I understand, the point is to have guest-initiated
> resets be forwarded to back-ends.  But by removing the RESET_OWNER
> fallback, no back-end will actually do a reset still.
>
> I understand that as per the specification, using RESET_OWNER for
> resetting is wrong.  But all implementations that implemented it before
> it was deprecated do interpret it as a reset, so I don’t think using it
> as a fallback is actually wrong.
>
> Hanna
>
> > The only caller of vhost_user_reset_device() is vhost_user_scsi_reset().
> > It checks that F_RESET_DEVICE was negotiated before calling it:
> >
> >    static void vhost_user_scsi_reset(VirtIODevice *vdev)
> >    {
> >        VHostSCSICommon *vsc = VHOST_SCSI_COMMON(vdev);
> >        struct vhost_dev *dev = &vsc->dev;
> >
> >        /*
> >         * Historically, reset was not implemented so only reset devices
> >         * that are expecting it.
> >         */
> >        if (!virtio_has_feature(dev->protocol_features,
> >                                VHOST_USER_PROTOCOL_F_RESET_DEVICE)) {
> >            return;
> >        }
> >
> >        if (dev->vhost_ops->vhost_reset_device) {
> >            dev->vhost_ops->vhost_reset_device(dev);
> >        }
> >    }
> >
> > Therefore VHOST_USER_RESET_OWNER is actually never sent by
> > vhost_user_reset_device(). Remove the dead code. This effectively moves
> > the vhost-user protocol specific code from vhost-user-scsi.c into
> > vhost-user.c where it belongs.
> >
> > Signed-off-by: Stefan Hajnoczi <stefa...@redhat.com>
> > ---
> >   hw/scsi/vhost-user-scsi.c |  9 ---------
> >   hw/virtio/vhost-user.c    | 13 +++++++++----
> >   2 files changed, 9 insertions(+), 13 deletions(-)
> >
> > diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
> > index ee99b19e7a..8582b2e8ab 100644
> > --- a/hw/scsi/vhost-user-scsi.c
> > +++ b/hw/scsi/vhost-user-scsi.c
> > @@ -71,15 +71,6 @@ static void vhost_user_scsi_reset(VirtIODevice *vdev)
> >       VHostSCSICommon *vsc = VHOST_SCSI_COMMON(vdev);
> >       struct vhost_dev *dev = &vsc->dev;
> >
> > -    /*
> > -     * Historically, reset was not implemented so only reset devices
> > -     * that are expecting it.
> > -     */
> > -    if (!virtio_has_feature(dev->protocol_features,
> > -                            VHOST_USER_PROTOCOL_F_RESET_DEVICE)) {
> > -        return;
> > -    }
> > -
> >       if (dev->vhost_ops->vhost_reset_device) {
> >           dev->vhost_ops->vhost_reset_device(dev);
> >       }
> > diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> > index 8dcf049d42..7bed9ad7d5 100644
> > --- a/hw/virtio/vhost-user.c
> > +++ b/hw/virtio/vhost-user.c
> > @@ -1492,12 +1492,17 @@ static int vhost_user_reset_device(struct vhost_dev 
> > *dev)
> >   {
> >       VhostUserMsg msg = {
> >           .hdr.flags = VHOST_USER_VERSION,
> > +        .hdr.request = VHOST_USER_RESET_DEVICE,
> >       };
> >
> > -    msg.hdr.request = virtio_has_feature(dev->protocol_features,
> > -                                         
> > VHOST_USER_PROTOCOL_F_RESET_DEVICE)
> > -        ? VHOST_USER_RESET_DEVICE
> > -        : VHOST_USER_RESET_OWNER;
> > +    /*
> > +     * Historically, reset was not implemented so only reset devices
> > +     * that are expecting it.
> > +     */
> > +    if (!virtio_has_feature(dev->protocol_features,
> > +                            VHOST_USER_PROTOCOL_F_RESET_DEVICE)) {
> > +        return -ENOSYS;
> > +    }
> >
> >       return vhost_user_write(dev, &msg, NULL, 0);
> >   }
>
>

Reply via email to