aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Lezcano <daniel.lezcano@linaro.org>2019-08-02 13:34:23 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-09-03 05:33:29 -0400
commit82e430a6df7f0b5972c7fe717faffea823c6b84a (patch)
tree464c1a59817af384666f36669b3e0d5187be2ffe
parent97d3eb9da84cae0548359b0aecb8619faad003b7 (diff)
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>
-rw-r--r--drivers/powercap/idle_inject.c2
-rw-r--r--drivers/thermal/intel/intel_powerclamp.c2
-rw-r--r--include/linux/cpu.h2
-rw-r--r--kernel/sched/idle.c7
4 files changed, 7 insertions, 6 deletions
diff --git a/drivers/powercap/idle_inject.c b/drivers/powercap/idle_inject.c
index 24ff2a068978..10601f4bdf72 100644
--- a/drivers/powercap/idle_inject.c
+++ b/drivers/powercap/idle_inject.c
@@ -138,7 +138,7 @@ static void idle_inject_fn(unsigned int cpu)
138 */ 138 */
139 iit->should_run = 0; 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/**
diff --git a/drivers/thermal/intel/intel_powerclamp.c b/drivers/thermal/intel/intel_powerclamp.c
index 5149a817456b..53216dcbe173 100644
--- a/drivers/thermal/intel/intel_powerclamp.c
+++ b/drivers/thermal/intel/intel_powerclamp.c
@@ -430,7 +430,7 @@ static void clamp_idle_injection_func(struct kthread_work *work)
430 if (should_skip) 430 if (should_skip)
431 goto balance; 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
435balance: 435balance:
436 if (clamping && w_data->clamping && cpu_online(w_data->cpu)) 436 if (clamping && w_data->clamping && cpu_online(w_data->cpu))
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index fcb1386bb0d4..88dc0c653925 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -179,7 +179,7 @@ void arch_cpu_idle_dead(void);
179int cpu_report_state(int cpu); 179int cpu_report_state(int cpu);
180int cpu_check_up_prepare(int cpu); 180int cpu_check_up_prepare(int cpu);
181void cpu_set_state_online(int cpu); 181void cpu_set_state_online(int cpu);
182void play_idle(unsigned long duration_ms); 182void play_idle(unsigned long duration_us);
183 183
184#ifdef CONFIG_HOTPLUG_CPU 184#ifdef CONFIG_HOTPLUG_CPU
185bool cpu_wait_death(unsigned int cpu, int seconds); 185bool cpu_wait_death(unsigned int cpu, int seconds);
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
index 80940939b733..b98283fc6914 100644
--- a/kernel/sched/idle.c
+++ b/kernel/sched/idle.c
@@ -311,7 +311,7 @@ static enum hrtimer_restart idle_inject_timer_fn(struct hrtimer *timer)
311 return HRTIMER_NORESTART; 311 return HRTIMER_NORESTART;
312} 312}
313 313
314void play_idle(unsigned long duration_ms) 314void play_idle(unsigned long duration_us)
315{ 315{
316 struct idle_timer it; 316 struct idle_timer it;
317 317
@@ -323,7 +323,7 @@ void play_idle(unsigned long duration_ms)
323 WARN_ON_ONCE(current->nr_cpus_allowed != 1); 323 WARN_ON_ONCE(current->nr_cpus_allowed != 1);
324 WARN_ON_ONCE(!(current->flags & PF_KTHREAD)); 324 WARN_ON_ONCE(!(current->flags & PF_KTHREAD));
325 WARN_ON_ONCE(!(current->flags & PF_NO_SETAFFINITY)); 325 WARN_ON_ONCE(!(current->flags & PF_NO_SETAFFINITY));
326 WARN_ON_ONCE(!duration_ms); 326 WARN_ON_ONCE(!duration_us);
327 327
328 rcu_sleep_check(); 328 rcu_sleep_check();
329 preempt_disable(); 329 preempt_disable();
@@ -333,7 +333,8 @@ void play_idle(unsigned long duration_ms)
333 it.done = 0; 333 it.done = 0;
334 hrtimer_init_on_stack(&it.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 334 hrtimer_init_on_stack(&it.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
335 it.timer.function = idle_inject_timer_fn; 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 while (!READ_ONCE(it.done)) 339 while (!READ_ONCE(it.done))
339 do_idle(); 340 do_idle();