On Wednesday 22 June 2011 12:47 pm, Andriy Gapon wrote:
> 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.

Can you please review/test the attached patch?  Also available from 
here:

http://people.freebsd.org/~jkim/tc_c3stop.diff

Thanks!

Jung-uk Kim
Index: sys/kern/kern_tc.c
===================================================================
--- sys/kern/kern_tc.c  (revision 223426)
+++ sys/kern/kern_tc.c  (working copy)
@@ -492,6 +492,10 @@ tc_windup(void)
 
        /* Now is a good time to change timecounters. */
        if (th->th_counter != timecounter) {
+               if ((timecounter->tc_flags & TC_FLAGS_C3STOP) != 0)
+                       cpu_disable_deep_sleep++;
+               if ((th->th_counter->tc_flags & TC_FLAGS_C3STOP) != 0)
+                       cpu_disable_deep_sleep--;
                th->th_counter = timecounter;
                th->th_offset_count = ncount;
                tc_min_ticktock_freq = max(1, timecounter->tc_frequency /
Index: sys/sparc64/sparc64/counter.c
===================================================================
--- sys/sparc64/sparc64/counter.c       (revision 223426)
+++ sys/sparc64/sparc64/counter.c       (working copy)
@@ -98,6 +98,7 @@ sparc64_counter_init(const char *name, bus_space_t
        tc->tc_name = strdup(name, M_DEVBUF);
        tc->tc_priv = sc;
        tc->tc_quality = COUNTER_QUALITY;
+       tc->tc_flags = 0;
        tc_init(tc);
 }
 
Index: sys/sys/timetc.h
===================================================================
--- sys/sys/timetc.h    (revision 223426)
+++ sys/sys/timetc.h    (working copy)
@@ -57,6 +57,8 @@ struct timecounter {
                 * another timecounter higher means better.  Negative
                 * means "only use at explicit request".
                 */
+       u_int                   tc_flags;
+#define        TC_FLAGS_C3STOP         1       /* Timer dies in C3. */
 
        void                    *tc_priv;
                /* Pointer to the timecounter's private parts. */
Index: sys/x86/x86/tsc.c
===================================================================
--- sys/x86/x86/tsc.c   (revision 223426)
+++ sys/x86/x86/tsc.c   (working copy)
@@ -451,6 +451,7 @@ init_TSC_tc(void)
         */
        if (cpu_can_deep_sleep && cpu_vendor_id == CPU_VENDOR_INTEL &&
            (amd_pminfo & AMDPM_TSC_INVARIANT) == 0) {
+               tsc_timecounter.tc_flags |= TC_FLAGS_C3STOP;
                tsc_timecounter.tc_quality = -1000;
                if (bootverbose)
                        printf("TSC timecounter disabled: C3 enabled.\n");
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to