[v5,2/5] vhost: implement rte_power_monitor API

Message ID 20211015151223.425847-3-miao.li@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Maxime Coquelin
Headers
Series Implement rte_power_monitor API in virtio/vhost PMD |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Li, Miao Oct. 15, 2021, 3:12 p.m. UTC
  This patch defines rte_vhost_power_monitor_cond which is used to pass
some information to vhost driver. The information is including the address
to monitor, the expected value, the mask to extract value read from 'addr',
the value size of monitor address, the match flag used to distinguish the
value used to match something or not match something. Vhost driver can use
these information to fill rte_power_monitor_cond.

Signed-off-by: Miao Li <miao.li@intel.com>
---
 doc/guides/rel_notes/release_21_11.rst |  4 +++
 lib/vhost/rte_vhost.h                  | 44 ++++++++++++++++++++++++++
 lib/vhost/version.map                  |  3 ++
 lib/vhost/vhost.c                      | 38 ++++++++++++++++++++++
 4 files changed, 89 insertions(+)
  

Comments

Chenbo Xia Oct. 15, 2021, 7:38 a.m. UTC | #1
Hi,

> -----Original Message-----
> From: Li, Miao <miao.li@intel.com>
> Sent: Friday, October 15, 2021 11:12 PM
> To: dev@dpdk.org
> Cc: Xia, Chenbo <chenbo.xia@intel.com>; maxime.coquelin@redhat.com; Li, Miao
> <miao.li@intel.com>
> Subject: [PATCH v5 2/5] vhost: implement rte_power_monitor API
> 
> This patch defines rte_vhost_power_monitor_cond which is used to pass
> some information to vhost driver. The information is including the address
> to monitor, the expected value, the mask to extract value read from 'addr',
> the value size of monitor address, the match flag used to distinguish the
> value used to match something or not match something. Vhost driver can use
> these information to fill rte_power_monitor_cond.
> 
> Signed-off-by: Miao Li <miao.li@intel.com>
> ---
>  doc/guides/rel_notes/release_21_11.rst |  4 +++
>  lib/vhost/rte_vhost.h                  | 44 ++++++++++++++++++++++++++
>  lib/vhost/version.map                  |  3 ++
>  lib/vhost/vhost.c                      | 38 ++++++++++++++++++++++
>  4 files changed, 89 insertions(+)
> 
> diff --git a/doc/guides/rel_notes/release_21_11.rst
> b/doc/guides/rel_notes/release_21_11.rst
> index 27dc896703..ad6d256a55 100644
> --- a/doc/guides/rel_notes/release_21_11.rst
> +++ b/doc/guides/rel_notes/release_21_11.rst
> @@ -72,6 +72,10 @@ New Features
>    Added macros ETH_RSS_IPV4_CHKSUM and ETH_RSS_L4_CHKSUM, now IPv4 and
>    TCP/UDP/SCTP header checksum field can be used as input set for RSS.
> 
> +* **Added power monitor API in vhost library.**
> +
> +  Added an API to support power monitor in vhost library.
> +
>  * **Updated virtio PMD.**
> 
>    Implement rte_power_monitor API in virtio PMD.
> diff --git a/lib/vhost/rte_vhost.h b/lib/vhost/rte_vhost.h
> index fd372d5259..42bda95e96 100644
> --- a/lib/vhost/rte_vhost.h
> +++ b/lib/vhost/rte_vhost.h
> @@ -292,6 +292,33 @@ struct vhost_device_ops {
>  	void *reserved[1]; /**< Reserved for future extension */
>  };
> 
> +/**
> + * Power monitor condition.
> + */
> +struct rte_vhost_power_monitor_cond {
> +	/**< Address to monitor for changes */
> +	volatile void *addr;
> +	/**< If the `mask` is non-zero, location pointed
> +	 *   to by `addr` will be read and masked, then
> +	 *   compared with this value.
> +	 */
> +	uint64_t val;
> +	/**< 64-bit mask to extract value read from `addr` */
> +	uint64_t mask;
> +	/**< Data size (in bytes) that will be read from the
> +	 *   monitored memory location (`addr`). Can be 1, 2,
> +	 *   4, or 8. Supplying any other value will result in
> +	 *   an error.

'Can be ...' part is not necessary, as this value is defined in vhost
lib and currently only has two different values for packed or split.

> +	 */
> +	uint8_t size;
> +	/**< If 1, and masked value that read from 'addr' equals
> +	 *   'val', the driver will skip core sleep. If 0, and

'will' -> 'should'. As it's a suggestion for vhost driver.

> +	 *  masked value that read from 'addr' does not equal 'val',
> +	 *  the driver will skip core sleep.

Ditto.

Thanks,
Chenbo

> +	 */
> +	uint8_t match;
> +};
> +
>  /**
>   * Convert guest physical address to host virtual address
>   *
> @@ -903,6 +930,23 @@ int rte_vhost_vring_call(int vid, uint16_t vring_idx);
>   */
>  uint32_t rte_vhost_rx_queue_count(int vid, uint16_t qid);
> 
> +/**
> + * Get power monitor address of the vhost device
> + *
> + * @param vid
> + *  vhost device ID
> + * @param queue_id
> + *  vhost queue ID
> + * @param pmc
> + *  power monitor condition
> + * @return
> + *  0 on success, -1 on failure
> + */
> +__rte_experimental
> +int
> +rte_vhost_get_monitor_addr(int vid, uint16_t queue_id,
> +		struct rte_vhost_power_monitor_cond *pmc);
> +
>  /**
>   * Get log base and log size of the vhost device
>   *
> diff --git a/lib/vhost/version.map b/lib/vhost/version.map
> index 8ebde3f694..c8599ddb97 100644
> --- a/lib/vhost/version.map
> +++ b/lib/vhost/version.map
> @@ -85,4 +85,7 @@ EXPERIMENTAL {
>  	rte_vhost_async_channel_register_thread_unsafe;
>  	rte_vhost_async_channel_unregister_thread_unsafe;
>  	rte_vhost_clear_queue_thread_unsafe;
> +
> +	# added in 21.11
> +	rte_vhost_get_monitor_addr;
>  };
> diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c
> index 9540522dac..36c896c9e2 100644
> --- a/lib/vhost/vhost.c
> +++ b/lib/vhost/vhost.c
> @@ -1889,5 +1889,43 @@ rte_vhost_async_get_inflight(int vid, uint16_t queue_id)
>  	return ret;
>  }
> 
> +int
> +rte_vhost_get_monitor_addr(int vid, uint16_t queue_id,
> +		struct rte_vhost_power_monitor_cond *pmc)
> +{
> +	struct virtio_net *dev = get_device(vid);
> +	struct vhost_virtqueue *vq;
> +
> +	if (dev == NULL)
> +		return -1;
> +	if (queue_id >= VHOST_MAX_VRING)
> +		return -1;
> +
> +	vq = dev->virtqueue[queue_id];
> +	if (vq == NULL)
> +		return -1;
> +
> +	if (vq_is_packed(dev)) {
> +		struct vring_packed_desc *desc;
> +		desc = vq->desc_packed;
> +		pmc->addr = &desc[vq->last_avail_idx].flags;
> +		if (vq->avail_wrap_counter)
> +			pmc->val = VRING_DESC_F_AVAIL;
> +		else
> +			pmc->val = VRING_DESC_F_USED;
> +		pmc->mask = VRING_DESC_F_AVAIL | VRING_DESC_F_USED;
> +		pmc->size = sizeof(desc[vq->last_avail_idx].flags);
> +		pmc->match = 1;
> +	} else {
> +		pmc->addr = &vq->avail->idx;
> +		pmc->val = vq->last_avail_idx & (vq->size - 1);
> +		pmc->mask = vq->size - 1;
> +		pmc->size = sizeof(vq->avail->idx);
> +		pmc->match = 0;
> +	}
> +
> +	return 0;
> +}
> +
>  RTE_LOG_REGISTER_SUFFIX(vhost_config_log_level, config, INFO);
>  RTE_LOG_REGISTER_SUFFIX(vhost_data_log_level, data, WARNING);
> --
> 2.25.1
  
Li, Miao Oct. 15, 2021, 8:47 a.m. UTC | #2
Hi Chenbo,

> -----Original Message-----
> From: Xia, Chenbo <chenbo.xia@intel.com>
> Sent: Friday, October 15, 2021 3:38 PM
> To: Li, Miao <miao.li@intel.com>; dev@dpdk.org
> Cc: maxime.coquelin@redhat.com
> Subject: RE: [PATCH v5 2/5] vhost: implement rte_power_monitor API
> 
> Hi,
> 
> > -----Original Message-----
> > From: Li, Miao <miao.li@intel.com>
> > Sent: Friday, October 15, 2021 11:12 PM
> > To: dev@dpdk.org
> > Cc: Xia, Chenbo <chenbo.xia@intel.com>; maxime.coquelin@redhat.com; Li,
> Miao
> > <miao.li@intel.com>
> > Subject: [PATCH v5 2/5] vhost: implement rte_power_monitor API
> >
> > This patch defines rte_vhost_power_monitor_cond which is used to pass
> > some information to vhost driver. The information is including the address
> > to monitor, the expected value, the mask to extract value read from 'addr',
> > the value size of monitor address, the match flag used to distinguish the
> > value used to match something or not match something. Vhost driver can use
> > these information to fill rte_power_monitor_cond.
> >
> > Signed-off-by: Miao Li <miao.li@intel.com>
> > ---
> >  doc/guides/rel_notes/release_21_11.rst |  4 +++
> >  lib/vhost/rte_vhost.h                  | 44 ++++++++++++++++++++++++++
> >  lib/vhost/version.map                  |  3 ++
> >  lib/vhost/vhost.c                      | 38 ++++++++++++++++++++++
> >  4 files changed, 89 insertions(+)
> >
> > diff --git a/doc/guides/rel_notes/release_21_11.rst
> > b/doc/guides/rel_notes/release_21_11.rst
> > index 27dc896703..ad6d256a55 100644
> > --- a/doc/guides/rel_notes/release_21_11.rst
> > +++ b/doc/guides/rel_notes/release_21_11.rst
> > @@ -72,6 +72,10 @@ New Features
> >    Added macros ETH_RSS_IPV4_CHKSUM and ETH_RSS_L4_CHKSUM, now IPv4
> and
> >    TCP/UDP/SCTP header checksum field can be used as input set for RSS.
> >
> > +* **Added power monitor API in vhost library.**
> > +
> > +  Added an API to support power monitor in vhost library.
> > +
> >  * **Updated virtio PMD.**
> >
> >    Implement rte_power_monitor API in virtio PMD.
> > diff --git a/lib/vhost/rte_vhost.h b/lib/vhost/rte_vhost.h
> > index fd372d5259..42bda95e96 100644
> > --- a/lib/vhost/rte_vhost.h
> > +++ b/lib/vhost/rte_vhost.h
> > @@ -292,6 +292,33 @@ struct vhost_device_ops {
> >  	void *reserved[1]; /**< Reserved for future extension */
> >  };
> >
> > +/**
> > + * Power monitor condition.
> > + */
> > +struct rte_vhost_power_monitor_cond {
> > +	/**< Address to monitor for changes */
> > +	volatile void *addr;
> > +	/**< If the `mask` is non-zero, location pointed
> > +	 *   to by `addr` will be read and masked, then
> > +	 *   compared with this value.
> > +	 */
> > +	uint64_t val;
> > +	/**< 64-bit mask to extract value read from `addr` */
> > +	uint64_t mask;
> > +	/**< Data size (in bytes) that will be read from the
> > +	 *   monitored memory location (`addr`). Can be 1, 2,
> > +	 *   4, or 8. Supplying any other value will result in
> > +	 *   an error.
> 
> 'Can be ...' part is not necessary, as this value is defined in vhost
> lib and currently only has two different values for packed or split.

I will remove it in the next version.

> 
> > +	 */
> > +	uint8_t size;
> > +	/**< If 1, and masked value that read from 'addr' equals
> > +	 *   'val', the driver will skip core sleep. If 0, and
> 
> 'will' -> 'should'. As it's a suggestion for vhost driver.
> 
> > +	 *  masked value that read from 'addr' does not equal 'val',
> > +	 *  the driver will skip core sleep.
> 
> Ditto.

I will modify them in the next version.

Thanks,
Miao

> 
> Thanks,
> Chenbo
> 
> > +	 */
> > +	uint8_t match;
> > +};
> > +
> >  /**
> >   * Convert guest physical address to host virtual address
> >   *
> > @@ -903,6 +930,23 @@ int rte_vhost_vring_call(int vid, uint16_t vring_idx);
> >   */
> >  uint32_t rte_vhost_rx_queue_count(int vid, uint16_t qid);
> >
> > +/**
> > + * Get power monitor address of the vhost device
> > + *
> > + * @param vid
> > + *  vhost device ID
> > + * @param queue_id
> > + *  vhost queue ID
> > + * @param pmc
> > + *  power monitor condition
> > + * @return
> > + *  0 on success, -1 on failure
> > + */
> > +__rte_experimental
> > +int
> > +rte_vhost_get_monitor_addr(int vid, uint16_t queue_id,
> > +		struct rte_vhost_power_monitor_cond *pmc);
> > +
> >  /**
> >   * Get log base and log size of the vhost device
> >   *
> > diff --git a/lib/vhost/version.map b/lib/vhost/version.map
> > index 8ebde3f694..c8599ddb97 100644
> > --- a/lib/vhost/version.map
> > +++ b/lib/vhost/version.map
> > @@ -85,4 +85,7 @@ EXPERIMENTAL {
> >  	rte_vhost_async_channel_register_thread_unsafe;
> >  	rte_vhost_async_channel_unregister_thread_unsafe;
> >  	rte_vhost_clear_queue_thread_unsafe;
> > +
> > +	# added in 21.11
> > +	rte_vhost_get_monitor_addr;
> >  };
> > diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c
> > index 9540522dac..36c896c9e2 100644
> > --- a/lib/vhost/vhost.c
> > +++ b/lib/vhost/vhost.c
> > @@ -1889,5 +1889,43 @@ rte_vhost_async_get_inflight(int vid, uint16_t
> queue_id)
> >  	return ret;
> >  }
> >
> > +int
> > +rte_vhost_get_monitor_addr(int vid, uint16_t queue_id,
> > +		struct rte_vhost_power_monitor_cond *pmc)
> > +{
> > +	struct virtio_net *dev = get_device(vid);
> > +	struct vhost_virtqueue *vq;
> > +
> > +	if (dev == NULL)
> > +		return -1;
> > +	if (queue_id >= VHOST_MAX_VRING)
> > +		return -1;
> > +
> > +	vq = dev->virtqueue[queue_id];
> > +	if (vq == NULL)
> > +		return -1;
> > +
> > +	if (vq_is_packed(dev)) {
> > +		struct vring_packed_desc *desc;
> > +		desc = vq->desc_packed;
> > +		pmc->addr = &desc[vq->last_avail_idx].flags;
> > +		if (vq->avail_wrap_counter)
> > +			pmc->val = VRING_DESC_F_AVAIL;
> > +		else
> > +			pmc->val = VRING_DESC_F_USED;
> > +		pmc->mask = VRING_DESC_F_AVAIL | VRING_DESC_F_USED;
> > +		pmc->size = sizeof(desc[vq->last_avail_idx].flags);
> > +		pmc->match = 1;
> > +	} else {
> > +		pmc->addr = &vq->avail->idx;
> > +		pmc->val = vq->last_avail_idx & (vq->size - 1);
> > +		pmc->mask = vq->size - 1;
> > +		pmc->size = sizeof(vq->avail->idx);
> > +		pmc->match = 0;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  RTE_LOG_REGISTER_SUFFIX(vhost_config_log_level, config, INFO);
> >  RTE_LOG_REGISTER_SUFFIX(vhost_data_log_level, data, WARNING);
> > --
> > 2.25.1
  

Patch

diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 27dc896703..ad6d256a55 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -72,6 +72,10 @@  New Features
   Added macros ETH_RSS_IPV4_CHKSUM and ETH_RSS_L4_CHKSUM, now IPv4 and
   TCP/UDP/SCTP header checksum field can be used as input set for RSS.
 
+* **Added power monitor API in vhost library.**
+
+  Added an API to support power monitor in vhost library.
+
 * **Updated virtio PMD.**
 
   Implement rte_power_monitor API in virtio PMD.
diff --git a/lib/vhost/rte_vhost.h b/lib/vhost/rte_vhost.h
index fd372d5259..42bda95e96 100644
--- a/lib/vhost/rte_vhost.h
+++ b/lib/vhost/rte_vhost.h
@@ -292,6 +292,33 @@  struct vhost_device_ops {
 	void *reserved[1]; /**< Reserved for future extension */
 };
 
