From patchwork Wed Dec 14 08:14:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Feifei Wang X-Patchwork-Id: 120875 X-Patchwork-Delegate: thomas@monjalon.net 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 46056A0543; Wed, 14 Dec 2022 09:14:45 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2CD1140A89; Wed, 14 Dec 2022 09:14:43 +0100 (CET) Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mails.dpdk.org (Postfix) with ESMTP id C9BF840685 for ; Wed, 14 Dec 2022 09:14:41 +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 E02F0FEC; Wed, 14 Dec 2022 00:15:21 -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 B99493F73B; Wed, 14 Dec 2022 00:14:39 -0800 (PST) From: Feifei Wang To: Ruifeng Wang Cc: dev@dpdk.org, nd@arm.com, Feifei Wang Subject: [PATCH v5 1/2] eal: add 8 bits case for wait scheme Date: Wed, 14 Dec 2022 16:14:29 +0800 Message-Id: <20221214081430.1717903-2-feifei.wang2@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221214081430.1717903-1-feifei.wang2@arm.com> References: <20220825064251.2637274-1-feifei.wang2@arm.com> <20221214081430.1717903-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 wait scheme generic helper, add 8 bits case. Signed-off-by: Feifei Wang Reviewed-by: Ruifeng Wang --- lib/eal/arm/include/rte_pause_64.h | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/eal/arm/include/rte_pause_64.h b/lib/eal/arm/include/rte_pause_64.h index fe4d42b1ea..c21600ca96 100644 --- a/lib/eal/arm/include/rte_pause_64.h +++ b/lib/eal/arm/include/rte_pause_64.h @@ -31,6 +31,25 @@ static inline void rte_pause(void) /* Put processor into low power WFE(Wait For Event) state. */ #define __RTE_ARM_WFE() { asm volatile("wfe" : : : "memory"); } +/* + * Atomic exclusive load from addr, it returns the 8-bit content of + * *addr while making it 'monitored', when it is written by someone + * else, the 'monitored' state is cleared and an event is generated + * implicitly to exit WFE. + */ +#define __RTE_ARM_LOAD_EXC_8(src, dst, memorder) { \ + if (memorder == __ATOMIC_RELAXED) { \ + asm volatile("ldxrb %w[tmp], [%x[addr]]" \ + : [tmp] "=&r" (dst) \ + : [addr] "r" (src) \ + : "memory"); \ + } else { \ + asm volatile("ldaxrb %w[tmp], [%x[addr]]" \ + : [tmp] "=&r" (dst) \ + : [addr] "r" (src) \ + : "memory"); \ + } } + /* * Atomic exclusive load from addr, it returns the 16-bit content of * *addr while making it 'monitored', when it is written by someone @@ -111,9 +130,11 @@ static inline void rte_pause(void) } } \ #define __RTE_ARM_LOAD_EXC(src, dst, memorder, size) { \ - RTE_BUILD_BUG_ON(size != 16 && size != 32 && \ - size != 64 && size != 128); \ - if (size == 16) \ + RTE_BUILD_BUG_ON(size != 8 && size != 16 && \ + size != 32 && size != 64 && size != 128); \ + if (size == 8) \ + __RTE_ARM_LOAD_EXC_8(src, dst, memorder) \ + else if (size == 16) \ __RTE_ARM_LOAD_EXC_16(src, dst, memorder) \ else if (size == 32) \ __RTE_ARM_LOAD_EXC_32(src, dst, memorder) \ From patchwork Wed Dec 14 08:14:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Feifei Wang X-Patchwork-Id: 120876 X-Patchwork-Delegate: thomas@monjalon.net 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 65AD3A0543; Wed, 14 Dec 2022 09:14:50 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 22B3A42B71; Wed, 14 Dec 2022 09:14:46 +0100 (CET) Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mails.dpdk.org (Postfix) with ESMTP id 3A96941611 for ; Wed, 14 Dec 2022 09:14:44 +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 52D85FEC; Wed, 14 Dec 2022 00:15:24 -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 E177E3F73B; Wed, 14 Dec 2022 00:14:41 -0800 (PST) From: Feifei Wang To: Ruifeng Wang Cc: dev@dpdk.org, nd@arm.com, Feifei Wang , David Hunt Subject: [PATCH v5 2/2] eal: add power mgmt support on Arm Date: Wed, 14 Dec 2022 16:14:30 +0800 Message-Id: <20221214081430.1717903-3-feifei.wang2@arm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221214081430.1717903-1-feifei.wang2@arm.com> References: <20220825064251.2637274-1-feifei.wang2@arm.com> <20221214081430.1717903-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 aarch, 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 --- lib/eal/arm/include/rte_pause_64.h | 5 ++- lib/eal/arm/rte_cpuflags.c | 5 +++ lib/eal/arm/rte_power_intrinsics.c | 72 ++++++++++++++++++++++++++++-- 3 files changed, 78 insertions(+), 4 deletions(-) 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..d7d8d7af2f 100644 --- a/lib/eal/arm/rte_power_intrinsics.c +++ b/lib/eal/arm/rte_power_intrinsics.c @@ -6,17 +6,75 @@ #include "rte_power_intrinsics.h" +#ifdef RTE_ARM_USE_WFE +static inline int +__check_val_size(const uint8_t sz) +{ + switch (sz) { + case sizeof(uint8_t): /* fall-through */ + case sizeof(uint16_t): /* fall-through */ + case sizeof(uint32_t): /* fall-through */ + case sizeof(uint64_t): /* fall-through */ + return 0; + default: + /* unexpected size */ + return -1; + } +} +#endif + /** - * 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 (__check_val_size(pmc->size) < 0) + 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() + } + + return 0; +#else + RTE_SET_USED(pmc); + return -ENOTSUP; +#endif } /** @@ -31,14 +89,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