diff mbox series

[RFC,v9,13/23] vhost: Add vhost_svq_inject

Message ID 20220706184008.1649478-14-eperezma@redhat.com
State New
Headers show
Series Net Control VQ support in SVQ | expand

Commit Message

Eugenio Perez Martin July 6, 2022, 6:39 p.m. UTC
This allows qemu to inject buffers to the device.

Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
---
 hw/virtio/vhost-shadow-virtqueue.h |  2 ++
 hw/virtio/vhost-shadow-virtqueue.c | 34 ++++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+)

Comments

Jason Wang July 11, 2022, 9:14 a.m. UTC | #1
在 2022/7/7 02:39, Eugenio Pérez 写道:
> This allows qemu to inject buffers to the device.


Not a native speaker but we probably need a better terminology than 
inject here.

Since the CVQ is totally under the control of the Qemu anyhow.


>
> Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
> ---
>   hw/virtio/vhost-shadow-virtqueue.h |  2 ++
>   hw/virtio/vhost-shadow-virtqueue.c | 34 ++++++++++++++++++++++++++++++
>   2 files changed, 36 insertions(+)
>
> diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
> index a811f90e01..d01d2370db 100644
> --- a/hw/virtio/vhost-shadow-virtqueue.h
> +++ b/hw/virtio/vhost-shadow-virtqueue.h
> @@ -98,6 +98,8 @@ bool vhost_svq_valid_features(uint64_t features, Error **errp);
>   
>   void vhost_svq_push_elem(VhostShadowVirtqueue *svq,
>                            const VirtQueueElement *elem, uint32_t len);
> +int vhost_svq_inject(VhostShadowVirtqueue *svq, const struct iovec *iov,
> +                     size_t out_num, size_t in_num, void *opaque);
>   void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd);
>   void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd);
>   void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq,
> diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
> index 492bb12b5f..bd9e34b413 100644
> --- a/hw/virtio/vhost-shadow-virtqueue.c
> +++ b/hw/virtio/vhost-shadow-virtqueue.c
> @@ -283,6 +283,40 @@ static bool vhost_svq_add_element(VhostShadowVirtqueue *svq,
>       return ok;
>   }
>   
> +/**
> + * Inject a chain of buffers to the device
> + *
> + * @svq: Shadow VirtQueue
> + * @iov: I/O vector
> + * @out_num: Number of front out descriptors
> + * @in_num: Number of last input descriptors
> + * @opaque: Contextual data to store in descriptor
> + *
> + * Return 0 on success, -ENOMEM if cannot inject
> + */
> +int vhost_svq_inject(VhostShadowVirtqueue *svq, const struct iovec *iov,
> +                     size_t out_num, size_t in_num, void *opaque)


If we manage to embed opaque into VirtqueueElement, we can simply use 
vhost_svq_add() here.

Thanks


