/* Interrupts not supported by PF PMD */
return 1;
} else if (dlb->umwait_allowed) {
+ struct rte_power_monitor_cond pmc;
volatile struct dlb_dequeue_qe *cq_base;
union {
uint64_t raw_qe[2];
else
expected_value = 0;
- rte_power_monitor(monitor_addr, expected_value,
- qe_mask.raw_qe[1], timeout + start_ticks,
- sizeof(uint64_t));
+ pmc.addr = monitor_addr;
+ pmc.val = expected_value;
+ pmc.mask = qe_mask.raw_qe[1];
+ pmc.data_sz = sizeof(uint64_t);
+
+ rte_power_monitor(&pmc, timeout + start_ticks);
DLB_INC_STAT(ev_port->stats.traffic.rx_umonitor_umwait, 1);
} else {
if (elapsed_ticks >= timeout) {
return 1;
} else if (dlb2->umwait_allowed) {
+ struct rte_power_monitor_cond pmc;
volatile struct dlb2_dequeue_qe *cq_base;
union {
uint64_t raw_qe[2];
else
expected_value = 0;
- rte_power_monitor(monitor_addr, expected_value,
- qe_mask.raw_qe[1], timeout + start_ticks,
- sizeof(uint64_t));
+ pmc.addr = monitor_addr;
+ pmc.val = expected_value;
+ pmc.mask = qe_mask.raw_qe[1];
+ pmc.data_sz = sizeof(uint64_t);
+
+ rte_power_monitor(&pmc, timeout + start_ticks);
DLB2_INC_STAT(ev_port->stats.traffic.rx_umonitor_umwait, 1);
} else {
* This function is not supported on ARM.
*/
int
-rte_power_monitor(const volatile void *p, const uint64_t expected_value,
- const uint64_t value_mask, const uint64_t tsc_timestamp,
- const uint8_t data_sz)
+rte_power_monitor(const struct rte_power_monitor_cond *pmc,
+ const uint64_t tsc_timestamp)
{
- RTE_SET_USED(p);
- RTE_SET_USED(expected_value);
- RTE_SET_USED(value_mask);
+ RTE_SET_USED(pmc);
RTE_SET_USED(tsc_timestamp);
- RTE_SET_USED(data_sz);
return -ENOTSUP;
}
* This function is not supported on ARM.
*/
int
-rte_power_monitor_sync(const volatile void *p, const uint64_t expected_value,
- const uint64_t value_mask, const uint64_t tsc_timestamp,
- const uint8_t data_sz, rte_spinlock_t *lck)
+rte_power_monitor_sync(const struct rte_power_monitor_cond *pmc,
+ const uint64_t tsc_timestamp, rte_spinlock_t *lck)
{
- RTE_SET_USED(p);
- RTE_SET_USED(expected_value);
- RTE_SET_USED(value_mask);
+ RTE_SET_USED(pmc);
RTE_SET_USED(tsc_timestamp);
RTE_SET_USED(lck);
- RTE_SET_USED(data_sz);
return -ENOTSUP;
}
* which are architecture-dependent.
*/
+struct rte_power_monitor_cond {
+ volatile void *addr; /**< Address to monitor for changes */
+ uint64_t val; /**< Before attempting the monitoring, the address
+ * may be read and compared against this value.
+ **/
+ uint64_t mask; /**< 64-bit mask to extract current value from addr */
+ uint8_t data_sz; /**< Data size (in bytes) that will be used to compare
+ * expected value with the memory address. Can be 1,
+ * 2, 4, or 8. Supplying any other value will lead to
+ * undefined result. */
+};
+
/**
* @warning
* @b EXPERIMENTAL: this API may change without prior notice
* @warning It is responsibility of the user to check if this function is
* supported at runtime using `rte_cpu_get_intrinsics_support()` API call.
*
- * @param p
- * Address to monitor for changes.
- * @param expected_value
- * Before attempting the monitoring, the `p` address may be read and compared
- * against this value. If `value_mask` is zero, this step will be skipped.
- * @param value_mask
- * The 64-bit mask to use to extract current value from `p`.
+ * @param pmc
+ * The monitoring condition structure.
* @param tsc_timestamp
* Maximum TSC timestamp to wait for. Note that the wait behavior is
* architecture-dependent.
- * @param data_sz
- * Data size (in bytes) that will be used to compare expected value with the
- * memory address. Can be 1, 2, 4 or 8. Supplying any other value will lead
- * to undefined result.
*
* @return
* 0 on success
* -ENOTSUP if unsupported
*/
__rte_experimental
-int rte_power_monitor(const volatile void *p,
- const uint64_t expected_value, const uint64_t value_mask,
- const uint64_t tsc_timestamp, const uint8_t data_sz);
-
+int rte_power_monitor(const struct rte_power_monitor_cond *pmc,
+ const uint64_t tsc_timestamp);
/**
* @warning
* @b EXPERIMENTAL: this API may change without prior notice
* @warning It is responsibility of the user to check if this function is
* supported at runtime using `rte_cpu_get_intrinsics_support()` API call.
*
- * @param p
- * Address to monitor for changes.
- * @param expected_value
- * Before attempting the monitoring, the `p` address may be read and compared
- * against this value. If `value_mask` is zero, this step will be skipped.
- * @param value_mask
- * The 64-bit mask to use to extract current value from `p`.
+ * @param pmc
+ * The monitoring condition structure.
* @param tsc_timestamp
* Maximum TSC timestamp to wait for. Note that the wait behavior is
* architecture-dependent.
- * @param data_sz
- * Data size (in bytes) that will be used to compare expected value with the
- * memory address. Can be 1, 2, 4 or 8. Supplying any other value will lead
- * to undefined result.
* @param lck
* A spinlock that must be locked before entering the function, will be
* unlocked while the CPU is sleeping, and will be locked again once the CPU
* -ENOTSUP if unsupported
*/
__rte_experimental
-int rte_power_monitor_sync(const volatile void *p,
- const uint64_t expected_value, const uint64_t value_mask,
- const uint64_t tsc_timestamp, const uint8_t data_sz,
- rte_spinlock_t *lck);
+int rte_power_monitor_sync(const struct rte_power_monitor_cond *pmc,
+ const uint64_t tsc_timestamp, rte_spinlock_t *lck);
/**
* @warning
* This function is not supported on PPC64.
*/
int
-rte_power_monitor(const volatile void *p, const uint64_t expected_value,
- const uint64_t value_mask, const uint64_t tsc_timestamp,
- const uint8_t data_sz)
+rte_power_monitor(const struct rte_power_monitor_cond *pmc,
+ const uint64_t tsc_timestamp)
{
- RTE_SET_USED(p);
- RTE_SET_USED(expected_value);
- RTE_SET_USED(value_mask);
+ RTE_SET_USED(pmc);
RTE_SET_USED(tsc_timestamp);
- RTE_SET_USED(data_sz);
return -ENOTSUP;
}
* This function is not supported on PPC64.
*/
int
-rte_power_monitor_sync(const volatile void *p, const uint64_t expected_value,
- const uint64_t value_mask, const uint64_t tsc_timestamp,
- const uint8_t data_sz, rte_spinlock_t *lck)
+rte_power_monitor_sync(const struct rte_power_monitor_cond *pmc,
+ const uint64_t tsc_timestamp, rte_spinlock_t *lck)
{
- RTE_SET_USED(p);
- RTE_SET_USED(expected_value);
- RTE_SET_USED(value_mask);
+ RTE_SET_USED(pmc);
RTE_SET_USED(tsc_timestamp);
RTE_SET_USED(lck);
- RTE_SET_USED(data_sz);
return -ENOTSUP;
}
* Intel(R) 64 and IA-32 Architectures Software Developer's Manual.
*/
int
-rte_power_monitor(const volatile void *p, const uint64_t expected_value,
- const uint64_t value_mask, const uint64_t tsc_timestamp,
- const uint8_t data_sz)
+rte_power_monitor(const struct rte_power_monitor_cond *pmc,
+ const uint64_t tsc_timestamp)
{
const uint32_t tsc_l = (uint32_t)tsc_timestamp;
const uint32_t tsc_h = (uint32_t)(tsc_timestamp >> 32);
if (!wait_supported)
return -ENOTSUP;
- if (__check_val_size(data_sz) < 0)
+ if (pmc == NULL)
+ return -EINVAL;
+
+ if (__check_val_size(pmc->data_sz) < 0)
return -EINVAL;
/*
/* set address for UMONITOR */
asm volatile(".byte 0xf3, 0x0f, 0xae, 0xf7;"
:
- : "D"(p));
+ : "D"(pmc->addr));
- if (value_mask) {
- const uint64_t cur_value = __get_umwait_val(p, data_sz);
- const uint64_t masked = cur_value & value_mask;
+ if (pmc->mask) {
+ const uint64_t cur_value = __get_umwait_val(
+ pmc->addr, pmc->data_sz);
+ const uint64_t masked = cur_value & pmc->mask;
/* if the masked value is already matching, abort */
- if (masked == expected_value)
+ if (masked == pmc->val)
return 0;
}
/* execute UMWAIT */
* Intel(R) 64 and IA-32 Architectures Software Developer's Manual.
*/
int
-rte_power_monitor_sync(const volatile void *p, const uint64_t expected_value,
- const uint64_t value_mask, const uint64_t tsc_timestamp,
- const uint8_t data_sz, rte_spinlock_t *lck)
+rte_power_monitor_sync(const struct rte_power_monitor_cond *pmc,
+ const uint64_t tsc_timestamp, rte_spinlock_t *lck)
{
const uint32_t tsc_l = (uint32_t)tsc_timestamp;
const uint32_t tsc_h = (uint32_t)(tsc_timestamp >> 32);
if (!wait_supported)
return -ENOTSUP;
- if (__check_val_size(data_sz) < 0)
+ if (pmc == NULL || lck == NULL)
+ return -EINVAL;
+
+ if (__check_val_size(pmc->data_sz) < 0)
return -EINVAL;
/*
/* set address for UMONITOR */
asm volatile(".byte 0xf3, 0x0f, 0xae, 0xf7;"
:
- : "D"(p));
+ : "D"(pmc->addr));
- if (value_mask) {
- const uint64_t cur_value = __get_umwait_val(p, data_sz);
- const uint64_t masked = cur_value & value_mask;
+ if (pmc->mask) {
+ const uint64_t cur_value = __get_umwait_val(
+ pmc->addr, pmc->data_sz);
+ const uint64_t masked = cur_value & pmc->mask;
/* if the masked value is already matching, abort */
- if (masked == expected_value)
+ if (masked == pmc->val)
return 0;
}
rte_spinlock_unlock(lck);