All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 0/3] Enable PMD power management on Arm
@ 2022-08-25  6:42 Feifei Wang
  2022-08-25  6:42 ` [PATCH v1 1/3] eal: add 8 bits case for wait scheme Feifei Wang
                   ` (7 more replies)
  0 siblings, 8 replies; 39+ messages in thread
From: Feifei Wang @ 2022-08-25  6:42 UTC (permalink / raw)
  Cc: dev, nd, Feifei Wang

For Arm aarch, use WFE instructions to enable PMD power management.

Feifei Wang (3):
  eal: add 8 bits case for wait scheme
  eal: add power mgmt support on Arm
  examples/l3fwd-power: enable PMD power monitor on Arm

 examples/l3fwd-power/main.c        | 30 ++++++++++++-
 lib/eal/arm/include/rte_pause_64.h | 32 +++++++++++--
 lib/eal/arm/rte_cpuflags.c         |  5 +++
 lib/eal/arm/rte_power_intrinsics.c | 72 ++++++++++++++++++++++++++++--
 4 files changed, 131 insertions(+), 8 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v1 1/3] eal: add 8 bits case for wait scheme
  2022-08-25  6:42 [PATCH v1 0/3] Enable PMD power management on Arm Feifei Wang
@ 2022-08-25  6:42 ` Feifei Wang
  2022-08-25  6:42 ` [PATCH v1 2/3] eal: add power mgmt support on Arm Feifei Wang
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2022-08-25  6:42 UTC (permalink / raw)
  To: Ruifeng Wang; +Cc: dev, nd, Feifei Wang

For wait scheme generic helper, add 8 bits case.

Signed-off-by: Feifei Wang <feifei.wang2@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
---
 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)  \
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v1 2/3] eal: add power mgmt support on Arm
  2022-08-25  6:42 [PATCH v1 0/3] Enable PMD power management on Arm Feifei Wang
  2022-08-25  6:42 ` [PATCH v1 1/3] eal: add 8 bits case for wait scheme Feifei Wang
@ 2022-08-25  6:42 ` Feifei Wang
  2022-08-25  6:42 ` [PATCH v1 3/3] examples/l3fwd-power: enable PMD power mgmt " Feifei Wang
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2022-08-25  6:42 UTC (permalink / raw)
  To: Ruifeng Wang, Jan Viktorin; +Cc: dev, nd, Feifei Wang

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 <feifei.wang2@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
---
 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 78f55b7203..2a94dd7cd9 100644
--- a/lib/eal/arm/rte_power_intrinsics.c
+++ b/lib/eal/arm/rte_power_intrinsics.c
@@ -4,17 +4,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
 }
 
 /**
@@ -29,14 +87,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
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v1 3/3] examples/l3fwd-power: enable PMD power mgmt on Arm
  2022-08-25  6:42 [PATCH v1 0/3] Enable PMD power management on Arm Feifei Wang
  2022-08-25  6:42 ` [PATCH v1 1/3] eal: add 8 bits case for wait scheme Feifei Wang
  2022-08-25  6:42 ` [PATCH v1 2/3] eal: add power mgmt support on Arm Feifei Wang
@ 2022-08-25  6:42 ` Feifei Wang
  2022-08-29 12:48   ` Hunt, David
  2022-10-20 22:09   ` Stephen Hemminger
  2022-11-07  7:04 ` [PATCH v2 0/3] Enable PMD power management " Feifei Wang
                   ` (4 subsequent siblings)
  7 siblings, 2 replies; 39+ messages in thread
From: Feifei Wang @ 2022-08-25  6:42 UTC (permalink / raw)
  To: David Hunt; +Cc: dev, nd, Feifei Wang, Ruifeng Wang

For Arm aarch, power monitor uses WFE instruction to enable, which can
not exit automatically within the time limit. This means
'rte_power_monitor_wakeup' API needs to be called to wake up sleep cores
if there is no store operation to monitored address.

Furthermore, we disable power monitor feature on the main core so that it
can be used to wake up other sleeping cores when it receives SIGINT
siginal.

Signed-off-by: Feifei Wang <feifei.wang2@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
---
 examples/l3fwd-power/main.c | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 887c6eae3f..2bd0d700f0 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -432,8 +432,16 @@ static void
 signal_exit_now(int sigtype)
 {
 
-	if (sigtype == SIGINT)
+	if (sigtype == SIGINT) {
+#if defined(RTE_ARCH_ARM64)
+	/**
+	 * wake_up api does not need input parameter on Arm,
+	 * so 0 is meaningless here.
+	 */
+		rte_power_monitor_wakeup(0);
+#endif
 		quit_signal = true;
+	}
 
 }
 
@@ -2885,6 +2893,25 @@ main(int argc, char **argv)
 						"Error setting scaling freq max: err=%d, lcore %d\n",
 							ret, lcore_id);
 
+#if defined(RTE_ARCH_ARM64)
+				/* Ensure the main lcore does not enter the power-monitor state,
+				 * so that it can be used to wake up other lcores on ARM.
+				 * This is due to WFE instruction has no timeout wake-up mechanism,
+				 * and if users want to exit actively, the main lcore is needed
+				 * to send SEV instruction to wake up other lcores.
+				 */
+				unsigned int main_lcore = rte_get_main_lcore();
+				if (lcore_id != main_lcore ||
+						pmgmt_type != RTE_POWER_MGMT_TYPE_MONITOR) {
+					ret = rte_power_ethdev_pmgmt_queue_enable(
+							lcore_id, portid, queueid,
+							pmgmt_type);
+					if (ret < 0)
+						rte_exit(EXIT_FAILURE,
+							"rte_power_ethdev_pmgmt_queue_enable: err=%d, port=%d\n",
+							ret, portid);
+				}
+#else
 				ret = rte_power_ethdev_pmgmt_queue_enable(
 						lcore_id, portid, queueid,
 						pmgmt_type);
@@ -2892,6 +2919,7 @@ main(int argc, char **argv)
 					rte_exit(EXIT_FAILURE,
 						"rte_power_ethdev_pmgmt_queue_enable: err=%d, port=%d\n",
 							ret, portid);
+#endif
 			}
 		}
 	}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH v1 3/3] examples/l3fwd-power: enable PMD power mgmt on Arm
  2022-08-25  6:42 ` [PATCH v1 3/3] examples/l3fwd-power: enable PMD power mgmt " Feifei Wang
@ 2022-08-29 12:48   ` Hunt, David
  2022-10-03  7:12     ` David Marchand
  2022-10-20 22:09   ` Stephen Hemminger
  1 sibling, 1 reply; 39+ messages in thread
From: Hunt, David @ 2022-08-29 12:48 UTC (permalink / raw)
  To: Feifei Wang; +Cc: dev, nd, Ruifeng Wang


On 25/08/2022 07:42, Feifei Wang wrote:
> For Arm aarch, power monitor uses WFE instruction to enable, which can
> not exit automatically within the time limit. This means
> 'rte_power_monitor_wakeup' API needs to be called to wake up sleep cores
> if there is no store operation to monitored address.
>
> Furthermore, we disable power monitor feature on the main core so that it
> can be used to wake up other sleeping cores when it receives SIGINT
> siginal.
>
> Signed-off-by: Feifei Wang <feifei.wang2@arm.com>
> Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> ---
>   examples/l3fwd-power/main.c | 30 +++++++++++++++++++++++++++++-
>   1 file changed, 29 insertions(+), 1 deletion(-)
>
> diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
> index 887c6eae3f..2bd0d700f0 100644
> --- a/examples/l3fwd-power/main.c
> +++ b/examples/l3fwd-power/main.c
> @@ -432,8 +432,16 @@ static void
>   signal_exit_now(int sigtype)
>   {
>   
> -	if (sigtype == SIGINT)
> +	if (sigtype == SIGINT) {
> +#if defined(RTE_ARCH_ARM64)
> +	/**
> +	 * wake_up api does not need input parameter on Arm,
> +	 * so 0 is meaningless here.
> +	 */
> +		rte_power_monitor_wakeup(0);
> +#endif
>   		quit_signal = true;
> +	}
>   
>   }
>   
> @@ -2885,6 +2893,25 @@ main(int argc, char **argv)
>   						"Error setting scaling freq max: err=%d, lcore %d\n",
>   							ret, lcore_id);
>   
> +#if defined(RTE_ARCH_ARM64)
> +				/* Ensure the main lcore does not enter the power-monitor state,
> +				 * so that it can be used to wake up other lcores on ARM.
> +				 * This is due to WFE instruction has no timeout wake-up mechanism,
> +				 * and if users want to exit actively, the main lcore is needed
> +				 * to send SEV instruction to wake up other lcores.
> +				 */
> +				unsigned int main_lcore = rte_get_main_lcore();
> +				if (lcore_id != main_lcore ||
> +						pmgmt_type != RTE_POWER_MGMT_TYPE_MONITOR) {
> +					ret = rte_power_ethdev_pmgmt_queue_enable(
> +							lcore_id, portid, queueid,
> +							pmgmt_type);
> +					if (ret < 0)
> +						rte_exit(EXIT_FAILURE,
> +							"rte_power_ethdev_pmgmt_queue_enable: err=%d, port=%d\n",
> +							ret, portid);
> +				}
> +#else
>   				ret = rte_power_ethdev_pmgmt_queue_enable(
>   						lcore_id, portid, queueid,
>   						pmgmt_type);
> @@ -2892,6 +2919,7 @@ main(int argc, char **argv)
>   					rte_exit(EXIT_FAILURE,
>   						"rte_power_ethdev_pmgmt_queue_enable: err=%d, port=%d\n",
>   							ret, portid);
> +#endif
>   			}
>   		}
>   	}


Hi Feifei,

Acked-by: David Hunt <david.hunt@intel.com>



