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: commit78eaa10f02
("cpuidle: powernv/pseries: Auto-promotion of snooze to deeper idle state") - commitdc2251bf98
("cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol") - Fix wakeup stats in governor for polling states commit5f26bdceb9
("cpuidle: menu: Fix wakeup statistics updates for polling state") Signed-off-by: Aboorva Devarajan <aboorvad@linux.vnet.ibm.com> Tested-by: Vishal Chourasia <vishalc@linux.vnet.ibm.com> Reviewed-by: Vaidyanathan Srinivasan <svaidy@linux.ibm.com> Reviewed-by: Vishal Chourasia <vishalc@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20221114145611.37669-1-aboorvad@linux.vnet.ibm.com
This commit is contained in:
parent
3ae7c96dd5
commit
5ddcc03a07
|
@ -76,6 +76,7 @@ static int snooze_loop(struct cpuidle_device *dev,
|
|||
local_irq_enable();
|
||||
|
||||
snooze_exit_time = get_tb() + get_snooze_timeout(dev, drv, index);
|
||||
dev->poll_time_limit = false;
|
||||
ppc64_runlatch_off();
|
||||
HMT_very_low();
|
||||
while (!need_resched()) {
|
||||
|
@ -86,6 +87,7 @@ static int snooze_loop(struct cpuidle_device *dev,
|
|||
* cleared to order subsequent test of need_resched().
|
||||
*/
|
||||
clear_thread_flag(TIF_POLLING_NRFLAG);
|
||||
dev->poll_time_limit = true;
|
||||
smp_mb();
|
||||
break;
|
||||
}
|
||||
|
@ -155,7 +157,8 @@ static struct cpuidle_state powernv_states[CPUIDLE_STATE_MAX] = {
|
|||
.desc = "snooze",
|
||||
.exit_latency = 0,
|
||||
.target_residency = 0,
|
||||
.enter = snooze_loop },
|
||||
.enter = snooze_loop,
|
||||
.flags = CPUIDLE_FLAG_POLLING },
|
||||
};
|
||||
|
||||
static int powernv_cpuidle_cpu_online(unsigned int cpu)
|
||||
|
|
|
@ -44,6 +44,7 @@ static int snooze_loop(struct cpuidle_device *dev,
|
|||
pseries_idle_prolog();
|
||||
local_irq_enable();
|
||||
snooze_exit_time = get_tb() + snooze_timeout;
|
||||
dev->poll_time_limit = false;
|
||||
|
||||
while (!need_resched()) {
|
||||
HMT_low();
|
||||
|
@ -54,6 +55,7 @@ static int snooze_loop(struct cpuidle_device *dev,
|
|||
* loop anyway. Require a barrier after polling is
|
||||
* cleared to order subsequent test of need_resched().
|
||||
*/
|
||||
dev->poll_time_limit = true;
|
||||
clear_thread_flag(TIF_POLLING_NRFLAG);
|
||||
smp_mb();
|
||||
break;
|
||||
|
@ -268,7 +270,8 @@ static struct cpuidle_state dedicated_states[NR_DEDICATED_STATES] = {
|
|||
.desc = "snooze",
|
||||
.exit_latency = 0,
|
||||
.target_residency = 0,
|
||||
.enter = &snooze_loop },
|
||||
.enter = &snooze_loop,
|
||||
.flags = CPUIDLE_FLAG_POLLING },
|
||||
{ /* CEDE */
|
||||
.name = "CEDE",
|
||||
.desc = "CEDE",
|
||||
|
@ -286,7 +289,8 @@ static struct cpuidle_state shared_states[] = {
|
|||
.desc = "snooze",
|
||||
.exit_latency = 0,
|
||||
.target_residency = 0,
|
||||
.enter = &snooze_loop },
|
||||
.enter = &snooze_loop,
|
||||
.flags = CPUIDLE_FLAG_POLLING },
|
||||
{ /* Shared Cede */
|
||||
.name = "Shared Cede",
|
||||
.desc = "Shared Cede",
|
||||
|
|
Loading…
Reference in New Issue