* Added port representors support on SN1000 SmartNICs
   * Added flow API transfer proxy support
 
+* **Added power monitor API in vhost library.**
+
+  Added an API to support power monitor in vhost library.
+
 * **Updated virtio PMD.**
 
   * Initial support for RSS receive mode has been added to the Virtio PMD,
 
        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`).
+        */
+       uint8_t size;
+       /**< If 1, and masked value that read from 'addr' equals
+        *   'val', the driver should skip core sleep. If 0, and
+        *  masked value that read from 'addr' does not equal 'val',
+        *  the driver should skip core sleep.
+        */
+       uint8_t match;
+};
+
 /**
  * Convert guest physical address to host virtual address
  *
  */
 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
  *
 
        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;
 };
 
        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);