Skip to content

Commit 5ddcc03

Browse files
AboorvaDevarajanmpe
authored andcommitted
powerpc/cpuidle: Set CPUIDLE_FLAG_POLLING for snooze state
During the comparative study of cpuidle governors, it is noticed that the menu governor does not select CEDE state in some scenarios even though when the sleep duration of the CPU exceeds the target residency of the CEDE idle state this is because the CPU exits the snooze "polling" state when snooze time limit is reached in the snooze_loop(), which is not a real wake up and it just means that the polling state selection was not adequate. cpuidle governors rely on CPUIDLE_FLAG_POLLING flag to be set for the polling states to handle the condition mentioned above. Hence, set the CPUIDLE_FLAG_POLLING flag for snooze state (polling state) in powerpc arch to make the cpuidle governor work as expected. Reference Commits: - Timeout enabled for snooze state: commit 78eaa10 ("cpuidle: powernv/pseries: Auto-promotion of snooze to deeper idle state") - commit dc2251b ("cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol") - Fix wakeup stats in governor for polling states commit 5f26bdc ("cpuidle: menu: Fix wakeup statistics updates for polling state") Signed-off-by: Aboorva Devarajan <[email protected]> Tested-by: Vishal Chourasia <[email protected]> Reviewed-by: Vaidyanathan Srinivasan <[email protected]> Reviewed-by: Vishal Chourasia <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 3ae7c96 commit 5ddcc03

File tree

2 files changed

+10
-3
lines changed

2 files changed

+10
-3
lines changed

drivers/cpuidle/cpuidle-powernv.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ static int snooze_loop(struct cpuidle_device *dev,
7676
local_irq_enable();
7777

7878
snooze_exit_time = get_tb() + get_snooze_timeout(dev, drv, index);
79+
dev->poll_time_limit = false;
7980
ppc64_runlatch_off();
8081
HMT_very_low();
8182
while (!need_resched()) {
@@ -86,6 +87,7 @@ static int snooze_loop(struct cpuidle_device *dev,
8687
* cleared to order subsequent test of need_resched().
8788
*/
8889
clear_thread_flag(TIF_POLLING_NRFLAG);
90+
dev->poll_time_limit = true;
8991
smp_mb();
9092
break;
9193
}
@@ -155,7 +157,8 @@ static struct cpuidle_state powernv_states[CPUIDLE_STATE_MAX] = {
155157
.desc = "snooze",
156158
.exit_latency = 0,
157159
.target_residency = 0,
158-
.enter = snooze_loop },
160+
.enter = snooze_loop,
161+
.flags = CPUIDLE_FLAG_POLLING },
159162
};
160163

161164
static int powernv_cpuidle_cpu_online(unsigned int cpu)

drivers/cpuidle/cpuidle-pseries.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ static int snooze_loop(struct cpuidle_device *dev,
4444
pseries_idle_prolog();
4545
local_irq_enable();
4646
snooze_exit_time = get_tb() + snooze_timeout;
47+
dev->poll_time_limit = false;
4748

4849
while (!need_resched()) {
4950
HMT_low();
@@ -54,6 +55,7 @@ static int snooze_loop(struct cpuidle_device *dev,
5455
* loop anyway. Require a barrier after polling is
5556
* cleared to order subsequent test of need_resched().
5657
*/
58+
dev->poll_time_limit = true;
5759
clear_thread_flag(TIF_POLLING_NRFLAG);
5860
smp_mb();
5961
break;
@@ -268,7 +270,8 @@ static struct cpuidle_state dedicated_states[NR_DEDICATED_STATES] = {
268270
.desc = "snooze",
269271
.exit_latency = 0,
270272
.target_residency = 0,
271-
.enter = &snooze_loop },
273+
.enter = &snooze_loop,
274+
.flags = CPUIDLE_FLAG_POLLING },
272275
{ /* CEDE */
273276
.name = "CEDE",
274277
.desc = "CEDE",
@@ -286,7 +289,8 @@ static struct cpuidle_state shared_states[] = {
286289
.desc = "snooze",
287290
.exit_latency = 0,
288291
.target_residency = 0,
289-
.enter = &snooze_loop },
292+
.enter = &snooze_loop,
293+
.flags = CPUIDLE_FLAG_POLLING },
290294
{ /* Shared Cede */
291295
.name = "Shared Cede",
292296
.desc = "Shared Cede",

0 commit comments

Comments
 (0)