Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Jun 2011 16:40:45 +0000 (UTC)
From:      Jung-uk Kim <jkim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r223426 - in head/sys: dev/acpica kern sys x86/x86
Message-ID:  <201106221640.p5MGejHY057164@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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)

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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106221640.p5MGejHY057164>