^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v1 3/3] examples/l3fwd-power: enable PMD power mgmt on Arm
  2022-08-29 12:48   ` Hunt, David
@ 2022-10-03  7:12     ` David Marchand
  2022-10-11  7:56       ` 回复: " Feifei Wang
  0 siblings, 1 reply; 39+ messages in thread
From: David Marchand @ 2022-10-03  7:12 UTC (permalink / raw)
  To: Hunt, David, Feifei Wang, Ruifeng Wang; +Cc: dev, nd, Thomas Monjalon

On Mon, Aug 29, 2022 at 2:48 PM Hunt, David <david.hunt@intel.com> wrote:
> On 25/08/2022 07:42, Feifei Wang wrote:
> > For Arm aarch, power monitor uses WFE instruction to enable, which can
> > not exit automatically within the time limit. This means
> > 'rte_power_monitor_wakeup' API needs to be called to wake up sleep cores
> > if there is no store operation to monitored address.
> >
> > Furthermore, we disable power monitor feature on the main core so that it
> > can be used to wake up other sleeping cores when it receives SIGINT
> > siginal.
> >
> > Signed-off-by: Feifei Wang <feifei.wang2@arm.com>
> > Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > ---
> >   examples/l3fwd-power/main.c | 30 +++++++++++++++++++++++++++++-
> >   1 file changed, 29 insertions(+), 1 deletion(-)
> >
> > diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
> > index 887c6eae3f..2bd0d700f0 100644
> > --- a/examples/l3fwd-power/main.c
> > +++ b/examples/l3fwd-power/main.c
> > @@ -432,8 +432,16 @@ static void
> >   signal_exit_now(int sigtype)
> >   {
> >
> > -     if (sigtype == SIGINT)
> > +     if (sigtype == SIGINT) {
> > +#if defined(RTE_ARCH_ARM64)

Having a arch specific behavior in the application shows that there is
something wrong either in the API, or in the Arm implementation of the
API.
I don't think this is a good solution.

Can't we find a better alternative? By changing the API probably?


> > +     /**
> > +      * wake_up api does not need input parameter on Arm,
> > +      * so 0 is meaningless here.
> > +      */
> > +             rte_power_monitor_wakeup(0);
> > +#endif
> >               quit_signal = true;
> > +     }
> >
> >   }
> >
> > @@ -2885,6 +2893,25 @@ main(int argc, char **argv)
> >                                               "Error setting scaling freq max: err=%d, lcore %d\n",
> >                                                       ret, lcore_id);
> >
> > +#if defined(RTE_ARCH_ARM64)
> > +                             /* Ensure the main lcore does not enter the power-monitor state,
> > +                              * so that it can be used to wake up other lcores on ARM.
> > +                              * This is due to WFE instruction has no timeout wake-up mechanism,
> > +                              * and if users want to exit actively, the main lcore is needed
> > +                              * to send SEV instruction to wake up other lcores.
> > +                              */
> > +                             unsigned int main_lcore = rte_get_main_lcore();
> > +                             if (lcore_id != main_lcore ||
> > +                                             pmgmt_type != RTE_POWER_MGMT_TYPE_MONITOR) {
> > +                                     ret = rte_power_ethdev_pmgmt_queue_enable(
> > +                                                     lcore_id, portid, queueid,
> > +                                                     pmgmt_type);
> > +                                     if (ret < 0)
> > +                                             rte_exit(EXIT_FAILURE,
> > +                                                     "rte_power_ethdev_pmgmt_queue_enable: err=%d, port=%d\n",
> > +                                                     ret, portid);
> > +                             }
> > +#else
> >                               ret = rte_power_ethdev_pmgmt_queue_enable(
> >                                               lcore_id, portid, queueid,
> >                                               pmgmt_type);
> > @@ -2892,6 +2919,7 @@ main(int argc, char **argv)
> >                                       rte_exit(EXIT_FAILURE,
> >                                               "rte_power_ethdev_pmgmt_queue_enable: err=%d, port=%d\n",
> >                                                       ret, portid);
> > +#endif
> >                       }
> >               }
> >       }
>
>
> Hi Feifei,
>
> Acked-by: David Hunt <david.hunt@intel.com>


-- 
David Marchand


^ permalink raw reply	[flat|nested] 39+ messages in thread

* 回复: [PATCH v1 3/3] examples/l3fwd-power: enable PMD power mgmt on Arm
  2022-10-03  7:12     ` David Marchand
@ 2022-10-11  7:56       ` Feifei Wang
  2022-10-20 20:41         ` Thomas Monjalon
  0 siblings, 1 reply; 39+ messages in thread
From: Feifei Wang @ 2022-10-11  7:56 UTC (permalink / raw)
  To: David Marchand, Hunt, David, Ruifeng Wang; +Cc: dev, nd, thomas, nd



> -----邮件原件-----
> 发件人: David Marchand <david.marchand@redhat.com>
> 发送时间: Monday, October 3, 2022 3:12 PM
> 收件人: Hunt, David <david.hunt@intel.com>; Feifei Wang
> <Feifei.Wang2@arm.com>; Ruifeng Wang <Ruifeng.Wang@arm.com>
> 抄送: dev@dpdk.org; nd <nd@arm.com>; thomas@monjalon.net
> 主题: Re: [PATCH v1 3/3] examples/l3fwd-power: enable PMD power mgmt
> on Arm
> 
> On Mon, Aug 29, 2022 at 2:48 PM Hunt, David <david.hunt@intel.com> wrote:
> > On 25/08/2022 07:42, Feifei Wang wrote:
> > > For Arm aarch, power monitor uses WFE instruction to enable, which
> > > can not exit automatically within the time limit. This means
> > > 'rte_power_monitor_wakeup' API needs to be called to wake up sleep
> > > cores if there is no store operation to monitored address.
> > >
> > > Furthermore, we disable power monitor feature on the main core so
> > > that it can be used to wake up other sleeping cores when it receives
> > > SIGINT siginal.
> > >
> > > Signed-off-by: Feifei Wang <feifei.wang2@arm.com>
> > > Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > > ---
> > >   examples/l3fwd-power/main.c | 30
> +++++++++++++++++++++++++++++-
> > >   1 file changed, 29 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/examples/l3fwd-power/main.c
> > > b/examples/l3fwd-power/main.c index 887c6eae3f..2bd0d700f0 100644
> > > --- a/examples/l3fwd-power/main.c
> > > +++ b/examples/l3fwd-power/main.c
> > > @@ -432,8 +432,16 @@ static void
> > >   signal_exit_now(int sigtype)
> > >   {
> > >
> > > -     if (sigtype == SIGINT)
> > > +     if (sigtype == SIGINT) {
> > > +#if defined(RTE_ARCH_ARM64)
> 
> Having a arch specific behavior in the application shows that there is
> something wrong either in the API, or in the Arm implementation of the API.
> I don't think this is a good solution.
> 
> Can't we find a better alternative? By changing the API probably?
Sorry I do not understand ' shows that there is something wrong either in the API'

Here we call ' rte_power_monitor_wakeup' API is due to that we need to wake
up all cores from WFE instructions in arm, and then l3fwd can exit correctly.

This is due to that arm arch is different from x86, if there is no packets received, x86's
'UMONITOR' can automatically exit from energy-saving state after waiting for a period of time.
But arm's 'WFE' can not exit automatically. It will wait 'SEV' instructions in wake_up API to wake
up it.

Finally, if user want to exit l3fwd by  'SIGINT' in arm, main core should firstly call 'wake_up' API
to force worker cores to exit from energy-saving state. 
Otherwise, the worker will stay in the energy-saving state forever if no packet is received.
> 
> 
> > > +     /**
> > > +      * wake_up api does not need input parameter on Arm,
> > > +      * so 0 is meaningless here.
> > > +      */
> > > +             rte_power_monitor_wakeup(0); #endif
> > >               quit_signal = true;
> > > +     }
> > >
> > >   }
> > >
> > > @@ -2885,6 +2893,25 @@ main(int argc, char **argv)
> > >                                               "Error setting scaling freq max: err=%d,
> lcore %d\n",
> > >                                                       ret,
> > > lcore_id);
> > >
> > > +#if defined(RTE_ARCH_ARM64)
> > > +                             /* Ensure the main lcore does not enter the power-
> monitor state,
> > > +                              * so that it can be used to wake up other lcores on ARM.
> > > +                              * This is due to WFE instruction has no timeout wake-up
> mechanism,
> > > +                              * and if users want to exit actively, the main lcore is
> needed
> > > +                              * to send SEV instruction to wake up other lcores.
> > > +                              */
> > > +                             unsigned int main_lcore = rte_get_main_lcore();
> > > +                             if (lcore_id != main_lcore ||
> > > +                                             pmgmt_type !=
> RTE_POWER_MGMT_TYPE_MONITOR) {
> > > +                                     ret = rte_power_ethdev_pmgmt_queue_enable(
> > > +                                                     lcore_id, portid, queueid,
> > > +                                                     pmgmt_type);
> > > +                                     if (ret < 0)
> > > +                                             rte_exit(EXIT_FAILURE,
> > > +                                                     "rte_power_ethdev_pmgmt_queue_enable:
> err=%d, port=%d\n",
> > > +                                                     ret, portid);
> > > +                             }
> > > +#else
> > >                               ret = rte_power_ethdev_pmgmt_queue_enable(
> > >                                               lcore_id, portid, queueid,
> > >                                               pmgmt_type); @@
> > > -2892,6 +2919,7 @@ main(int argc, char **argv)
> > >                                       rte_exit(EXIT_FAILURE,
> > >                                               "rte_power_ethdev_pmgmt_queue_enable:
> err=%d, port=%d\n",
> > >                                                       ret, portid);
> > > +#endif
> > >                       }
> > >               }
> > >       }
> >
> >
> > Hi Feifei,
> >
> > Acked-by: David Hunt <david.hunt@intel.com>
> 
> 
> --
> David Marchand


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: 回复: [PATCH v1 3/3] examples/l3fwd-power: enable PMD power mgmt on Arm
  2022-10-11  7:56       ` 回复: " Feifei Wang
@ 2022-10-20 20:41         ` Thomas Monjalon
  2022-10-27  9:38           ` 回复: " Feifei Wang
  0 siblings, 1 reply; 39+ messages in thread
From: Thomas Monjalon @ 2022-10-20 20:41 UTC (permalink / raw)
  To: David Marchand; +Cc: Hunt, David, Ruifeng Wang, dev, nd, Feifei Wang

11/10/2022 09:56, Feifei Wang:
> David Marchand <david.marchand@redhat.com>
> > > On 25/08/2022 07:42, Feifei Wang wrote:
> > > > --- a/examples/l3fwd-power/main.c
> > > > +++ b/examples/l3fwd-power/main.c
> > > > @@ -432,8 +432,16 @@ static void
> > > >   signal_exit_now(int sigtype)
> > > >   {
> > > >
> > > > -     if (sigtype == SIGINT)
> > > > +     if (sigtype == SIGINT) {
> > > > +#if defined(RTE_ARCH_ARM64)
> > 
> > Having a arch specific behavior in the application shows that there is
> > something wrong either in the API, or in the Arm implementation of the API.
> > I don't think this is a good solution.
> > 
> > Can't we find a better alternative? By changing the API probably?
> Sorry I do not understand ' shows that there is something wrong either in the API'

David means the application developer should not have to be aware
of the arch differences.
When you use an API, you don't check how it is implemented,
and you are not supposed to use #ifdef.
The API must be arch-agnostic.

> Here we call ' rte_power_monitor_wakeup' API is due to that we need to wake
> up all cores from WFE instructions in arm, and then l3fwd can exit correctly.
> 
> This is due to that arm arch is different from x86, if there is no packets received, x86's
> 'UMONITOR' can automatically exit from energy-saving state after waiting for a period of time.
> But arm's 'WFE' can not exit automatically. It will wait 'SEV' instructions in wake_up API to wake
> up it.
> 
> Finally, if user want to exit l3fwd by  'SIGINT' in arm, main core should firstly call 'wake_up' API
> to force worker cores to exit from energy-saving state. 
> Otherwise, the worker will stay in the energy-saving state forever if no packet is received.

Please find a way to have a common API,
even if the API implementation is empty in x86 case.

> > 
> > 
> > > > +     /**
> > > > +      * wake_up api does not need input parameter on Arm,
> > > > +      * so 0 is meaningless here.
> > > > +      */
> > > > +             rte_power_monitor_wakeup(0); #endif
> > > >               quit_signal = true;
> > > > +     }




^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v1 3/3] examples/l3fwd-power: enable PMD power mgmt on Arm
  2022-08-25  6:42 ` [PATCH v1 3/3] examples/l3fwd-power: enable PMD power mgmt " Feifei Wang
  2022-08-29 12:48   ` Hunt, David
@ 2022-10-20 22:09   ` Stephen Hemminger
  2022-10-27  9:43     ` 回复: " Feifei Wang
  1 sibling, 1 reply; 39+ messages in thread
From: Stephen Hemminger @ 2022-10-20 22:09 UTC (permalink / raw)
  To: Feifei Wang; +Cc: David Hunt, dev, nd, Ruifeng Wang

On Thu, 25 Aug 2022 14:42:51 +0800
Feifei Wang <feifei.wang2@arm.com> wrote:

> diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
> index 887c6eae3f..2bd0d700f0 100644
> --- a/examples/l3fwd-power/main.c
> +++ b/examples/l3fwd-power/main.c
> @@ -432,8 +432,16 @@ static void
>  signal_exit_now(int sigtype)
>  {
>  
> -	if (sigtype == SIGINT)
> +	if (sigtype == SIGINT) {
> +#if defined(RTE_ARCH_ARM64)
> +	/**
> +	 * wake_up api does not need input parameter on Arm,
> +	 * so 0 is meaningless here.
> +	 */
> +		rte_power_monitor_wakeup(0);
> +#endif
>  		quit_signal = true;
> +	}
>  

This method is problematic. There is no guarantee that power
monitor is async signal safe.


^ permalink raw reply	[flat|nested] 39+ messages in thread

* 回复: 回复: [PATCH v1 3/3] examples/l3fwd-power: enable PMD power mgmt on Arm
  2022-10-20 20:41         ` Thomas Monjalon
