Hi, > -----Original Message----- > From: Li, Miao <miao...@intel.com> > Sent: Friday, October 15, 2021 11:12 PM > To: dev@dpdk.org > Cc: Xia, Chenbo <chenbo....@intel.com>; maxime.coque...@redhat.com; Li, Miao > <miao...@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...@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