On 09/05/08 17:47, Li, Aubrey wrote:
> Bill.Holler wrote:
>
>
>> Can't this code can just read the TSC directly with something like
>> tsc_read(). :-) Both gethrtime() calls are done with interrupts
>> disabled on the same CPU just before and after going into
>> Deep C-State. Interrups are not enabled between the two
>> gethrtime() calls. The two TSC values will be accurate with each
>> other during this interval. A difference is computed,
>> so tsc_sync_tick_delta is not needed.
>>
>> The TSC difference will have to be scaled to nonoseconds
>> with something like tsc_scalehrtime.
>>
>>
>
> Do you mean the following change? :-)
>
Yes, this change is exactly when I meant.
> I tried it yesterday, I still saw 80%~ in C0 in powertop when system is
> idle.
> Current cstate of most cpus are also in C0. But vmstat and mpstat shows
> that idle is almost 100%(obtained from mstate). I didn't figure out
> yesterday.
>
This has me baffled too. :-0
mpstat and vmstat show the same almost 100% idle on my system.
I will not be able to look into it until tomorrow.
> Did I miss anything?
>
What is happening inside the DTRACE_PROBE1 ?
Is it using gethrtime()?
Thank you,
Bill
> Thanks,
> -Aubrey
> =================================================================
> diff -r 6adc6a654072 usr/src/uts/i86pc/io/cpudrv/cpu_idle.c
> --- a/usr/src/uts/i86pc/io/cpudrv/cpu_idle.c Thu Sep 04 13:40:03 2008
> +0800
> +++ b/usr/src/uts/i86pc/io/cpudrv/cpu_idle.c Fri Sep 05 14:00:00 2008
> +0800
> @@ -414,7 +414,7 @@
> /* DTRACE_PROBE1(idle__state__transition, uint_t,
> (uint_t)cs_type); */
> cpu_dtrace_idle_probe((uint_t)cs_type);
>
> - start = gethrtime();
> + start = tsc_read();
> (void) snprintf(mcpu->curr_cstate, KSTAT_STRLEN - 1,
> "C%d", cs_type);
> if (type == ACPI_ADR_SPACE_FIXED_HARDWARE) {
> @@ -507,9 +507,15 @@
> }
> (void) snprintf(mcpu->curr_cstate, KSTAT_STRLEN - 1,
> "C%d", CPU_ACPI_C0);
> - delta = (gethrtime() - start) / 1000ul;
> + delta = tsc_read() - start;
> /* DTRACE_PROBE1(idle__state__transition, uint_t, CPU_ACPI_C0);
> */
> cpu_dtrace_idle_probe(CPU_ACPI_C0);
> +
> + /*
> + * Convert delta in macroseconds
> + */
> + scalehrtimef(&delta);
> + delta = delta / 1000ul;
>
> /*
> * We're no longer halted
> @@ -591,13 +597,18 @@
>
> switch (cs_type) {
> case CPU_ACPI_C1:
> - start = gethrtime();
> + start = tsc_read();
> (void) snprintf(mcpu->curr_cstate, KSTAT_STRLEN - 1,
> "C%d", cs_type);
> (*CPU->shadow_idle_cpu)();
> (void) snprintf(mcpu->curr_cstate, KSTAT_STRLEN - 1,
> "C%d", CPU_ACPI_C0);
> - delta = (gethrtime() - start) / 1000ul;
> + delta = tsc_read() - start;
> + /*
> + * Convert delta in macroseconds
> + */
> + scalehrtimef(&delta);
> + delta = delta / 1000ul;
> break;
>
> case CPU_ACPI_C2:
>