@ 2022-10-27  9:38           ` Feifei Wang
  0 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2022-10-27  9:38 UTC (permalink / raw)
  To: thomas, David Marchand; +Cc: Hunt, David, Ruifeng Wang, dev, nd, nd



> -----邮件原件-----
> 发件人: Thomas Monjalon <thomas@monjalon.net>
> 发送时间: Friday, October 21, 2022 4:42 AM
> 收件人: David Marchand <david.marchand@redhat.com>
> 抄送: Hunt, David <david.hunt@intel.com>; Ruifeng Wang
> <Ruifeng.Wang@arm.com>; dev@dpdk.org; nd <nd@arm.com>; Feifei
> Wang <Feifei.Wang2@arm.com>
> 主题: Re: 回复: [PATCH v1 3/3] examples/l3fwd-power: enable PMD power
> mgmt on Arm
> 
> 11/10/2022 09:56, Feifei Wang:
> > David Marchand <david.marchand@redhat.com>
> > > > On 25/08/2022 07:42, Feifei Wang wrote:
> > > > > --- a/examples/l3fwd-power/main.c
> > > > > +++ b/examples/l3fwd-power/main.c
> > > > > @@ -432,8 +432,16 @@ static void
> > > > >   signal_exit_now(int sigtype)
> > > > >   {
> > > > >
> > > > > -     if (sigtype == SIGINT)
> > > > > +     if (sigtype == SIGINT) {
> > > > > +#if defined(RTE_ARCH_ARM64)
> > >
> > > Having a arch specific behavior in the application shows that there
> > > is something wrong either in the API, or in the Arm implementation of
> the API.
> > > I don't think this is a good solution.
> > >
> > > Can't we find a better alternative? By changing the API probably?
> > Sorry I do not understand ' shows that there is something wrong either in
> the API'
> 
> David means the application developer should not have to be aware of the
> arch differences.
> When you use an API, you don't check how it is implemented, and you are
> not supposed to use #ifdef.
> The API must be arch-agnostic.

Ok, Understand. Thanks for the explanation.
> 
> > Here we call ' rte_power_monitor_wakeup' API is due to that we need to
> > wake up all cores from WFE instructions in arm, and then l3fwd can exit
> correctly.
> >
> > This is due to that arm arch is different from x86, if there is no
> > packets received, x86's 'UMONITOR' can automatically exit from energy-
> saving state after waiting for a period of time.
> > But arm's 'WFE' can not exit automatically. It will wait 'SEV'
> > instructions in wake_up API to wake up it.
> >
> > Finally, if user want to exit l3fwd by  'SIGINT' in arm, main core
> > should firstly call 'wake_up' API to force worker cores to exit from energy-
> saving state.
> > Otherwise, the worker will stay in the energy-saving state forever if no
> packet is received.
> 
> Please find a way to have a common API,
> even if the API implementation is empty in x86 case.

Yes, I think what we need to do is not a create a new API, it is to look
for a correct location to call 'rte_power_monitor_wakeup'. 

> 
> > >
> > >
> > > > > +     /**
> > > > > +      * wake_up api does not need input parameter on Arm,
> > > > > +      * so 0 is meaningless here.
> > > > > +      */
> > > > > +             rte_power_monitor_wakeup(0); #endif
> > > > >               quit_signal = true;
> > > > > +     }
> 
> 


^ permalink raw reply	[flat|nested] 39+ messages in thread

* 回复: [PATCH v1 3/3] examples/l3fwd-power: enable PMD power mgmt on Arm
  2022-10-20 22:09   ` Stephen Hemminger
@ 2022-10-27  9:43     ` Feifei Wang
  0 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2022-10-27  9:43 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Hunt, dev, nd, Ruifeng Wang, nd



> -----邮件原件-----
> 发件人: Stephen Hemminger <stephen@networkplumber.org>
> 发送时间: Friday, October 21, 2022 6:10 AM
> 收件人: Feifei Wang <Feifei.Wang2@arm.com>
> 抄送: David Hunt <david.hunt@intel.com>; dev@dpdk.org; nd
> <nd@arm.com>; Ruifeng Wang <Ruifeng.Wang@arm.com>
> 主题: Re: [PATCH v1 3/3] examples/l3fwd-power: enable PMD power mgmt
> on Arm
> 
> On Thu, 25 Aug 2022 14:42:51 +0800
> Feifei Wang <feifei.wang2@arm.com> wrote:
> 
> > diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-
> power/main.c
> > index 887c6eae3f..2bd0d700f0 100644
> > --- a/examples/l3fwd-power/main.c
> > +++ b/examples/l3fwd-power/main.c
> > @@ -432,8 +432,16 @@ static void
> >  signal_exit_now(int sigtype)
> >  {
> >
> > -	if (sigtype == SIGINT)
> > +	if (sigtype == SIGINT) {
> > +#if defined(RTE_ARCH_ARM64)
> > +	/**
> > +	 * wake_up api does not need input parameter on Arm,
> > +	 * so 0 is meaningless here.
> > +	 */
> > +		rte_power_monitor_wakeup(0);
> > +#endif
> >  		quit_signal = true;
> > +	}
> >
> 
> This method is problematic. There is no guarantee that power monitor is
> async signal safe.

Agree with this. We will put 'rte_power_monitor_wakeup' out of signal_exit.
And put it after that main_lcore exit 'main_empty_poll_loop':
-----------------------------------------------------------------------------------------------------------------
rte_eal_mp_remote_launch(main_telemetry_loop, NULL, CALL_MAIN);


%wake up all worker calls from low power state.
rte_power_monitor_wakeup(0);

if (app_mode == APP_MODE_EMPTY_POLL || app_mode == APP_MODE_TELEMETRY)
	launch_timer(rte_lcore_id());

RTE_LCORE_FOREACH_WORKER(lcore_id) {
	if (rte_eal_wait_lcore(lcore_id) < 0)
		return -1;
}
-----------------------------------------------------------------------------------------------------------------



^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v2 0/3] Enable PMD power management on Arm
  2022-08-25  6:42 [PATCH v1 0/3] Enable PMD power management on Arm Feifei Wang
                   ` (2 preceding siblings ...)
  2022-08-25  6:42 ` [PATCH v1 3/3] examples/l3fwd-power: enable PMD power mgmt " Feifei Wang
@ 2022-11-07  7:04 ` Feifei Wang
  2022-11-07  7:04   ` [PATCH v2 1/3] eal: add 8 bits case for wait scheme Feifei Wang
                     ` (2 more replies)
  2022-11-11  7:26 ` [PATCH v3 0/3] Enable PMD power management " Feifei Wang
                   ` (3 subsequent siblings)
  7 siblings, 3 replies; 39+ messages in thread
From: Feifei Wang @ 2022-11-07  7:04 UTC (permalink / raw)
  Cc: dev, david.hunt, david.marchand, thomas, stephen, nd, Feifei Wang

For Arm aarch, use WFE instructions to enable PMD power management.

Test Results:
dynamic instructions over 1sec	without wfe	with wfe	percentage
ampere-altra			6,298,483,712	9,117,624	-99.855%
thunderx2			6,990,909,373	3,247,226	-99.954%

