From patchwork Mon Feb 20 08:51:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Feifei Wang X-Patchwork-Id: 124180 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 114E641CE4; Mon, 20 Feb 2023 09:51:34 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id F2A564300E; Mon, 20 Feb 2023 09:51:26 +0100 (CET) Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mails.dpdk.org (Postfix) with ESMTP id 6543543008 for ; Mon, 20 Feb 2023 09:51:25 +0100 (CET) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9D686C14; Mon, 20 Feb 2023 00:52:07 -0800 (PST) Received: from net-x86-dell-8268.shanghai.arm.com (net-x86-dell-8268.shanghai.arm.com [10.169.210.116]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 5090A3F703; Mon, 20 Feb 2023 00:51:22 -0800 (PST) From: Feifei Wang To: Ruifeng Wang Cc: dev@dpdk.org, david.hunt@intel.com, stephen@networkplumber.org, thomas@monjalon.net, nd@arm.com, Feifei Wang Subject: [PATCH v6 2/2] eal: add power mgmt support on Arm Date: Mon, 20 Feb 2023 16:51:09 +0800 Message-Id: <20230220085109.3463640-3-feifei.wang2@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230220085109.3463640-1-feifei.wang2@arm.com> References: <20220825064251.2637274-1-feifei.wang2@arm.com> <20230220085109.3463640-1-feifei.wang2@arm.com> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org For Arm arch, use WFE instruction to enable power monitor API, and use SEV instruction to enable wake up API. Signed-off-by: Feifei Wang Reviewed-by: Ruifeng Wang Acked-by: David Hunt --- doc/guides/rel_notes/release_23_03.rst | 4 ++ lib/eal/arm/include/rte_pause_64.h | 5 ++- lib/eal/arm/rte_cpuflags.c | 5 +++ lib/eal/arm/rte_power_intrinsics.c | 55 ++++++++++++++++++++++++-- 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst index 7da3d19278..4a5995f2c8 100644 --- a/doc/guides/rel_notes/release_23_03.rst +++ b/doc/guides/rel_notes/release_23_03.rst @@ -192,6 +192,10 @@ New Features * Added support to capture packets at each graph node with packet metadata and node name. +* **Added ARM support for power monitor in the power management library.** + * Added power monitor and wake up API support with WFE/SVE + instructions for Arm architecture. + Removed Items ------------- diff --git a/lib/eal/arm/include/rte_pause_64.h b/lib/eal/arm/include/rte_pause_64.h index c21600ca96..5f70e97481 100644 --- a/lib/eal/arm/include/rte_pause_64.h +++ b/lib/eal/arm/include/rte_pause_64.h @@ -25,9 +25,12 @@ static inline void rte_pause(void) #ifdef RTE_WAIT_UNTIL_EQUAL_ARCH_DEFINED -/* Send an event to quit WFE. */ +/* Send a local event to quit WFE. */ #define __RTE_ARM_SEVL() { asm volatile("sevl" : : : "memory"); } +/* Send a global event to quit WFE for all cores. */ +#define __RTE_ARM_SEV() { asm volatile("sev" : : : "memory"); } + /* Put processor into low power WFE(Wait For Event) state. */ #define __RTE_ARM_WFE() { asm volatile("wfe" : : : "memory"); } diff --git a/lib/eal/arm/rte_cpuflags.c b/lib/eal/arm/rte_cpuflags.c index 93461191c7..90b80709fd 100644 --- a/lib/eal/arm/rte_cpuflags.c +++ b/lib/eal/arm/rte_cpuflags.c @@ -163,4 +163,9 @@ void rte_cpu_get_intrinsics_support(struct rte_cpu_intrinsics *intrinsics) { memset(intrinsics, 0, sizeof(*intrinsics)); + +#ifdef RTE_ARM_USE_WFE + intrinsics->power_monitor = 1; +#endif + } diff --git a/lib/eal/arm/rte_power_intrinsics.c b/lib/eal/arm/rte_power_intrinsics.c index 13f6a3264d..b518401225 100644 --- a/lib/eal/arm/rte_power_intrinsics.c +++ b/lib/eal/arm/rte_power_intrinsics.c @@ -7,16 +7,57 @@ #include "rte_power_intrinsics.h" /** - * This function is not supported on ARM. + * This function uses WFE instruction to make lcore suspend + * execution on ARM. + * Note that timestamp based timeout is not supported yet. */ int rte_power_monitor(const struct rte_power_monitor_cond *pmc, const uint64_t tsc_timestamp) { - RTE_SET_USED(pmc); RTE_SET_USED(tsc_timestamp); +#ifdef RTE_ARM_USE_WFE + const unsigned int lcore_id = rte_lcore_id(); + uint64_t cur_value; + + /* prevent non-EAL thread from using this API */ + if (lcore_id >= RTE_MAX_LCORE) + return -EINVAL; + + if (pmc == NULL) + return -EINVAL; + + if (pmc->fn == NULL) + return -EINVAL; + + switch (pmc->size) { + case sizeof(uint8_t): + __RTE_ARM_LOAD_EXC_8(pmc->addr, cur_value, __ATOMIC_RELAXED); + __RTE_ARM_WFE() + break; + case sizeof(uint16_t): + __RTE_ARM_LOAD_EXC_16(pmc->addr, cur_value, __ATOMIC_RELAXED); + __RTE_ARM_WFE() + break; + case sizeof(uint32_t): + __RTE_ARM_LOAD_EXC_32(pmc->addr, cur_value, __ATOMIC_RELAXED); + __RTE_ARM_WFE() + break; + case sizeof(uint64_t): + __RTE_ARM_LOAD_EXC_64(pmc->addr, cur_value, __ATOMIC_RELAXED); + __RTE_ARM_WFE() + break; + default: + return -EINVAL; /* unexpected size */ + } + + return 0; +#else + RTE_SET_USED(pmc); + return -ENOTSUP; +#endif } /** @@ -31,14 +72,22 @@ rte_power_pause(const uint64_t tsc_timestamp) } /** - * This function is not supported on ARM. + * This function uses SEV instruction to wake up all cores + * on ARM. + * Note that lcore_id is not used here. */ int rte_power_monitor_wakeup(const unsigned int lcore_id) { RTE_SET_USED(lcore_id); +#ifdef RTE_ARM_USE_WFE + __RTE_ARM_SEV() + + return 0; +#else return -ENOTSUP; +#endif } int