dpdk/lib/eal/include/generic/rte_power_intrinsics.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2020 Intel Corporation
   3 */
   4
   5#ifndef _RTE_POWER_INTRINSIC_H_
   6#define _RTE_POWER_INTRINSIC_H_
   7
   8#include <inttypes.h>
   9
  10#include <rte_compat.h>
  11#include <rte_spinlock.h>
  12
  13/**
  14 * @file
  15 * Advanced power management operations.
  16 *
  17 * This file define APIs for advanced power management,
  18 * which are architecture-dependent.
  19 */
  20
  21/** Size of the opaque data in monitor condition */
  22#define RTE_POWER_MONITOR_OPAQUE_SZ 4
  23
  24/**
  25 * Callback definition for monitoring conditions. Callbacks with this signature
  26 * will be used by `rte_power_monitor()` to check if the entering of power
  27 * optimized state should be aborted.
  28 *
  29 * @param val
  30 *   The value read from memory.
  31 * @param opaque
  32 *   Callback-specific data.
  33 *
  34 * @return
  35 *   0 if entering of power optimized state should proceed
  36 *   -1 if entering of power optimized state should be aborted
  37 */
  38typedef int (*rte_power_monitor_clb_t)(const uint64_t val,
  39                const uint64_t opaque[RTE_POWER_MONITOR_OPAQUE_SZ]);
  40
  41struct rte_power_monitor_cond {
  42        volatile void *addr;  /**< Address to monitor for changes */
  43        uint8_t size;    /**< Data size (in bytes) that will be read from the
  44                          *   monitored memory location (`addr`). Can be 1, 2,
  45                          *   4, or 8. Supplying any other value will result in
  46                          *   an error.
  47                          */
  48        rte_power_monitor_clb_t fn; /**< Callback to be used to check if
  49                                     *   entering power optimized state should
  50                                     *   be aborted.
  51                                     */
  52        uint64_t opaque[RTE_POWER_MONITOR_OPAQUE_SZ];
  53        /**< Callback-specific data */
  54};
  55
  56/**
  57 * @warning
  58 * @b EXPERIMENTAL: this API may change without prior notice.
  59 *
  60 * Monitor specific address for changes. This will cause the CPU to enter an
  61 * architecture-defined optimized power state until either the specified
  62 * memory address is written to, a certain TSC timestamp is reached, or other
  63 * reasons cause the CPU to wake up.
  64 *
  65 * Additionally, an expected value (`pmc->val`), mask (`pmc->mask`), and data
  66 * size (`pmc->size`) are provided in the `pmc` power monitoring condition. If
  67 * the mask is non-zero, the current value pointed to by the `pmc->addr` pointer
  68 * will be read and compared against the expected value, and if they match, the
  69 * entering of optimized power state will be aborted. This is intended to
  70 * prevent the CPU from entering optimized power state and waiting on a write
  71 * that has already happened by the time this API is called.
  72 *
  73 * @warning It is responsibility of the user to check if this function is
  74 *   supported at runtime using `rte_cpu_get_intrinsics_support()` API call.
  75 *
  76 * @param pmc
  77 *   The monitoring condition structure.
  78 * @param tsc_timestamp
  79 *   Maximum TSC timestamp to wait for. Note that the wait behavior is
  80 *   architecture-dependent.
  81 *
  82 * @return
  83 *   0 on success
  84 *   -EINVAL on invalid parameters
  85 *   -ENOTSUP if unsupported
  86 */
  87__rte_experimental
  88int rte_power_monitor(const struct rte_power_monitor_cond *pmc,
  89                const uint64_t tsc_timestamp);
  90
  91/**
  92 * @warning
  93 * @b EXPERIMENTAL: this API may change without prior notice.
  94 *
  95 * Wake up a specific lcore that is in a power optimized state and is monitoring
  96 * an address.
  97 *
  98 * @note It is safe to call this function if the lcore in question is not
  99 *   sleeping. The function will have no effect.
 100 *
 101 * @note This function will *not* wake up a core that is in a power optimized
 102 *   state due to calling `rte_power_pause`.
 103 *
 104 * @param lcore_id
 105 *   Lcore ID of a sleeping thread.
 106 */
 107__rte_experimental
 108int rte_power_monitor_wakeup(const unsigned int lcore_id);
 109
 110/**
 111 * @warning
 112 * @b EXPERIMENTAL: this API may change without prior notice.
 113 *
 114 * Enter an architecture-defined optimized power state until a certain TSC
 115 * timestamp is reached.
 116 *
 117 * @warning It is responsibility of the user to check if this function is
 118 *   supported at runtime using `rte_cpu_get_intrinsics_support()` API call.
 119 *
 120 * @param tsc_timestamp
 121 *   Maximum TSC timestamp to wait for. Note that the wait behavior is
 122 *   architecture-dependent.
 123 *
 124 * @return
 125 *   0 on success
 126 *   -EINVAL on invalid parameters
 127 *   -ENOTSUP if unsupported
 128 */
 129__rte_experimental
 130int rte_power_pause(const uint64_t tsc_timestamp);
 131
 132/**
 133 * @warning
 134 * @b EXPERIMENTAL: this API may change without prior notice
 135 *
 136 * Monitor a set of addresses for changes. This will cause the CPU to enter an
 137 * architecture-defined optimized power state until either one of the specified
 138 * memory addresses is written to, a certain TSC timestamp is reached, or other
 139 * reasons cause the CPU to wake up.
 140 *
 141 * Additionally, `expected` 64-bit values and 64-bit masks are provided. If
 142 * mask is non-zero, the current value pointed to by the `p` pointer will be
 143 * checked against the expected value, and if they do not match, the entering of
 144 * optimized power state may be aborted.
 145 *
 146 * @warning It is responsibility of the user to check if this function is
 147 *   supported at runtime using `rte_cpu_get_intrinsics_support()` API call.
 148 *   Failing to do so may result in an illegal CPU instruction error.
 149 *
 150 * @param pmc
 151 *   An array of monitoring condition structures.
 152 * @param num
 153 *   Length of the `pmc` array.
 154 * @param tsc_timestamp
 155 *   Maximum TSC timestamp to wait for. Note that the wait behavior is
 156 *   architecture-dependent.
 157 *
 158 * @return
 159 *   0 on success
 160 *   -EINVAL on invalid parameters
 161 *   -ENOTSUP if unsupported
 162 */
 163__rte_experimental
 164int rte_power_monitor_multi(const struct rte_power_monitor_cond pmc[],
 165                const uint32_t num, const uint64_t tsc_timestamp);
 166
 167#endif /* _RTE_POWER_INTRINSIC_H_ */
 168