When power efficient PMD is enabled by using WFE on Arm, if no pkts
received, the instructions that CPU executes is reduced by 99%.

V2:
1. move rte_wake_up API out of signal_exit(David Marchand, Thomas, Stephen)
2. Add test results when using wfe on ARM server

Feifei Wang (3):
  eal: add 8 bits case for wait scheme
  eal: add power mgmt support on Arm
  examples/l3fwd-power: enable PMD power monitor on Arm

 examples/l3fwd-power/main.c        | 33 ++++++++++++++
 lib/eal/arm/include/rte_pause_64.h | 32 +++++++++++--
 lib/eal/arm/rte_cpuflags.c         |  5 +++
 lib/eal/arm/rte_power_intrinsics.c | 72 ++++++++++++++++++++++++++++--
 4 files changed, 135 insertions(+), 7 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v2 1/3] eal: add 8 bits case for wait scheme
  2022-11-07  7:04 ` [PATCH v2 0/3] Enable PMD power management " Feifei Wang
@ 2022-11-07  7:04   ` Feifei Wang
  2022-11-07  7:04   ` [PATCH v2 2/3] eal: add power mgmt support on Arm Feifei Wang
  2022-11-07  7:04   ` [PATCH v2 3/3] examples/l3fwd-power: enable PMD power monitor " Feifei Wang
  2 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2022-11-07  7:04 UTC (permalink / raw)
  To: Ruifeng Wang
  Cc: dev, david.hunt, david.marchand, thomas, stephen, nd, Feifei Wang

For wait scheme generic helper, add 8 bits case.

Signed-off-by: Feifei Wang <feifei.wang2@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
---
 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)  \
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 2/3] eal: add power mgmt support on Arm
  2022-11-07  7:04 ` [PATCH v2 0/3] Enable PMD power management " Feifei Wang
  2022-11-07  7:04   ` [PATCH v2 1/3] eal: add 8 bits case for wait scheme Feifei Wang
@ 2022-11-07  7:04   ` Feifei Wang
  2022-11-07  7:04   ` [PATCH v2 3/3] examples/l3fwd-power: enable PMD power monitor " Feifei Wang
  2 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2022-11-07  7:04 UTC (permalink / raw)
  To: Ruifeng Wang
  Cc: dev, david.hunt, david.marchand, thomas, stephen, nd, Feifei Wang

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 <feifei.wang2@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
---
 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
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v2 3/3] examples/l3fwd-power: enable PMD power monitor on Arm
  2022-11-07  7:04 ` [PATCH v2 0/3] Enable PMD power management " Feifei Wang
  2022-11-07  7:04   ` [PATCH v2 1/3] eal: add 8 bits case for wait scheme Feifei Wang
  2022-11-07  7:04   ` [PATCH v2 2/3] eal: add power mgmt support on Arm Feifei Wang
@ 2022-11-07  7:04   ` Feifei Wang
  2022-11-07 16:01     ` Stephen Hemminger
  2 siblings, 1 reply; 39+ messages in thread
From: Feifei Wang @ 2022-11-07  7:04 UTC (permalink / raw)
  To: David Hunt
  Cc: dev, david.marchand, thomas, stephen, nd, Feifei Wang, Ruifeng Wang

For Arm aarch, power monitor uses WFE instruction to enable, which can
not exit automatically within the time limit. This means
'rte_power_monitor_wakeup' API needs to be called to wake up sleep cores
if there is no store operation to monitored address.

Furthermore, we disable power monitor feature on the main core so that
it can be used to wake up other sleeping cores after it exit from loop.

Signed-off-by: Feifei Wang <feifei.wang2@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
Acked-by: David Hunt <david.hunt@intel.com>
---
 examples/l3fwd-power/main.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index fd3ade330f..ffd2ad686a 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -3006,6 +3006,25 @@ main(int argc, char **argv)
 						"Error setting scaling freq max: err=%d, lcore %d\n",
 							ret, lcore_id);
 
+#if defined(RTE_ARCH_ARM64)
+				/* Ensure the main lcore does not enter the power-monitor state,
+				 * so that it can be used to wake up other lcores on ARM.
+				 * This is due to WFE instruction has no timeout wake-up mechanism,
+				 * and if users want to exit actively, the main lcore is needed
+				 * to send SEV instruction to wake up other lcores.
+				 */
+				unsigned int main_lcore = rte_get_main_lcore();
+				if (lcore_id != main_lcore ||
+						pmgmt_type != RTE_POWER_MGMT_TYPE_MONITOR) {
+					ret = rte_power_ethdev_pmgmt_queue_enable(
+							lcore_id, portid, queueid,
+							pmgmt_type);
+					if (ret < 0)
+						rte_exit(EXIT_FAILURE,
+							"rte_power_ethdev_pmgmt_queue_enable: err=%d, port=%d\n",
+							ret, portid);
+				}
+#else
 				ret = rte_power_ethdev_pmgmt_queue_enable(
 						lcore_id, portid, queueid,
 						pmgmt_type);
@@ -3013,6 +3032,7 @@ main(int argc, char **argv)
 					rte_exit(EXIT_FAILURE,
 						"rte_power_ethdev_pmgmt_queue_enable: err=%d, port=%d\n",
 							ret, portid);
+#endif
 			}
 		}
 	}
@@ -3113,6 +3133,19 @@ main(int argc, char **argv)
 	if (app_mode == APP_MODE_EMPTY_POLL || app_mode == APP_MODE_TELEMETRY)
 		launch_timer(rte_lcore_id());
 
+	/* wake up all worker cores from sleeping state */
+	if (app_mode == APP_MODE_PMD_MGMT) {
+		for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
+			if (rte_lcore_is_enabled(lcore_id) == 0)
+				continue;
+
+			if (lcore_id == rte_get_main_lcore())
+				continue;
+
+			rte_power_monitor_wakeup(lcore_id);
+		}
+	}
+
 	RTE_LCORE_FOREACH_WORKER(lcore_id) {
 		if (rte_eal_wait_lcore(lcore_id) < 0)
 			return -1;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH v2 3/3] examples/l3fwd-power: enable PMD power monitor on Arm
  2022-11-07  7:04   ` [PATCH v2 3/3] examples/l3fwd-power: enable PMD power monitor " Feifei Wang
@ 2022-11-07 16:01     ` Stephen Hemminger
  2022-11-08  3:25       ` 回复: " Feifei Wang
  0 siblings, 1 reply; 39+ messages in thread
From: Stephen Hemminger @ 2022-11-07 16:01 UTC (permalink / raw)
  To: Feifei Wang; +Cc: David Hunt, dev, david.marchand, thomas, nd, Ruifeng Wang

On Mon,  7 Nov 2022 15:04:49 +0800
Feifei Wang <feifei.wang2@arm.com> wrote:

> +				/* Ensure the main lcore does not enter the power-monitor state,
> +				 * so that it can be used to wake up other lcores on ARM.
> +				 * This is due to WFE instruction has no timeout wake-up mechanism,
> +				 * and if users want to exit actively, the main lcore is needed
> +				 * to send SEV instruction to wake up other lcores.
> +				 */
> +				unsigned int main_lcore = rte_get_main_lcore();

This can be done in a simpler an cleaner manner with a continue statement
earlier in the loop.

diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index fd3ade330f82..115535fd4cd7 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -2984,6 +2984,16 @@ main(int argc, char **argv)
 			}
 
 			if (app_mode == APP_MODE_PMD_MGMT && !baseline_enabled) {
+#ifdef RTE_ARCH_ARM64
+				/* Ensure the main lcore does not enter the power-monitor state,
+				 * so that it can be used to wake up other lcores on ARM.
+				 * This is due to WFE instruction has no timeout wake-up mechanism,
+				 * and if users want to exit actively, the main lcore is needed
+				 * to send SEV instruction to wake up other lcors.
+				 */
+				if (lcore_id == rte_get_main_lcore())
+					continue;
+#endif
 				/* Set power_pmd_mgmt configs passed by user */
 				rte_power_pmd_mgmt_set_emptypoll_max(max_empty_polls);
 				ret = rte_power_pmd_mgmt_set_pause_duration(pause_duration);

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* 回复: [PATCH v2 3/3] examples/l3fwd-power: enable PMD power monitor on Arm
  2022-11-07 16:01     ` Stephen Hemminger
@ 2022-11-08  3:25       ` Feifei Wang
  0 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2022-11-08  3:25 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: David Hunt, dev, david.marchand, thomas, nd, Ruifeng Wang, nd

Hi, Stephen

> -----邮件原件-----
> 发件人: Stephen Hemminger <stephen@networkplumber.org>
> 发送时间: Tuesday, November 8, 2022 12:02 AM
> 收件人: Feifei Wang <Feifei.Wang2@arm.com>
> 抄送: David Hunt <david.hunt@intel.com>; dev@dpdk.org;
> david.marchand@redhat.com; thomas@monjalon.net; nd <nd@arm.com>;
> Ruifeng Wang <Ruifeng.Wang@arm.com>
> 主题: Re: [PATCH v2 3/3] examples/l3fwd-power: enable PMD power
> monitor on Arm
> 
> On Mon,  7 Nov 2022 15:04:49 +0800
> Feifei Wang <feifei.wang2@arm.com> wrote:
> 
> > +				/* Ensure the main lcore does not enter the
> power-monitor state,
> > +				 * so that it can be used to wake up other
> lcores on ARM.
> > +				 * This is due to WFE instruction has no
> timeout wake-up mechanism,
> > +				 * and if users want to exit actively, the main
> lcore is needed
> > +				 * to send SEV instruction to wake up other
> lcores.
> > +				 */
> > +				unsigned int main_lcore =
> rte_get_main_lcore();
> 
> This can be done in a simpler an cleaner manner with a continue statement
> earlier in the loop.
> 
> diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
> index fd3ade330f82..115535fd4cd7 100644
> --- a/examples/l3fwd-power/main.c
> +++ b/examples/l3fwd-power/main.c
> @@ -2984,6 +2984,16 @@ main(int argc, char **argv)
>  			}
> 
>  			if (app_mode == APP_MODE_PMD_MGMT
> && !baseline_enabled) {
> +#ifdef RTE_ARCH_ARM64
> +				/* Ensure the main lcore does not enter the
> power-monitor state,
> +				 * so that it can be used to wake up other
> lcores on ARM.
> +				 * This is due to WFE instruction has no
> timeout wake-up mechanism,
> +				 * and if users want to exit actively, the main
> lcore is needed
> +				 * to send SEV instruction to wake up other
> lcors.
> +				 */
> +				if (lcore_id == rte_get_main_lcore())
> +					continue;
> +#endif
>  				/* Set power_pmd_mgmt configs passed by
> user */
> 
> 	rte_power_pmd_mgmt_set_emptypoll_max(max_empty_polls);
>  				ret =
> rte_power_pmd_mgmt_set_pause_duration(pause_duration);

Thanks for the comment.
There maybe some problems for this change. This is due to that we just want to disable power monitor
feature on the main core when "app_mode == APP_MODE_PMD_MGMT && pmgmt_type == RTE_POWER_MGMT_TYPE_MONITOR".
When “pmgmt_type == RTE_POWER_MGMT_TYPE_PAUSE || pmgmt_type == RTE_POWER_MGMT_TYPE_SCALE", main core
power management mode can be enabled.

Best Regards
Feifei

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v3 0/3] Enable PMD power management on Arm
  2022-08-25  6:42 [PATCH v1 0/3] Enable PMD power management on Arm Feifei Wang
                   ` (3 preceding siblings ...)
  2022-11-07  7:04 ` [PATCH v2 0/3] Enable PMD power management " Feifei Wang
