[PATCH 5/8] cell: enable pause(0) in cpu_idle
Milton Miller
miltonm at bga.com
Sun Dec 11 03:24:58 EST 2005
Much better, Just a few more things. One cut and paste error, the rest
are more cleanups and probes of the idle code now it is in one place to
see.
On Sat Dec 10 05:04:19 EST 2005, Arnd Bergmann wrote:
> This patch enables support for pause(0) power management state
> for the Cell Broadband Processor, which is import for power efficient
> operation. The pervasive infrastructure will in the future enable
> us to introduce more functionality specific to the Cell's
> pervasive unit.
>
> This version contains fixes for a few problems found by
> Milton Miller and a fix to keep running on Cell BE DD2
> CPUs, where the hardware feature is broken.
>
> From: Maximino Aguilar <maguilar at us.ibm.com>
> Signed-off-by: Arnd Bergmann <arndb at de.ibm.com>
...
> +#include "pervasive.h"
> +
> +struct cbe_pervasive {
> + struct pmd_regs __iomem *regs;
> + int power_management_enable;
> +};
> +
> +static DEFINE_PER_CPU(struct cbe_pervasive, cbe_pervasive);
> +
> +static void pause_zero(void)
> +{
> + unsigned int multi_threading_control;
> +
> + /* Reset Thread Run Latch (latch is set in idle.c) */
runlatch_off is both here and in pause zero idle. It is turned on
below in pause_zero_idle.
> + ppc64_runlatch_off();
> +
> + local_irq_disable();
> + if (__get_cpu_var(cbe_pervasive).power_management_enable) {
> + /* Pause the PU */
> + HMT_low();
> + multi_threading_control = 0;
> + mtspr(SPRN_CTRLT,multi_threading_control);
What is the purpose of the stack variable set to 0 every loop and
only used as an argument to mtspr?
> + }
> + local_irq_disable();
oops, local_irq_enable()
> +}
> +
> +static void pause_zero_idle(void)
> +{
> + set_thread_flag(TIF_POLLING_NRFLAG);
> +
So your cpu keeps running, just slowly. (This flag says don't bother
to ipi the processor when there is work to do, it is polling waiting
for work. If you set this when you are sleeping then you will incurr
wakeup latency until the next decrementer tick.
> + while (1) {
> + if (!need_resched()) {
> + while (!need_resched()) {
> + ppc64_runlatch_off();
> + pause_zero();
> + /*
> + * Go into low thread priority and
> possibly
> + * low power mode.
> + */
> + HMT_low();
> + HMT_very_low();
Does your cpu support very_low? Can it be disabled without disabling
low? If not, only one of these is needed. The generic has both
because some older cpus did not have very_low. This code results in a
periodic bump up to low on cpus that support both.
And you set HMT_low in pauze_zero.
> + }
> +
> + HMT_medium();
> + }
> +
> + ppc64_runlatch_on();
> + preempt_enable_no_resched();
> + schedule();
> + preempt_disable();
> + }
> +}
>
Rest looks good. Thanks.
milton
More information about the Linuxppc64-dev
mailing list