[dpdk-dev,07/17] vhost: export vhost vring info

Message ID 1488534682-3494-8-git-send-email-yuanhan.liu@linux.intel.com (mailing list archive)
State Superseded, archived
Delegated to: Yuanhan Liu
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation fail apply patch file failure

Commit Message

Yuanhan Liu March 3, 2017, 9:51 a.m. UTC
  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

Maxime Coquelin March 14, 2017, 12:11 p.m. UTC | #1
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
  
Yuanhan Liu March 16, 2017, 7:24 a.m. UTC | #2
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
  
Maxime Coquelin March 16, 2017, 9:20 a.m. UTC | #3
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
  

Patch

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)
+		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
 #define VHOST_MAX_QUEUE_PAIRS		0x80
 
 /*