@ 2022-11-11  7:26 ` Feifei Wang
  2022-11-11  7:26   ` [PATCH v3 1/3] eal: add 8 bits case for wait scheme Feifei Wang
                     ` (2 more replies)
  2022-11-11 10:20 ` [PATCH v4 0/4] Enable PMD power management " Feifei Wang
                   ` (2 subsequent siblings)
  7 siblings, 3 replies; 39+ messages in thread
From: Feifei Wang @ 2022-11-11  7:26 UTC (permalink / raw)
  Cc: dev, david.hunt, david.marchand, thomas, stephen, nd, Feifei Wang

For Arm aarch, use WFE instructions to enable PMD power management.

Test Results:
dynamic instructions over 1sec	without wfe	with wfe	percentage
ampere-altra			6,298,483,712	9,117,624	-99.855%
thunderx2			6,990,909,373	3,247,226	-99.954%

When power efficient PMD is enabled by using WFE on Arm, if no pkts
received, the instructions that CPU executes is reduced by 99%.

V2:
1. move rte_wake_up API out of signal_exit(David Marchand, Thomas, Stephen)
2. Add test results when using wfe on ARM server

v3:
1. make code cleaner (Stephen)

Feifei Wang (3):
  eal: add 8 bits case for wait scheme
  eal: add power mgmt support on Arm
  examples/l3fwd-power: enable PMD power monitor on Arm

 examples/l3fwd-power/main.c        | 25 +++++++++++
 lib/eal/arm/include/rte_pause_64.h | 32 +++++++++++--
 lib/eal/arm/rte_cpuflags.c         |  5 +++
 lib/eal/arm/rte_power_intrinsics.c | 72 ++++++++++++++++++++++++++++--
 4 files changed, 127 insertions(+), 7 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v3 1/3] eal: add 8 bits case for wait scheme
  2022-11-11  7:26 ` [PATCH v3 0/3] Enable PMD power management " Feifei Wang
@ 2022-11-11  7:26   ` Feifei Wang
  2022-11-11  7:26   ` [PATCH v3 2/3] eal: add power mgmt support on Arm Feifei Wang
  2022-11-11  7:26   ` [PATCH v3 3/3] examples/l3fwd-power: enable PMD power monitor " Feifei Wang
  2 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2022-11-11  7:26 UTC (permalink / raw)
  To: Ruifeng Wang
  Cc: dev, david.hunt, david.marchand, thomas, stephen, nd, Feifei Wang

For wait scheme generic helper, add 8 bits case.

Signed-off-by: Feifei Wang <feifei.wang2@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
---
 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)  \
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v3 2/3] eal: add power mgmt support on Arm
  2022-11-11  7:26 ` [PATCH v3 0/3] Enable PMD power management " Feifei Wang
  2022-11-11  7:26   ` [PATCH v3 1/3] eal: add 8 bits case for wait scheme Feifei Wang
@ 2022-11-11  7:26   ` Feifei Wang
  2022-11-11  7:26   ` [PATCH v3 3/3] examples/l3fwd-power: enable PMD power monitor " Feifei Wang
  2 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2022-11-11  7:26 UTC (permalink / raw)
  To: Ruifeng Wang
  Cc: dev, david.hunt, david.marchand, thomas, stephen, nd, Feifei Wang

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 <feifei.wang2@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
---
 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
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v3 3/3] examples/l3fwd-power: enable PMD power monitor on Arm
  2022-11-11  7:26 ` [PATCH v3 0/3] Enable PMD power management " Feifei Wang
  2022-11-11  7:26   ` [PATCH v3 1/3] eal: add 8 bits case for wait scheme Feifei Wang
  2022-11-11  7:26   ` [PATCH v3 2/3] eal: add power mgmt support on Arm Feifei Wang
@ 2022-11-11  7:26   ` Feifei Wang
  2022-11-11  8:22     ` Thomas Monjalon
  2 siblings, 1 reply; 39+ messages in thread
From: Feifei Wang @ 2022-11-11  7:26 UTC (permalink / raw)
  To: David Hunt
  Cc: dev, david.marchand, thomas, stephen, nd, Feifei Wang, Ruifeng Wang

For Arm aarch, power monitor uses WFE instruction to enable, which can
not exit automatically within the time limit. This means
'rte_power_monitor_wakeup' API needs to be called to wake up sleep cores
if there is no store operation to monitored address.

Furthermore, we disable power monitor feature on the main core so that
it can be used to wake up other sleeping cores after it exit from loop.

Signed-off-by: Feifei Wang <feifei.wang2@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
Acked-by: David Hunt <david.hunt@intel.com>
---
 examples/l3fwd-power/main.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index fd3ade330f..7c41159c43 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -3006,6 +3006,18 @@ main(int argc, char **argv)
 						"Error setting scaling freq max: err=%d, lcore %d\n",
 							ret, lcore_id);
 
+#if defined(RTE_ARCH_ARM64)
+				/* Ensure the main lcore does not enter the power-monitor state,
+				 * so that it can be used to wake up other lcores on ARM.
+				 * This is due to WFE instruction has no timeout wake-up mechanism,
+				 * and if users want to exit actively, the main lcore is needed
+				 * to send SEV instruction to wake up other lcores.
+				 */
+				unsigned int main_lcore = rte_get_main_lcore();
+				if (lcore_id == main_lcore &&
+						pmgmt_type == RTE_POWER_MGMT_TYPE_MONITOR)
+					continue;
+#endif
 				ret = rte_power_ethdev_pmgmt_queue_enable(
 						lcore_id, portid, queueid,
 						pmgmt_type);
@@ -3113,6 +3125,19 @@ main(int argc, char **argv)
 	if (app_mode == APP_MODE_EMPTY_POLL || app_mode == APP_MODE_TELEMETRY)
 		launch_timer(rte_lcore_id());
 
