svn commit: r223426 - in head/sys: dev/acpica kern sys x86/x86
Andriy Gapon
avg at FreeBSD.org
Wed Jun 22 16:47:14 UTC 2011
on 22/06/2011 19:40 Jung-uk Kim said the following:
> Author: jkim
> Date: Wed Jun 22 16:40:45 2011
> New Revision: 223426
> URL: http://svn.freebsd.org/changeset/base/223426
>
> Log:
> Set negative quality to TSC timecounter when C3 state is enabled for Intel
> processors unless the invariant TSC bit of CPUID is set. Intel processors
> may stop incrementing TSC when DPSLP# pin is asserted, according to Intel
> processor manuals, i. e., TSC timecounter is useless if the processor can
> enter deep sleep state (C3/C4). This problem was accidentally uncovered by
> r222869, which increased timecounter quality of P-state invariant TSC, e.g.,
> for Core2 Duo T5870 (Family 6, Model f) and Atom N270 (Family 6, Model 1c).
>
> Reported by: Fabian Keil (freebsd-listen at fabiankeil dot de)
> Ian FREISLICH (ianf at clue dot co dot za)
> Tested by: Fabian Keil (freebsd-listen at fabiankeil dot de)
> - Core2 Duo T5870 (C3 state available/enabled)
> jkim - Xeon X5150 (C3 state unavailable)
I think that this change should have a counterpart similar to what was done for
event timers. That is, if a user forces use of TSC as a timecounter vis sysctl
and it is known that TSC stops in the deep C-state, then the deep C-states should
not be entered. This is what cpu_disable_deep_sleep does for LAPIC timers.
> Modified:
> head/sys/dev/acpica/acpi_cpu.c
> head/sys/kern/kern_clocksource.c
> head/sys/sys/systm.h
> head/sys/x86/x86/tsc.c
>
> Modified: head/sys/dev/acpica/acpi_cpu.c
> ==============================================================================
> --- head/sys/dev/acpica/acpi_cpu.c Wed Jun 22 16:26:21 2011 (r223425)
> +++ head/sys/dev/acpica/acpi_cpu.c Wed Jun 22 16:40:45 2011 (r223426)
> @@ -856,6 +856,8 @@ acpi_cpu_cx_list(struct acpi_cpu_softc *
> sbuf_printf(&sb, "C%d/%d ", i + 1, sc->cpu_cx_states[i].trans_lat);
> if (sc->cpu_cx_states[i].type < ACPI_STATE_C3)
> sc->cpu_non_c3 = i;
> + else
> + cpu_can_deep_sleep = 1;
> }
> sbuf_trim(&sb);
> sbuf_finish(&sb);
>
> Modified: head/sys/kern/kern_clocksource.c
> ==============================================================================
> --- head/sys/kern/kern_clocksource.c Wed Jun 22 16:26:21 2011 (r223425)
> +++ head/sys/kern/kern_clocksource.c Wed Jun 22 16:40:45 2011 (r223426)
> @@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
> cyclic_clock_func_t cyclic_clock_func = NULL;
> #endif
>
> +int cpu_can_deep_sleep = 0; /* C3 state is available. */
> int cpu_disable_deep_sleep = 0; /* Timer dies in C3. */
>
> static void setuptimer(void);
>
> Modified: head/sys/sys/systm.h
> ==============================================================================
> --- head/sys/sys/systm.h Wed Jun 22 16:26:21 2011 (r223425)
> +++ head/sys/sys/systm.h Wed Jun 22 16:40:45 2011 (r223426)
> @@ -253,6 +253,7 @@ void cpu_startprofclock(void);
> void cpu_stopprofclock(void);
> void cpu_idleclock(void);
> void cpu_activeclock(void);
> +extern int cpu_can_deep_sleep;
> extern int cpu_disable_deep_sleep;
>
> int cr_cansee(struct ucred *u1, struct ucred *u2);
>
> Modified: head/sys/x86/x86/tsc.c
> ==============================================================================
> --- head/sys/x86/x86/tsc.c Wed Jun 22 16:26:21 2011 (r223425)
> +++ head/sys/x86/x86/tsc.c Wed Jun 22 16:40:45 2011 (r223426)
> @@ -444,6 +444,19 @@ init_TSC_tc(void)
> goto init;
> }
>
> + /*
> + * We cannot use the TSC if it stops incrementing in deep sleep.
> + * Currently only Intel CPUs are known for this problem unless
> + * the invariant TSC bit is set.
> + */
> + if (cpu_can_deep_sleep && cpu_vendor_id == CPU_VENDOR_INTEL &&
> + (amd_pminfo & AMDPM_TSC_INVARIANT) == 0) {
> + tsc_timecounter.tc_quality = -1000;
> + if (bootverbose)
> + printf("TSC timecounter disabled: C3 enabled.\n");
> + goto init;
> + }
> +
> #ifdef SMP
> /*
> * We can not use the TSC in SMP mode unless the TSCs on all CPUs are
--
Andriy Gapon
More information about the svn-src-all
mailing list