Bill.Holler wrote:

> Li, Aubrey wrote:
>> Bill.Holler wrote:
>> 
>> 
>>> Li, Aubrey wrote:
>>> 
>>>> Bill.Holler wrote:
>>>> 
>>>> 
>>>> 
>>>>> Li, Aubrey wrote:
>>>>> 
>>>>> 
>>>>>> the function to place processor into deeper c-state is added.
>>>>>> 
>>>>>> I discussed with Bill about how to enter deeper c-state.
>>>>>> The ACPI documentation uses reading ACPI register address to
>>>>>> enter, while Intel Processor programming guides indicate MWAIT
>>>>>> is prefered. 
>>>>>> 
>>>>>> We know, to wake up an idle CPU, mwait just needs monitor memory
>>>>>> write. But "halt" and ACPI reading IO port need an IPI.
>>>>>> Obviously, mwait has the better performance.
>>>>>> 
>>>>>> So, here, I didn't see any advantage to follow ACPI on the
>>>>>> mwait-supported processors. The logic breaking ACPI rule in the
>>>>>> committed code is as follows: 
>>>>>> 
>>>>>> if (mwait is supported)
>>>>>>  use monitor/mwait to enter deep c-state
>>>>>> else
>>>>>>  reading IO port from ACPI
>>>>>> 
>>>>>> Of course this logic depends on the info reading from ACPI
>>>>>> objects. So disp_enq_thread doesn't need to be changed.
>>>>>> 
>>>>>> Any objects/thoughts?
>>>>>> 
>>>>>> 
>>>>>> 
>>>>> Do we have a mechanism to map ACPI c-states to/from MWAIT
>>>>> c-states? 
>>>>> 
>>>>> 
>>>> No, we don't.
>>>> 
>>>>  The Solaris idle threads will have to restore more state
>>>> 
>>>> 
>>>>> when returning from deeper ACPI c-states such as C3. The idle
>>>>> threads will need to be aware of the MWAIT<->ACPI c-state mapping.
>>>>> 
>>>>> 
>>>>> 
>>>> I think restoring job should be done in
>>>> 
>>> idle_cpu->cpu_acpi_idle, not out
>>> 
>>>> of idle_cpu
>>>> in idle thread. So mapping may not be necessary.
>>>> But correct me if I'm wrong, ;-)
>>>> 
>>>> 
>>>> 
>>> I do not understand how idle_cpu->cpu_acpi_idle or
>>> cpu_acpi_idle_mwait will know what it needs to restore?
>>> 
>> 
>> Maybe you have to explain what exactly needs to be restored in the
>> idle thread. 
>> 
> For example the APIC and TSC may need to be restored if they were
> powered off in a deep idle state.

I think this exactly could be done in idle_cpu->cpu_acpi_idle().

cpu_acpi_idle()
{
switch(cstate_type) {
case CPU_ACPI_C2/C3:
        tsc_base = read_TSC();
        apic_base = read_APIC_TIMER();
        start = read_HPET();
        /* TSC and ACPI timer lost   */
        enter_deeper_cstate();
        end = read_HPET();
        re-initialize_TSC() { TSC= tsc_base + end - start }
        re-initialize_APIC() { APIC = apic_base + end - start }
}

Does this make sense?


>>> Does Intel guaranty MWAIT eax ecx states will not map to deeper
>>> ACPI c-states than the eax value?
>>> 
>>> 
>> 
>> MWAIT Extension Register (ECX)
>> Bit0 - Treat Interrupt as break-event, even when interrupts are
>> disabled Bit31: 1 - Reserved 
>> 
>> MWAIT Hints Register (EAX)
>> Bit3 : 0 - Sub C-state within a C-state, indicated by bits [7:4]
>> Bit7 : 4 - Target C-state* Bit31 : 8 - Reserved
>> 
>> Maybe I didn't catch your point, but can the register definitions
>> answer your question? 
>> 
>> 
> Hi Aubrey,
> 
> Are we guarantied the processor will not enter a deeper idle state
> than specified by the MWAIT command?  I am confused because
> I thought the hardware could go into a deeper idle state than
> specified by the MWAIT instruction target c-state and sub c-state.
> For example if MWAIT target c-state 1 does not power off the APIC,
> are we guarantied the processor will not enter ACPI c-state where
> the TSC and APIC may be powered off?
> 

if monitor/mwait is supported, we use MWAIT to enter deeper cstate.
otherwise we'll read io port to enter deeper cstate. so mwait is not the
only code path to power off TSC and APIC.

But both of the two ways are wrapped in cpu_acpi_cx(), let's take a look
again at the above piece of pseudo code.

cpu_acpi_idle()
{
switch(cstate_type) {
case CPU_ACPI_C2/C3:
        tsc_base = read_TSC();
        apic_base = read_APIC_TIMER();
        start = read_HPET();
        /* TSC and ACPI timer lost   */
        enter_deeper_cstate(); <== cpu_acpi_cx();
        end = read_HPET();
        re-initialize_TSC() { TSC= tsc_base + end - start }
        re-initialize_APIC() { APIC = apic_base + end - start }
}

here, TSC and APIC issue will be dealt for both mwait and reading io
port ways
to enter deeper c-state.

Please correct me if I'm wrong, ;-)

Thanks,
-Aubrey

Reply via email to