]> git.droids-corp.org - dpdk.git/commitdiff
vhost: add power monitor API
authorMiao Li <miao.li@intel.com>
Mon, 25 Oct 2021 14:47:22 +0000 (14:47 +0000)
committerMaxime Coquelin <maxime.coquelin@redhat.com>
Fri, 29 Oct 2021 10:32:29 +0000 (12:32 +0200)
This commit 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>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
Acked-by: David Hunt <david.hunt@intel.com>
doc/guides/rel_notes/release_21_11.rst
lib/vhost/rte_vhost.h
lib/vhost/version.map
lib/vhost/vhost.c

index 3682d54a546f9c5a337ba9446086964848ccba27..2e4fd9ac8fb14820c2c0dec81c764b5749347426 100644 (file)
@@ -199,6 +199,10 @@ New Features
   * 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,
index fd372d52594bb99e5cd04f332165a79e345e6b65..6f0915b98fca2619b92ac06367b2310a40d993ee 100644 (file)
@@ -292,6 +292,31 @@ 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`).
+        */
+       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
  *
@@ -903,6 +928,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
  *
index 8ebde3f69420185baa564178851b592794190b29..c8599ddb97ccfb8c8eeb2833f924999da72b139e 100644 (file)
@@ -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;
 };
index 3b674ac3209096c0dc9869a13c4ac396a2d44406..150b97a2dfae28f135c580af13b2c4737b25ca6c 100644 (file)
@@ -1892,5 +1892,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);