> +{
> +    bool ok;
> +
> +    /*
> +     * All vhost_svq_inject calls are controlled by qemu so we won't hit this
> +     * assertions.
> +     */
> +    assert(out_num || in_num);
> +    assert(svq->ops);
> +
> +    if (unlikely(svq->next_guest_avail_elem)) {
> +        error_report("Injecting in a full queue");
> +        return -ENOMEM;
> +    }
> +
> +    ok = vhost_svq_add(svq, iov, out_num, iov + out_num, in_num, opaque);
> +    assert(ok);
> +    vhost_svq_kick(svq);
> +    return 0;
> +}
> +
>   /**
>    * Forward available buffers.
>    *
Eugenio Perez Martin July 11, 2022, 9:43 a.m. UTC | #2
On Mon, Jul 11, 2022 at 11:14 AM Jason Wang <jasowang@redhat.com> wrote:
>
>
> 在 2022/7/7 02:39, Eugenio Pérez 写道:
> > This allows qemu to inject buffers to the device.
>
>
> Not a native speaker but we probably need a better terminology than
> inject here.
>
> Since the CVQ is totally under the control of the Qemu anyhow.
>

I'm totally fine to change terminology

>
> >
> > Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
> > ---
> >   hw/virtio/vhost-shadow-virtqueue.h |  2 ++
> >   hw/virtio/vhost-shadow-virtqueue.c | 34 ++++++++++++++++++++++++++++++
> >   2 files changed, 36 insertions(+)
> >
> > diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
> > index a811f90e01..d01d2370db 100644
> > --- a/hw/virtio/vhost-shadow-virtqueue.h
> > +++ b/hw/virtio/vhost-shadow-virtqueue.h
> > @@ -98,6 +98,8 @@ bool vhost_svq_valid_features(uint64_t features, Error **errp);
> >
> >   void vhost_svq_push_elem(VhostShadowVirtqueue *svq,
> >                            const VirtQueueElement *elem, uint32_t len);
> > +int vhost_svq_inject(VhostShadowVirtqueue *svq, const struct iovec *iov,
> > +                     size_t out_num, size_t in_num, void *opaque);
> >   void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd);
> >   void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd);
> >   void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq,
> > diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
> > index 492bb12b5f..bd9e34b413 100644
> > --- a/hw/virtio/vhost-shadow-virtqueue.c
> > +++ b/hw/virtio/vhost-shadow-virtqueue.c
> > @@ -283,6 +283,40 @@ static bool vhost_svq_add_element(VhostShadowVirtqueue *svq,
> >       return ok;
> >   }
> >
> > +/**
> > + * Inject a chain of buffers to the device
> > + *
> > + * @svq: Shadow VirtQueue
> > + * @iov: I/O vector
> > + * @out_num: Number of front out descriptors
> > + * @in_num: Number of last input descriptors
> > + * @opaque: Contextual data to store in descriptor
> > + *
> > + * Return 0 on success, -ENOMEM if cannot inject
> > + */
> > +int vhost_svq_inject(VhostShadowVirtqueue *svq, const struct iovec *iov,
> > +                     size_t out_num, size_t in_num, void *opaque)
>
>
> If we manage to embed opaque into VirtqueueElement, we can simply use
> vhost_svq_add() here.
>

That works fine as long as SVQ only forwards elements, but it needs to
do more than that: We need to inject new elements without guest
notice.

How could we track elements that do not have corresponding
VirtQueueElement, like the elements sent to restore the status at the
LM destination?

I'll try to make it clearer in the patch message.

Thanks!

> Thanks
>
>
> > +{
> > +    bool ok;
> > +
> > +    /*
> > +     * All vhost_svq_inject calls are controlled by qemu so we won't hit this
> > +     * assertions.
> > +     */
> > +    assert(out_num || in_num);
> > +    assert(svq->ops);
> > +
> > +    if (unlikely(svq->next_guest_avail_elem)) {
> > +        error_report("Injecting in a full queue");
> > +        return -ENOMEM;
> > +    }
> > +
> > +    ok = vhost_svq_add(svq, iov, out_num, iov + out_num, in_num, opaque);
> > +    assert(ok);
> > +    vhost_svq_kick(svq);
> > +    return 0;
> > +}
> > +
> >   /**
> >    * Forward available buffers.
> >    *
>
Jason Wang July 12, 2022, 7:58 a.m. UTC | #3
在 2022/7/11 17:43, Eugenio Perez Martin 写道:
> On Mon, Jul 11, 2022 at 11:14 AM Jason Wang <jasowang@redhat.com> wrote:
>>
>> 在 2022/7/7 02:39, Eugenio Pérez 写道:
>>> This allows qemu to inject buffers to the device.
>>
>> Not a native speaker but we probably need a better terminology than
>> inject here.
>>
>> Since the CVQ is totally under the control of the Qemu anyhow.
>>
> I'm totally fine to change terminology
>
>>> Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
>>> ---
>>>    hw/virtio/vhost-shadow-virtqueue.h |  2 ++
>>>    hw/virtio/vhost-shadow-virtqueue.c | 34 ++++++++++++++++++++++++++++++
>>>    2 files changed, 36 insertions(+)
>>>
>>> diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
>>> index a811f90e01..d01d2370db 100644
>>> --- a/hw/virtio/vhost-shadow-virtqueue.h
>>> +++ b/hw/virtio/vhost-shadow-virtqueue.h
>>> @@ -98,6 +98,8 @@ bool vhost_svq_valid_features(uint64_t features, Error **errp);
>>>
>>>    void vhost_svq_push_elem(VhostShadowVirtqueue *svq,
>>>                             const VirtQueueElement *elem, uint32_t len);
>>> +int vhost_svq_inject(VhostShadowVirtqueue *svq, const struct iovec *iov,
>>> +                     size_t out_num, size_t in_num, void *opaque);
>>>    void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd);
>>>    void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd);
>>>    void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq,
>>> diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
>>> index 492bb12b5f..bd9e34b413 100644
>>> --- a/hw/virtio/vhost-shadow-virtqueue.c
>>> +++ b/hw/virtio/vhost-shadow-virtqueue.c
>>> @@ -283,6 +283,40 @@ static bool vhost_svq_add_element(VhostShadowVirtqueue *svq,
>>>        return ok;
>>>    }
>>>
>>> +/**
>>> + * Inject a chain of buffers to the device
>>> + *
>>> + * @svq: Shadow VirtQueue
>>> + * @iov: I/O vector
>>> + * @out_num: Number of front out descriptors
>>> + * @in_num: Number of last input descriptors
>>> + * @opaque: Contextual data to store in descriptor
>>> + *
>>> + * Return 0 on success, -ENOMEM if cannot inject
>>> + */
>>> +int vhost_svq_inject(VhostShadowVirtqueue *svq, const struct iovec *iov,
>>> +                     size_t out_num, size_t in_num, void *opaque)
>>
>> If we manage to embed opaque into VirtqueueElement, we can simply use
>> vhost_svq_add() here.
>>
> That works fine as long as SVQ only forwards elements, but it needs to
> do more than that: We need to inject new elements without guest
> notice.
>
> How could we track elements that do not have corresponding
> VirtQueueElement, like the elements sent to restore the status at the
> LM destination?


