Skip to content

Commit 6221403

Browse files
committed
Merge branch 'pm-cpuidle'
* pm-cpuidle: cpuidle: Pass exit latency limit to cpuidle_use_deepest_state() cpuidle: Allow idle injection to apply exit latency limit cpuidle: Introduce cpuidle_driver_state_disabled() for driver quirks cpuidle: teo: Avoid code duplication in conditionals cpuidle: teo: Avoid using "early hits" incorrectly cpuidle: teo: Exclude cpuidle overhead from computations cpuidle: Use nanoseconds as the unit of time cpuidle: Consolidate disabled state checks ACPI: processor_idle: Skip dummy wait if kernel is in guest cpuidle: Do not unset the driver if it is there already cpuidle: teo: Fix "early hits" handling for disabled idle states cpuidle: teo: Consider hits and misses metrics of disabled states cpuidle: teo: Rename local variable in teo_select() cpuidle: teo: Ignore disabled idle states that are too deep
2 parents 05ff1ba + 5aa9ba6 commit 6221403

File tree

16 files changed

+401
-264
lines changed

16 files changed

+401
-264
lines changed

arch/arm/mach-imx/cpuidle-imx6q.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,13 @@ static struct cpuidle_driver imx6q_cpuidle_driver = {
6262
*/
6363
void imx6q_cpuidle_fec_irqs_used(void)
6464
{
65-
imx6q_cpuidle_driver.states[1].disabled = true;
65+
cpuidle_driver_state_disabled(&imx6q_cpuidle_driver, 1, true);
6666
}
6767
EXPORT_SYMBOL_GPL(imx6q_cpuidle_fec_irqs_used);
6868

6969
void imx6q_cpuidle_fec_irqs_unused(void)
7070
{
71-
imx6q_cpuidle_driver.states[1].disabled = false;
71+
cpuidle_driver_state_disabled(&imx6q_cpuidle_driver, 1, false);
7272
}
7373
EXPORT_SYMBOL_GPL(imx6q_cpuidle_fec_irqs_unused);
7474

arch/arm/mach-tegra/cpuidle-tegra20.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ void tegra20_cpuidle_pcie_irqs_in_use(void)
203203
{
204204
pr_info_once(
205205
"Disabling cpuidle LP2 state, since PCIe IRQs are in use\n");
206-
tegra_idle_driver.states[1].disabled = true;
206+
cpuidle_driver_state_disabled(&tegra_idle_driver, 1, true);
207207
}
208208

209209
int __init tegra20_cpuidle_init(void)

drivers/acpi/processor_idle.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,19 @@ static int acpi_idle_bm_check(void)
642642
return bm_status;
643643
}
644644

645+
static void wait_for_freeze(void)
646+
{
647+
#ifdef CONFIG_X86
648+
/* No delay is needed if we are in guest */
649+
if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
650+
return;
651+
#endif
652+
/* Dummy wait op - must do something useless after P_LVL2 read
653+
because chipsets cannot guarantee that STPCLK# signal
654+
gets asserted in time to freeze execution properly. */
655+
inl(acpi_gbl_FADT.xpm_timer_block.address);
656+
}
657+
645658
/**
646659
* acpi_idle_do_entry - enter idle state using the appropriate method
647660
* @cx: cstate data
@@ -658,10 +671,7 @@ static void __cpuidle acpi_idle_do_entry(struct acpi_processor_cx *cx)
658671
} else {
659672
/* IO port based C-state */
660673
inb(cx->address);
661-
/* Dummy wait op - must do something useless after P_LVL2 read
662-
because chipsets cannot guarantee that STPCLK# signal
663-
gets asserted in time to freeze execution properly. */
664-
inl(acpi_gbl_FADT.xpm_timer_block.address);
674+
wait_for_freeze();
665675
}
666676
}
667677

@@ -682,8 +692,7 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index)
682692
safe_halt();
683693
else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) {
684694
inb(cx->address);
685-
/* See comment in acpi_idle_do_entry() */
686-
inl(acpi_gbl_FADT.xpm_timer_block.address);
695+
wait_for_freeze();
687696
} else
688697
return -ENODEV;
689698
}

