Date: Wed, 22 Jun 2011 19:47:10 +0300 From: Andriy Gapon <avg@FreeBSD.org> To: Jung-uk Kim <jkim@FreeBSD.org> Cc: svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org Subject: Re: svn commit: r223426 - in head/sys: dev/acpica kern sys x86/x86 Message-ID: <4E021C8E.8010904@FreeBSD.org> In-Reply-To: <201106221640.p5MGejHY057164@svn.freebsd.org> References: <201106221640.p5MGejHY057164@svn.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4E021C8E.8010904>