+	/* wake up all worker cores from sleeping state */
+	if (pmgmt_type == RTE_POWER_MGMT_TYPE_MONITOR) {
+		for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
+			if (rte_lcore_is_enabled(lcore_id) == 0)
+				continue;
+
+			if (lcore_id == rte_get_main_lcore())
+				continue;
+
+			rte_power_monitor_wakeup(lcore_id);
+		}
+	}
+
 	RTE_LCORE_FOREACH_WORKER(lcore_id) {
 		if (rte_eal_wait_lcore(lcore_id) < 0)
 			return -1;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH v3 3/3] examples/l3fwd-power: enable PMD power monitor on Arm
  2022-11-11  7:26   ` [PATCH v3 3/3] examples/l3fwd-power: enable PMD power monitor " Feifei Wang
@ 2022-11-11  8:22     ` Thomas Monjalon
  2022-11-11 10:21       ` 回复: " Feifei Wang
  0 siblings, 1 reply; 39+ messages in thread
From: Thomas Monjalon @ 2022-11-11  8:22 UTC (permalink / raw)
  To: Feifei Wang
  Cc: David Hunt, dev, david.marchand, stephen, nd, Ruifeng Wang,
	honnappa.nagarahalli

11/11/2022 08:26, Feifei Wang:
> For Arm aarch, power monitor uses WFE instruction to enable, which can
> not exit automatically within the time limit. This means
> 'rte_power_monitor_wakeup' API needs to be called to wake up sleep cores
> if there is no store operation to monitored address.
> 
> Furthermore, we disable power monitor feature on the main core so that
> it can be used to wake up other sleeping cores after it exit from loop.
> 
> Signed-off-by: Feifei Wang <feifei.wang2@arm.com>
> Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> Acked-by: David Hunt <david.hunt@intel.com>
> ---
> +#if defined(RTE_ARCH_ARM64)
> +				/* Ensure the main lcore does not enter the power-monitor state,
> +				 * so that it can be used to wake up other lcores on ARM.
> +				 * This is due to WFE instruction has no timeout wake-up mechanism,
> +				 * and if users want to exit actively, the main lcore is needed
> +				 * to send SEV instruction to wake up other lcores.
> +				 */
> +				unsigned int main_lcore = rte_get_main_lcore();
> +				if (lcore_id == main_lcore &&
> +						pmgmt_type == RTE_POWER_MGMT_TYPE_MONITOR)
> +					continue;
> +#endif

We need to have this logic abstracted in the API for all architectures.
We cannot afford having such #ifdef per CPU in the application.



^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v4 0/4] Enable PMD power management on Arm
  2022-08-25  6:42 [PATCH v1 0/3] Enable PMD power management on Arm Feifei Wang
                   ` (4 preceding siblings ...)
  2022-11-11  7:26 ` [PATCH v3 0/3] Enable PMD power management " Feifei Wang
@ 2022-11-11 10:20 ` Feifei Wang
  2022-11-11 10:20   ` [PATCH v4 1/4] eal: add 8 bits case for wait scheme Feifei Wang
                     ` (3 more replies)
  2022-12-14  8:14 ` [PATCH v5 0/2] Enable PMD power management on Arm Feifei Wang
  2023-02-20  8:51 ` [PATCH v6 " Feifei Wang
  7 siblings, 4 replies; 39+ messages in thread
From: Feifei Wang @ 2022-11-11 10:20 UTC (permalink / raw)
  Cc: dev, david.hunt, david.marchand, thomas, stephen, nd, Feifei Wang

For Arm aarch, use WFE instructions to enable PMD power management.

Test Results:
dynamic instructions over 1sec	without wfe	with wfe	percentage
ampere-altra			6,298,483,712	9,117,624	-99.855%
thunderx2			6,990,909,373	3,247,226	-99.954%

When power efficient PMD is enabled by using WFE on Arm, if no pkts
received, the instructions that CPU executes is reduced by 99%.

V2:
1. move rte_wake_up API out of signal_exit(David Marchand, Thomas, Stephen)
2. Add test results when using wfe on ARM server

v3:
1. make code cleaner (Stephen)

v4:
1. add support check in API (Thomas)

Feifei Wang (4):
  eal: add 8 bits case for wait scheme
  eal: add power mgmt support on Arm
  power: add power monitor support check
  examples/l3fwd-power: add power monitor wake up API

 examples/l3fwd-power/main.c        | 13 ++++++
 lib/eal/arm/include/rte_pause_64.h | 32 +++++++++++--
 lib/eal/arm/rte_cpuflags.c         |  5 +++
 lib/eal/arm/rte_power_intrinsics.c | 72 ++++++++++++++++++++++++++++--
 lib/power/rte_power_pmd_mgmt.c     | 12 +++++
 lib/power/rte_power_pmd_mgmt.h     |  1 +
 6 files changed, 128 insertions(+), 7 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v4 1/4] eal: add 8 bits case for wait scheme
  2022-11-11 10:20 ` [PATCH v4 0/4] Enable PMD power management " Feifei Wang
@ 2022-11-11 10:20   ` Feifei Wang
  2022-11-11 10:20   ` [PATCH v4 2/4] eal: add power mgmt support on Arm Feifei Wang
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2022-11-11 10:20 UTC (permalink / raw)
  To: Ruifeng Wang
  Cc: dev, david.hunt, david.marchand, thomas, stephen, nd, Feifei Wang

For wait scheme generic helper, add 8 bits case.

Signed-off-by: Feifei Wang <feifei.wang2@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
---
 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)  \
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 2/4] eal: add power mgmt support on Arm
  2022-11-11 10:20 ` [PATCH v4 0/4] Enable PMD power management " Feifei Wang
  2022-11-11 10:20   ` [PATCH v4 1/4] eal: add 8 bits case for wait scheme Feifei Wang
@ 2022-11-11 10:20   ` Feifei Wang
  2022-11-11 10:20   ` [PATCH v4 3/4] power: add power monitor support check Feifei Wang
  2022-11-11 10:20   ` [PATCH v4 4/4] examples/l3fwd-power: add power monitor wake up API Feifei Wang
  3 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2022-11-11 10:20 UTC (permalink / raw)
  To: Ruifeng Wang
  Cc: dev, david.hunt, david.marchand, thomas, stephen, nd, Feifei Wang

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 <feifei.wang2@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
---
 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
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 3/4] power: add power monitor support check
  2022-11-11 10:20 ` [PATCH v4 0/4] Enable PMD power management " Feifei Wang
  2022-11-11 10:20   ` [PATCH v4 1/4] eal: add 8 bits case for wait scheme Feifei Wang
  2022-11-11 10:20   ` [PATCH v4 2/4] eal: add power mgmt support on Arm Feifei Wang
@ 2022-11-11 10:20   ` Feifei Wang
  2022-11-11 10:20   ` [PATCH v4 4/4] examples/l3fwd-power: add power monitor wake up API Feifei Wang
  3 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2022-11-11 10:20 UTC (permalink / raw)
  To: David Hunt
  Cc: dev, david.marchand, thomas, stephen, nd, Feifei Wang, Ruifeng Wang

On ARM, WFE instruction, which is used to power monitor, has no timeout
wake-up mechanism, and if users want to exit power monitor actively, the
main lcore is needed to send SEV instruction to wake up other lcores.

So it is necessary to ensure the main lcore does not enter the
power-monitor state. To solve this, main core support check on ARM is
added.

Signed-off-by: Feifei Wang <feifei.wang2@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
---
 lib/power/rte_power_pmd_mgmt.c | 12 ++++++++++++
 lib/power/rte_power_pmd_mgmt.h |  1 +
 2 files changed, 13 insertions(+)

diff --git a/lib/power/rte_power_pmd_mgmt.c b/lib/power/rte_power_pmd_mgmt.c
index ca1840387c..3f3478b2c1 100644
--- a/lib/power/rte_power_pmd_mgmt.c
+++ b/lib/power/rte_power_pmd_mgmt.c
@@ -490,6 +490,18 @@ rte_power_ethdev_pmgmt_queue_enable(unsigned int lcore_id, uint16_t port_id,
 	rte_rx_callback_fn clb;
 	int ret;
 
+#if defined(RTE_ARCH_ARM64)
+	/* Ensure the main lcore does not enter the power-monitor state,
+	 * so that it can be used to wake up other lcores on ARM.
+	 * This is due to WFE instruction has no timeout wake-up mechanism,
+	 * and if users want to exit actively, the main lcore is needed
+	 * to send SEV instruction to wake up other lcores.
+	 */
+	if (lcore_id == rte_get_main_lcore() &&
+			mode == RTE_POWER_MGMT_TYPE_MONITOR)
+		return EPERM;
+#endif
+
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
 	if (queue_id >= RTE_MAX_QUEUES_PER_PORT || lcore_id >= RTE_MAX_LCORE) {
diff --git a/lib/power/rte_power_pmd_mgmt.h b/lib/power/rte_power_pmd_mgmt.h
index 7ae6ef2d32..b1a0989b88 100644
--- a/lib/power/rte_power_pmd_mgmt.h
+++ b/lib/power/rte_power_pmd_mgmt.h
@@ -52,6 +52,7 @@ enum rte_power_pmd_mgmt_type {
  *   The power management scheme to use for specified Rx queue.
  * @return
  *   0 on success
+ *   EPERM main core cannot be supported on ARM
  *   <0 on error
  */
 __rte_experimental
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v4 4/4] examples/l3fwd-power: add power monitor wake up API
  2022-11-11 10:20 ` [PATCH v4 0/4] Enable PMD power management " Feifei Wang
                     ` (2 preceding siblings ...)
  2022-11-11 10:20   ` [PATCH v4 3/4] power: add power monitor support check Feifei Wang
@ 2022-11-11 10:20   ` Feifei Wang
  3 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2022-11-11 10:20 UTC (permalink / raw)
  To: David Hunt
  Cc: dev, david.marchand, thomas, stephen, nd, Feifei Wang, Ruifeng Wang

For ARM aarch, power monitor uses WFE instruction to enable, which can
not exit automatically within the time limit. This means
'rte_power_monitor_wakeup' API needs to be called to wake up sleep cores
if there is no store operation to monitored address.

For other aarch, 'rte_power_monitor_wakeup' API can also make sure all
lcores wake up from sleeping state.

Signed-off-by: Feifei Wang <feifei.wang2@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
Acked-by: David Hunt <david.hunt@intel.com>
---
 examples/l3fwd-power/main.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index fd3ade330f..a47a91ce6f 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -3113,6 +3113,19 @@ main(int argc, char **argv)
 	if (app_mode == APP_MODE_EMPTY_POLL || app_mode == APP_MODE_TELEMETRY)
 		launch_timer(rte_lcore_id());
 
+	/* wake up all worker cores from sleeping state */
+	if (pmgmt_type == RTE_POWER_MGMT_TYPE_MONITOR) {
+		for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
+			if (rte_lcore_is_enabled(lcore_id) == 0)
+				continue;
+
+			if (lcore_id == rte_get_main_lcore())
+				continue;
+
+			rte_power_monitor_wakeup(lcore_id);
+		}
+	}
+
 	RTE_LCORE_FOREACH_WORKER(lcore_id) {
 		if (rte_eal_wait_lcore(lcore_id) < 0)
 			return -1;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* 回复: [PATCH v3 3/3] examples/l3fwd-power: enable PMD power monitor on Arm
  2022-11-11  8:22     ` Thomas Monjalon