+/**
+ * Power monitor condition.
+ */
+struct rte_vhost_power_monitor_cond {
+	/**< Address to monitor for changes */
+	volatile void *addr;
+	/**< If the `mask` is non-zero, location pointed
+	 *   to by `addr` will be read and masked, then
+	 *   compared with this value.
+	 */
+	uint64_t val;
+	/**< 64-bit mask to extract value read from `addr` */
+	uint64_t mask;
+	/**< Data size (in bytes) that will be read from the
+	 *   monitored memory location (`addr`). Can be 1, 2,
+	 *   4, or 8. Supplying any other value will result in
+	 *   an error.
+	 */
+	uint8_t size;
+	/**< If 1, and masked value that read from 'addr' equals
+	 *   'val', the driver will skip core sleep. If 0, and
+	 *  masked value that read from 'addr' does not equal 'val',
+	 *  the driver will skip core sleep.
+	 */
+	uint8_t match;
+};
+
 /**
  * Convert guest physical address to host virtual address
  *
@@ -903,6 +930,23 @@  int rte_vhost_vring_call(int vid, uint16_t vring_idx);
  */
 uint32_t rte_vhost_rx_queue_count(int vid, uint16_t qid);
 
+/**
+ * Get power monitor address of the vhost device
+ *
+ * @param vid
+ *  vhost device ID
+ * @param queue_id
+ *  vhost queue ID
+ * @param pmc
+ *  power monitor condition
+ * @return
+ *  0 on success, -1 on failure
+ */
+__rte_experimental
+int
+rte_vhost_get_monitor_addr(int vid, uint16_t queue_id,
+		struct rte_vhost_power_monitor_cond *pmc);
+
 /**
  * Get log base and log size of the vhost device
  *
diff --git a/lib/vhost/version.map b/lib/vhost/version.map
index 8ebde3f694..c8599ddb97 100644
--- a/lib/vhost/version.map
+++ b/lib/vhost/version.map
@@ -85,4 +85,7 @@  EXPERIMENTAL {
 	rte_vhost_async_channel_register_thread_unsafe;
 	rte_vhost_async_channel_unregister_thread_unsafe;
 	rte_vhost_clear_queue_thread_unsafe;
+
+	# added in 21.11
+	rte_vhost_get_monitor_addr;
 };
diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c
index 9540522dac..36c896c9e2 100644
--- a/lib/vhost/vhost.c
+++ b/lib/vhost/vhost.c
@@ -1889,5 +1889,43 @@  rte_vhost_async_get_inflight(int vid, uint16_t queue_id)
 	return ret;
 }
 
+int
+rte_vhost_get_monitor_addr(int vid, uint16_t queue_id,
+		struct rte_vhost_power_monitor_cond *pmc)
+{
+	struct virtio_net *dev = get_device(vid);
+	struct vhost_virtqueue *vq;
+
+	if (dev == NULL)
+		return -1;
+	if (queue_id >= VHOST_MAX_VRING)
+		return -1;
+
+	vq = dev->virtqueue[queue_id];
+	if (vq == NULL)
+		return -1;
+
+	if (vq_is_packed(dev)) {
+		struct vring_packed_desc *desc;
+		desc = vq->desc_packed;
+		pmc->addr = &desc[vq->last_avail_idx].flags;
+		if (vq->avail_wrap_counter)
+			pmc->val = VRING_DESC_F_AVAIL;
+		else
+			pmc->val = VRING_DESC_F_USED;
+		pmc->mask = VRING_DESC_F_AVAIL | VRING_DESC_F_USED;
+		pmc->size = sizeof(desc[vq->last_avail_idx].flags);
+		pmc->match = 1;
+	} else {
+		pmc->addr = &vq->avail->idx;
+		pmc->val = vq->last_avail_idx & (vq->size - 1);
+		pmc->mask = vq->size - 1;
+		pmc->size = sizeof(vq->avail->idx);
+		pmc->match = 0;
+	}
+
+	return 0;
+}
+
 RTE_LOG_REGISTER_SUFFIX(vhost_config_log_level, config, INFO);
 RTE_LOG_REGISTER_SUFFIX(vhost_data_log_level, data, WARNING);