[dpdk-dev,07/17] vhost: export vhost vring info
Checks
Commit Message
Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
---
lib/librte_vhost/rte_vhost_version.map | 1 +
lib/librte_vhost/rte_virtio_net.h | 13 +++++++++++++
lib/librte_vhost/vhost.c | 30 ++++++++++++++++++++++++++++++
lib/librte_vhost/vhost.h | 2 ++
4 files changed, 46 insertions(+)
Comments
On 03/03/2017 10:51 AM, Yuanhan Liu wrote:
> Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
> ---
> lib/librte_vhost/rte_vhost_version.map | 1 +
> lib/librte_vhost/rte_virtio_net.h | 13 +++++++++++++
> lib/librte_vhost/vhost.c | 30 ++++++++++++++++++++++++++++++
> lib/librte_vhost/vhost.h | 2 ++
> 4 files changed, 46 insertions(+)
>
> diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
> index 85a2796..efde936 100644
> --- a/lib/librte_vhost/rte_vhost_version.map
> +++ b/lib/librte_vhost/rte_vhost_version.map
> @@ -37,5 +37,6 @@ DPDK_17.05 {
> rte_vhost_driver_set_features;
> rte_vhost_get_negotiated_features
> rte_vhost_get_vhost_memory;
> + rte_vhost_get_vhost_vring;
>
> } DPDK_16.07;
> diff --git a/lib/librte_vhost/rte_virtio_net.h b/lib/librte_vhost/rte_virtio_net.h
> index e7b1599..80209ad 100644
> --- a/lib/librte_vhost/rte_virtio_net.h
> +++ b/lib/librte_vhost/rte_virtio_net.h
> @@ -80,6 +80,17 @@ struct rte_vhost_memory {
> struct rte_vhost_mem_region regions[0];
> };
>
> +struct rte_vhost_vring {
> + struct vring_desc *desc;
> + struct vring_avail *avail;
> + struct vring_used *used;
> + uint64_t log_guest_addr;
> +
> + int callfd;
> + int kickfd;
> + uint16_t size;
> +};
> +
> /**
> * Device and vring operations.
> */
> @@ -211,5 +222,7 @@ uint16_t rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
>
> int rte_vhost_get_vhost_memory(int vid, struct rte_vhost_memory **mem);
> uint64_t rte_vhost_get_negotiated_features(int vid);
> +int rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
> + struct rte_vhost_vring *vring);
>
> #endif /* _VIRTIO_NET_H_ */
> diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
> index 8046aef..b175f0e 100644
> --- a/lib/librte_vhost/vhost.c
> +++ b/lib/librte_vhost/vhost.c
> @@ -375,6 +375,36 @@ struct virtio_net *
> return 0;
> }
>
> +int
> +rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
> + struct rte_vhost_vring *vring)
> +{
> + struct virtio_net *dev;
> + struct vhost_virtqueue *vq;
> +
> + dev = get_device(vid);
> + if (!dev)
> + return -1;
> +
> + if (vring_idx > VHOST_MAX_VRING)
Shouldn't be ">=" ?
> + return -1;
> +
> + vq = dev->virtqueue[vring_idx];
> + if (!vq)
> + return -1;
> +
> + vring->desc = vq->desc;
> + vring->avail = vq->avail;
> + vring->used = vq->used;
> + vring->log_guest_addr = vq->log_guest_addr;
> +
> + vring->callfd = vq->callfd;
> + vring->kickfd = vq->kickfd;
> + vring->size = vq->size;
> +
> + return 0;
> +}
> +
> uint16_t
> rte_vhost_avail_entries(int vid, uint16_t queue_id)
> {
> diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
> index ed7b2c9..b0ef0cc 100644
> --- a/lib/librte_vhost/vhost.h
> +++ b/lib/librte_vhost/vhost.h
> @@ -138,6 +138,8 @@ struct vhost_virtqueue {
> #ifndef VIRTIO_NET_F_MQ
> #define VIRTIO_NET_F_MQ 22
> #endif
> +
> +#define VHOST_MAX_VRING 0x100
Looking at the code, I'm not clear where this limitation comes from.
It seems that it can be up to 0x10000, no?
struct virtio_net {
...
struct vhost_virtqueue *virtqueue[VHOST_MAX_QUEUE_PAIRS * 2];
with:
#ifdef VIRTIO_NET_F_MQ
#define VHOST_MAX_QUEUE_PAIRS VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX
#define VHOST_SUPPORTS_MQ (1ULL << VIRTIO_NET_F_MQ)
#else
#define VHOST_MAX_QUEUE_PAIRS 1
#define VHOST_SUPPORTS_MQ 0
#endif
and:
#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX 0x8000
Regards,
Maxime
On Tue, Mar 14, 2017 at 01:11:24PM +0100, Maxime Coquelin wrote:
> >+int
> >+rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
> >+ struct rte_vhost_vring *vring)
> >+{
> >+ struct virtio_net *dev;
> >+ struct vhost_virtqueue *vq;
> >+
> >+ dev = get_device(vid);
> >+ if (!dev)
> >+ return -1;
> >+
> >+ if (vring_idx > VHOST_MAX_VRING)
> Shouldn't be ">=" ?
Nice catch!
> >+#define VHOST_MAX_VRING 0x100
> Looking at the code, I'm not clear where this limitation comes from.
> It seems that it can be up to 0x10000, no?
It comes from the vhost-user spec:
--yliu
---
* VHOST_USER_SET_VRING_KICK
Id: 12
Equivalent ioctl: VHOST_SET_VRING_KICK
Master payload: u64
Set the event file descriptor for adding buffers to the vring. It
is passed in the ancillary data.
Bits (0-7) of the payload contain the vring index. Bit 8 is the
invalid FD flag. This flag is set when there is no file descriptor
in the ancillary data. This signals that polling should be used
instead of waiting for a kick.
>
> struct virtio_net {
> ...
> struct vhost_virtqueue *virtqueue[VHOST_MAX_QUEUE_PAIRS * 2];
>
> with:
> #ifdef VIRTIO_NET_F_MQ
> #define VHOST_MAX_QUEUE_PAIRS VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX
> #define VHOST_SUPPORTS_MQ (1ULL << VIRTIO_NET_F_MQ)
> #else
> #define VHOST_MAX_QUEUE_PAIRS 1
> #define VHOST_SUPPORTS_MQ 0
> #endif
>
> and:
> #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX 0x8000
>
>
> Regards,
> Maxime
On 03/16/2017 08:24 AM, Yuanhan Liu wrote:
> On Tue, Mar 14, 2017 at 01:11:24PM +0100, Maxime Coquelin wrote:
>>> +int
>>> +rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
>>> + struct rte_vhost_vring *vring)
>>> +{
>>> + struct virtio_net *dev;
>>> + struct vhost_virtqueue *vq;
>>> +
>>> + dev = get_device(vid);
>>> + if (!dev)
>>> + return -1;
>>> +
>>> + if (vring_idx > VHOST_MAX_VRING)
>> Shouldn't be ">=" ?
>
> Nice catch!
>
>>> +#define VHOST_MAX_VRING 0x100
>> Looking at the code, I'm not clear where this limitation comes from.
>> It seems that it can be up to 0x10000, no?
>
> It comes from the vhost-user spec:
>
> --yliu
>
> ---
> * VHOST_USER_SET_VRING_KICK
>
> Id: 12
> Equivalent ioctl: VHOST_SET_VRING_KICK
> Master payload: u64
>
> Set the event file descriptor for adding buffers to the vring. It
> is passed in the ancillary data.
> Bits (0-7) of the payload contain the vring index. Bit 8 is the
> invalid FD flag. This flag is set when there is no file descriptor
> in the ancillary data. This signals that polling should be used
> instead of waiting for a kick.
Thanks for the pointer.
With the vring_idx check fixed you can add my:
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Cheers,
Maxime
@@ -37,5 +37,6 @@ DPDK_17.05 {
rte_vhost_driver_set_features;
rte_vhost_get_negotiated_features
rte_vhost_get_vhost_memory;
+ rte_vhost_get_vhost_vring;
} DPDK_16.07;
@@ -80,6 +80,17 @@ struct rte_vhost_memory {
struct rte_vhost_mem_region regions[0];
};
+struct rte_vhost_vring {
+ struct vring_desc *desc;
+ struct vring_avail *avail;
+ struct vring_used *used;
+ uint64_t log_guest_addr;
+
+ int callfd;
+ int kickfd;
+ uint16_t size;
+};
+
/**
* Device and vring operations.
*/
@@ -211,5 +222,7 @@ uint16_t rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
int rte_vhost_get_vhost_memory(int vid, struct rte_vhost_memory **mem);
uint64_t rte_vhost_get_negotiated_features(int vid);
+int rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
+ struct rte_vhost_vring *vring);
#endif /* _VIRTIO_NET_H_ */
@@ -375,6 +375,36 @@ struct virtio_net *
return 0;
}
+int
+rte_vhost_get_vhost_vring(int vid, uint16_t vring_idx,
+ struct rte_vhost_vring *vring)
+{
+ struct virtio_net *dev;
+ struct vhost_virtqueue *vq;
+
+ dev = get_device(vid);
+ if (!dev)
+ return -1;
+
+ if (vring_idx > VHOST_MAX_VRING)
+ return -1;
+
+ vq = dev->virtqueue[vring_idx];
+ if (!vq)
+ return -1;
+
+ vring->desc = vq->desc;
+ vring->avail = vq->avail;
+ vring->used = vq->used;
+ vring->log_guest_addr = vq->log_guest_addr;
+
+ vring->callfd = vq->callfd;
+ vring->kickfd = vq->kickfd;
+ vring->size = vq->size;
+
+ return 0;
+}
+
uint16_t
rte_vhost_avail_entries(int vid, uint16_t queue_id)
{
@@ -138,6 +138,8 @@ struct vhost_virtqueue {
#ifndef VIRTIO_NET_F_MQ
#define VIRTIO_NET_F_MQ 22
#endif
+
+#define VHOST_MAX_VRING 0x100
#define VHOST_MAX_QUEUE_PAIRS 0x80
/*