@ 2022-11-11 10:21       ` Feifei Wang
  0 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2022-11-11 10:21 UTC (permalink / raw)
  To: thomas
  Cc: David Hunt, dev, david.marchand, stephen, nd, Ruifeng Wang,
	Honnappa Nagarahalli, nd

Hi, Thomas
> -----邮件原件-----
> 发件人: Thomas Monjalon <thomas@monjalon.net>
> 发送时间: Friday, November 11, 2022 4:22 PM
> 收件人: Feifei Wang <Feifei.Wang2@arm.com>
> 抄送: David Hunt <david.hunt@intel.com>; dev@dpdk.org;
> david.marchand@redhat.com; stephen@networkplumber.org; nd
> <nd@arm.com>; Ruifeng Wang <Ruifeng.Wang@arm.com>; Honnappa
> Nagarahalli <Honnappa.Nagarahalli@arm.com>
> 主题: Re: [PATCH v3 3/3] examples/l3fwd-power: enable PMD power
> monitor on Arm
> 
> 11/11/2022 08:26, Feifei Wang:
> > For Arm aarch, power monitor uses WFE instruction to enable, which can
> > not exit automatically within the time limit. This means
> > 'rte_power_monitor_wakeup' API needs to be called to wake up sleep
> > cores if there is no store operation to monitored address.
> >
> > Furthermore, we disable power monitor feature on the main core so that
> > it can be used to wake up other sleeping cores after it exit from loop.
> >
> > Signed-off-by: Feifei Wang <feifei.wang2@arm.com>
> > Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > Acked-by: David Hunt <david.hunt@intel.com>
> > ---
> > +#if defined(RTE_ARCH_ARM64)
> > +				/* Ensure the main lcore does not enter the
> power-monitor state,
> > +				 * so that it can be used to wake up other
> lcores on ARM.
> > +				 * This is due to WFE instruction has no
> timeout wake-up mechanism,
> > +				 * and if users want to exit actively, the main
> lcore is needed
> > +				 * to send SEV instruction to wake up other
> lcores.
> > +				 */
> > +				unsigned int main_lcore =
> rte_get_main_lcore();
> > +				if (lcore_id == main_lcore &&
> > +						pmgmt_type ==
> RTE_POWER_MGMT_TYPE_MONITOR)
> > +					continue;
> > +#endif
> 
> We need to have this logic abstracted in the API for all architectures.
> We cannot afford having such #ifdef per CPU in the application.

Thanks for the comment. I will move this into API.

Best Regards
Feifei
> 


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v5 0/2] Enable PMD power management on Arm
  2022-08-25  6:42 [PATCH v1 0/3] Enable PMD power management on Arm Feifei Wang
                   ` (5 preceding siblings ...)
  2022-11-11 10:20 ` [PATCH v4 0/4] Enable PMD power management " Feifei Wang
@ 2022-12-14  8:14 ` Feifei Wang
  2022-12-14  8:14   ` [PATCH v5 1/2] eal: add 8 bits case for wait scheme Feifei Wang
                     ` (2 more replies)
  2023-02-20  8:51 ` [PATCH v6 " Feifei Wang
  7 siblings, 3 replies; 39+ messages in thread
From: Feifei Wang @ 2022-12-14  8:14 UTC (permalink / raw)
  Cc: dev, nd, Feifei Wang

For Arm aarch, use WFE instructions to enable PMD power management.

Test Results:
dynamic instructions over 1sec	without wfe	with wfe	percentage
ampere-altra			6,298,483,712	9,117,624	-99.855%
thunderx2			6,990,909,373	3,247,226	-99.954%

When power efficient PMD is enabled by using WFE on Arm, if no pkts
received, the instructions that CPU executes is reduced by 99%.

V2:
1. move rte_wake_up API out of signal_exit(David Marchand, Thomas, Stephen)
2. Add test results when using wfe on ARM server

v3:
1. make code cleaner (Stephen)

v4:
1. add support check in API (Thomas)

v5:
1. delete v4 check patch and l3fwd-power change. This is due to
that WFE instructions can be applied into all lcores. 
When all cores are in 'WFE' state, kernal can run normally and
receive interrupt signal to send it to the l3fwd-power thread.
Thus core in 'WFE' state can exit from sleeping by interrupt event.


Feifei Wang (2):
  eal: add 8 bits case for wait scheme
  eal: add power mgmt support on Arm

 lib/eal/arm/include/rte_pause_64.h | 32 +++++++++++--
 lib/eal/arm/rte_cpuflags.c         |  5 +++
 lib/eal/arm/rte_power_intrinsics.c | 72 ++++++++++++++++++++++++++++--
 3 files changed, 102 insertions(+), 7 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v5 1/2] eal: add 8 bits case for wait scheme
  2022-12-14  8:14 ` [PATCH v5 0/2] Enable PMD power management on Arm Feifei Wang
@ 2022-12-14  8:14   ` Feifei Wang
  2022-12-14  8:14   ` [PATCH v5 2/2] eal: add power mgmt support on Arm Feifei Wang
  2023-02-17  8:26   ` 回复: [PATCH v5 0/2] Enable PMD power management " Feifei Wang
  2 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2022-12-14  8:14 UTC (permalink / raw)
  To: Ruifeng Wang; +Cc: dev, nd, Feifei Wang

For wait scheme generic helper, add 8 bits case.

Signed-off-by: Feifei Wang <feifei.wang2@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
---
 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)  \
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v5 2/2] eal: add power mgmt support on Arm
  2022-12-14  8:14 ` [PATCH v5 0/2] Enable PMD power management on Arm Feifei Wang
  2022-12-14  8:14   ` [PATCH v5 1/2] eal: add 8 bits case for wait scheme Feifei Wang
@ 2022-12-14  8:14   ` Feifei Wang
  2023-02-17 16:23     ` Stephen Hemminger
  2023-02-17  8:26   ` 回复: [PATCH v5 0/2] Enable PMD power management " Feifei Wang
  2 siblings, 1 reply; 39+ messages in thread
From: Feifei Wang @ 2022-12-14  8:14 UTC (permalink / raw)
  To: Ruifeng Wang; +Cc: dev, nd, Feifei Wang, David Hunt

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 <feifei.wang2@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
Acked-by: David Hunt <david.hunt@intel.com>
---
 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
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* 回复: [PATCH v5 0/2] Enable PMD power management on Arm
  2022-12-14  8:14 ` [PATCH v5 0/2] Enable PMD power management on Arm Feifei Wang
  2022-12-14  8:14   ` [PATCH v5 1/2] eal: add 8 bits case for wait scheme Feifei Wang
  2022-12-14  8:14   ` [PATCH v5 2/2] eal: add power mgmt support on Arm Feifei Wang
@ 2023-02-17  8:26   ` Feifei Wang
  2 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2023-02-17  8:26 UTC (permalink / raw)
  To: Feifei Wang; +Cc: dev, nd, nd

> -----邮件原件-----
> 发件人: Feifei Wang <feifei.wang2@arm.com>
> 发送时间: Wednesday, December 14, 2022 4:14 PM
> 抄送: dev@dpdk.org; nd <nd@arm.com>; Feifei Wang
> <Feifei.Wang2@arm.com>
> 主题: [PATCH v5 0/2] Enable PMD power management on Arm
> 
> For Arm aarch, use WFE instructions to enable PMD power management.
> 
> Test Results:
> dynamic instructions over 1sec	without wfe	with wfe	percentage
> ampere-altra			6,298,483,712	9,117,624	-99.855%
> thunderx2			6,990,909,373	3,247,226	-99.954%
> 
> When power efficient PMD is enabled by using WFE on Arm, if no pkts
> received, the instructions that CPU executes is reduced by 99%.
> 
> V2:
> 1. move rte_wake_up API out of signal_exit(David Marchand, Thomas,
> Stephen) 2. Add test results when using wfe on ARM server
> 
> v3:
> 1. make code cleaner (Stephen)
> 
> v4:
> 1. add support check in API (Thomas)
> 
> v5:
> 1. delete v4 check patch and l3fwd-power change. This is due to that WFE
> instructions can be applied into all lcores.
> When all cores are in 'WFE' state, kernal can run normally and receive
> interrupt signal to send it to the l3fwd-power thread.
> Thus core in 'WFE' state can exit from sleeping by interrupt event.
> 
> 
> Feifei Wang (2):
>   eal: add 8 bits case for wait scheme
>   eal: add power mgmt support on Arm
> 
>  lib/eal/arm/include/rte_pause_64.h | 32 +++++++++++--
>  lib/eal/arm/rte_cpuflags.c         |  5 +++
>  lib/eal/arm/rte_power_intrinsics.c | 72
> ++++++++++++++++++++++++++++--
>  3 files changed, 102 insertions(+), 7 deletions(-)
> 
> --
> 2.25.1

+ping

Would the maintainers help review this patch?
Thanks very much~

Best Regards
Feifei

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v5 2/2] eal: add power mgmt support on Arm
  2022-12-14  8:14   ` [PATCH v5 2/2] eal: add power mgmt support on Arm Feifei Wang
@ 2023-02-17 16:23     ` Stephen Hemminger
  2023-02-20  1:56       ` 回复: " Feifei Wang
  0 siblings, 1 reply; 39+ messages in thread
From: Stephen Hemminger @ 2023-02-17 16:23 UTC (permalink / raw)
  To: Feifei Wang; +Cc: Ruifeng Wang, dev, nd, David Hunt

On Wed, 14 Dec 2022 16:14:30 +0800
Feifei Wang <feifei.wang2@arm.com> wrote:

> +__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

One simplification would be to get rid of this function
and just check for unexpected size in the switch
statement in rte_power_monitor().

> +	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()

	default:
		return -1; /* unexpected size */
> +	}

^ permalink raw reply	[flat|nested] 39+ messages in thread

* 回复: [PATCH v5 2/2] eal: add power mgmt support on Arm
  2023-02-17 16:23     ` Stephen Hemminger
@ 2023-02-20  1:56       ` Feifei Wang
  0 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2023-02-20  1:56 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Ruifeng Wang, dev, nd, David Hunt, nd



> -----邮件原件-----
> 发件人: Stephen Hemminger <stephen@networkplumber.org>
> 发送时间: Saturday, February 18, 2023 12:23 AM
> 收件人: Feifei Wang <Feifei.Wang2@arm.com>
> 抄送: Ruifeng Wang <Ruifeng.Wang@arm.com>; dev@dpdk.org; nd
> <nd@arm.com>; David Hunt <david.hunt@intel.com>
> 主题: Re: [PATCH v5 2/2] eal: add power mgmt support on Arm
> 
> On Wed, 14 Dec 2022 16:14:30 +0800
> Feifei Wang <feifei.wang2@arm.com> wrote:
> 
> > +__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
> 
> One simplification would be to get rid of this function and just check for
> unexpected size in the switch statement in rte_power_monitor().


Thanks for the comments.

__check_val_size API is following intel path. And agree with your comments, 
for arm path, it is unnecessary.

Thus I will delete __check_val_size and simplify the code.

Best Regards
Feifei
> 
> > +	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()
> 
> 	default:
> 		return -1; /* unexpected size */
> > +	}

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v6 0/2] Enable PMD power management on Arm
  2022-08-25  6:42 [PATCH v1 0/3] Enable PMD power management on Arm Feifei Wang
                   ` (6 preceding siblings ...)
  2022-12-14  8:14 ` [PATCH v5 0/2] Enable PMD power management on Arm Feifei Wang
@ 2023-02-20  8:51 ` Feifei Wang
  2023-02-20  8:51   ` [PATCH v6 1/2] eal: add 8 bits case for wait scheme Feifei Wang
                     ` (2 more replies)
  7 siblings, 3 replies; 39+ messages in thread
From: Feifei Wang @ 2023-02-20  8:51 UTC (permalink / raw)
  Cc: dev, david.hunt, stephen, thomas, nd, Feifei Wang

For Arm aarch, use WFE instructions to enable PMD power management.

Test Results:
dynamic instructions over 1sec	without wfe	with wfe	percentage
ampere-altra			6,298,483,712	9,117,624	-99.855%
thunderx2			6,990,909,373	3,247,226	-99.954%

When power efficient PMD is enabled by using WFE on Arm, if no pkts
received, the instructions that CPU executes is reduced by 99%.

V2:
1. move rte_wake_up API out of signal_exit(David Marchand, Thomas, Stephen)
2. Add test results when using wfe on ARM server