drivers/cpuidle/cpuidle-powernv.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,10 @@ static u64 get_snooze_timeout(struct cpuidle_device *dev,
5656
return default_snooze_timeout;
5757

5858
for (i = index + 1; i < drv->state_count; i++) {
59-
struct cpuidle_state *s = &drv->states[i];
60-
struct cpuidle_state_usage *su = &dev->states_usage[i];
61-
62-
if (s->disabled || su->disable)
59+
if (dev->states_usage[i].disable)
6360
continue;
6461

65-
return s->target_residency * tb_ticks_per_usec;
62+
return drv->states[i].target_residency * tb_ticks_per_usec;
6663
}
6764

6865
return default_snooze_timeout;

drivers/cpuidle/cpuidle.c

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -75,44 +75,45 @@ int cpuidle_play_dead(void)
7575

7676
static int find_deepest_state(struct cpuidle_driver *drv,
7777
struct cpuidle_device *dev,
78-
unsigned int max_latency,
78+
u64 max_latency_ns,
7979
unsigned int forbidden_flags,
8080
bool s2idle)
8181
{
82-
unsigned int latency_req = 0;
82+
u64 latency_req = 0;
8383
int i, ret = 0;
8484

8585
for (i = 1; i < drv->state_count; i++) {
8686
struct cpuidle_state *s = &drv->states[i];
87-
struct cpuidle_state_usage *su = &dev->states_usage[i];
8887

89-
if (s->disabled || su->disable || s->exit_latency <= latency_req
90-
|| s->exit_latency > max_latency
91-
|| (s->flags & forbidden_flags)
92-
|| (s2idle && !s->enter_s2idle))
88+
if (dev->states_usage[i].disable ||
89+
s->exit_latency_ns <= latency_req ||
90+
s->exit_latency_ns > max_latency_ns ||
91+
(s->flags & forbidden_flags) ||
92+
(s2idle && !s->enter_s2idle))
9393
continue;
9494

95-
latency_req = s->exit_latency;
95+
latency_req = s->exit_latency_ns;
9696
ret = i;
9797
}
9898
return ret;
9999
}
100100

101101
/**
102-
* cpuidle_use_deepest_state - Set/clear governor override flag.
103-
* @enable: New value of the flag.
102+
* cpuidle_use_deepest_state - Set/unset governor override mode.
103+
* @latency_limit_ns: Idle state exit latency limit (or no override if 0).
104104
*
105-
* Set/unset the current CPU to use the deepest idle state (override governors
106-
* going forward if set).
105+
* If @latency_limit_ns is nonzero, set the current CPU to use the deepest idle
106+
* state with exit latency within @latency_limit_ns (override governors going
107+
* forward), or do not override governors if it is zero.
107108
*/
108-
void cpuidle_use_deepest_state(bool enable)
109+
void cpuidle_use_deepest_state(u64 latency_limit_ns)
109110
{
110111
struct cpuidle_device *dev;
111112

112113
preempt_disable();
113114
dev = cpuidle_get_device();
114115
if (dev)
115-
dev->use_deepest_state = enable;
116+
dev->forced_idle_latency_limit_ns = latency_limit_ns;
116117
preempt_enable();
117118
}
118119

@@ -122,9 +123,10 @@ void cpuidle_use_deepest_state(bool enable)
122123
* @dev: cpuidle device for the given CPU.
123124
*/
124125
int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
125-
struct cpuidle_device *dev)
126+
struct cpuidle_device *dev,
127+
u64 latency_limit_ns)
126128
{
127-
return find_deepest_state(drv, dev, UINT_MAX, 0, false);
129+
return find_deepest_state(drv, dev, latency_limit_ns, 0, false);
128130
}
129131

130132
#ifdef CONFIG_SUSPEND
@@ -180,7 +182,7 @@ int cpuidle_enter_s2idle(struct cpuidle_driver *drv, struct cpuidle_device *dev)
180182
* that interrupts won't be enabled when it exits and allows the tick to
181183
* be frozen safely.
182184
*/
183-
index = find_deepest_state(drv, dev, UINT_MAX, 0, true);
185+
index = find_deepest_state(drv, dev, U64_MAX, 0, true);
184186
if (index > 0)
185187
enter_s2idle_proper(drv, dev, index);
186188

