On Wed, 2006-01-11 at 00:17 +0100, Dominik Brodowski wrote:
> Hi,
> 
> On Tue, Jan 10, 2006 at 12:12:56PM +0800, Shaohua Li wrote:
> > Enhancements:
> > 1. it does all policy calculation before going into idle, so other tasks
> > can be quickly scheduled after idle.
> 
> This is much more tricky:
> 
> if CONFIG_PREEMPTION isn't set, this is (mostly) correct.
> 
> IDLE:
>       acpi_processor_idle()
>       {
>               local_irq_disable()
>               ... -> pre_cx()
>               ? need_resched()
>               ENTER_CSTATE
>               local_irq_enable()
>               ... -> post_cx()
>       }
> 
> However: all calculations are done with IRQs -- needlessly -- off. All IRQs
> appearing between local_irq_disable() and ENTER_CSTATE will cause a failed
> transition, and only be handled afterwards. And that's bad for two reasons:
> firstly it took some time until we handled the IRQ, secondly because failed
> transitions into C-States cost time and power and thus energy. Therefore,
> the span between the putting IRQs off and entering the C-State must be quite
> small.
> 
> Also, if CONFIG_PREEMTPION is set, something else happens: the idle task's
> instruction pointer points right after the "local_irq_enable()" call. As
> once we enabled IRQs, we also allowed the lowest-priority idle thread to be
> preempted by any other process wanting to run. Therefore, once the system
> becomes idle, we'll first do the "->post_cx()" calculation (with IRQs
> off!) before going back to the loop which calls acpi_processor_idle()
> again, and only then IRQs are disabled, "->pre_cx()" is called, and so on.
> 
> As the behaviour is so totally different whether CONFIG_PREEMPTION is set or
> not, I'd suggest the following (untested): add a "schedule()" right after
> "local_irq_enable()". This will force the same behaviour as
> CONFIG_PREEMPTION does currently also for the !CONFIG_PREEMTPION case.
I only do bm check with irq disabled. promotion/demotion calculation is
done with irq enabled. As I said, idle currently can't be preempted at
any places.

> > It's still not very good. Comments/suggestions are highly appreciated.
> Take a look at my four patches, please, and all the tricks and tweaks they
> do ;-)
Sure, I did look at your patches. They did have many good staffs. As I
said, Len hopes smooth move, so adding a new module might be better. 

> > +   while (diff) {
> > +           /* if we didn't get called, assume there was busmaster activity 
> > */
> ... this turned out to be a bad  idea, especially with dyn ticks enabled.
I only did this when there is bus activity. With this trick, dyn ticks
works fine in my test.

> > +           diff --;
> > +           if (diff)
> > +                   pr->power.bm_activity |= 0x1;
> > +           pr->power.bm_activity <<= 1;
> > +   }
> > +
> > +   if (bm_status) {
> > +           pr->power.bm_activity++;
> |= 0x1 not ++;
Ok.

> 
> Also, the actual checking for bm_activity should be common code, e.g.
It's policy specific. Each policy could have its own method to calculate
bm_activity.

Thanks,
Shaohua


-
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to