v3:
1. make code cleaner (Stephen)

v4:
1. add support check in API (Thomas)

v5:
1. delete v4 check patch and l3fwd-power change. This is due to
that WFE instructions can be applied into all lcores. 
When all cores are in 'WFE' state, kernal can run normally and
receive interrupt signal to send it to the l3fwd-power thread.
Thus core in 'WFE' state can exit from sleeping by interrupt event.

v6:
1. delete '__check_val_size' API in ARM to simplify the code (Stephen)

Feifei Wang (2):
  eal: add 8 bits case for wait scheme
  eal: add power mgmt support on Arm

 doc/guides/rel_notes/release_23_03.rst |  4 ++
 lib/eal/arm/include/rte_pause_64.h     | 32 +++++++++++++--
 lib/eal/arm/rte_cpuflags.c             |  5 +++
 lib/eal/arm/rte_power_intrinsics.c     | 55 ++++++++++++++++++++++++--
 4 files changed, 89 insertions(+), 7 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v6 1/2] eal: add 8 bits case for wait scheme
  2023-02-20  8:51 ` [PATCH v6 " Feifei Wang
@ 2023-02-20  8:51   ` Feifei Wang
  2023-02-20  8:51   ` [PATCH v6 2/2] eal: add power mgmt support on Arm Feifei Wang
  2023-02-20 12:07   ` [PATCH v6 0/2] Enable PMD power management " David Marchand
  2 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2023-02-20  8:51 UTC (permalink / raw)
  To: Ruifeng Wang; +Cc: dev, david.hunt, stephen, thomas, nd, Feifei Wang

For wait scheme generic helper, add 8 bits case.

Signed-off-by: Feifei Wang <feifei.wang2@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
---
 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)  \
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH v6 2/2] eal: add power mgmt support on Arm
  2023-02-20  8:51 ` [PATCH v6 " Feifei Wang
  2023-02-20  8:51   ` [PATCH v6 1/2] eal: add 8 bits case for wait scheme Feifei Wang
@ 2023-02-20  8:51   ` Feifei Wang
  2023-02-20 12:07   ` [PATCH v6 0/2] Enable PMD power management " David Marchand
  2 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2023-02-20  8:51 UTC (permalink / raw)
  To: Ruifeng Wang; +Cc: dev, david.hunt, stephen, thomas, nd, Feifei Wang

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 <feifei.wang2@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
Acked-by: David Hunt <david.hunt@intel.com>
---
 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
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH v6 0/2] Enable PMD power management on Arm
  2023-02-20  8:51 ` [PATCH v6 " Feifei Wang
  2023-02-20  8:51   ` [PATCH v6 1/2] eal: add 8 bits case for wait scheme Feifei Wang
  2023-02-20  8:51   ` [PATCH v6 2/2] eal: add power mgmt support on Arm Feifei Wang
@ 2023-02-20 12:07   ` David Marchand
  2023-02-21  2:37     ` 回复: " Feifei Wang
  2 siblings, 1 reply; 39+ messages in thread
From: David Marchand @ 2023-02-20 12:07 UTC (permalink / raw)
  To: Feifei Wang; +Cc: dev, david.hunt, stephen, thomas, nd

On Mon, Feb 20, 2023 at 9:51 AM Feifei Wang <feifei.wang2@arm.com> wrote:
>
> For Arm aarch, use WFE instructions to enable PMD power management.
>
> Test Results:
> dynamic instructions over 1sec  without wfe     with wfe        percentage
> ampere-altra                    6,298,483,712   9,117,624       -99.855%
> thunderx2                       6,990,909,373   3,247,226       -99.954%
>
> When power efficient PMD is enabled by using WFE on Arm, if no pkts
> received, the instructions that CPU executes is reduced by 99%.
>
> Feifei Wang (2):
>   eal: add 8 bits case for wait scheme
>   eal: add power mgmt support on Arm
>
>  doc/guides/rel_notes/release_23_03.rst |  4 ++
>  lib/eal/arm/include/rte_pause_64.h     | 32 +++++++++++++--
>  lib/eal/arm/rte_cpuflags.c             |  5 +++
>  lib/eal/arm/rte_power_intrinsics.c     | 55 ++++++++++++++++++++++++--
>  4 files changed, 89 insertions(+), 7 deletions(-)

Fixed release notes, squashed patches and applied, thanks.


-- 
David Marchand


^ permalink raw reply	[flat|nested] 39+ messages in thread

* 回复: [PATCH v6 0/2] Enable PMD power management on Arm
  2023-02-20 12:07   ` [PATCH v6 0/2] Enable PMD power management " David Marchand
@ 2023-02-21  2:37     ` Feifei Wang
  0 siblings, 0 replies; 39+ messages in thread
From: Feifei Wang @ 2023-02-21  2:37 UTC (permalink / raw)
  To: David Marchand; +Cc: dev, david.hunt, stephen, thomas, nd, Ruifeng Wang, nd



> -----邮件原件-----
> 发件人: David Marchand <david.marchand@redhat.com>
> 发送时间: Monday, February 20, 2023 8:07 PM
> 收件人: Feifei Wang <Feifei.Wang2@arm.com>
> 抄送: dev@dpdk.org; david.hunt@intel.com; stephen@networkplumber.org;
> thomas@monjalon.net; nd <nd@arm.com>
> 主题: Re: [PATCH v6 0/2] Enable PMD power management on Arm
> 
> On Mon, Feb 20, 2023 at 9:51 AM Feifei Wang <feifei.wang2@arm.com>
> wrote:
> >
> > For Arm aarch, use WFE instructions to enable PMD power management.
> >
> > Test Results:
> > dynamic instructions over 1sec  without wfe     with wfe        percentage
> > ampere-altra                    6,298,483,712   9,117,624       -99.855%
> > thunderx2                       6,990,909,373   3,247,226       -99.954%
> >
> > When power efficient PMD is enabled by using WFE on Arm, if no pkts
> > received, the instructions that CPU executes is reduced by 99%.
> >
> > Feifei Wang (2):
> >   eal: add 8 bits case for wait scheme
> >   eal: add power mgmt support on Arm
> >
> >  doc/guides/rel_notes/release_23_03.rst |  4 ++
> >  lib/eal/arm/include/rte_pause_64.h     | 32 +++++++++++++--
> >  lib/eal/arm/rte_cpuflags.c             |  5 +++
> >  lib/eal/arm/rte_power_intrinsics.c     | 55 ++++++++++++++++++++++++--
> >  4 files changed, 89 insertions(+), 7 deletions(-)
> 
> Fixed release notes, squashed patches and applied, thanks.
Thanks for the fix.
> 
> 
> --
> David Marchand


^ permalink raw reply	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2023-02-21  2:37 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-25  6:42 [PATCH v1 0/3] Enable PMD power management on Arm Feifei Wang
2022-08-25  6:42 ` [PATCH v1 1/3] eal: add 8 bits case for wait scheme Feifei Wang
2022-08-25  6:42 ` [PATCH v1 2/3] eal: add power mgmt support on Arm Feifei Wang
2022-08-25  6:42 ` [PATCH v1 3/3] examples/l3fwd-power: enable PMD power mgmt " Feifei Wang
2022-08-29 12:48   ` Hunt, David
2022-10-03  7:12     ` David Marchand
2022-10-11  7:56       ` 回复: " Feifei Wang
2022-10-20 20:41         ` Thomas Monjalon
2022-10-27  9:38           ` 回复: " Feifei Wang
2022-10-20 22:09   ` Stephen Hemminger
2022-10-27  9:43     ` 回复: " Feifei Wang
2022-11-07  7:04 ` [PATCH v2 0/3] Enable PMD power management " Feifei Wang
2022-11-07  7:04   ` [PATCH v2 1/3] eal: add 8 bits case for wait scheme Feifei Wang
2022-11-07  7:04   ` [PATCH v2 2/3] eal: add power mgmt support on Arm Feifei Wang
2022-11-07  7:04   ` [PATCH v2 3/3] examples/l3fwd-power: enable PMD power monitor " Feifei Wang
2022-11-07 16:01     ` Stephen Hemminger
2022-11-08  3:25       ` 回复: " Feifei Wang
2022-11-11  7:26 ` [PATCH v3 0/3] Enable PMD power management " Feifei Wang
2022-11-11  7:26   ` [PATCH v3 1/3] eal: add 8 bits case for wait scheme Feifei Wang
2022-11-11  7:26   ` [PATCH v3 2/3] eal: add power mgmt support on Arm Feifei Wang
2022-11-11  7:26   ` [PATCH v3 3/3] examples/l3fwd-power: enable PMD power monitor " Feifei Wang
2022-11-11  8:22     ` Thomas Monjalon
2022-11-11 10:21       ` 回复: " Feifei Wang
2022-11-11 10:20 ` [PATCH v4 0/4] Enable PMD power management " Feifei Wang
2022-11-11 10:20   ` [PATCH v4 1/4] eal: add 8 bits case for wait scheme Feifei Wang
2022-11-11 10:20   ` [PATCH v4 2/4] eal: add power mgmt support on Arm Feifei Wang
2022-11-11 10:20   ` [PATCH v4 3/4] power: add power monitor support check Feifei Wang
2022-11-11 10:20   ` [PATCH v4 4/4] examples/l3fwd-power: add power monitor wake up API Feifei Wang
2022-12-14  8:14 ` [PATCH v5 0/2] Enable PMD power management on Arm Feifei Wang
2022-12-14  8:14   ` [PATCH v5 1/2] eal: add 8 bits case for wait scheme Feifei Wang
2022-12-14  8:14   ` [PATCH v5 2/2] eal: add power mgmt support on Arm Feifei Wang
2023-02-17 16:23     ` Stephen Hemminger
2023-02-20  1:56       ` 回复: " Feifei Wang
2023-02-17  8:26   ` 回复: [PATCH v5 0/2] Enable PMD power management " Feifei Wang
2023-02-20  8:51 ` [PATCH v6 " Feifei Wang
2023-02-20  8:51   ` [PATCH v6 1/2] eal: add 8 bits case for wait scheme Feifei Wang
2023-02-20  8:51   ` [PATCH v6 2/2] eal: add power mgmt support on Arm Feifei Wang
2023-02-20 12:07   ` [PATCH v6 0/2] Enable PMD power management " David Marchand
2023-02-21  2:37     ` 回复: " Feifei Wang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.