diff options
author | Deepthi Dharwar <deepthi@linux.vnet.ibm.com> | 2012-10-03 14:42:18 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-10-17 19:57:24 -0400 |
commit | 8ea959a17fe6e27f7954dddad5b17b0e33f0d7ee (patch) | |
tree | e16bf4c3b7a9bbcb2822c862fccf7b1b8ab336b0 /arch/powerpc/platforms/pseries/processor_idle.c | |
parent | 817deb05df45577d4037230f2facee486c11d9df (diff) |
cpuidle/powerpc: Fix smt_snooze_delay functionality.
smt_snooze_delay was designed to delay idle loop's nap entry
in the native idle code before it got ported over to use as part of
the cpuidle framework.
A -ve value assigned to smt_snooze_delay should result in
busy looping, in other words disabling the entry to nap state.
- https://lists.ozlabs.org/pipermail/linuxppc-dev/2010-May/082450.html
This particular functionality can be achieved currently by
echo 1 > /sys/devices/system/cpu/cpu*/state1/disable
but it is broken when one assigns -ve value to the smt_snooze_delay
variable either via sysfs entry or ppc64_cpu util.
This patch aims to fix this, by disabling nap state when smt_snooze_delay
variable is set to -ve value.
Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms/pseries/processor_idle.c')
-rw-r--r-- | arch/powerpc/platforms/pseries/processor_idle.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c index 02e425aa2af8..a32d56d1f854 100644 --- a/arch/powerpc/platforms/pseries/processor_idle.c +++ b/arch/powerpc/platforms/pseries/processor_idle.c | |||
@@ -33,13 +33,6 @@ static int max_idle_state = MAX_IDLE_STATE_COUNT - 1; | |||
33 | static struct cpuidle_device __percpu *pseries_cpuidle_devices; | 33 | static struct cpuidle_device __percpu *pseries_cpuidle_devices; |
34 | static struct cpuidle_state *cpuidle_state_table; | 34 | static struct cpuidle_state *cpuidle_state_table; |
35 | 35 | ||
36 | void update_smt_snooze_delay(int snooze) | ||
37 | { | ||
38 | struct cpuidle_driver *drv = cpuidle_get_driver(); | ||
39 | if (drv) | ||
40 | drv->states[0].target_residency = snooze; | ||
41 | } | ||
42 | |||
43 | static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before) | 36 | static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before) |
44 | { | 37 | { |
45 | 38 | ||
@@ -190,6 +183,23 @@ static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = { | |||
190 | .enter = &shared_cede_loop }, | 183 | .enter = &shared_cede_loop }, |
191 | }; | 184 | }; |
192 | 185 | ||
186 | void update_smt_snooze_delay(int cpu, int residency) | ||
187 | { | ||
188 | struct cpuidle_driver *drv = cpuidle_get_driver(); | ||
189 | struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu); | ||
190 | |||
191 | if (cpuidle_state_table != dedicated_states) | ||
192 | return; | ||
193 | |||
194 | if (residency < 0) { | ||
195 | /* Disable the Nap state on that cpu */ | ||
196 | if (dev) | ||
197 | dev->states_usage[1].disable = 1; | ||
198 | } else | ||
199 | if (drv) | ||
200 | drv->states[0].target_residency = residency; | ||
201 | } | ||
202 | |||
193 | static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n, | 203 | static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n, |
194 | unsigned long action, void *hcpu) | 204 | unsigned long action, void *hcpu) |
195 | { | 205 | { |