Skip to content

Commit dc2251b

Browse files
committed
cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol
On some architectures the first (index 0) idle state is a polling one and it doesn't really save energy, so there is the CPUIDLE_DRIVER_STATE_START symbol allowing some pieces of cpuidle code to avoid using that state. However, this makes the code rather hard to follow. It is better to explicitly avoid the polling state, so add a new cpuidle state flag CPUIDLE_FLAG_POLLING to mark it and make the relevant code check that flag for the first state instead of using the CPUIDLE_DRIVER_STATE_START symbol. In the ACPI processor driver that cannot always rely on the state flags (like before the states table has been set up) define a new internal symbol ACPI_IDLE_STATE_START equivalent to the CPUIDLE_DRIVER_STATE_START one and drop the latter. Signed-off-by: Rafael J. Wysocki <[email protected]> Tested-by: Sudeep Holla <[email protected]> Acked-by: Daniel Lezcano <[email protected]>
1 parent 84dc414 commit dc2251b

File tree

5 files changed

+21
-24
lines changed

5 files changed

+21
-24
lines changed

drivers/acpi/processor_idle.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
4949
ACPI_MODULE_NAME("processor_idle");
5050

51+
#define ACPI_IDLE_STATE_START (IS_ENABLED(CONFIG_ARCH_HAS_CPU_RELAX) ? 1 : 0)
52+
5153
static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
5254
module_param(max_cstate, uint, 0000);
5355
static unsigned int nocst __read_mostly;
@@ -761,7 +763,7 @@ static int acpi_idle_enter(struct cpuidle_device *dev,
761763

762764
if (cx->type != ACPI_STATE_C1) {
763765
if (acpi_idle_fallback_to_c1(pr) && num_online_cpus() > 1) {
764-
index = CPUIDLE_DRIVER_STATE_START;
766+
index = ACPI_IDLE_STATE_START;
765767
cx = per_cpu(acpi_cstate[index], dev->cpu);
766768
} else if (cx->type == ACPI_STATE_C3 && pr->flags.bm_check) {
767769
if (cx->bm_sts_skip || !acpi_idle_bm_check()) {
@@ -813,7 +815,7 @@ static void acpi_idle_enter_freeze(struct cpuidle_device *dev,
813815
static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr,
814816
struct cpuidle_device *dev)
815817
{
816-
int i, count = CPUIDLE_DRIVER_STATE_START;
818+
int i, count = ACPI_IDLE_STATE_START;
817819
struct acpi_processor_cx *cx;
818820

819821
if (max_cstate == 0)
@@ -840,7 +842,7 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr,
840842

841843
static int acpi_processor_setup_cstates(struct acpi_processor *pr)
842844
{
843-
int i, count = CPUIDLE_DRIVER_STATE_START;
845+
int i, count = ACPI_IDLE_STATE_START;
844846
struct acpi_processor_cx *cx;
845847
struct cpuidle_state *state;
846848
struct cpuidle_driver *drv = &acpi_idle_driver;
@@ -1291,7 +1293,7 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
12911293
return -EINVAL;
12921294

12931295
drv->safe_state_index = -1;
1294-
for (i = CPUIDLE_DRIVER_STATE_START; i < CPUIDLE_STATE_MAX; i++) {
1296+
for (i = ACPI_IDLE_STATE_START; i < CPUIDLE_STATE_MAX; i++) {
12951297
drv->states[i].name[0] = '\0';
12961298
drv->states[i].desc[0] = '\0';
12971299
}

drivers/cpuidle/driver.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ static void poll_idle_init(struct cpuidle_driver *drv)
204204
state->power_usage = -1;
205205
state->enter = poll_idle;
206206
state->disabled = false;
207+
state->flags = CPUIDLE_FLAG_POLLING;
207208
}
208209
#else
209210
static void poll_idle_init(struct cpuidle_driver *drv) {}

drivers/cpuidle/governors/ladder.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ static int ladder_select_state(struct cpuidle_driver *drv,
6969
struct ladder_device *ldev = this_cpu_ptr(&ladder_devices);
7070
struct ladder_device_state *last_state;
7171
int last_residency, last_idx = ldev->last_state_idx;
72+
int first_idx = drv->states[0].flags & CPUIDLE_FLAG_POLLING ? 1 : 0;
7273
int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
7374

7475
/* Special case when user has set very strict latency requirement */
@@ -96,21 +97,21 @@ static int ladder_select_state(struct cpuidle_driver *drv,
9697
}
9798

9899
/* consider demotion */
99-
if (last_idx > CPUIDLE_DRIVER_STATE_START &&
100+
if (last_idx > first_idx &&
100101
(drv->states[last_idx].disabled ||
101102
dev->states_usage[last_idx].disable ||
102103
drv->states[last_idx].exit_latency > latency_req)) {
103104
int i;
104105

105-
for (i = last_idx - 1; i > CPUIDLE_DRIVER_STATE_START; i--) {
106+
for (i = last_idx - 1; i > first_idx; i--) {
106107
if (drv->states[i].exit_latency <= latency_req)
107108
break;
108109
}
109110
ladder_do_selection(ldev, last_idx, i);
110111
return i;
111112
}
112113

113-
if (last_idx > CPUIDLE_DRIVER_STATE_START &&
114+
if (last_idx > first_idx &&
114115
last_residency < last_state->threshold.demotion_time) {
115116
last_state->stats.demotion_count++;
116117
last_state->stats.promotion_count = 0;
@@ -133,13 +134,14 @@ static int ladder_enable_device(struct cpuidle_driver *drv,
133134
struct cpuidle_device *dev)
134135
{
135136
int i;
137+
int first_idx = drv->states[0].flags & CPUIDLE_FLAG_POLLING ? 1 : 0;
136138
struct ladder_device *ldev = &per_cpu(ladder_devices, dev->cpu);
137139
struct ladder_device_state *lstate;
138140
struct cpuidle_state *state;
139141

140-
ldev->last_state_idx = CPUIDLE_DRIVER_STATE_START;
142+
ldev->last_state_idx = first_idx;
141143

142-
for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) {
144+
for (i = first_idx; i < drv->state_count; i++) {
143145
state = &drv->states[i];
144146
lstate = &ldev->states[i];
145147

@@ -151,7 +153,7 @@ static int ladder_enable_device(struct cpuidle_driver *drv,
151153

152154
if (i < drv->state_count - 1)
153155
lstate->threshold.promotion_time = state->exit_latency;
154-
if (i > CPUIDLE_DRIVER_STATE_START)
156+
if (i > first_idx)
155157
lstate->threshold.demotion_time = state->exit_latency;
156158
}
157159

drivers/cpuidle/governors/menu.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,9 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
324324
expected_interval = get_typical_interval(data);
325325
expected_interval = min(expected_interval, data->next_timer_us);
326326

327-
if (CPUIDLE_DRIVER_STATE_START > 0) {
328-
struct cpuidle_state *s = &drv->states[CPUIDLE_DRIVER_STATE_START];
327+
first_idx = 0;
328+
if (drv->states[0].flags & CPUIDLE_FLAG_POLLING) {
329+
struct cpuidle_state *s = &drv->states[1];
329330
unsigned int polling_threshold;
330331

331332
/*
@@ -336,12 +337,8 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
336337
polling_threshold = max_t(unsigned int, 20, s->target_residency);
337338
if (data->next_timer_us > polling_threshold &&
338339
latency_req > s->exit_latency && !s->disabled &&
339-
!dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable)
340-
first_idx = CPUIDLE_DRIVER_STATE_START;
341-
else
342-
first_idx = CPUIDLE_DRIVER_STATE_START - 1;
343-
} else {
344-
first_idx = 0;
340+
!dev->states_usage[1].disable)
341+
first_idx = 1;
345342
}
346343

347344
/*

include/linux/cpuidle.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ struct cpuidle_state {
6363

6464
/* Idle State Flags */
6565
#define CPUIDLE_FLAG_NONE (0x00)
66+
#define CPUIDLE_FLAG_POLLING (0x01) /* polling state */
6667
#define CPUIDLE_FLAG_COUPLED (0x02) /* state applies to multiple cpus */
6768
#define CPUIDLE_FLAG_TIMER_STOP (0x04) /* timer is stopped on this state */
6869

@@ -250,12 +251,6 @@ static inline int cpuidle_register_governor(struct cpuidle_governor *gov)
250251
{return 0;}
251252
#endif
252253

253-
#ifdef CONFIG_ARCH_HAS_CPU_RELAX
254-
#define CPUIDLE_DRIVER_STATE_START 1
255-
#else
256-
#define CPUIDLE_DRIVER_STATE_START 0
257-
#endif
258-
259254
#define CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx) \
260255
({ \
261256
int __ret; \

0 commit comments

Comments
 (0)