Having a token for each VirtQueueElement will work? Or maybe I can ask 
differently, what kind of extra state that need to be tracked here?

(For virtio state it should be handled by shadow virtqueue core).

Thanks


>
> I'll try to make it clearer in the patch message.
>
> Thanks!
>
>> Thanks
>>
>>
>>> +{
>>> +    bool ok;
>>> +
>>> +    /*
>>> +     * All vhost_svq_inject calls are controlled by qemu so we won't hit this
>>> +     * assertions.
>>> +     */
>>> +    assert(out_num || in_num);
>>> +    assert(svq->ops);
>>> +
>>> +    if (unlikely(svq->next_guest_avail_elem)) {
>>> +        error_report("Injecting in a full queue");
>>> +        return -ENOMEM;
>>> +    }
>>> +
>>> +    ok = vhost_svq_add(svq, iov, out_num, iov + out_num, in_num, opaque);
>>> +    assert(ok);
>>> +    vhost_svq_kick(svq);
>>> +    return 0;
>>> +}
>>> +
>>>    /**
>>>     * Forward available buffers.
>>>     *
diff mbox series

Patch

diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
index a811f90e01..d01d2370db 100644
--- a/hw/virtio/vhost-shadow-virtqueue.h
+++ b/hw/virtio/vhost-shadow-virtqueue.h
@@ -98,6 +98,8 @@  bool vhost_svq_valid_features(uint64_t features, Error **errp);
 
 void vhost_svq_push_elem(VhostShadowVirtqueue *svq,
                          const VirtQueueElement *elem, uint32_t len);
+int vhost_svq_inject(VhostShadowVirtqueue *svq, const struct iovec *iov,
+                     size_t out_num, size_t in_num, void *opaque);
 void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd);
 void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd);
 void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq,
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
index 492bb12b5f..bd9e34b413 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -283,6 +283,40 @@  static bool vhost_svq_add_element(VhostShadowVirtqueue *svq,
     return ok;
 }
 
+/**
+ * Inject a chain of buffers to the device
+ *
+ * @svq: Shadow VirtQueue
+ * @iov: I/O vector
+ * @out_num: Number of front out descriptors
+ * @in_num: Number of last input descriptors
+ * @opaque: Contextual data to store in descriptor
+ *
+ * Return 0 on success, -ENOMEM if cannot inject
+ */
+int vhost_svq_inject(VhostShadowVirtqueue *svq, const struct iovec *iov,
+                     size_t out_num, size_t in_num, void *opaque)
+{
+    bool ok;
+
+    /*
+     * All vhost_svq_inject calls are controlled by qemu so we won't hit this
+     * assertions.
+     */
+    assert(out_num || in_num);
+    assert(svq->ops);
+
+    if (unlikely(svq->next_guest_avail_elem)) {
+        error_report("Injecting in a full queue");
+        return -ENOMEM;
+    }
+
+    ok = vhost_svq_add(svq, iov, out_num, iov + out_num, in_num, opaque);
+    assert(ok);
+    vhost_svq_kick(svq);
+    return 0;
+}
+
 /**
  * Forward available buffers.
  *