Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cpuidle: play_idle: Increase the resolution to usec

The play_idle resolution is 1ms. The intel_powerclamp bases the idle
duration on jiffies. The idle injection API is also using msec based
duration but has no user yet.

Unfortunately, msec based time does not fit well when we want to
inject idle cycle precisely with shallow idle state.

In order to set the scene for the incoming idle injection user, move
the precision up to usec when calling play_idle.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Daniel Lezcano and committed by
Rafael J. Wysocki
82e430a6 97d3eb9d

+7 -6
+1 -1
drivers/powercap/idle_inject.c
··· 138 138 */ 139 139 iit->should_run = 0; 140 140 141 - play_idle(READ_ONCE(ii_dev->idle_duration_ms)); 141 + play_idle(READ_ONCE(ii_dev->idle_duration_ms) * USEC_PER_MSEC); 142 142 } 143 143 144 144 /**
+1 -1
drivers/thermal/intel/intel_powerclamp.c
··· 430 430 if (should_skip) 431 431 goto balance; 432 432 433 - play_idle(jiffies_to_msecs(w_data->duration_jiffies)); 433 + play_idle(jiffies_to_usecs(w_data->duration_jiffies)); 434 434 435 435 balance: 436 436 if (clamping && w_data->clamping && cpu_online(w_data->cpu))
+1 -1
include/linux/cpu.h
··· 179 179 int cpu_report_state(int cpu); 180 180 int cpu_check_up_prepare(int cpu); 181 181 void cpu_set_state_online(int cpu); 182 - void play_idle(unsigned long duration_ms); 182 + void play_idle(unsigned long duration_us); 183 183 184 184 #ifdef CONFIG_HOTPLUG_CPU 185 185 bool cpu_wait_death(unsigned int cpu, int seconds);
+4 -3
kernel/sched/idle.c
··· 311 311 return HRTIMER_NORESTART; 312 312 } 313 313 314 - void play_idle(unsigned long duration_ms) 314 + void play_idle(unsigned long duration_us) 315 315 { 316 316 struct idle_timer it; 317 317 ··· 323 323 WARN_ON_ONCE(current->nr_cpus_allowed != 1); 324 324 WARN_ON_ONCE(!(current->flags & PF_KTHREAD)); 325 325 WARN_ON_ONCE(!(current->flags & PF_NO_SETAFFINITY)); 326 - WARN_ON_ONCE(!duration_ms); 326 + WARN_ON_ONCE(!duration_us); 327 327 328 328 rcu_sleep_check(); 329 329 preempt_disable(); ··· 333 333 it.done = 0; 334 334 hrtimer_init_on_stack(&it.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 335 335 it.timer.function = idle_inject_timer_fn; 336 - hrtimer_start(&it.timer, ms_to_ktime(duration_ms), HRTIMER_MODE_REL_PINNED); 336 + hrtimer_start(&it.timer, ns_to_ktime(duration_us * NSEC_PER_USEC), 337 + HRTIMER_MODE_REL_PINNED); 337 338 338 339 while (!READ_ONCE(it.done)) 339 340 do_idle();