@@ -209,7 +211,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
209211
* CPU as a broadcast timer, this call may fail if it is not available.
210212
*/
211213
if (broadcast && tick_broadcast_enter()) {
212-
index = find_deepest_state(drv, dev, target_state->exit_latency,
214+
index = find_deepest_state(drv, dev, target_state->exit_latency_ns,
213215
CPUIDLE_FLAG_TIMER_STOP, false);
214216
if (index < 0) {
215217
default_idle_call();
@@ -247,26 +249,23 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
247249
local_irq_enable();
248250

249251
if (entered_state >= 0) {
250-
s64 diff, delay = drv->states[entered_state].exit_latency;
252+
s64 diff, delay = drv->states[entered_state].exit_latency_ns;
251253
int i;
252254

253255
/*
254256
* Update cpuidle counters
255257
* This can be moved to within driver enter routine,
256258
* but that results in multiple copies of same code.
257259
*/
258-
diff = ktime_us_delta(time_end, time_start);
259-
if (diff > INT_MAX)
260-
diff = INT_MAX;
260+
diff = ktime_sub(time_end, time_start);
261261

262-
dev->last_residency = (int)diff;
263-
dev->states_usage[entered_state].time += dev->last_residency;
262+
dev->last_residency_ns = diff;
263+
dev->states_usage[entered_state].time_ns += diff;
264264
dev->states_usage[entered_state].usage++;
265265

266-
if (diff < drv->states[entered_state].target_residency) {
266+
if (diff < drv->states[entered_state].target_residency_ns) {
267267
for (i = entered_state - 1; i >= 0; i--) {
268-
if (drv->states[i].disabled ||
269-
dev->states_usage[i].disable)
268+
if (dev->states_usage[i].disable)
270269
continue;
271270

272271
/* Shallower states are enabled, so update. */
@@ -275,22 +274,21 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
275274
}
276275
} else if (diff > delay) {
277276
for (i = entered_state + 1; i < drv->state_count; i++) {
278-
if (drv->states[i].disabled ||
279-
dev->states_usage[i].disable)
277+
if (dev->states_usage[i].disable)
280278
continue;
281279

282280
/*
283281
* Update if a deeper state would have been a
284282
* better match for the observed idle duration.
285283
*/
286-
if (diff - delay >= drv->states[i].target_residency)
284+
if (diff - delay >= drv->states[i].target_residency_ns)
287285
dev->states_usage[entered_state].below++;
288286

289287
break;
290288
}
291289
}
292290
} else {
293-
dev->last_residency = 0;
291+
dev->last_residency_ns = 0;
294292
}
295293

296294
return entered_state;
@@ -380,10 +378,10 @@ u64 cpuidle_poll_time(struct cpuidle_driver *drv,
380378

381379
limit_ns = TICK_NSEC;
382380
for (i = 1; i < drv->state_count; i++) {
383-
if (drv->states[i].disabled || dev->states_usage[i].disable)
381+
if (dev->states_usage[i].disable)
384382
continue;
385383

386-
limit_ns = (u64)drv->states[i].target_residency * NSEC_PER_USEC;
384+
limit_ns = (u64)drv->states[i].target_residency_ns;
387385
}
388386

389387
dev->poll_limit_ns = limit_ns;
@@ -554,7 +552,7 @@ static void __cpuidle_unregister_device(struct cpuidle_device *dev)
554552
static void __cpuidle_device_init(struct cpuidle_device *dev)
555553
{
556554
memset(dev->states_usage, 0, sizeof(dev->states_usage));
557-
dev->last_residency = 0;
555+
dev->last_residency_ns = 0;
558556
dev->next_hrtimer = 0;
559557
}
560558

@@ -567,12 +565,16 @@ static void __cpuidle_device_init(struct cpuidle_device *dev)
567565
*/
568566
static int __cpuidle_register_device(struct cpuidle_device *dev)
569567
{
570-
int ret;
571568
struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
569+
int i, ret;
572570

573571
if (!try_module_get(drv->owner))
574572
return -EINVAL;
575573

574+
for (i = 0; i < drv->state_count; i++)
575+
if (drv->states[i].disabled)
576+
dev->states_usage[i].disable |= CPUIDLE_STATE_DISABLED_BY_DRIVER;
577+
576578
per_cpu(cpuidle_devices, dev->cpu) = dev;
577579
list_add(&dev->device_list, &cpuidle_detected_devices);
578580

drivers/cpuidle/driver.c

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,24 +62,23 @@ static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv)
6262
* __cpuidle_set_driver - set per CPU driver variables for the given driver.
6363
* @drv: a valid pointer to a struct cpuidle_driver
6464
*
65-
* For each CPU in the driver's cpumask, unset the registered driver per CPU
66-
* to @drv.
67-
*
68-
* Returns 0 on success, -EBUSY if the CPUs have driver(s) already.
65+
* Returns 0 on success, -EBUSY if any CPU in the cpumask have a driver
66+
* different from drv already.
6967
*/
7068
static inline int __cpuidle_set_driver(struct cpuidle_driver *drv)
7169
{
7270
int cpu;
7371

7472
for_each_cpu(cpu, drv->cpumask) {
73+
struct cpuidle_driver *old_drv;
7574

76-
if (__cpuidle_get_cpu_driver(cpu)) {
77-
__cpuidle_unset_driver(drv);
75+
old_drv = __cpuidle_get_cpu_driver(cpu);
76+
if (old_drv && old_drv != drv)
7877
return -EBUSY;
79-
}
78+
}
8079

80+
for_each_cpu(cpu, drv->cpumask)
8181
per_cpu(cpuidle_drivers, cpu) = drv;
82-
}
8382

8483
return 0;
8584
}
@@ -166,16 +165,27 @@ static void __cpuidle_driver_init(struct cpuidle_driver *drv)
166165
if (!drv->cpumask)
167166
drv->cpumask = (struct cpumask *)cpu_possible_mask;
168167

169-
/*
170-
* Look for the timer stop flag in the different states, so that we know
171-
* if the broadcast timer has to be set up. The loop is in the reverse
172-
* order, because usually one of the deeper states have this flag set.
173-
*/
174-
for (i = drv->state_count - 1; i >= 0 ; i--) {
175-
if (drv->states[i].flags & CPUIDLE_FLAG_TIMER_STOP) {
168+
for (i = 0; i < drv->state_count; i++) {
169+
struct cpuidle_state *s = &drv->states[i];
170+
171+
/*
172+
* Look for the timer stop flag in the different states and if
173+
* it is found, indicate that the broadcast timer has to be set
174+
* up.
175+
*/
176+
if (s->flags & CPUIDLE_FLAG_TIMER_STOP)
176177
drv->bctimer = 1;
177-
break;
178-
}
178+
179+
/*
180+
* The core will use the target residency and exit latency
181+
* values in nanoseconds, but allow drivers to provide them in
182+
* microseconds too.
183+
*/
184+
if (s->target_residency > 0)
185+
s->target_residency_ns = s->target_residency * NSEC_PER_USEC;
186+
187+
if (s->exit_latency > 0)
188+
s->exit_latency_ns = s->exit_latency * NSEC_PER_USEC;
179189
}
180190
}
181191

@@ -379,3 +389,31 @@ void cpuidle_driver_unref(void)
379389

380390
spin_unlock(&cpuidle_driver_lock);
381391
}
392+
393+
/**
394+
* cpuidle_driver_state_disabled - Disable or enable an idle state
395+
* @drv: cpuidle driver owning the state
396+
* @idx: State index
397+
* @disable: Whether or not to disable the state
398+
*/
399+
void cpuidle_driver_state_disabled(struct cpuidle_driver *drv, int idx,
400+
bool disable)
401+
{
402+
unsigned int cpu;
403+
404+
mutex_lock(&cpuidle_lock);
405+
406+
for_each_cpu(cpu, drv->cpumask) {
407+
struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu);
408+
409+
if (!dev)
410+
continue;
411+
412+
if (disable)
413+
dev->states_usage[idx].disable |= CPUIDLE_STATE_DISABLED_BY_DRIVER;
414+
else
415+
dev->states_usage[idx].disable &= ~CPUIDLE_STATE_DISABLED_BY_DRIVER;
416+
}
417+
418+
mutex_unlock(&cpuidle_lock);
419+
}

drivers/cpuidle/governor.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,14 @@ int cpuidle_register_governor(struct cpuidle_governor *gov)
107107
* cpuidle_governor_latency_req - Compute a latency constraint for CPU
108108
* @cpu: Target CPU
109109
*/
110-
int cpuidle_governor_latency_req(unsigned int cpu)
110+
s64 cpuidle_governor_latency_req(unsigned int cpu)
111111
{
112112
int global_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
113113
struct device *device = get_cpu_device(cpu);
114114
int device_req = dev_pm_qos_raw_resume_latency(device);
115115

116-
return device_req < global_req ? device_req : global_req;
116+
if (device_req > global_req)
117+
device_req = global_req;
118+
119+
return (s64)device_req * NSEC_PER_USEC;
117120
}

0 commit comments

Comments
 (0)