Skip site navigation (1)Skip section navigation (2)
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>