[PATCH] cpuidle: teo: Use this_cpu_ptr where possible

Christian Loehle posted 1 patch 2 months, 4 weeks ago
drivers/cpuidle/governors/teo.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
[PATCH] cpuidle: teo: Use this_cpu_ptr where possible
Posted by Christian Loehle 2 months, 4 weeks ago
The cpuidle governor callbacks for update, select and reflect
are always running on the actual idle entering/exiting CPU, so
use the more optimized this_cpu_ptr() to access the internal teo
data.

This brings down the latency-critical teo_reflect() from
static void teo_reflect(struct cpuidle_device *dev, int state)
{
ffffffc080ffcff0:	hint	#0x19
ffffffc080ffcff4:	stp	x29, x30, [sp, #-48]!
	struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu);
ffffffc080ffcff8:	adrp	x2, ffffffc0848c0000 <gicv5_global_data+0x28>
{
ffffffc080ffcffc:	add	x29, sp, #0x0
ffffffc080ffd000:	stp	x19, x20, [sp, #16]
ffffffc080ffd004:	orr	x20, xzr, x0
	struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu);
ffffffc080ffd008:	add	x0, x2, #0xc20
{
ffffffc080ffd00c:	stp	x21, x22, [sp, #32]
	struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu);
ffffffc080ffd010:	adrp	x19, ffffffc083eb5000 <cpu_devices+0x78>
ffffffc080ffd014:	add	x19, x19, #0xbb0
ffffffc080ffd018:	ldr	w3, [x20, #4]

	dev->last_state_idx = state;

to

static void teo_reflect(struct cpuidle_device *dev, int state)
{
ffffffc080ffd034:	hint	#0x19
ffffffc080ffd038:	stp	x29, x30, [sp, #-48]!
ffffffc080ffd03c:	add	x29, sp, #0x0
ffffffc080ffd040:	stp	x19, x20, [sp, #16]
ffffffc080ffd044:	orr	x20, xzr, x0
	struct teo_cpu *cpu_data = this_cpu_ptr(&teo_cpus);
ffffffc080ffd048:	adrp	x19, ffffffc083eb5000 <cpu_devices+0x78>
{
ffffffc080ffd04c:	stp	x21, x22, [sp, #32]
	struct teo_cpu *cpu_data = this_cpu_ptr(&teo_cpus);
ffffffc080ffd050:	add	x19, x19, #0xbb0

	dev->last_state_idx = state;

This saves us:
	adrp    x2, ffffffc0848c0000 <gicv5_global_data+0x28>
	add     x0, x2, #0xc20
	ldr     w3, [x20, #4]

Signed-off-by: Christian Loehle <christian.loehle@arm.com>
---
 drivers/cpuidle/governors/teo.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/cpuidle/governors/teo.c b/drivers/cpuidle/governors/teo.c
index bfa55c1eab5b..a3ebc2cda093 100644
--- a/drivers/cpuidle/governors/teo.c
+++ b/drivers/cpuidle/governors/teo.c
@@ -155,7 +155,7 @@ static DEFINE_PER_CPU(struct teo_cpu, teo_cpus);
  */
 static void teo_update(struct cpuidle_driver *drv, struct cpuidle_device *dev)
 {
-	struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu);
+	struct teo_cpu *cpu_data = this_cpu_ptr(&teo_cpus);
 	int i, idx_timer = 0, idx_duration = 0;
 	s64 target_residency_ns;
 	u64 measured_ns;
@@ -268,7 +268,7 @@ static int teo_find_shallower_state(struct cpuidle_driver *drv,
 static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
 		      bool *stop_tick)
 {
-	struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu);
+	struct teo_cpu *cpu_data = this_cpu_ptr(&teo_cpus);
 	s64 latency_req = cpuidle_governor_latency_req(dev->cpu);
 	ktime_t delta_tick = TICK_NSEC / 2;
 	unsigned int idx_intercept_sum = 0;
@@ -504,7 +504,7 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
  */
 static void teo_reflect(struct cpuidle_device *dev, int state)
 {
-	struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu);
+	struct teo_cpu *cpu_data = this_cpu_ptr(&teo_cpus);
 
 	dev->last_state_idx = state;
 	if (dev->poll_time_limit ||
-- 
2.34.1
Re: [PATCH] cpuidle: teo: Use this_cpu_ptr where possible
Posted by Rafael J. Wysocki 2 months, 3 weeks ago
On Mon, Nov 10, 2025 at 1:08 PM Christian Loehle
<christian.loehle@arm.com> wrote:
>
> The cpuidle governor callbacks for update, select and reflect
> are always running on the actual idle entering/exiting CPU, so
> use the more optimized this_cpu_ptr() to access the internal teo
> data.
>
> This brings down the latency-critical teo_reflect() from
> static void teo_reflect(struct cpuidle_device *dev, int state)
> {
> ffffffc080ffcff0:       hint    #0x19
> ffffffc080ffcff4:       stp     x29, x30, [sp, #-48]!
>         struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu);
> ffffffc080ffcff8:       adrp    x2, ffffffc0848c0000 <gicv5_global_data+0x28>
> {
> ffffffc080ffcffc:       add     x29, sp, #0x0
> ffffffc080ffd000:       stp     x19, x20, [sp, #16]
> ffffffc080ffd004:       orr     x20, xzr, x0
>         struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu);
> ffffffc080ffd008:       add     x0, x2, #0xc20
> {
> ffffffc080ffd00c:       stp     x21, x22, [sp, #32]
>         struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu);
> ffffffc080ffd010:       adrp    x19, ffffffc083eb5000 <cpu_devices+0x78>
> ffffffc080ffd014:       add     x19, x19, #0xbb0
> ffffffc080ffd018:       ldr     w3, [x20, #4]
>
>         dev->last_state_idx = state;
>
> to
>
> static void teo_reflect(struct cpuidle_device *dev, int state)
> {
> ffffffc080ffd034:       hint    #0x19
> ffffffc080ffd038:       stp     x29, x30, [sp, #-48]!
> ffffffc080ffd03c:       add     x29, sp, #0x0
> ffffffc080ffd040:       stp     x19, x20, [sp, #16]
> ffffffc080ffd044:       orr     x20, xzr, x0
>         struct teo_cpu *cpu_data = this_cpu_ptr(&teo_cpus);
> ffffffc080ffd048:       adrp    x19, ffffffc083eb5000 <cpu_devices+0x78>
> {
> ffffffc080ffd04c:       stp     x21, x22, [sp, #32]
>         struct teo_cpu *cpu_data = this_cpu_ptr(&teo_cpus);
> ffffffc080ffd050:       add     x19, x19, #0xbb0
>
>         dev->last_state_idx = state;
>
> This saves us:
>         adrp    x2, ffffffc0848c0000 <gicv5_global_data+0x28>
>         add     x0, x2, #0xc20
>         ldr     w3, [x20, #4]
>
> Signed-off-by: Christian Loehle <christian.loehle@arm.com>
> ---
>  drivers/cpuidle/governors/teo.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/cpuidle/governors/teo.c b/drivers/cpuidle/governors/teo.c
> index bfa55c1eab5b..a3ebc2cda093 100644
> --- a/drivers/cpuidle/governors/teo.c
> +++ b/drivers/cpuidle/governors/teo.c
> @@ -155,7 +155,7 @@ static DEFINE_PER_CPU(struct teo_cpu, teo_cpus);
>   */
>  static void teo_update(struct cpuidle_driver *drv, struct cpuidle_device *dev)
>  {
> -       struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu);
> +       struct teo_cpu *cpu_data = this_cpu_ptr(&teo_cpus);
>         int i, idx_timer = 0, idx_duration = 0;
>         s64 target_residency_ns;
>         u64 measured_ns;
> @@ -268,7 +268,7 @@ static int teo_find_shallower_state(struct cpuidle_driver *drv,
>  static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
>                       bool *stop_tick)
>  {
> -       struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu);
> +       struct teo_cpu *cpu_data = this_cpu_ptr(&teo_cpus);
>         s64 latency_req = cpuidle_governor_latency_req(dev->cpu);
>         ktime_t delta_tick = TICK_NSEC / 2;
>         unsigned int idx_intercept_sum = 0;
> @@ -504,7 +504,7 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
>   */
>  static void teo_reflect(struct cpuidle_device *dev, int state)
>  {
> -       struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu);
> +       struct teo_cpu *cpu_data = this_cpu_ptr(&teo_cpus);
>
>         dev->last_state_idx = state;
>         if (dev->poll_time_limit ||
> --

Applied as 6.19 material, thanks!